first step toward reading Collada FX materials

This commit is contained in:
rdb 2011-05-29 19:46:38 +00:00
parent 9bf5812c93
commit 2d6edaf18b
8 changed files with 201 additions and 43 deletions

View File

@ -6,6 +6,8 @@
#define COMBINED_SOURCES collada_composite1.cxx
#define SOURCES \
colladaBindMaterial.cxx \
colladaBindMaterial.h \
colladaInput.cxx \
colladaInput.h colladaInput.I \
colladaLoader.cxx \

View File

@ -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]->
}
}

View File

@ -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

View File

@ -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) {
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);
// 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<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();
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 <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) {
}

View File

@ -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"

View File

@ -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;
}

View File

@ -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;
}
}

View File

@ -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"