mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
lots of improvements to the COLLADA loader
This commit is contained in:
parent
70f6605442
commit
b33ffd9636
@ -6,8 +6,12 @@
|
||||
#define COMBINED_SOURCES collada_composite1.cxx
|
||||
|
||||
#define SOURCES \
|
||||
colladaInput.cxx \
|
||||
colladaInput.h colladaInput.I \
|
||||
colladaLoader.cxx \
|
||||
colladaLoader.h colladaLoader.I \
|
||||
colladaPrimitive.cxx \
|
||||
colladaPrimitive.h colladaPrimitive.I \
|
||||
config_collada.h \
|
||||
load_collada_file.h \
|
||||
loaderFileTypeDae.h
|
||||
|
33
panda/src/collada/colladaInput.I
Normal file
33
panda/src/collada/colladaInput.I
Normal file
@ -0,0 +1,33 @@
|
||||
// Filename: colladaInput.I
|
||||
// Created by: rdb (23May11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::is_vertex_source
|
||||
// Description: Returns true if this has a <vertices> element as
|
||||
// source.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ColladaInput::
|
||||
is_vertex_source() const {
|
||||
return (_semantic == "VERTEX");
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::get_offset
|
||||
// Description: Returns the offset associated with this input.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
unsigned int ColladaInput::
|
||||
get_offset() const {
|
||||
return _offset;
|
||||
}
|
277
panda/src/collada/colladaInput.cxx
Normal file
277
panda/src/collada/colladaInput.cxx
Normal file
@ -0,0 +1,277 @@
|
||||
// Filename: colladaInput.cxx
|
||||
// Created by: rdb (23May11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "colladaInput.h"
|
||||
#include "string_utils.h"
|
||||
#include "geomVertexArrayFormat.h"
|
||||
#include "geomVertexWriter.h"
|
||||
|
||||
// Collada DOM includes. No other includes beyond this point.
|
||||
#include "pre_collada_include.h"
|
||||
#include <dom/domAccessor.h>
|
||||
#include <dom/domP.h>
|
||||
#include <dom/domSource.h>
|
||||
#include <dom/domVertices.h>
|
||||
|
||||
#if PANDA_COLLADA_VERSION >= 15
|
||||
#include <dom/domInput_local_offset.h>
|
||||
#include <dom/domInput_local.h>
|
||||
#else
|
||||
#include <dom/domInputLocalOffset.h>
|
||||
#include <dom/domInputLocal.h>
|
||||
#define domList_of_floats domListOfFloats
|
||||
#define domList_of_uints domListOfUInts
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::Constructor
|
||||
// Description: Pretty obvious what this does.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaInput::
|
||||
ColladaInput(const string &semantic) :
|
||||
_column_name (NULL),
|
||||
_semantic (semantic),
|
||||
_offset (0),
|
||||
_have_set (false),
|
||||
_set (0) {
|
||||
|
||||
if (semantic == "POSITION") {
|
||||
_column_name = InternalName::get_vertex();
|
||||
_column_contents = GeomEnums::C_point;
|
||||
} else if (semantic == "COLOR") {
|
||||
_column_name = InternalName::get_color();
|
||||
_column_contents = GeomEnums::C_color;
|
||||
} else if (semantic == "NORMAL") {
|
||||
_column_name = InternalName::get_normal();
|
||||
_column_contents = GeomEnums::C_vector;
|
||||
} else if (semantic == "TEXCOORD") {
|
||||
_column_name = InternalName::get_texcoord();
|
||||
_column_contents = GeomEnums::C_texcoord;
|
||||
} else if (semantic == "TEXBINORMAL") {
|
||||
_column_name = InternalName::get_binormal();
|
||||
_column_contents = GeomEnums::C_vector;
|
||||
} else if (semantic == "TEXTANGENT") {
|
||||
_column_name = InternalName::get_tangent();
|
||||
_column_contents = GeomEnums::C_vector;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::Constructor
|
||||
// Description: Pretty obvious what this does.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaInput::
|
||||
ColladaInput(const string &semantic, unsigned int set) :
|
||||
_column_name (NULL),
|
||||
_semantic (semantic),
|
||||
_offset (0),
|
||||
_have_set (true),
|
||||
_set (set) {
|
||||
|
||||
ostringstream setstr;
|
||||
setstr << _set;
|
||||
|
||||
if (semantic == "POSITION") {
|
||||
_column_name = InternalName::get_vertex();
|
||||
_column_contents = GeomEnums::C_point;
|
||||
} else if (semantic == "COLOR") {
|
||||
_column_name = InternalName::get_color();
|
||||
_column_contents = GeomEnums::C_color;
|
||||
} else if (semantic == "NORMAL") {
|
||||
_column_name = InternalName::get_normal();
|
||||
_column_contents = GeomEnums::C_vector;
|
||||
} else if (semantic == "TEXCOORD") {
|
||||
_column_name = InternalName::get_texcoord_name(setstr.str());
|
||||
_column_contents = GeomEnums::C_texcoord;
|
||||
} else if (semantic == "TEXBINORMAL") {
|
||||
_column_name = InternalName::get_binormal_name(setstr.str());
|
||||
_column_contents = GeomEnums::C_vector;
|
||||
} else if (semantic == "TEXTANGENT") {
|
||||
_column_name = InternalName::get_tangent_name(setstr.str());
|
||||
_column_contents = GeomEnums::C_vector;
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::from_dom
|
||||
// Description: Returns the ColladaInput object that represents
|
||||
// the provided DOM input element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaInput *ColladaInput::
|
||||
from_dom(domInput_local_offset &input) {
|
||||
// If we already loaded it before, use that.
|
||||
if (input.getUserData() != NULL) {
|
||||
return (ColladaInput *) input.getUserData();
|
||||
}
|
||||
|
||||
ColladaInput *new_input = new ColladaInput(input.getSemantic(), input.getSet());
|
||||
new_input->_offset = input.getOffset();
|
||||
|
||||
// If this has the VERTEX semantic, it points to a <vertices> element.
|
||||
if (new_input->is_vertex_source()) {
|
||||
domVertices *verts = daeSafeCast<domVertices> (input.getSource().getElement());
|
||||
nassertr(verts != NULL, NULL);
|
||||
daeTArray<domInput_localRef> &inputs = verts->getInput_array();
|
||||
|
||||
// Iterate over the <input> elements in <vertices>.
|
||||
for (size_t i = 0; i < inputs.getCount(); ++i) {
|
||||
PT(ColladaInput) vtx_input = ColladaInput::from_dom(*inputs[i]);
|
||||
new_input->_vertex_inputs.push_back(vtx_input);
|
||||
}
|
||||
} else {
|
||||
domSource *source = daeSafeCast<domSource> (input.getSource().getElement());
|
||||
nassertr(source != NULL, NULL);
|
||||
new_input->read_data(*source);
|
||||
}
|
||||
|
||||
return new_input;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::from_dom
|
||||
// Description: Returns the ColladaInput object that represents
|
||||
// the provided DOM input element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaInput *ColladaInput::
|
||||
from_dom(domInput_local &input) {
|
||||
// If we already loaded it before, use that.
|
||||
if (input.getUserData() != NULL) {
|
||||
return (ColladaInput *) input.getUserData();
|
||||
}
|
||||
|
||||
ColladaInput *new_input = new ColladaInput(input.getSemantic());
|
||||
new_input->_offset = 0;
|
||||
|
||||
nassertr (!new_input->is_vertex_source(), NULL);
|
||||
|
||||
domSource *source = daeSafeCast<domSource> (input.getSource().getElement());
|
||||
nassertr(source != NULL, NULL);
|
||||
new_input->read_data(*source);
|
||||
|
||||
return new_input;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::make_vertex_columns
|
||||
// Description: Takes a semantic and source URI, and adds a new
|
||||
// column to the format. If this is a vertex source,
|
||||
// adds all of the inputs from the corresponding
|
||||
// <vertices> element. Returns the number of
|
||||
// columns added to the format.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
int ColladaInput::
|
||||
make_vertex_columns(GeomVertexArrayFormat *format) const {
|
||||
|
||||
if (is_vertex_source()) {
|
||||
int counter = 0;
|
||||
Inputs::const_iterator it;
|
||||
for (it = _vertex_inputs.begin(); it != _vertex_inputs.end(); ++it) {
|
||||
counter += (*it)->make_vertex_columns(format);
|
||||
}
|
||||
return counter;
|
||||
}
|
||||
|
||||
nassertr(_column_name != NULL, 0);
|
||||
|
||||
format->add_column(_column_name, _num_bound_params, GeomEnums::NT_float32, _column_contents);
|
||||
return 1;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::read_data
|
||||
// Description: Reads the data from the source and fills in _data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
bool ColladaInput::
|
||||
read_data(domSource &source) {
|
||||
_data.clear();
|
||||
|
||||
// Get this, get that
|
||||
domFloat_array* float_array = source.getFloat_array();
|
||||
if (float_array == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
domList_of_floats &floats = float_array->getValue();
|
||||
domAccessor &accessor = *source.getTechnique_common()->getAccessor();
|
||||
domParam_Array ¶ms = accessor.getParam_array();
|
||||
|
||||
// Count the number of params that have a name attribute.
|
||||
_num_bound_params = 0;
|
||||
for (size_t p = 0; p < params.getCount(); ++p) {
|
||||
if (params[p]->getName()) {
|
||||
++_num_bound_params;
|
||||
}
|
||||
}
|
||||
|
||||
_data.reserve(accessor.getCount());
|
||||
|
||||
domUint pos = accessor.getOffset();
|
||||
for (domUint a = 0; a < accessor.getCount(); ++a) {
|
||||
domUint c = 0;
|
||||
// Yes, the last component defaults to 1 to work around a
|
||||
// perspective divide that Panda3D does internally for points.
|
||||
LVecBase4f v (0, 0, 0, 1);
|
||||
for (domUint p = 0; p < params.getCount(); ++p) {
|
||||
if (params[c]->getName()) {
|
||||
v._v.data[c++] = floats[pos + p];
|
||||
}
|
||||
}
|
||||
_data.push_back(v);
|
||||
pos += accessor.getStride();
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::write_data
|
||||
// Description: Writes data to the indicated GeomVertexData using
|
||||
// the given indices.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ColladaInput::
|
||||
write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride) const {
|
||||
if (is_vertex_source()) {
|
||||
Inputs::const_iterator it;
|
||||
for (it = _vertex_inputs.begin(); it != _vertex_inputs.end(); ++it) {
|
||||
(*it)->write_data(vdata, start_row, p, stride, _offset);
|
||||
}
|
||||
|
||||
} else {
|
||||
write_data(vdata, start_row, p, stride, _offset);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaInput::write_data
|
||||
// Description: Called internally by the other write_data.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ColladaInput::
|
||||
write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride, unsigned int offset) const {
|
||||
nassertv(_column_name != NULL);
|
||||
GeomVertexWriter writer (vdata, _column_name);
|
||||
writer.set_row(start_row);
|
||||
|
||||
domList_of_uints &indices = p.getValue();
|
||||
|
||||
// Allocate space for all the rows we're going to write.
|
||||
int min_length = start_row + indices.getCount() / stride;
|
||||
if (vdata->get_num_rows() < min_length) {
|
||||
vdata->unclean_set_num_rows(start_row);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < indices.getCount(); i += stride) {
|
||||
size_t index = indices[i + offset];
|
||||
writer.add_data4f(_data[index]);
|
||||
}
|
||||
}
|
79
panda/src/collada/colladaInput.h
Normal file
79
panda/src/collada/colladaInput.h
Normal file
@ -0,0 +1,79 @@
|
||||
// Filename: colladaInput.h
|
||||
// Created by: rdb (23May11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COLLADAINPUT_H
|
||||
#define COLLADAINPUT_H
|
||||
|
||||
#include "config_collada.h"
|
||||
#include "referenceCount.h"
|
||||
#include "pvector.h"
|
||||
#include "pta_LVecBase4f.h"
|
||||
#include "internalName.h"
|
||||
#include "geomEnums.h"
|
||||
|
||||
class GeomPrimitive;
|
||||
class GeomVertexArrayFormat;
|
||||
class GeomVertexData;
|
||||
|
||||
#if PANDA_COLLADA_VERSION < 15
|
||||
#define domInput_local domInputLocal
|
||||
#define domInput_localRef domInputLocalRef
|
||||
#define domInput_local_offset domInputLocalOffset
|
||||
#define domInput_local_offsetRef domInputLocalOffsetRef
|
||||
#endif
|
||||
|
||||
class domInput_local;
|
||||
class domInput_local_offset;
|
||||
class domP;
|
||||
class domSource;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ColladaInput
|
||||
// Description : Class that deals with COLLADA data sources.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class ColladaInput : public ReferenceCount {
|
||||
public:
|
||||
static ColladaInput *from_dom(domInput_local_offset &input);
|
||||
static ColladaInput *from_dom(domInput_local &input);
|
||||
|
||||
int make_vertex_columns(GeomVertexArrayFormat *fmt) const;
|
||||
void write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride) const;
|
||||
|
||||
INLINE bool is_vertex_source() const;
|
||||
INLINE unsigned int get_offset() const;
|
||||
|
||||
private:
|
||||
ColladaInput(const string &semantic);
|
||||
ColladaInput(const string &semantic, unsigned int set);
|
||||
bool read_data(domSource &source);
|
||||
void write_data(GeomVertexData *vdata, int start_row, domP &p, unsigned int stride, unsigned int offset) const;
|
||||
|
||||
typedef pvector<PT(ColladaInput)> Inputs;
|
||||
Inputs _vertex_inputs;
|
||||
PTA_LVecBase4f _data;
|
||||
|
||||
// Only filled in when appropriate.
|
||||
PT(InternalName) _column_name;
|
||||
GeomEnums::Contents _column_contents;
|
||||
|
||||
unsigned int _num_bound_params;
|
||||
unsigned int _offset;
|
||||
string _semantic;
|
||||
bool _have_set;
|
||||
unsigned int _set;
|
||||
};
|
||||
|
||||
#include "colladaInput.I"
|
||||
|
||||
#endif
|
@ -26,11 +26,10 @@
|
||||
#include "pointLight.h"
|
||||
#include "spotlight.h"
|
||||
|
||||
// Ugh, undef some macros that conflict with COLLADA.
|
||||
#undef INLINE
|
||||
#undef tolower
|
||||
#include "colladaPrimitive.h"
|
||||
|
||||
#include <dae.h>
|
||||
// Collada DOM includes. No other includes beyond this point.
|
||||
#include "pre_collada_include.h"
|
||||
#include <dom/domCOLLADA.h>
|
||||
#include <dom/domNode.h>
|
||||
#include <dom/domVisual_scene.h>
|
||||
@ -43,12 +42,11 @@
|
||||
#else
|
||||
#include <dom/domInstanceWithExtra.h>
|
||||
#define domInstance_with_extra domInstanceWithExtra
|
||||
#define domInput_localRef domInputLocalRef
|
||||
#define domInput_local_offsetRef domInputLocalOffsetRef
|
||||
#define domList_of_uints domListOfUInts
|
||||
#define domList_of_floats domListOfFloats
|
||||
#define domTargetable_floatRef domTargetableFloatRef
|
||||
#endif
|
||||
|
||||
#define TOSTRING(x) (x == NULL ? "" : x)
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaLoader::Constructor
|
||||
// Description:
|
||||
@ -128,7 +126,7 @@ load_visual_scene(domVisual_scene& scene, PandaNode *parent) {
|
||||
return;
|
||||
}
|
||||
|
||||
PT(PandaNode) pnode = new PandaNode(scene.getName());
|
||||
PT(PandaNode) pnode = new PandaNode(TOSTRING(scene.getName()));
|
||||
scene.setUserData((void *) pnode);
|
||||
parent->add_child(pnode);
|
||||
|
||||
@ -149,7 +147,7 @@ load_visual_scene(domVisual_scene& scene, PandaNode *parent) {
|
||||
CPT(LightAttrib) lattr = DCAST(LightAttrib, LightAttrib::make());
|
||||
pvector<LightNode*>::iterator it;
|
||||
for (it = _lights.begin(); it != _lights.end(); ++it) {
|
||||
lattr = DCAST(LightAttrib, lattr->add_light(*it));
|
||||
lattr = DCAST(LightAttrib, lattr->add_on_light(*it));
|
||||
}
|
||||
pnode->set_state(RenderState::make(lattr));
|
||||
|
||||
@ -171,7 +169,7 @@ load_node(domNode& node, PandaNode *parent) {
|
||||
|
||||
// Create the node.
|
||||
PT(PandaNode) pnode;
|
||||
pnode = new PandaNode(node.getName());
|
||||
pnode = new PandaNode(TOSTRING(node.getName()));
|
||||
node.setUserData((void *) pnode);
|
||||
parent->add_child(pnode);
|
||||
|
||||
@ -179,8 +177,8 @@ load_node(domNode& node, PandaNode *parent) {
|
||||
LMatrix4f transform (LMatrix4f::ident_mat());
|
||||
|
||||
daeElementRefArray &elements = node.getContents();
|
||||
for (size_t i = elements.getCount() - 1; i > 0; --i) {
|
||||
daeElementRef &elem = elements[i];
|
||||
for (size_t i = elements.getCount(); i > 0; --i) {
|
||||
daeElementRef &elem = elements[i - 1];
|
||||
|
||||
switch (elem->getElementType()) {
|
||||
case COLLADA_TYPE::LOOKAT: {
|
||||
@ -221,7 +219,7 @@ load_node(domNode& node, PandaNode *parent) {
|
||||
break;
|
||||
}
|
||||
case COLLADA_TYPE::SKEW:
|
||||
// FIXME: implement skew
|
||||
//FIXME: implement skew
|
||||
collada_cat.error() << "<skew> not supported yet\n";
|
||||
break;
|
||||
case COLLADA_TYPE::TRANSLATE: {
|
||||
@ -246,11 +244,22 @@ load_node(domNode& node, PandaNode *parent) {
|
||||
load_camera(*target, pnode);
|
||||
}
|
||||
|
||||
// See if this node instantiates any controllers.
|
||||
domInstance_controller_Array &ctrlinst = node.getInstance_controller_array();
|
||||
for (size_t i = 0; i < ctrlinst.getCount(); ++i) {
|
||||
domController* target = daeSafeCast<domController> (ctrlinst[i]->getUrl().getElement());
|
||||
//TODO: implement controllers. For now, let's just read the geometry
|
||||
if (target->getSkin() != NULL) {
|
||||
domGeometry* geom = daeSafeCast<domGeometry> (target->getSkin()->getSource().getElement());
|
||||
//TODO: bind_material stuff
|
||||
load_geometry(*geom, pnode);
|
||||
}
|
||||
}
|
||||
|
||||
// See if this node instantiates any geoms.
|
||||
domInstance_geometry_Array &ginst = node.getInstance_geometry_array();
|
||||
for (size_t i = 0; i < ginst.getCount(); ++i) {
|
||||
domGeometry* target = daeSafeCast<domGeometry> (ginst[i]->getUrl().getElement());
|
||||
load_geometry(*target, pnode);
|
||||
load_instance_geometry(*ginst[i], pnode);
|
||||
}
|
||||
|
||||
// See if this node instantiates any lights.
|
||||
@ -327,6 +336,26 @@ load_camera(domCamera &cam, PandaNode *parent) {
|
||||
//TODO
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaLoader::load_instance_geometry
|
||||
// Description: Loads a COLLADA <instance_geometry> as a PandaNode
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ColladaLoader::
|
||||
load_instance_geometry(domInstance_geometry &inst, PandaNode *parent) {
|
||||
domGeometry* geom = daeSafeCast<domGeometry> (inst.getUrl().getElement());
|
||||
nassertv(geom != NULL);
|
||||
|
||||
domBind_materialRef bind_mat = inst.getBind_material();
|
||||
if (bind_mat == NULL) {
|
||||
load_geometry(*geom, parent);
|
||||
return;
|
||||
}
|
||||
|
||||
domInstance_material_Array &mat_instances = bind_mat->getTechnique_common()->getInstance_material_array();
|
||||
load_geometry(*geom, parent);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaLoader::load_geometry
|
||||
// Description: Loads a COLLADA <geometry> as a GeomNode object.
|
||||
@ -346,104 +375,66 @@ load_geometry(domGeometry &geom, PandaNode *parent) {
|
||||
}
|
||||
|
||||
// Create the node.
|
||||
PT(GeomNode) gnode = new GeomNode(geom.getName());
|
||||
PT(GeomNode) gnode = new GeomNode(TOSTRING(geom.getName()));
|
||||
geom.setUserData((void *) gnode);
|
||||
parent->add_child(gnode);
|
||||
|
||||
// First handle the <vertices> element.
|
||||
domVertices &vertices = *mesh->getVertices();
|
||||
daeTArray<domInput_localRef> &vtx_inputs = vertices.getInput_array();
|
||||
|
||||
PT(GeomVertexArrayFormat) vtx_aformat = new GeomVertexArrayFormat;
|
||||
PTA_LVecBase4f *vtx_values = new PTA_LVecBase4f[vtx_inputs.getCount()];
|
||||
CPT(InternalName) *vtx_names = new CPT(InternalName)[vtx_inputs.getCount()];
|
||||
|
||||
for (size_t i = 0; i < vtx_inputs.getCount(); ++i) {
|
||||
const string semantic = vtx_inputs[i]->getSemantic();
|
||||
domSource *source = daeSafeCast<domSource>(vtx_inputs[i]->getSource().getElement());
|
||||
nassertd(source != NULL) continue;
|
||||
|
||||
vtx_names[i] = load_input(vtx_aformat, vtx_values[i], semantic, *source);
|
||||
//TODO: support other than just triangles.
|
||||
domLines_Array &lines_array = mesh->getLines_array();
|
||||
for (size_t i = 0; i < lines_array.getCount(); ++i) {
|
||||
PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*lines_array[i]);
|
||||
if (prim != NULL) {
|
||||
gnode->add_geom(prim->get_geom());
|
||||
}
|
||||
}
|
||||
|
||||
domLinestrips_Array &linestrips_array = mesh->getLinestrips_array();
|
||||
for (size_t i = 0; i < linestrips_array.getCount(); ++i) {
|
||||
PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*linestrips_array[i]);
|
||||
if (prim != NULL) {
|
||||
gnode->add_geom(prim->get_geom());
|
||||
}
|
||||
}
|
||||
|
||||
domPolygons_Array &polygons_array = mesh->getPolygons_array();
|
||||
for (size_t i = 0; i < polygons_array.getCount(); ++i) {
|
||||
PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*polygons_array[i]);
|
||||
if (prim != NULL) {
|
||||
gnode->add_geom(prim->get_geom());
|
||||
}
|
||||
}
|
||||
|
||||
domPolylist_Array &polylist_array = mesh->getPolylist_array();
|
||||
for (size_t i = 0; i < polylist_array.getCount(); ++i) {
|
||||
PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*polylist_array[i]);
|
||||
if (prim != NULL) {
|
||||
gnode->add_geom(prim->get_geom());
|
||||
}
|
||||
}
|
||||
|
||||
//TODO: support other than just triangles.
|
||||
domTriangles_Array &triangles_array = mesh->getTriangles_array();
|
||||
for (size_t i = 0; i < triangles_array.getCount(); ++i) {
|
||||
domTriangles &tris = *triangles_array[i];
|
||||
|
||||
if (tris.getP() == NULL) {
|
||||
continue;
|
||||
PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*triangles_array[i]);
|
||||
if (prim != NULL) {
|
||||
gnode->add_geom(prim->get_geom());
|
||||
}
|
||||
domList_of_uints &p = tris.getP()->getValue();
|
||||
|
||||
// Read out the inputs.
|
||||
daeTArray<domInput_local_offsetRef> &inputs = tris.getInput_array();
|
||||
|
||||
PT(GeomVertexArrayFormat) aformat = new GeomVertexArrayFormat;
|
||||
PTA_LVecBase4f *values = new PTA_LVecBase4f[inputs.getCount()];
|
||||
CPT(InternalName) *names = new CPT(InternalName)[inputs.getCount()];
|
||||
|
||||
domUint stride = 1;
|
||||
for (size_t in = 0; in < inputs.getCount(); ++in) {
|
||||
const string semantic = inputs[in]->getSemantic();
|
||||
if (semantic == "VERTEX") {
|
||||
names[in] = NULL;
|
||||
continue;
|
||||
}
|
||||
domSource *source = daeSafeCast<domSource>(inputs[in]->getSource().getElement());
|
||||
nassertd(source != NULL) continue;
|
||||
|
||||
names[in] = load_input(aformat, values[in], semantic, *source, inputs[i]->getSet());
|
||||
|
||||
if (inputs[in]->getOffset() >= stride) {
|
||||
stride = inputs[in]->getOffset() + 1;
|
||||
}
|
||||
}
|
||||
|
||||
// Create the vertex data.
|
||||
PT(GeomVertexFormat) format = new GeomVertexFormat();
|
||||
format->add_array(vtx_aformat);
|
||||
format->add_array(aformat);
|
||||
PT(GeomVertexData) vdata = new GeomVertexData(geom.getName(), GeomVertexFormat::register_format(format), GeomEnums::UH_static);
|
||||
|
||||
// Time to go and write the data.
|
||||
PT(GeomTriangles) gtris = new GeomTriangles(GeomEnums::UH_static);
|
||||
for (size_t in = 0; in < inputs.getCount(); ++in) {
|
||||
if (names[in] == NULL) {
|
||||
// Refers to a <vertices> tag, so write the vertex inputs.
|
||||
int counter = 0;
|
||||
for (size_t in = 0; in < vtx_inputs.getCount(); ++in) {
|
||||
GeomVertexWriter writer(vdata, vtx_names[in]);
|
||||
for (size_t j = 0; j < p.getCount(); j += stride * 3) {
|
||||
for (char v = 0; v < 3; ++v) {
|
||||
int idx = p[j + v * stride];
|
||||
writer.add_data4f(vtx_values[in][idx]);
|
||||
gtris->add_vertex(counter++);
|
||||
}
|
||||
gtris->close_primitive();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
GeomVertexWriter writer(vdata, names[in]);
|
||||
for (size_t j = 0; j < p.getCount(); j += stride * 3) {
|
||||
for (char v = 0; v < 3; ++v) {
|
||||
int idx = p[j + v * stride + inputs[in]->getOffset()];
|
||||
writer.add_data4f(values[in][idx]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PT(Geom) geom = new Geom(vdata);
|
||||
geom->add_primitive(gtris);
|
||||
gnode->add_geom(geom);
|
||||
|
||||
delete[] values;
|
||||
delete[] names;
|
||||
}
|
||||
|
||||
delete[] vtx_values;
|
||||
delete[] vtx_names;
|
||||
domTrifans_Array &trifans_array = mesh->getTrifans_array();
|
||||
for (size_t i = 0; i < trifans_array.getCount(); ++i) {
|
||||
PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*trifans_array[i]);
|
||||
if (prim != NULL) {
|
||||
gnode->add_geom(prim->get_geom());
|
||||
}
|
||||
}
|
||||
|
||||
domTristrips_Array &tristrips_array = mesh->getTristrips_array();
|
||||
for (size_t i = 0; i < tristrips_array.getCount(); ++i) {
|
||||
PT(ColladaPrimitive) prim = ColladaPrimitive::from_dom(*tristrips_array[i]);
|
||||
if (prim != NULL) {
|
||||
gnode->add_geom(prim->get_geom());
|
||||
}
|
||||
}
|
||||
|
||||
// Load in any tags.
|
||||
domExtra_Array &extras = geom.getExtra_array();
|
||||
@ -452,80 +443,6 @@ load_geometry(domGeometry &geom, PandaNode *parent) {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaLoader::load_input
|
||||
// Description: Takes a semantic and source URI, and adds a new
|
||||
// column to the format. Also fills up the values
|
||||
// into the indicated PTA_LVecBase4f.
|
||||
// Returns the InternalName of the input.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
CPT(InternalName) ColladaLoader::
|
||||
load_input(GeomVertexArrayFormat *fmt, PTA_LVecBase4f &values,
|
||||
const string &semantic, domSource &source, unsigned int set) {
|
||||
|
||||
PT(InternalName) cname;
|
||||
GeomEnums::Contents contents = GeomEnums::C_other;
|
||||
|
||||
ostringstream setstr;
|
||||
setstr << set;
|
||||
|
||||
if (semantic == "POSITION") {
|
||||
cname = InternalName::get_vertex();
|
||||
contents = GeomEnums::C_point;
|
||||
} else if (semantic == "COLOR") {
|
||||
cname = InternalName::get_color();
|
||||
contents = GeomEnums::C_color;
|
||||
} else if (semantic == "NORMAL") {
|
||||
cname = InternalName::get_normal();
|
||||
contents = GeomEnums::C_vector;
|
||||
} else if (semantic == "TEXCOORD") {
|
||||
cname = InternalName::get_texcoord_name(setstr.str());
|
||||
contents = GeomEnums::C_texcoord;
|
||||
} else if (semantic == "TEXBINORMAL") {
|
||||
cname = InternalName::get_binormal_name(setstr.str());
|
||||
contents = GeomEnums::C_vector;
|
||||
} else if (semantic == "TEXTANGENT") {
|
||||
cname = InternalName::get_tangent_name(setstr.str());
|
||||
contents = GeomEnums::C_vector;
|
||||
} else {
|
||||
collada_cat.warning() << "Unrecognized semantic " << semantic << "\n";
|
||||
cname = InternalName::make(downcase(semantic));
|
||||
}
|
||||
|
||||
// Get this, get that
|
||||
domFloat_array* float_array = source.getFloat_array();
|
||||
nassertr(float_array != NULL, cname);
|
||||
domList_of_floats &floats = float_array->getValue();
|
||||
domAccessor &accessor = *source.getTechnique_common()->getAccessor();
|
||||
domParam_Array ¶ms = accessor.getParam_array();
|
||||
|
||||
// Count the number of params that have a name attribute.
|
||||
domUint num_bound_params = 0;
|
||||
for (size_t p = 0; p < params.getCount(); ++p) {
|
||||
if (params[p]->getName()) {
|
||||
++num_bound_params;
|
||||
}
|
||||
}
|
||||
|
||||
domUint pos = accessor.getOffset();
|
||||
for (domUint a = 0; a < accessor.getCount(); ++a) {
|
||||
domUint c = 0;
|
||||
// Yes, the last component defaults to 1 to work around a
|
||||
// perspective divide that Panda3D does internally for points.
|
||||
LVecBase4f v (0, 0, 0, 1);
|
||||
for (domUint p = 0; p < params.getCount(); ++p) {
|
||||
if (params[c]->getName()) {
|
||||
v._v.data[c++] = floats[pos + p];
|
||||
}
|
||||
}
|
||||
values.push_back(v);
|
||||
pos += accessor.getStride();
|
||||
}
|
||||
|
||||
fmt->add_column(cname, num_bound_params, GeomEnums::NT_float32, contents);
|
||||
return cname;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaLoader::load_light
|
||||
// Description: Loads a COLLADA <light> as a LightNode object.
|
||||
@ -541,18 +458,20 @@ load_light(domLight &light, PandaNode *parent) {
|
||||
PT(LightNode) lnode;
|
||||
domLight::domTechnique_common &tc = *light.getTechnique_common();
|
||||
|
||||
// Check for an ambient light.
|
||||
domLight::domTechnique_common::domAmbientRef ambient = tc.getAmbient();
|
||||
if (ambient != NULL) {
|
||||
PT(AmbientLight) alight = new AmbientLight(light.getName());
|
||||
PT(AmbientLight) alight = new AmbientLight(TOSTRING(light.getName()));
|
||||
lnode = DCAST(LightNode, alight);
|
||||
|
||||
domFloat3 &color = ambient->getColor()->getValue();
|
||||
alight->set_color(Colorf(color[0], color[1], color[2], 1.0));
|
||||
}
|
||||
|
||||
// Check for a directional light.
|
||||
domLight::domTechnique_common::domDirectionalRef directional = tc.getDirectional();
|
||||
if (directional != NULL) {
|
||||
PT(DirectionalLight) dlight = new DirectionalLight(light.getName());
|
||||
PT(DirectionalLight) dlight = new DirectionalLight(TOSTRING(light.getName()));
|
||||
lnode = DCAST(LightNode, dlight);
|
||||
|
||||
domFloat3 &color = directional->getColor()->getValue();
|
||||
@ -560,34 +479,70 @@ load_light(domLight &light, PandaNode *parent) {
|
||||
dlight->set_direction(LVector3f(0, 0, -1));
|
||||
}
|
||||
|
||||
// Check for a point light.
|
||||
domLight::domTechnique_common::domPointRef point = tc.getPoint();
|
||||
if (point != NULL) {
|
||||
PT(PointLight) plight = new PointLight(light.getName());
|
||||
PT(PointLight) plight = new PointLight(TOSTRING(light.getName()));
|
||||
lnode = DCAST(LightNode, plight);
|
||||
|
||||
domFloat3 &color = point->getColor()->getValue();
|
||||
plight->set_color(Colorf(color[0], color[1], color[2], 1.0));
|
||||
plight->set_attenuation(LVecBase3f(
|
||||
point->getConstant_attenuation()->getValue(),
|
||||
point->getLinear_attenuation()->getValue(),
|
||||
point->getQuadratic_attenuation()->getValue()
|
||||
));
|
||||
|
||||
LVecBase3f atten (1.0f, 0.0f, 0.0f);
|
||||
domTargetable_floatRef fval = point->getConstant_attenuation();
|
||||
if (fval != NULL) {
|
||||
atten[0] = fval->getValue();
|
||||
}
|
||||
fval = point->getLinear_attenuation();
|
||||
if (fval != NULL) {
|
||||
atten[1] = fval->getValue();
|
||||
}
|
||||
fval = point->getQuadratic_attenuation();
|
||||
if (fval != NULL) {
|
||||
atten[2] = fval->getValue();
|
||||
}
|
||||
|
||||
plight->set_attenuation(atten);
|
||||
}
|
||||
|
||||
// Check for a spot light.
|
||||
domLight::domTechnique_common::domSpotRef spot = tc.getSpot();
|
||||
if (spot != NULL) {
|
||||
PT(Spotlight) slight = new Spotlight(light.getName());
|
||||
PT(Spotlight) slight = new Spotlight(TOSTRING(light.getName()));
|
||||
lnode = DCAST(LightNode, slight);
|
||||
|
||||
domFloat3 &color = spot->getColor()->getValue();
|
||||
slight->set_color(Colorf(color[0], color[1], color[2], 1.0));
|
||||
slight->set_attenuation(LVecBase3f(
|
||||
spot->getConstant_attenuation()->getValue(),
|
||||
spot->getLinear_attenuation()->getValue(),
|
||||
spot->getQuadratic_attenuation()->getValue()
|
||||
));
|
||||
slight->get_lens()->set_fov(spot->getFalloff_angle()->getValue());
|
||||
slight->set_exponent(spot->getFalloff_exponent()->getValue());
|
||||
|
||||
LVecBase3f atten (1.0f, 0.0f, 0.0f);
|
||||
domTargetable_floatRef fval = spot->getConstant_attenuation();
|
||||
if (fval != NULL) {
|
||||
atten[0] = fval->getValue();
|
||||
}
|
||||
fval = spot->getLinear_attenuation();
|
||||
if (fval != NULL) {
|
||||
atten[1] = fval->getValue();
|
||||
}
|
||||
fval = spot->getQuadratic_attenuation();
|
||||
if (fval != NULL) {
|
||||
atten[2] = fval->getValue();
|
||||
}
|
||||
|
||||
slight->set_attenuation(atten);
|
||||
|
||||
fval = spot->getFalloff_angle();
|
||||
if (fval != NULL) {
|
||||
slight->get_lens()->set_fov(fval->getValue());
|
||||
} else {
|
||||
slight->get_lens()->set_fov(180.0f);
|
||||
}
|
||||
|
||||
fval = spot->getFalloff_exponent();
|
||||
if (fval != NULL) {
|
||||
slight->set_exponent(fval->getValue());
|
||||
} else {
|
||||
slight->set_exponent(0.0f);
|
||||
}
|
||||
}
|
||||
|
||||
if (lnode == NULL) {
|
||||
@ -603,3 +558,13 @@ load_light(domLight &light, PandaNode *parent) {
|
||||
load_tags(*extras[i], lnode);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaLoader::load_material
|
||||
// Description: Loads a COLLADA <bind_material> as a RenderState
|
||||
// object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ColladaLoader::
|
||||
load_material(domBind_material &bind_mat, PandaNode *node) {
|
||||
|
||||
}
|
||||
|
@ -26,11 +26,13 @@
|
||||
class BamCacheRecord;
|
||||
class LightNode;
|
||||
|
||||
class domBind_material;
|
||||
class domCOLLADA;
|
||||
class domNode;
|
||||
class domVisual_scene;
|
||||
class domExtra;
|
||||
class domGeometry;
|
||||
class domInstance_geometry;
|
||||
class domLight;
|
||||
class domCamera;
|
||||
class domSource;
|
||||
@ -64,9 +66,10 @@ private:
|
||||
void load_node(domNode &node, PandaNode *parent);
|
||||
void load_tags(domExtra &extra, PandaNode *node);
|
||||
void load_camera(domCamera &cam, PandaNode *parent);
|
||||
void load_instance_geometry(domInstance_geometry &inst, PandaNode *parent);
|
||||
void load_geometry(domGeometry &geom, PandaNode *parent);
|
||||
CPT(InternalName) load_input(GeomVertexArrayFormat *fmt, PTA_LVecBase4f &values, const string &semantic, domSource &src, unsigned int set=0);
|
||||
void load_light(domLight &light, PandaNode *parent);
|
||||
void load_material(domBind_material &bind_mat, PandaNode *node);
|
||||
};
|
||||
|
||||
#include "colladaLoader.I"
|
||||
|
35
panda/src/collada/colladaPrimitive.I
Normal file
35
panda/src/collada/colladaPrimitive.I
Normal file
@ -0,0 +1,35 @@
|
||||
// Filename: colladaPrimitive.I
|
||||
// Created by: rdb (23May11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::add_input
|
||||
// Description: Adds a new ColladaInput to this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE void ColladaPrimitive::
|
||||
add_input(ColladaInput *input) {
|
||||
if (input->get_offset() >= _stride) {
|
||||
_stride = input->get_offset() + 1;
|
||||
}
|
||||
_inputs.push_back(input);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::get_geom
|
||||
// Description: Returns the Goem associated with this primitive.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
INLINE PT(Geom) ColladaPrimitive::
|
||||
get_geom() const {
|
||||
return _geom;
|
||||
}
|
298
panda/src/collada/colladaPrimitive.cxx
Normal file
298
panda/src/collada/colladaPrimitive.cxx
Normal file
@ -0,0 +1,298 @@
|
||||
// Filename: colladaPrimitive.cxx
|
||||
// Created by: rdb (23May11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "colladaPrimitive.h"
|
||||
#include "geomLines.h"
|
||||
#include "geomLinestrips.h"
|
||||
#include "geomTriangles.h"
|
||||
#include "geomTrifans.h"
|
||||
#include "geomTristrips.h"
|
||||
|
||||
// Collada DOM includes. No other includes beyond this point.
|
||||
#include "pre_collada_include.h"
|
||||
#include <dom/domLines.h>
|
||||
#include <dom/domLinestrips.h>
|
||||
#include <dom/domPolygons.h>
|
||||
#include <dom/domPolylist.h>
|
||||
#include <dom/domTriangles.h>
|
||||
#include <dom/domTrifans.h>
|
||||
#include <dom/domTristrips.h>
|
||||
|
||||
#if PANDA_COLLADA_VERSION < 15
|
||||
#define domInput_local_offsetRef domInputLocalOffsetRef
|
||||
#endif
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::Constructor
|
||||
// Description: Why do I even bother documenting the simplest of
|
||||
// constructors? A private one at that.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaPrimitive::
|
||||
ColladaPrimitive(GeomPrimitive *prim, daeTArray<domInput_local_offsetRef> &inputs)
|
||||
: _stride (1), _gprim (prim) {
|
||||
|
||||
PT(GeomVertexArrayFormat) aformat = new GeomVertexArrayFormat;
|
||||
|
||||
// Add the inputs one by one.
|
||||
for (size_t in = 0; in < inputs.getCount(); ++in) {
|
||||
PT(ColladaInput) input = ColladaInput::from_dom(*inputs[in]);
|
||||
add_input(input);
|
||||
|
||||
input->make_vertex_columns(aformat);
|
||||
}
|
||||
|
||||
// Create the vertex data.
|
||||
PT(GeomVertexFormat) format = new GeomVertexFormat();
|
||||
format->add_array(aformat);
|
||||
_vdata = new GeomVertexData("", GeomVertexFormat::register_format(format), GeomEnums::UH_static);
|
||||
_geom = new Geom(_vdata);
|
||||
_geom->add_primitive(_gprim);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::from_dom
|
||||
// Description: Returns the ColladaPrimitive object that represents
|
||||
// the provided DOM input element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaPrimitive *ColladaPrimitive::
|
||||
from_dom(domLines &prim) {
|
||||
// If we already loaded it before, use that.
|
||||
if (prim.getUserData() != NULL) {
|
||||
return (ColladaPrimitive *) prim.getUserData();
|
||||
}
|
||||
|
||||
ColladaPrimitive *new_prim =
|
||||
new ColladaPrimitive(new GeomLines(GeomEnums::UH_static),
|
||||
prim.getInput_array());
|
||||
|
||||
prim.setUserData(new_prim);
|
||||
|
||||
domPRef p = prim.getP();
|
||||
if (p != NULL) {
|
||||
new_prim->load_primitive(*p);
|
||||
}
|
||||
|
||||
return new_prim;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::from_dom
|
||||
// Description: Returns the ColladaPrimitive object that represents
|
||||
// the provided DOM input element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaPrimitive *ColladaPrimitive::
|
||||
from_dom(domLinestrips &prim) {
|
||||
// If we already loaded it before, use that.
|
||||
if (prim.getUserData() != NULL) {
|
||||
return (ColladaPrimitive *) prim.getUserData();
|
||||
}
|
||||
|
||||
ColladaPrimitive *new_prim =
|
||||
new ColladaPrimitive(new GeomLinestrips(GeomEnums::UH_static),
|
||||
prim.getInput_array());
|
||||
|
||||
prim.setUserData(new_prim);
|
||||
|
||||
new_prim->load_primitives(prim.getP_array());
|
||||
|
||||
return new_prim;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::from_dom
|
||||
// Description: Returns the ColladaPrimitive object that represents
|
||||
// the provided DOM input element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaPrimitive *ColladaPrimitive::
|
||||
from_dom(domPolygons &prim) {
|
||||
// If we already loaded it before, use that.
|
||||
if (prim.getUserData() != NULL) {
|
||||
return (ColladaPrimitive *) prim.getUserData();
|
||||
}
|
||||
|
||||
// We use trifans to represent polygons, seems to be easiest.
|
||||
// I tried using tristrips instead, but for some reason,
|
||||
// this resulted in a few flipped polygons. Weird.
|
||||
ColladaPrimitive *new_prim =
|
||||
new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static),
|
||||
prim.getInput_array());
|
||||
|
||||
prim.setUserData(new_prim);
|
||||
|
||||
new_prim->load_primitives(prim.getP_array());
|
||||
|
||||
if (prim.getPh_array().getCount() > 0) {
|
||||
collada_cat.error()
|
||||
<< "Polygons with holes are not supported!\n";
|
||||
}
|
||||
|
||||
return new_prim;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::from_dom
|
||||
// Description: Returns the ColladaPrimitive object that represents
|
||||
// the provided DOM input element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaPrimitive *ColladaPrimitive::
|
||||
from_dom(domPolylist &prim) {
|
||||
// If we already loaded it before, use that.
|
||||
if (prim.getUserData() != NULL) {
|
||||
return (ColladaPrimitive *) prim.getUserData();
|
||||
}
|
||||
|
||||
// We use trifans to represent polygons, seems to be easiest.
|
||||
// I tried using tristrips instead, but for some reason,
|
||||
// this resulted in a few flipped polygons. Weird.
|
||||
PT(GeomPrimitive) gprim = new GeomTrifans(GeomEnums::UH_static);
|
||||
|
||||
ColladaPrimitive *new_prim =
|
||||
new ColladaPrimitive(gprim, prim.getInput_array());
|
||||
|
||||
prim.setUserData(new_prim);
|
||||
|
||||
domPRef p = prim.getP();
|
||||
domPolylist::domVcountRef vcounts = prim.getVcount();
|
||||
if (p == NULL || vcounts == NULL) {
|
||||
return new_prim;
|
||||
}
|
||||
|
||||
new_prim->write_data(new_prim->_vdata, 0, *p);
|
||||
|
||||
daeTArray<domUint> &values = vcounts->getValue();
|
||||
for (size_t i = 0; i < values.getCount(); ++i) {
|
||||
unsigned int vcount = values[i];
|
||||
gprim->add_next_vertices(vcount);
|
||||
gprim->close_primitive();
|
||||
}
|
||||
|
||||
return new_prim;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::from_dom
|
||||
// Description: Returns the ColladaPrimitive object that represents
|
||||
// the provided DOM input element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaPrimitive *ColladaPrimitive::
|
||||
from_dom(domTriangles &prim) {
|
||||
// If we already loaded it before, use that.
|
||||
if (prim.getUserData() != NULL) {
|
||||
return (ColladaPrimitive *) prim.getUserData();
|
||||
}
|
||||
|
||||
ColladaPrimitive *new_prim =
|
||||
new ColladaPrimitive(new GeomTriangles(GeomEnums::UH_static),
|
||||
prim.getInput_array());
|
||||
|
||||
prim.setUserData(new_prim);
|
||||
|
||||
domPRef p = prim.getP();
|
||||
if (p != NULL) {
|
||||
new_prim->load_primitive(*p);
|
||||
}
|
||||
|
||||
return new_prim;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::from_dom
|
||||
// Description: Returns the ColladaPrimitive object that represents
|
||||
// the provided DOM input element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaPrimitive *ColladaPrimitive::
|
||||
from_dom(domTrifans &prim) {
|
||||
// If we already loaded it before, use that.
|
||||
if (prim.getUserData() != NULL) {
|
||||
return (ColladaPrimitive *) prim.getUserData();
|
||||
}
|
||||
|
||||
ColladaPrimitive *new_prim =
|
||||
new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static),
|
||||
prim.getInput_array());
|
||||
|
||||
prim.setUserData(new_prim);
|
||||
|
||||
new_prim->load_primitives(prim.getP_array());
|
||||
|
||||
return new_prim;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::from_dom
|
||||
// Description: Returns the ColladaPrimitive object that represents
|
||||
// the provided DOM input element.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
ColladaPrimitive *ColladaPrimitive::
|
||||
from_dom(domTristrips &prim) {
|
||||
// If we already loaded it before, use that.
|
||||
if (prim.getUserData() != NULL) {
|
||||
return (ColladaPrimitive *) prim.getUserData();
|
||||
}
|
||||
|
||||
ColladaPrimitive *new_prim =
|
||||
new ColladaPrimitive(new GeomTristrips(GeomEnums::UH_static),
|
||||
prim.getInput_array());
|
||||
|
||||
prim.setUserData(new_prim);
|
||||
|
||||
new_prim->load_primitives(prim.getP_array());
|
||||
|
||||
return new_prim;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::write_data
|
||||
// Description: Writes the vertex data to the GeomVertexData.
|
||||
// Returns the number of rows written.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
unsigned int ColladaPrimitive::
|
||||
write_data(GeomVertexData *vdata, int start_row, domP &p) {
|
||||
unsigned int num_vertices = p.getValue().getCount() / _stride;
|
||||
|
||||
Inputs::iterator it;
|
||||
for (it = _inputs.begin(); it != _inputs.end(); ++it) {
|
||||
(*it)->write_data(vdata, start_row, p, _stride);
|
||||
}
|
||||
|
||||
return num_vertices;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::load_primitive
|
||||
// Description: Adds the given indices to the primitive, and
|
||||
// writes the relevant data to the geom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ColladaPrimitive::
|
||||
load_primitive(domP &p) {
|
||||
_gprim->add_next_vertices(write_data(_vdata, 0, p));
|
||||
_gprim->close_primitive();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: ColladaPrimitive::load_primitives
|
||||
// Description: Adds the given indices to the primitive, and
|
||||
// writes the relevant data to the geom.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void ColladaPrimitive::
|
||||
load_primitives(domP_Array &p_array) {
|
||||
int start_row = 0;
|
||||
|
||||
for (size_t i = 0; i < p_array.getCount(); ++i) {
|
||||
unsigned int num_vertices = write_data(_vdata, start_row, *p_array[i]);
|
||||
_gprim->add_next_vertices(num_vertices);
|
||||
_gprim->close_primitive();
|
||||
start_row += num_vertices;
|
||||
}
|
||||
}
|
71
panda/src/collada/colladaPrimitive.h
Normal file
71
panda/src/collada/colladaPrimitive.h
Normal file
@ -0,0 +1,71 @@
|
||||
// Filename: colladaPrimitive.h
|
||||
// Created by: rdb (23May11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef COLLADAPRIMITIVE_H
|
||||
#define COLLADAPRIMITIVE_H
|
||||
|
||||
#include "config_collada.h"
|
||||
#include "referenceCount.h"
|
||||
#include "geomVertexData.h"
|
||||
#include "geom.h"
|
||||
#include "geomPrimitive.h"
|
||||
|
||||
#include "colladaInput.h"
|
||||
|
||||
class domP;
|
||||
class domLines;
|
||||
class domLinestrips;
|
||||
class domPolygons;
|
||||
class domPolylist;
|
||||
class domTriangles;
|
||||
class domTrifans;
|
||||
class domTristrips;
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Class : ColladaPrimitive
|
||||
// Description : Class that deals with COLLADA primitive structures,
|
||||
// such as <triangles> and <polylist>.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
class ColladaPrimitive : public ReferenceCount {
|
||||
public:
|
||||
static ColladaPrimitive *from_dom(domLines &lines);
|
||||
static ColladaPrimitive *from_dom(domLinestrips &linestrips);
|
||||
static ColladaPrimitive *from_dom(domPolygons &polygons);
|
||||
static ColladaPrimitive *from_dom(domPolylist &polylist);
|
||||
static ColladaPrimitive *from_dom(domTriangles &triangles);
|
||||
static ColladaPrimitive *from_dom(domTrifans &trifans);
|
||||
static ColladaPrimitive *from_dom(domTristrips &tristrips);
|
||||
|
||||
unsigned int write_data(GeomVertexData *vdata, int start_row, domP &p);
|
||||
|
||||
INLINE PT(Geom) get_geom() const;
|
||||
|
||||
private:
|
||||
ColladaPrimitive(GeomPrimitive *prim, daeTArray<daeSmartRef<domInput_local_offset> > &inputs);
|
||||
void load_primitive(domP &p);
|
||||
void load_primitives(daeTArray<daeSmartRef<domP> > &p_array);
|
||||
INLINE void add_input(ColladaInput *input);
|
||||
|
||||
typedef pvector<PT(ColladaInput)> Inputs;
|
||||
Inputs _inputs;
|
||||
|
||||
unsigned int _stride;
|
||||
PT(Geom) _geom;
|
||||
PT(GeomVertexData) _vdata;
|
||||
PT(GeomPrimitive) _gprim;
|
||||
};
|
||||
|
||||
#include "colladaPrimitive.I"
|
||||
|
||||
#endif
|
@ -20,6 +20,8 @@
|
||||
#include "notifyCategoryProxy.h"
|
||||
#include "dconfig.h"
|
||||
|
||||
template<class T> class daeTArray;
|
||||
template<class T> class daeSmartRef;
|
||||
|
||||
ConfigureDecl(config_collada, EXPCL_COLLADA, EXPTP_COLLADA);
|
||||
NotifyCategoryDecl(collada, EXPCL_COLLADA, EXPTP_COLLADA);
|
||||
|
@ -33,7 +33,13 @@ LoaderFileTypeDae() {
|
||||
////////////////////////////////////////////////////////////////////
|
||||
string LoaderFileTypeDae::
|
||||
get_name() const {
|
||||
return "COLLADA Digital Asset Exchange";
|
||||
#if PANDA_COLLADA_VERSION == 14
|
||||
return "COLLADA 1.4";
|
||||
#elif PANDA_COLLADA_VERSION == 15
|
||||
return "COLLADA 1.5";
|
||||
#else
|
||||
return "COLLADA";
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
29
panda/src/collada/pre_collada_include.h
Normal file
29
panda/src/collada/pre_collada_include.h
Normal file
@ -0,0 +1,29 @@
|
||||
// Filename: pre_collada_include.h
|
||||
// Created by: rdb (23May11)
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
//
|
||||
// PANDA 3D SOFTWARE
|
||||
// Copyright (c) Carnegie Mellon University. All rights reserved.
|
||||
//
|
||||
// All use of this software is subject to the terms of the revised BSD
|
||||
// license. You should have received a copy of this license along
|
||||
// with this source code in a file named "LICENSE."
|
||||
//
|
||||
////////////////////////////////////////////////////////////////////
|
||||
|
||||
// This header file should be included before including any of the
|
||||
// COLLADA DOM headers. It should only be included in a .cxx file
|
||||
// (not in a header file) and no Panda3D headers should be included
|
||||
// after the pre_collada_include.h include.
|
||||
|
||||
#ifdef PRE_COLLADA_INCLUDE_H
|
||||
#error Don't include any Panda headers after including pre_collada_include.h!
|
||||
#endif
|
||||
#define PRE_COLLADA_INCLUDE_H
|
||||
|
||||
// Undef some macros that conflict with COLLADA.
|
||||
#undef INLINE
|
||||
#undef tolower
|
||||
|
||||
#include <dae.h>
|
Loading…
x
Reference in New Issue
Block a user