浏览代码

first step toward reading Collada FX materials

rdb 14 年之前
父节点
当前提交
2d6edaf18b

+ 2 - 0
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 \

+ 98 - 0
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 <dom/domBind_material.h>
+#include <dom/domEffect.h>
+#include <dom/domInstance_effect.h>
+#include <dom/domInstance_material.h>
+#include <dom/domMaterial.h>
+
+#if PANDA_COLLADA_VERSION >= 15
+#include <dom/domFx_profile.h>
+#else
+#include <dom/domFx_profile_abstract.h>
+#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<domMaterial> (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<domEffect>
+    (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]->
+  }
+}

+ 44 - 0
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<string, CPT(RenderState)> _states;
+};
+
+#endif

+ 30 - 37
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<domGeometry> (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 <instance_geometry> as a PandaNode
+//  Description: Loads a COLLADA <instance_geometry> as a GeomNode
 //               object.
 ////////////////////////////////////////////////////////////////////
 void ColladaLoader::
 load_instance_geometry(domInstance_geometry &inst, PandaNode *parent) {
+  // If we already loaded it before, instantiate the stored node.
+  if (inst.getUserData() != NULL) {
+    parent->add_child((PandaNode *) inst.getUserData());
+    return;
+  }
+
   domGeometry* geom = daeSafeCast<domGeometry> (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();
-  if (bind_mat == NULL) {
-    load_geometry(*geom, parent);
-    return;
+  ColladaBindMaterial cbm;
+  if (bind_mat != NULL) {
+    cbm.load_bind_material(*bind_mat);
   }
 
-  domInstance_material_Array &mat_instances = bind_mat->getTechnique_common()->getInstance_material_array();
-  load_geometry(*geom, parent);
+  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 <geometry> as a GeomNode object.
+//  Description: Loads a COLLADA <geometry> 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 <bind_material> as a RenderState
-//               object.
-////////////////////////////////////////////////////////////////////
-void ColladaLoader::
-load_material(domBind_material &bind_mat, PandaNode *node) {
-
-}

+ 3 - 2
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"

+ 11 - 1
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;
+}

+ 8 - 0
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;
   }
 }
+

+ 2 - 0
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<daeSmartRef<domInput_local_offset> > &inputs);
@@ -64,6 +65,7 @@ private:
   PT(Geom) _geom;
   PT(GeomVertexData) _vdata;
   PT(GeomPrimitive) _gprim;
+  string _material;
 };
 
 #include "colladaPrimitive.I"