mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-04 10:54:24 -04:00
initial xfile pass
This commit is contained in:
parent
16b5c0f9ee
commit
5250719a11
23
pandatool/src/xfile/Sources.pp
Normal file
23
pandatool/src/xfile/Sources.pp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
#define DIRECTORY_IF_DX yes
|
||||||
|
#define USE_DX yes
|
||||||
|
|
||||||
|
#begin bin_target
|
||||||
|
#define TARGET egg2x
|
||||||
|
#define LOCAL_LIBS eggbase progbase pandatoolbase
|
||||||
|
#define OTHER_LIBS \
|
||||||
|
egg:c pandaegg:m \
|
||||||
|
mathutil:c linmath:c putil:c panda:m \
|
||||||
|
express:c pandaexpress:m \
|
||||||
|
dtoolconfig dtool pystub \
|
||||||
|
|
||||||
|
#define WIN_SYS_LIBS \
|
||||||
|
d3dxof.lib
|
||||||
|
|
||||||
|
#define SOURCES \
|
||||||
|
xFileMaker.cxx xFileMaker.h
|
||||||
|
|
||||||
|
#define SOURCES \
|
||||||
|
$[SOURCES] \
|
||||||
|
eggToX.cxx eggToX.h
|
||||||
|
|
||||||
|
#end bin_target
|
134
pandatool/src/xfile/bam2x.cxx
Normal file
134
pandatool/src/xfile/bam2x.cxx
Normal file
@ -0,0 +1,134 @@
|
|||||||
|
// Filename: bamInfo.cxx
|
||||||
|
// Created by: drose (19Jun01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "bam2x.h"
|
||||||
|
|
||||||
|
#include <bamFile.h>
|
||||||
|
#include <node.h>
|
||||||
|
#include <renderRelation.h>
|
||||||
|
#include <geomNode.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Bam2X::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
Bam2X::
|
||||||
|
Bam2X() : WithOutputFile(true, false, true) {
|
||||||
|
set_program_description
|
||||||
|
("This program reads a Bam file and outputs an equivalent, "
|
||||||
|
"or nearly equivalent, DirectX-style .x file. Meshes as generated "
|
||||||
|
"by the Panda mesher are preserved, but advanced features like "
|
||||||
|
"LOD's and characters cannot be supported.");
|
||||||
|
|
||||||
|
clear_runlines();
|
||||||
|
add_runline("[opts] input.bam output.x");
|
||||||
|
add_runline("[opts] -o output.x input.bam");
|
||||||
|
|
||||||
|
add_option
|
||||||
|
("o", "filename", 50,
|
||||||
|
"Specify the filename to which the resulting .x file will be written. "
|
||||||
|
"If this option is omitted, the last parameter name is taken to be the "
|
||||||
|
"name of the output file.",
|
||||||
|
&Bam2X::dispatch_filename, &_got_output_filename, &_output_filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Bam2X::run
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Bam2X::
|
||||||
|
run() {
|
||||||
|
BamFile bam_file;
|
||||||
|
|
||||||
|
if (!bam_file.open_read(_input_filename)) {
|
||||||
|
nout << "Unable to read.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef vector<TypedWritable *> Objects;
|
||||||
|
Objects objects;
|
||||||
|
TypedWritable *object = bam_file.read_object();
|
||||||
|
while (object != (TypedWritable *)NULL || !bam_file.is_eof()) {
|
||||||
|
if (object != (TypedWritable *)NULL) {
|
||||||
|
objects.push_back(object);
|
||||||
|
}
|
||||||
|
object = bam_file.read_object();
|
||||||
|
}
|
||||||
|
bam_file.resolve();
|
||||||
|
bam_file.close();
|
||||||
|
|
||||||
|
if (objects.size() == 1 && objects[0]->is_of_type(Node::get_class_type())) {
|
||||||
|
convert_scene_graph(DCAST(Node, objects[0]));
|
||||||
|
} else {
|
||||||
|
nout << _input_filename << " does not contain a scene graph.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Bam2X::handle_args
|
||||||
|
// Access: Protected, Virtual
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool Bam2X::
|
||||||
|
handle_args(ProgramBase::Args &args) {
|
||||||
|
if (!check_last_arg(args, 1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (args.size() != 1) {
|
||||||
|
nout << "You must specify one Bam file to read on the command line.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
_input_filename = args[0];
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
Bam2X prog;
|
||||||
|
prog.parse_command_line(argc, argv);
|
||||||
|
prog.run();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: Bam2X::convert_scene_graph
|
||||||
|
// Access: Private
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void Bam2X::
|
||||||
|
convert_scene_graph(Node *root) {
|
||||||
|
nout << "Got root: " << *root << "\n";
|
||||||
|
|
||||||
|
if (!_x.open(get_output_filename())) {
|
||||||
|
nout << "Unable to open " << get_output_filename() << " for output.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
if (!_x.add_node(root)) {
|
||||||
|
nout << "Unable to add " << *root << " to output.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
_x.close();
|
||||||
|
}
|
53
pandatool/src/xfile/bam2x.h
Normal file
53
pandatool/src/xfile/bam2x.h
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
// Filename: bam2X.h
|
||||||
|
// Created by: drose (19Jun01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef BAM2X_H
|
||||||
|
#define BAM2X_H
|
||||||
|
|
||||||
|
#include <pandatoolbase.h>
|
||||||
|
#include "xFileMaker.h"
|
||||||
|
|
||||||
|
#include <programBase.h>
|
||||||
|
#include <withOutputFile.h>
|
||||||
|
#include <filename.h>
|
||||||
|
|
||||||
|
class Node;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : Bam2X
|
||||||
|
// Description : A program to read in a bam file and write an
|
||||||
|
// equivalent, or nearly equivalent, DirectX-style "x"
|
||||||
|
// file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class Bam2X : public ProgramBase, public WithOutputFile {
|
||||||
|
public:
|
||||||
|
Bam2X();
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
virtual bool handle_args(Args &args);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void convert_scene_graph(Node *root);
|
||||||
|
|
||||||
|
Filename _input_filename;
|
||||||
|
XFileMaker _x;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
67
pandatool/src/xfile/eggToX.cxx
Normal file
67
pandatool/src/xfile/eggToX.cxx
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
// Filename: eggToX.cxx
|
||||||
|
// Created by: drose (19Jun01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "eggToX.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggToX::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
EggToX::
|
||||||
|
EggToX() : EggToSomething("DirectX", "x") {
|
||||||
|
set_program_description
|
||||||
|
("This program reads an Egg file and outputs an equivalent, "
|
||||||
|
"or nearly equivalent, DirectX-style .x file. Only simple "
|
||||||
|
"hierarchy and polygon meshes are supported; advanced features "
|
||||||
|
"like LOD's, decals, and characters cannot be supported.");
|
||||||
|
|
||||||
|
// X files are always y-up-left.
|
||||||
|
remove_option("cs");
|
||||||
|
_got_coordinate_system = true;
|
||||||
|
_coordinate_system = CS_yup_left;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: EggToX::run
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void EggToX::
|
||||||
|
run() {
|
||||||
|
if (!_x.open(get_output_filename())) {
|
||||||
|
nout << "Unable to open " << get_output_filename() << " for output.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!_x.add_tree(_data)) {
|
||||||
|
nout << "Unable to define egg structure.\n";
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
_x.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
|
EggToX prog;
|
||||||
|
prog.parse_command_line(argc, argv);
|
||||||
|
prog.run();
|
||||||
|
return 0;
|
||||||
|
}
|
51
pandatool/src/xfile/eggToX.h
Normal file
51
pandatool/src/xfile/eggToX.h
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
// Filename: eggToX.h
|
||||||
|
// Created by: drose (19Jun01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef EGGTOX_H
|
||||||
|
#define EGGTOX_H
|
||||||
|
|
||||||
|
#include "pandatoolbase.h"
|
||||||
|
#include "eggToSomething.h"
|
||||||
|
#include "xFileMaker.h"
|
||||||
|
|
||||||
|
#include <programBase.h>
|
||||||
|
#include <withOutputFile.h>
|
||||||
|
#include <filename.h>
|
||||||
|
|
||||||
|
class Node;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : EggToX
|
||||||
|
// Description : A program to read in a egg file and write an
|
||||||
|
// equivalent, or nearly equivalent, DirectX-style "x"
|
||||||
|
// file.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class EggToX : public EggToSomething {
|
||||||
|
public:
|
||||||
|
EggToX();
|
||||||
|
|
||||||
|
void run();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void convert_scene_graph(Node *root);
|
||||||
|
|
||||||
|
Filename _input_filename;
|
||||||
|
XFileMaker _x;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
413
pandatool/src/xfile/xFileMaker.cxx
Normal file
413
pandatool/src/xfile/xFileMaker.cxx
Normal file
@ -0,0 +1,413 @@
|
|||||||
|
// Filename: xFileMaker.cxx
|
||||||
|
// Created by: drose (19Jun01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "xFileMaker.h"
|
||||||
|
#include "notify.h"
|
||||||
|
#include "eggGroupNode.h"
|
||||||
|
#include "eggGroup.h"
|
||||||
|
#include "eggBin.h"
|
||||||
|
#include "eggPolysetMaker.h"
|
||||||
|
#include "eggVertexPool.h"
|
||||||
|
#include "eggVertex.h"
|
||||||
|
#include "eggPolygon.h"
|
||||||
|
#include "eggData.h"
|
||||||
|
#include "pvector.h"
|
||||||
|
#include "vector_int.h"
|
||||||
|
#include "string_utils.h"
|
||||||
|
|
||||||
|
// This must be included only in exactly one .cxx file, since
|
||||||
|
// including defines the structure!
|
||||||
|
#include <rmxftmpl.h>
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
XFileMaker::
|
||||||
|
XFileMaker() {
|
||||||
|
_dx_file = NULL;
|
||||||
|
_dx_file_save = NULL;
|
||||||
|
_mesh_index = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::Destructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
XFileMaker::
|
||||||
|
~XFileMaker() {
|
||||||
|
close();
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::open
|
||||||
|
// Access: Public
|
||||||
|
// Description: Opens the indicated filename for writing, and writes
|
||||||
|
// the .x header information; returns true on success,
|
||||||
|
// false otherwise.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileMaker::
|
||||||
|
open(const Filename &filename) {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
close();
|
||||||
|
hr = DirectXFileCreate(&_dx_file);
|
||||||
|
if (hr != DXFILE_OK) {
|
||||||
|
nout << "Unable to create X interface.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Register our templates.
|
||||||
|
hr = _dx_file->RegisterTemplates(D3DRM_XTEMPLATES, D3DRM_XTEMPLATE_BYTES);
|
||||||
|
if (hr != DXFILE_OK) {
|
||||||
|
nout << "Unable to register templates.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
string os_file = filename.to_os_specific();
|
||||||
|
hr = _dx_file->CreateSaveObject(os_file.c_str(), DXFILEFORMAT_TEXT,
|
||||||
|
&_dx_file_save);
|
||||||
|
if (hr != DXFILE_OK) {
|
||||||
|
nout << "Unable to open X file: " << os_file << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Save the templates we will use.
|
||||||
|
static const GUID *temps[] = {
|
||||||
|
&TID_D3DRMVector,
|
||||||
|
&TID_D3DRMMeshFace,
|
||||||
|
&TID_D3DRMMesh,
|
||||||
|
&TID_D3DRMFrame,
|
||||||
|
};
|
||||||
|
static const int num_temps = sizeof(temps) / sizeof(temps[0]);
|
||||||
|
hr = _dx_file_save->SaveTemplates(num_temps, temps);
|
||||||
|
if (hr != DXFILE_OK) {
|
||||||
|
nout << "Unable to save templates.\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::close
|
||||||
|
// Access: Public
|
||||||
|
// Description: Finalizes and closes the file previously opened via
|
||||||
|
// open().
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void XFileMaker::
|
||||||
|
close() {
|
||||||
|
if (_dx_file != NULL) {
|
||||||
|
if (_dx_file_save != NULL) {
|
||||||
|
_dx_file_save->Release();
|
||||||
|
_dx_file_save = NULL;
|
||||||
|
}
|
||||||
|
_dx_file->Release();
|
||||||
|
_dx_file = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::add_tree
|
||||||
|
// Access: Public
|
||||||
|
// Description: Adds the egg tree rooted at the indicated node to the
|
||||||
|
// DX structure. This may be somewhat destructive of
|
||||||
|
// the egg tree. Returns true on success, false on
|
||||||
|
// failure.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileMaker::
|
||||||
|
add_tree(EggData &egg_data) {
|
||||||
|
// Now collect all the polygons together into polysets.
|
||||||
|
EggPolysetMaker pmaker;
|
||||||
|
int num_bins = pmaker.make_bins(&egg_data);
|
||||||
|
|
||||||
|
// And now we're ready to traverse the egg hierarchy.
|
||||||
|
return add_node(&egg_data, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::add_node
|
||||||
|
// Access: Private
|
||||||
|
// Description: Adds the node to the DX structure, in whatever form
|
||||||
|
// it is supported.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileMaker::
|
||||||
|
add_node(EggNode *egg_node, LPDIRECTXFILEDATA dx_parent) {
|
||||||
|
if (egg_node->is_of_type(EggBin::get_class_type())) {
|
||||||
|
return add_bin(DCAST(EggBin, egg_node), dx_parent);
|
||||||
|
|
||||||
|
} else if (egg_node->is_of_type(EggGroup::get_class_type())) {
|
||||||
|
return add_group(DCAST(EggGroup, egg_node), dx_parent);
|
||||||
|
|
||||||
|
} else if (egg_node->is_of_type(EggGroupNode::get_class_type())) {
|
||||||
|
// A grouping node of some kind.
|
||||||
|
EggGroupNode *egg_group = DCAST(EggGroupNode, egg_node);
|
||||||
|
LPDIRECTXFILEDATA data;
|
||||||
|
if (!create_frame(data, egg_group->get_name())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!recurse_nodes(egg_group, data)) {
|
||||||
|
data->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attach_and_release(data, dx_parent)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Some unsupported node type. Ignore it.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::add_group
|
||||||
|
// Access: Private
|
||||||
|
// Description: Adds a frame for the indicated group node.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileMaker::
|
||||||
|
add_group(EggGroup *egg_group, LPDIRECTXFILEDATA dx_parent) {
|
||||||
|
LPDIRECTXFILEDATA data;
|
||||||
|
if (!create_frame(data, egg_group->get_name())) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!recurse_nodes(egg_group, data)) {
|
||||||
|
data->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attach_and_release(data, dx_parent)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::add_bin
|
||||||
|
// Access: Private
|
||||||
|
// Description: Determines what kind of object needs to be added for
|
||||||
|
// the indicated bin node.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileMaker::
|
||||||
|
add_bin(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent) {
|
||||||
|
switch (egg_bin->get_bin_number()) {
|
||||||
|
case EggPolysetMaker::BN_polyset:
|
||||||
|
return add_polyset(egg_bin, dx_parent);
|
||||||
|
}
|
||||||
|
|
||||||
|
cerr << "Unexpected bin type " << egg_bin->get_bin_number() << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::add_polyset
|
||||||
|
// Access: Private
|
||||||
|
// Description: Adds a mesh object corresponding to the collection of
|
||||||
|
// polygons within the indicated bin.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileMaker::
|
||||||
|
add_polyset(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent) {
|
||||||
|
// Make sure that all our polygons are reasonable.
|
||||||
|
egg_bin->remove_invalid_primitives();
|
||||||
|
|
||||||
|
// First, we need to collect all the common vertices for the
|
||||||
|
// polygons in this polyset. We can do this fairly easily using a
|
||||||
|
// vertex pool.
|
||||||
|
PT(EggVertexPool) vpool = new EggVertexPool("");
|
||||||
|
|
||||||
|
int num_polys = 0;
|
||||||
|
|
||||||
|
EggGroupNode::iterator ci;
|
||||||
|
for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
|
||||||
|
EggPolygon *poly;
|
||||||
|
DCAST_INTO_R(poly, *ci, false);
|
||||||
|
|
||||||
|
// A temporary holder for the newly converted vertices of the
|
||||||
|
// polygon.
|
||||||
|
PT(EggPolygon) vertex_holder = new EggPolygon;
|
||||||
|
|
||||||
|
num_polys++;
|
||||||
|
EggPolygon::iterator vi;
|
||||||
|
for (vi = poly->begin(); vi != poly->end(); ++vi) {
|
||||||
|
// Make a copy of the polygon's original vertex.
|
||||||
|
PT(EggVertex) vtx_copy = new EggVertex(*(*vi));
|
||||||
|
|
||||||
|
// Now change the properties on the vertex as appropriate to our
|
||||||
|
// mesh.
|
||||||
|
if (!vtx_copy->has_color()) {
|
||||||
|
vtx_copy->set_color(poly->get_color());
|
||||||
|
}
|
||||||
|
vtx_copy->_dnormals.clear();
|
||||||
|
vtx_copy->_duvs.clear();
|
||||||
|
vtx_copy->_drgbas.clear();
|
||||||
|
vtx_copy->_dxyzs.clear();
|
||||||
|
|
||||||
|
// And create the unique vertex.
|
||||||
|
EggVertex *vtx = vpool->create_unique_vertex(*vtx_copy);
|
||||||
|
vertex_holder->add_vertex(vtx);
|
||||||
|
}
|
||||||
|
|
||||||
|
poly->copy_vertices(*vertex_holder);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now create the raw data for the Mesh object.
|
||||||
|
int highest_index = vpool->get_highest_index();
|
||||||
|
Datagram raw_data;
|
||||||
|
raw_data.add_int32(highest_index);
|
||||||
|
for (int i = 1; i <= highest_index; i++) {
|
||||||
|
EggVertex *vtx = vpool->get_vertex(i);
|
||||||
|
nassertr(vtx != (EggVertex *)NULL, false);
|
||||||
|
Vertexd pos = vtx->get_pos3();
|
||||||
|
raw_data.add_float32(pos[0]);
|
||||||
|
raw_data.add_float32(pos[1]);
|
||||||
|
raw_data.add_float32(pos[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
raw_data.add_int32(num_polys);
|
||||||
|
for (ci = egg_bin->begin(); ci != egg_bin->end(); ++ci) {
|
||||||
|
EggPolygon *poly;
|
||||||
|
DCAST_INTO_R(poly, *ci, false);
|
||||||
|
|
||||||
|
raw_data.add_int32(poly->size());
|
||||||
|
EggPolygon::reverse_iterator vi;
|
||||||
|
for (vi = poly->rbegin(); vi != poly->rend(); ++vi) {
|
||||||
|
int index = (*vi)->get_index();
|
||||||
|
raw_data.add_int32(index - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, create the Mesh object.
|
||||||
|
HRESULT hr;
|
||||||
|
LPDIRECTXFILEDATA data;
|
||||||
|
|
||||||
|
string name = "mesh" + format_string(_mesh_index);
|
||||||
|
_mesh_index++;
|
||||||
|
|
||||||
|
hr = _dx_file_save->CreateDataObject
|
||||||
|
(TID_D3DRMMesh, name.c_str(), NULL,
|
||||||
|
raw_data.get_length(), (void *)raw_data.get_data(),
|
||||||
|
&data);
|
||||||
|
if (hr != DXFILE_OK) {
|
||||||
|
nout << "Unable to create Mesh object\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!attach_and_release(data, dx_parent)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::recurse_nodes
|
||||||
|
// Access: Private
|
||||||
|
// Description: Adds each child of the indicated Node as a child of
|
||||||
|
// the indicated DX object.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileMaker::
|
||||||
|
recurse_nodes(EggGroupNode *egg_node, LPDIRECTXFILEDATA dx_parent) {
|
||||||
|
EggGroupNode::iterator ci;
|
||||||
|
for (ci = egg_node->begin(); ci != egg_node->end(); ++ci) {
|
||||||
|
EggNode *node = (*ci);
|
||||||
|
if (!add_node(node, dx_parent)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::create_frame
|
||||||
|
// Access: Private
|
||||||
|
// Description: Creates a "frame" object with the indicated name.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileMaker::
|
||||||
|
create_frame(LPDIRECTXFILEDATA &data, const string &name) {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
string nice_name = make_nice_name(name);
|
||||||
|
hr = _dx_file_save->CreateDataObject
|
||||||
|
(TID_D3DRMFrame, nice_name.c_str(), NULL, 0, NULL, &data);
|
||||||
|
if (hr != DXFILE_OK) {
|
||||||
|
nout << "Unable to create frame object for " << name << "\n";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::attach_and_release
|
||||||
|
// Access: Private
|
||||||
|
// Description: Assigns the indicated X data object to the indicated
|
||||||
|
// parent, and releases the pointer.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileMaker::
|
||||||
|
attach_and_release(LPDIRECTXFILEDATA data, LPDIRECTXFILEDATA dx_parent) {
|
||||||
|
HRESULT hr;
|
||||||
|
|
||||||
|
if (dx_parent == NULL) {
|
||||||
|
// No parent; it's a toplevel object.
|
||||||
|
hr = _dx_file_save->SaveData(data);
|
||||||
|
if (hr != DXFILE_OK) {
|
||||||
|
nout << "Unable to save data object\n";
|
||||||
|
data->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Got a parent; it's a child of the indicated object.
|
||||||
|
hr = dx_parent->AddDataObject(data);
|
||||||
|
if (hr != DXFILE_OK) {
|
||||||
|
nout << "Unable to save data object\n";
|
||||||
|
data->Release();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
data->Release();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileMaker::make_nice_name
|
||||||
|
// Access: Private, Static
|
||||||
|
// Description: Transforms the indicated egg name to a name that is
|
||||||
|
// acceptable to the DirectX format.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
string XFileMaker::
|
||||||
|
make_nice_name(const string &str) {
|
||||||
|
string result;
|
||||||
|
|
||||||
|
string::const_iterator si;
|
||||||
|
for (si = str.begin(); si != str.end(); ++si) {
|
||||||
|
if (isalnum(*si)) {
|
||||||
|
result += *si;
|
||||||
|
} else {
|
||||||
|
result += "_";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
73
pandatool/src/xfile/xFileMaker.h
Normal file
73
pandatool/src/xfile/xFileMaker.h
Normal file
@ -0,0 +1,73 @@
|
|||||||
|
// Filename: xFileMaker.h
|
||||||
|
// Created by: drose (19Jun01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef XFILEMAKER_H
|
||||||
|
#define XFILEMAKER_H
|
||||||
|
|
||||||
|
#include <pandatoolbase.h>
|
||||||
|
|
||||||
|
#include <filename.h>
|
||||||
|
|
||||||
|
#define WIN32_LEAN_AND_MEAN
|
||||||
|
#include <windows.h>
|
||||||
|
#include <d3d.h>
|
||||||
|
#include <dxfile.h>
|
||||||
|
#include <rmxfguid.h>
|
||||||
|
#undef WIN32_LEAN_AND_MEAN
|
||||||
|
|
||||||
|
class EggNode;
|
||||||
|
class EggGroupNode;
|
||||||
|
class EggGroup;
|
||||||
|
class EggBin;
|
||||||
|
class EggData;
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : XFileMaker
|
||||||
|
// Description : This class converts a Panda scene graph into a .X
|
||||||
|
// file and writes it out.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class XFileMaker {
|
||||||
|
public:
|
||||||
|
XFileMaker();
|
||||||
|
~XFileMaker();
|
||||||
|
|
||||||
|
bool open(const Filename &filename);
|
||||||
|
void close();
|
||||||
|
|
||||||
|
bool add_tree(EggData &egg_data);
|
||||||
|
|
||||||
|
private:
|
||||||
|
bool add_node(EggNode *egg_node, LPDIRECTXFILEDATA dx_parent);
|
||||||
|
bool add_group(EggGroup *egg_group, LPDIRECTXFILEDATA dx_parent);
|
||||||
|
bool add_bin(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent);
|
||||||
|
bool add_polyset(EggBin *egg_bin, LPDIRECTXFILEDATA dx_parent);
|
||||||
|
|
||||||
|
bool recurse_nodes(EggGroupNode *egg_node, LPDIRECTXFILEDATA dx_parent);
|
||||||
|
bool create_frame(LPDIRECTXFILEDATA &data, const string &name);
|
||||||
|
bool attach_and_release(LPDIRECTXFILEDATA data, LPDIRECTXFILEDATA dx_parent);
|
||||||
|
|
||||||
|
static string make_nice_name(const string &str);
|
||||||
|
|
||||||
|
LPDIRECTXFILE _dx_file;
|
||||||
|
LPDIRECTXFILESAVEOBJECT _dx_file_save;
|
||||||
|
|
||||||
|
int _mesh_index;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
84
pandatool/src/xfile/xFileVertex.cxx
Normal file
84
pandatool/src/xfile/xFileVertex.cxx
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
// Filename: xFileVertex.cxx
|
||||||
|
// Created by: drose (19Jun01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#include "xFileVertex.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileVertex::Constructor
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
XFileVertex::
|
||||||
|
XFileVertex(const Vertexf &point) :
|
||||||
|
_point(point),
|
||||||
|
_normal(0.0, 0.0, 0.0),
|
||||||
|
_uv(0.0, 0.0),
|
||||||
|
_color(1.0, 1.0, 1.0, 1.0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileVertex::set_normal
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void XFileVertex::
|
||||||
|
set_normal(const Normalf &normal) {
|
||||||
|
_normal = normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileVertex::set_uv
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void XFileVertex::
|
||||||
|
set_uv(const TexCoordf &uv) {
|
||||||
|
_uv = uv;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileVertex::set_color
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
void XFileVertex::
|
||||||
|
set_color(const Colorf &color) {
|
||||||
|
_color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Function: XFileVertex::Ordering Operator
|
||||||
|
// Access: Public
|
||||||
|
// Description:
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
bool XFileVertex::
|
||||||
|
operator < (const XFileVertex &other) const {
|
||||||
|
int ct;
|
||||||
|
ct = _point.compare_to(other._point);
|
||||||
|
if (ct == 0) {
|
||||||
|
ct = _normal.compare_to(other._normal);
|
||||||
|
}
|
||||||
|
if (ct == 0) {
|
||||||
|
ct = _uv.compare_to(other._uv);
|
||||||
|
}
|
||||||
|
if (ct == 0) {
|
||||||
|
ct = _color.compare_to(other._color);
|
||||||
|
}
|
||||||
|
return (ct < 0);
|
||||||
|
}
|
48
pandatool/src/xfile/xFileVertex.h
Normal file
48
pandatool/src/xfile/xFileVertex.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Filename: xFileVertex.h
|
||||||
|
// Created by: drose (19Jun01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef XFILEVERTEX_H
|
||||||
|
#define XFILEVERTEX_H
|
||||||
|
|
||||||
|
#include "pandatoolbase.h"
|
||||||
|
#include "luse.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : XFileVertex
|
||||||
|
// Description : This class represents a single Vertex as extracted
|
||||||
|
// from a Geom and added to the vertex pool.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class XFileVertex {
|
||||||
|
public:
|
||||||
|
XFileVertex(const Vertexf &point);
|
||||||
|
|
||||||
|
void set_normal(const Normalf &normal);
|
||||||
|
void set_uv(const TexCoordf &uv);
|
||||||
|
void set_color(const Colorf &color);
|
||||||
|
|
||||||
|
bool operator < (const XFileVertex &other) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vertexf _point;
|
||||||
|
Normalf _normal;
|
||||||
|
TexCoordf _uv;
|
||||||
|
Colorf _color;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
58
pandatool/src/xfile/xFileVertexPool.h
Normal file
58
pandatool/src/xfile/xFileVertexPool.h
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
// Filename: xFileVertexPool.h
|
||||||
|
// Created by: drose (19Jun01)
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
//
|
||||||
|
// PANDA 3D SOFTWARE
|
||||||
|
// Copyright (c) 2001, Disney Enterprises, Inc. All rights reserved
|
||||||
|
//
|
||||||
|
// All use of this software is subject to the terms of the Panda 3d
|
||||||
|
// Software license. You should have received a copy of this license
|
||||||
|
// along with this source code; you will also find a current copy of
|
||||||
|
// the license at http://www.panda3d.org/license.txt .
|
||||||
|
//
|
||||||
|
// To contact the maintainers of this program write to
|
||||||
|
// panda3d@yahoogroups.com .
|
||||||
|
//
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
#ifndef XFILEVERTEXPOOL_H
|
||||||
|
#define XFILEVERTEXPOOL_H
|
||||||
|
|
||||||
|
#include "pandatoolbase.h"
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
// Class : XFileVertexPool
|
||||||
|
// Description : This is a collection of unique vertices as extracted
|
||||||
|
// out of a Geom or a series of Geoms.
|
||||||
|
////////////////////////////////////////////////////////////////////
|
||||||
|
class XFileVertexPool {
|
||||||
|
public:
|
||||||
|
XFileVertexPool();
|
||||||
|
~XFileVertexPool();
|
||||||
|
|
||||||
|
int add_vertex(const XFileVertex &vertex);
|
||||||
|
|
||||||
|
int get_num_vertices();
|
||||||
|
const Vertexf *get_vertices();
|
||||||
|
const Normalf *get_normals();
|
||||||
|
const TexCoordf *get_uvs();
|
||||||
|
const Colorf *get_colors();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
void set_normal(const Normalf &normal);
|
||||||
|
void set_uv(const TexCoordf &uv);
|
||||||
|
void set_color(const Colorf &color);
|
||||||
|
|
||||||
|
bool operator < (const XFileVertexPool &other) const;
|
||||||
|
|
||||||
|
private:
|
||||||
|
Vertexf _point;
|
||||||
|
Normalf _normal;
|
||||||
|
TexCoordf _uv;
|
||||||
|
Colorf _color;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user