diff --git a/panda/src/collada/Sources.pp b/panda/src/collada/Sources.pp index 34c3e1a42e..59f1fd67fc 100644 --- a/panda/src/collada/Sources.pp +++ b/panda/src/collada/Sources.pp @@ -6,6 +6,8 @@ #define COMBINED_SOURCES collada_composite1.cxx #define SOURCES \ + colladaBindMaterial.cxx \ + colladaBindMaterial.h \ colladaInput.cxx \ colladaInput.h colladaInput.I \ colladaLoader.cxx \ diff --git a/panda/src/collada/colladaBindMaterial.cxx b/panda/src/collada/colladaBindMaterial.cxx new file mode 100644 index 0000000000..c106cf63b0 --- /dev/null +++ b/panda/src/collada/colladaBindMaterial.cxx @@ -0,0 +1,98 @@ +// Filename: colladaBindMaterial.cxx +// Created by: rdb (26May11) +// +//////////////////////////////////////////////////////////////////// +// +// 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 "colladaBindMaterial.h" +#include "colladaPrimitive.h" + +// Collada DOM includes. No other includes beyond this point. +#include "pre_collada_include.h" +#include +#include +#include +#include +#include + +#if PANDA_COLLADA_VERSION >= 15 +#include +#else +#include +#define domFx_profile domFx_profile_abstract +#define domFx_profile_Array domFx_profile_abstract_Array +#define getFx_profile_array getFx_profile_abstract_array +#endif + +//////////////////////////////////////////////////////////////////// +// Function: ColladaBindMaterial::get_material +// Description: Returns the material to be applied to the given +// primitive, or NULL if there was none bound. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) ColladaBindMaterial:: +get_material(const ColladaPrimitive *prim) const { + if (prim == NULL || _states.count(prim->get_material()) == 0) { + return NULL; + } + return _states.find(prim->get_material())->second; +} + +//////////////////////////////////////////////////////////////////// +// Function: ColladaBindMaterial::get_material +// Description: Returns the bound material with the indicated +// symbol, or NULL if it was not found. +//////////////////////////////////////////////////////////////////// +CPT(RenderState) ColladaBindMaterial:: +get_material(const string &symbol) const { + if (_states.count(symbol) == 0) { + return NULL; + } + return _states.find(symbol)->second; +} + +//////////////////////////////////////////////////////////////////// +// Function: ColladaBindMaterial::load_bind_material +// Description: Loads a bind_material object. +//////////////////////////////////////////////////////////////////// +void ColladaBindMaterial:: +load_bind_material(domBind_material &bind_mat) { + domInstance_material_Array &mat_instances + = bind_mat.getTechnique_common()->getInstance_material_array(); + + for (size_t i = 0; i < mat_instances.getCount(); ++i) { + load_instance_material(*mat_instances[i]); + } +} + +//////////////////////////////////////////////////////////////////// +// Function: ColladaBindMaterial::load_instance_material +// Description: Loads an instance_material object. +//////////////////////////////////////////////////////////////////// +void ColladaBindMaterial:: +load_instance_material(domInstance_material &inst) { + domMaterialRef mat = daeSafeCast (inst.getTarget().getElement()); + nassertv(mat != NULL); + + domInstance_effectRef einst = mat->getInstance_effect(); + nassertv(einst != NULL); + + domInstance_effect::domSetparam_Array &setparams = einst->getSetparam_array(); + + domEffectRef effect = daeSafeCast + (mat->getInstance_effect()->getUrl().getElement()); + + //TODO: read params + + const domFx_profile_Array &profiles = effect->getFx_profile_array(); + for (size_t i = 0; i < profiles.getCount(); ++i) { + //profiles[i]-> + } +} diff --git a/panda/src/collada/colladaBindMaterial.h b/panda/src/collada/colladaBindMaterial.h new file mode 100644 index 0000000000..d5ec2e39fa --- /dev/null +++ b/panda/src/collada/colladaBindMaterial.h @@ -0,0 +1,44 @@ +// Filename: colladaBindMaterial.h +// Created by: rdb (25May11) +// +//////////////////////////////////////////////////////////////////// +// +// 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 COLLADABINDMATERIAL_H +#define COLLADABINDMATERIAL_H + +#include "config_collada.h" +#include "renderState.h" +#include "pmap.h" + +class ColladaPrimitive; + +class domBind_material; +class domInstance_material; + +//////////////////////////////////////////////////////////////////// +// Class : ColladaBindMaterial +// Description : Class that deals with binding materials to +// COLLADA geometry. +//////////////////////////////////////////////////////////////////// +class ColladaBindMaterial { +public: + CPT(RenderState) get_material(const ColladaPrimitive *prim) const; + CPT(RenderState) get_material(const string &symbol) const; + + void load_bind_material(domBind_material &bind_mat); + void load_instance_material(domInstance_material &inst); + +private: + pmap _states; +}; + +#endif diff --git a/panda/src/collada/colladaLoader.cxx b/panda/src/collada/colladaLoader.cxx index 90ee9d7de6..46b3d4aec3 100644 --- a/panda/src/collada/colladaLoader.cxx +++ b/panda/src/collada/colladaLoader.cxx @@ -26,6 +26,7 @@ #include "pointLight.h" #include "spotlight.h" +#include "colladaBindMaterial.h" #include "colladaPrimitive.h" // Collada DOM includes. No other includes beyond this point. @@ -251,8 +252,8 @@ load_node(domNode& node, PandaNode *parent) { //TODO: implement controllers. For now, let's just read the geometry if (target->getSkin() != NULL) { domGeometry* geom = daeSafeCast (target->getSkin()->getSource().getElement()); - //TODO: bind_material stuff - load_geometry(*geom, pnode); + //TODO + //load_geometry(*geom, ctrlinst[i]->getBind_material(), pnode); } } @@ -286,6 +287,8 @@ load_node(domNode& node, PandaNode *parent) { domExtra_Array &extras = node.getExtra_array(); for (size_t i = 0; i < extras.getCount(); ++i) { load_tags(*extras[i], pnode); + //TODO: load SI_Visibility under XSI profile + //TODO: support OpenSceneGraph's switch nodes } } @@ -338,47 +341,53 @@ load_camera(domCamera &cam, PandaNode *parent) { //////////////////////////////////////////////////////////////////// // Function: ColladaLoader::load_instance_geometry -// Description: Loads a COLLADA as a PandaNode +// Description: Loads a COLLADA as a GeomNode // object. //////////////////////////////////////////////////////////////////// void ColladaLoader:: load_instance_geometry(domInstance_geometry &inst, PandaNode *parent) { - domGeometry* geom = daeSafeCast (inst.getUrl().getElement()); - nassertv(geom != NULL); - - domBind_materialRef bind_mat = inst.getBind_material(); - if (bind_mat == NULL) { - load_geometry(*geom, parent); + // If we already loaded it before, instantiate the stored node. + if (inst.getUserData() != NULL) { + parent->add_child((PandaNode *) inst.getUserData()); return; } - domInstance_material_Array &mat_instances = bind_mat->getTechnique_common()->getInstance_material_array(); - load_geometry(*geom, parent); + domGeometry* geom = daeSafeCast (inst.getUrl().getElement()); + nassertv(geom != NULL); + + // Create the node. + PT(GeomNode) gnode = new GeomNode(TOSTRING(geom->getName())); + inst.setUserData((void *) gnode); + parent->add_child(gnode); + + domBind_materialRef bind_mat = inst.getBind_material(); + ColladaBindMaterial cbm; + if (bind_mat != NULL) { + cbm.load_bind_material(*bind_mat); + } + + load_geometry(*geom, gnode, cbm); + + // Load in any tags. + domExtra_Array &extras = geom->getExtra_array(); + for (size_t i = 0; i < extras.getCount(); ++i) { + load_tags(*extras[i], gnode); + } } //////////////////////////////////////////////////////////////////// // Function: ColladaLoader::load_geometry -// Description: Loads a COLLADA as a GeomNode object. +// Description: Loads a COLLADA and adds the primitives +// to the given GeomNode object. //////////////////////////////////////////////////////////////////// void ColladaLoader:: -load_geometry(domGeometry &geom, PandaNode *parent) { - // If we already loaded it before, instantiate the stored node. - if (geom.getUserData() != NULL) { - parent->add_child((PandaNode *) geom.getUserData()); - return; - } - +load_geometry(domGeometry &geom, GeomNode *gnode, ColladaBindMaterial &bind_mat) { domMesh* mesh = geom.getMesh(); if (mesh == NULL) { //TODO: support non-mesh geometry. return; } - // Create the node. - PT(GeomNode) gnode = new GeomNode(TOSTRING(geom.getName())); - geom.setUserData((void *) gnode); - parent->add_child(gnode); - //TODO: support other than just triangles. domLines_Array &lines_array = mesh->getLines_array(); for (size_t i = 0; i < lines_array.getCount(); ++i) { @@ -435,12 +444,6 @@ load_geometry(domGeometry &geom, PandaNode *parent) { gnode->add_geom(prim->get_geom()); } } - - // Load in any tags. - domExtra_Array &extras = geom.getExtra_array(); - for (size_t i = 0; i < extras.getCount(); ++i) { - load_tags(*extras[i], gnode); - } } //////////////////////////////////////////////////////////////////// @@ -558,13 +561,3 @@ load_light(domLight &light, PandaNode *parent) { load_tags(*extras[i], lnode); } } - -//////////////////////////////////////////////////////////////////// -// Function: ColladaLoader::load_material -// Description: Loads a COLLADA as a RenderState -// object. -//////////////////////////////////////////////////////////////////// -void ColladaLoader:: -load_material(domBind_material &bind_mat, PandaNode *node) { - -} diff --git a/panda/src/collada/colladaLoader.h b/panda/src/collada/colladaLoader.h index 219494f965..bb77f7d1fa 100644 --- a/panda/src/collada/colladaLoader.h +++ b/panda/src/collada/colladaLoader.h @@ -23,7 +23,9 @@ #include "pvector.h" #include "pta_LVecBase4f.h" +class ColladaBindMaterial; class BamCacheRecord; +class GeomNode; class LightNode; class domBind_material; @@ -67,9 +69,8 @@ private: 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); + void load_geometry(domGeometry &geom, GeomNode *parent, ColladaBindMaterial &bind_mat); void load_light(domLight &light, PandaNode *parent); - void load_material(domBind_material &bind_mat, PandaNode *node); }; #include "colladaLoader.I" diff --git a/panda/src/collada/colladaPrimitive.I b/panda/src/collada/colladaPrimitive.I index db5be67efa..7462524ed2 100644 --- a/panda/src/collada/colladaPrimitive.I +++ b/panda/src/collada/colladaPrimitive.I @@ -27,9 +27,19 @@ add_input(ColladaInput *input) { //////////////////////////////////////////////////////////////////// // Function: ColladaPrimitive::get_geom -// Description: Returns the Goem associated with this primitive. +// Description: Returns the Geom associated with this primitive. //////////////////////////////////////////////////////////////////// INLINE PT(Geom) ColladaPrimitive:: get_geom() const { return _geom; } + +//////////////////////////////////////////////////////////////////// +// Function: ColladaPrimitive::get_material +// Description: Returns the name of this primitive's material, or +// the empty string if none was assigned. +//////////////////////////////////////////////////////////////////// +INLINE const string &ColladaPrimitive:: +get_material() const { + return _material; +} diff --git a/panda/src/collada/colladaPrimitive.cxx b/panda/src/collada/colladaPrimitive.cxx index 93295ecbd2..ffa1266459 100644 --- a/panda/src/collada/colladaPrimitive.cxx +++ b/panda/src/collada/colladaPrimitive.cxx @@ -75,6 +75,7 @@ from_dom(domLines &prim) { ColladaPrimitive *new_prim = new ColladaPrimitive(new GeomLines(GeomEnums::UH_static), prim.getInput_array()); + new_prim->_material = prim.getMaterial(); prim.setUserData(new_prim); @@ -101,6 +102,7 @@ from_dom(domLinestrips &prim) { ColladaPrimitive *new_prim = new ColladaPrimitive(new GeomLinestrips(GeomEnums::UH_static), prim.getInput_array()); + new_prim->_material = prim.getMaterial(); prim.setUserData(new_prim); @@ -127,6 +129,7 @@ from_dom(domPolygons &prim) { ColladaPrimitive *new_prim = new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static), prim.getInput_array()); + new_prim->_material = prim.getMaterial(); prim.setUserData(new_prim); @@ -159,6 +162,7 @@ from_dom(domPolylist &prim) { ColladaPrimitive *new_prim = new ColladaPrimitive(gprim, prim.getInput_array()); + new_prim->_material = prim.getMaterial(); prim.setUserData(new_prim); @@ -195,6 +199,7 @@ from_dom(domTriangles &prim) { ColladaPrimitive *new_prim = new ColladaPrimitive(new GeomTriangles(GeomEnums::UH_static), prim.getInput_array()); + new_prim->_material = prim.getMaterial(); prim.setUserData(new_prim); @@ -221,6 +226,7 @@ from_dom(domTrifans &prim) { ColladaPrimitive *new_prim = new ColladaPrimitive(new GeomTrifans(GeomEnums::UH_static), prim.getInput_array()); + new_prim->_material = prim.getMaterial(); prim.setUserData(new_prim); @@ -244,6 +250,7 @@ from_dom(domTristrips &prim) { ColladaPrimitive *new_prim = new ColladaPrimitive(new GeomTristrips(GeomEnums::UH_static), prim.getInput_array()); + new_prim->_material = prim.getMaterial(); prim.setUserData(new_prim); @@ -296,3 +303,4 @@ load_primitives(domP_Array &p_array) { start_row += num_vertices; } } + diff --git a/panda/src/collada/colladaPrimitive.h b/panda/src/collada/colladaPrimitive.h index 53a40f12d0..659499fff9 100644 --- a/panda/src/collada/colladaPrimitive.h +++ b/panda/src/collada/colladaPrimitive.h @@ -50,6 +50,7 @@ public: unsigned int write_data(GeomVertexData *vdata, int start_row, domP &p); INLINE PT(Geom) get_geom() const; + INLINE const string &get_material() const; private: ColladaPrimitive(GeomPrimitive *prim, daeTArray > &inputs); @@ -64,6 +65,7 @@ private: PT(Geom) _geom; PT(GeomVertexData) _vdata; PT(GeomPrimitive) _gprim; + string _material; }; #include "colladaPrimitive.I"