add NodePath::find_material(), find_all_texcoords(), etc. Make Material be directly modifiable.

This commit is contained in:
David Rose 2006-01-15 06:34:33 +00:00
parent 28321721ac
commit cf01ef9cd6
37 changed files with 1198 additions and 103 deletions

View File

@ -124,7 +124,7 @@ private:
NodePath _projector;
PT(LensNode) _projector_node;
CPT(InternalName) _texcoord_name;
PT(InternalName) _texcoord_name;
bool _invert_uvs;
bool _vignette_on;
Colorf _vignette_color;

View File

@ -118,7 +118,7 @@ munge_format_impl(const GeomVertexFormat *orig,
for (int i = 0; i < num_stages; ++i) {
TextureStage *stage = _texture->get_on_stage(i);
const InternalName *name = stage->get_texcoord_name();
InternalName *name = stage->get_texcoord_name();
if (used_stages.insert(name).second) {
// This is the first time we've encountered this texcoord name.
const GeomVertexColumn *texcoord_type = orig->get_column(name);

View File

@ -118,7 +118,7 @@ munge_format_impl(const GeomVertexFormat *orig,
for (int i = 0; i < num_stages; ++i) {
TextureStage *stage = _texture->get_on_stage(i);
const InternalName *name = stage->get_texcoord_name();
InternalName *name = stage->get_texcoord_name();
if (used_stages.insert(name).second) {
// This is the first time we've encountered this texcoord name.
const GeomVertexColumn *texcoord_type = orig->get_column(name);

View File

@ -2156,8 +2156,7 @@ record_morph(GeomVertexArrayFormat *array_format,
CharacterMaker *character_maker,
const string &morph_name, InternalName *column_name,
int num_components) {
CPT(InternalName) slider_name = InternalName::make(morph_name);
CPT(InternalName) delta_name =
PT(InternalName) delta_name =
InternalName::get_morph(column_name, morph_name);
if (!array_format->has_column(delta_name)) {
array_format->add_column

View File

@ -450,7 +450,7 @@ get_material_attrib(const EggMaterial *egg_mat, bool bface) {
// Ok, this is the first time we've seen this particular
// EggMaterial. Create a new Material that matches it.
PT(Material) mat = new Material;
PT(Material) mat = new Material(egg_mat->get_name());
if (egg_mat->has_diff()) {
mat->set_diffuse(egg_mat->get_diff());
// By default, ambient is the same as diffuse, if diffuse is
@ -476,7 +476,7 @@ get_material_attrib(const EggMaterial *egg_mat, bool bface) {
mat->set_twoside(bface);
// Now get a global Material pointer, shared with other models.
const Material *shared_mat = MaterialPool::get_material(mat);
Material *shared_mat = MaterialPool::get_material(mat);
// And create a MaterialAttrib for this Material.
CPT(RenderAttrib) mt = MaterialAttrib::make(shared_mat);

View File

@ -49,7 +49,7 @@ GeomVertexArrayFormat() :
// Description:
////////////////////////////////////////////////////////////////////
GeomVertexArrayFormat::
GeomVertexArrayFormat(const InternalName *name0, int num_components0,
GeomVertexArrayFormat(InternalName *name0, int num_components0,
GeomVertexArrayFormat::NumericType numeric_type0,
GeomVertexArrayFormat::Contents contents0) :
_is_registered(false),
@ -67,10 +67,10 @@ GeomVertexArrayFormat(const InternalName *name0, int num_components0,
// Description:
////////////////////////////////////////////////////////////////////
GeomVertexArrayFormat::
GeomVertexArrayFormat(const InternalName *name0, int num_components0,
GeomVertexArrayFormat(InternalName *name0, int num_components0,
GeomVertexArrayFormat::NumericType numeric_type0,
GeomVertexArrayFormat::Contents contents0,
const InternalName *name1, int num_components1,
InternalName *name1, int num_components1,
GeomVertexArrayFormat::NumericType numeric_type1,
GeomVertexArrayFormat::Contents contents1) :
_is_registered(false),
@ -89,13 +89,13 @@ GeomVertexArrayFormat(const InternalName *name0, int num_components0,
// Description:
////////////////////////////////////////////////////////////////////
GeomVertexArrayFormat::
GeomVertexArrayFormat(const InternalName *name0, int num_components0,
GeomVertexArrayFormat(InternalName *name0, int num_components0,
GeomVertexArrayFormat::NumericType numeric_type0,
GeomVertexArrayFormat::Contents contents0,
const InternalName *name1, int num_components1,
InternalName *name1, int num_components1,
GeomVertexArrayFormat::NumericType numeric_type1,
GeomVertexArrayFormat::Contents contents1,
const InternalName *name2, int num_components2,
InternalName *name2, int num_components2,
GeomVertexArrayFormat::NumericType numeric_type2,
GeomVertexArrayFormat::Contents contents2) :
_is_registered(false),
@ -115,16 +115,16 @@ GeomVertexArrayFormat(const InternalName *name0, int num_components0,
// Description:
////////////////////////////////////////////////////////////////////
GeomVertexArrayFormat::
GeomVertexArrayFormat(const InternalName *name0, int num_components0,
GeomVertexArrayFormat(InternalName *name0, int num_components0,
GeomVertexArrayFormat::NumericType numeric_type0,
GeomVertexArrayFormat::Contents contents0,
const InternalName *name1, int num_components1,
InternalName *name1, int num_components1,
GeomVertexArrayFormat::NumericType numeric_type1,
GeomVertexArrayFormat::Contents contents1,
const InternalName *name2, int num_components2,
InternalName *name2, int num_components2,
GeomVertexArrayFormat::NumericType numeric_type2,
GeomVertexArrayFormat::Contents contents2,
const InternalName *name3, int num_components3,
InternalName *name3, int num_components3,
GeomVertexArrayFormat::NumericType numeric_type3,
GeomVertexArrayFormat::Contents contents3) :
_is_registered(false),
@ -208,7 +208,7 @@ GeomVertexArrayFormat::
// type.
////////////////////////////////////////////////////////////////////
int GeomVertexArrayFormat::
add_column(const InternalName *name, int num_components,
add_column(InternalName *name, int num_components,
GeomVertexArrayFormat::NumericType numeric_type,
GeomVertexArrayFormat::Contents contents, int start) {
if (start < 0) {

View File

@ -57,25 +57,25 @@ class EXPCL_PANDA GeomVertexArrayFormat : public TypedWritableReferenceCount, pu
PUBLISHED:
GeomVertexArrayFormat();
GeomVertexArrayFormat(const GeomVertexArrayFormat &copy);
GeomVertexArrayFormat(const InternalName *name0, int num_components0,
GeomVertexArrayFormat(InternalName *name0, int num_components0,
NumericType numeric_type0, Contents contents0);
GeomVertexArrayFormat(const InternalName *name0, int num_components0,
GeomVertexArrayFormat(InternalName *name0, int num_components0,
NumericType numeric_type0, Contents contents0,
const InternalName *name1, int num_components1,
InternalName *name1, int num_components1,
NumericType numeric_type1, Contents contents1);
GeomVertexArrayFormat(const InternalName *name0, int num_components0,
GeomVertexArrayFormat(InternalName *name0, int num_components0,
NumericType numeric_type0, Contents contents0,
const InternalName *name1, int num_components1,
InternalName *name1, int num_components1,
NumericType numeric_type1, Contents contents1,
const InternalName *name2, int num_components2,
InternalName *name2, int num_components2,
NumericType numeric_type2, Contents contents2);
GeomVertexArrayFormat(const InternalName *name0, int num_components0,
GeomVertexArrayFormat(InternalName *name0, int num_components0,
NumericType numeric_type0, Contents contents0,
const InternalName *name1, int num_components1,
InternalName *name1, int num_components1,
NumericType numeric_type1, Contents contents1,
const InternalName *name2, int num_components2,
InternalName *name2, int num_components2,
NumericType numeric_type2, Contents contents2,
const InternalName *name3, int num_components3,
InternalName *name3, int num_components3,
NumericType numeric_type3, Contents contents3);
void operator = (const GeomVertexArrayFormat &copy);
~GeomVertexArrayFormat();
@ -89,7 +89,7 @@ PUBLISHED:
INLINE int get_total_bytes() const;
INLINE int get_pad_to() const;
int add_column(const InternalName *name, int num_components,
int add_column(InternalName *name, int num_components,
NumericType numeric_type, Contents contents,
int start = -1);
int add_column(const GeomVertexColumn &column);

View File

@ -35,9 +35,9 @@ GeomVertexColumn() :
// Description:
////////////////////////////////////////////////////////////////////
INLINE GeomVertexColumn::
GeomVertexColumn(const InternalName *name, int num_components,
NumericType numeric_type, Contents contents,
int start) :
GeomVertexColumn(InternalName *name, int num_components,
NumericType numeric_type, Contents contents,
int start) :
_name(name),
_num_components(num_components),
_numeric_type(numeric_type),
@ -84,7 +84,7 @@ INLINE GeomVertexColumn::
// system-defined field types. Only the system-defined
// field types are used for the actual rendering.
////////////////////////////////////////////////////////////////////
INLINE const InternalName *GeomVertexColumn::
INLINE InternalName *GeomVertexColumn::
get_name() const {
return _name;
}

View File

@ -46,14 +46,14 @@ PUBLISHED:
private:
INLINE GeomVertexColumn();
PUBLISHED:
INLINE GeomVertexColumn(const InternalName *name, int num_components,
NumericType numeric_type, Contents contents,
int start);
INLINE GeomVertexColumn(InternalName *name, int num_components,
NumericType numeric_type, Contents contents,
int start);
INLINE GeomVertexColumn(const GeomVertexColumn &copy);
void operator = (const GeomVertexColumn &copy);
INLINE ~GeomVertexColumn();
INLINE const InternalName *get_name() const;
INLINE InternalName *get_name() const;
INLINE int get_num_components() const;
INLINE int get_num_values() const;
INLINE NumericType get_numeric_type() const;
@ -89,7 +89,7 @@ public:
void fillin(DatagramIterator &scan, BamReader *manager);
private:
CPT(InternalName) _name;
PT(InternalName) _name;
int _num_components;
int _num_values;
NumericType _numeric_type;

View File

@ -963,7 +963,7 @@ bytewise_copy(unsigned char *to, int to_stride,
// anything else.
////////////////////////////////////////////////////////////////////
PT(GeomVertexData) GeomVertexData::
replace_column(const InternalName *name, int num_components,
replace_column(InternalName *name, int num_components,
GeomVertexData::NumericType numeric_type,
GeomVertexData::Contents contents) const {
PT(GeomVertexFormat) new_format = new GeomVertexFormat(*_format);

View File

@ -136,7 +136,7 @@ PUBLISHED:
CPT(GeomVertexData) animate_vertices() const;
PT(GeomVertexData)
replace_column(const InternalName *name, int num_components,
replace_column(InternalName *name, int num_components,
NumericType numeric_type, Contents contents) const;
void output(ostream &out) const;

View File

@ -174,6 +174,24 @@ get_ancestor(int n) const {
}
}
////////////////////////////////////////////////////////////////////
// Function: InternalName::get_top
// Access: Published
// Description: Returns the oldest ancestor in the InternalName's
// chain, not counting the root. This will be the first
// name in the string, e.g. "texcoord.foo.bar" will
// return the InternalName "texcoord".
////////////////////////////////////////////////////////////////////
const InternalName *InternalName::
get_top() const {
test_ref_count_integrity();
if (_parent != (InternalName *)NULL && _parent != get_root()) {
return _parent->get_top();
}
return this;
}
////////////////////////////////////////////////////////////////////
// Function: InternalName::get_net_basename
// Access: Published
@ -184,7 +202,10 @@ get_ancestor(int n) const {
////////////////////////////////////////////////////////////////////
string InternalName::
get_net_basename(int n) const {
if (n == 0) {
if (n < 0) {
return "";
} else if (n == 0) {
return _basename;
} else if (_parent != (InternalName *)NULL && _parent != get_root()) {

View File

@ -57,6 +57,7 @@ PUBLISHED:
int find_ancestor(const string &basename) const;
const InternalName *get_ancestor(int n) const;
const InternalName *get_top() const;
string get_net_basename(int n) const;
void output(ostream &out) const;

View File

@ -23,7 +23,7 @@
// Description:
////////////////////////////////////////////////////////////////////
INLINE Material::
Material() {
Material(const string &name) : Namable(name) {
_ambient.set(1.0f, 1.0f, 1.0f, 1.0f);
_diffuse.set(1.0f, 1.0f, 1.0f, 1.0f);
_specular.set(0.0f, 0.0f, 0.0f, 1.0f);
@ -38,7 +38,7 @@ Material() {
// Description:
////////////////////////////////////////////////////////////////////
INLINE Material::
Material(const Material &copy) {
Material(const Material &copy) : Namable(copy) {
operator = (copy);
}

View File

@ -33,6 +33,7 @@ TypeHandle Material::_type_handle;
////////////////////////////////////////////////////////////////////
void Material::
operator = (const Material &copy) {
Namable::operator = (copy);
_ambient = copy._ambient;
_diffuse = copy._diffuse;
_specular = copy._specular;
@ -148,7 +149,7 @@ compare_to(const Material &other) const {
return get_shininess() < other.get_shininess() ? -1 : 1;
}
return 0;
return strcmp(get_name().c_str(), other.get_name().c_str());
}
////////////////////////////////////////////////////////////////////
@ -158,7 +159,7 @@ compare_to(const Material &other) const {
////////////////////////////////////////////////////////////////////
void Material::
output(ostream &out) const {
out << "material";
out << "Material " << get_name();
if (has_ambient()) {
out << " a(" << get_ambient() << ")";
}
@ -183,21 +184,22 @@ output(ostream &out) const {
////////////////////////////////////////////////////////////////////
void Material::
write(ostream &out, int indent_level) const {
indent(out, indent_level) << "Material " << get_name() << "\n";
if (has_ambient()) {
indent(out, indent_level) << "ambient = " << get_ambient() << "\n";
indent(out, indent_level + 2) << "ambient = " << get_ambient() << "\n";
}
if (has_diffuse()) {
indent(out, indent_level) << "diffuse = " << get_diffuse() << "\n";
indent(out, indent_level + 2) << "diffuse = " << get_diffuse() << "\n";
}
if (has_specular()) {
indent(out, indent_level) << "specular = " << get_specular() << "\n";
indent(out, indent_level + 2) << "specular = " << get_specular() << "\n";
}
if (has_emission()) {
indent(out, indent_level) << "emission = " << get_emission() << "\n";
indent(out, indent_level + 2) << "emission = " << get_emission() << "\n";
}
indent(out, indent_level) << "shininess = " << get_shininess() << "\n";
indent(out, indent_level) << "local = " << get_local() << "\n";
indent(out, indent_level) << "twoside = " << get_twoside() << "\n";
indent(out, indent_level + 2) << "shininess = " << get_shininess() << "\n";
indent(out, indent_level + 2) << "local = " << get_local() << "\n";
indent(out, indent_level + 2) << "twoside = " << get_twoside() << "\n";
}
@ -220,6 +222,7 @@ register_with_read_factory() {
////////////////////////////////////////////////////////////////////
void Material::
write_datagram(BamWriter *manager, Datagram &me) {
me.add_string(get_name());
_ambient.write_datagram(me);
_diffuse.write_datagram(me);
_specular.write_datagram(me);
@ -253,7 +256,10 @@ make_Material(const FactoryParams &params) {
// place
////////////////////////////////////////////////////////////////////
void Material::
fillin(DatagramIterator& scan, BamReader* manager) {
fillin(DatagramIterator &scan, BamReader *manager) {
if (manager->get_file_minor_ver() >= 6) {
set_name(scan.get_string());
}
_ambient.read_datagram(scan);
_diffuse.read_datagram(scan);
_specular.read_datagram(scan);

View File

@ -22,6 +22,7 @@
#include "pandabase.h"
#include "typedWritableReferenceCount.h"
#include "namable.h"
#include "luse.h"
class FactoryParams;
@ -32,9 +33,9 @@ class FactoryParams;
// lighting. A material is only necessary if lighting
// is to be enabled; otherwise, the material isn't used.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA Material : public TypedWritableReferenceCount {
class EXPCL_PANDA Material : public TypedWritableReferenceCount, public Namable {
PUBLISHED:
INLINE Material();
INLINE Material(const string &name = "");
INLINE Material(const Material &copy);
void operator = (const Material &copy);
INLINE ~Material();

View File

@ -20,18 +20,15 @@
////////////////////////////////////////////////////////////////////
// Function: MaterialPool::get_material
// Access: Public, Static
// Description: Returns a const Material pointer that represents the
// Description: Returns a Material pointer that represents the
// same material described by temp, except that it is a
// shared pointer.
//
// Each call to get_material() passing an equivalent
// Material pointer will return the same shared pointer.
//
// This shared pointer must not be further modified.
// Doing so will (a) cause global changes to other
// objects that may share this material, and (b) damage
// the sorted container that stores these things, so
// that future pointers may not be properly shared.
// If you modify the shared pointer, it will
// automatically disassociate it from the pool.
//
// Also, the return value may be a different pointer
// than that passed in, or it may be the same pointer.
@ -40,8 +37,8 @@
// again (like any other PointerTo, it will be freed
// when the last reference count is removed).
////////////////////////////////////////////////////////////////////
INLINE const Material *MaterialPool::
get_material(const CPT(Material) &temp) {
INLINE Material *MaterialPool::
get_material(Material *temp) {
return get_ptr()->ns_get_material(temp);
}

View File

@ -39,10 +39,20 @@ write(ostream &out) {
// Access: Public
// Description: The nonstatic implementation of get_material().
////////////////////////////////////////////////////////////////////
const Material *MaterialPool::
ns_get_material(const CPT(Material) &temp) {
Materials::iterator mi = _materials.insert(temp).first;
return (*mi);
Material *MaterialPool::
ns_get_material(Material *temp) {
CPT(Material) cpttemp = temp;
Materials::iterator mi = _materials.find(cpttemp);
if (mi == _materials.end()) {
mi = _materials.insert(Materials::value_type(new Material(*temp), temp)).first;
} else {
if (*(*mi).first != *(*mi).second) {
// The pointer no longer matches its original value. Save a new
// one.
(*mi).second = temp;
}
}
return (*mi).second;
}
////////////////////////////////////////////////////////////////////
@ -57,11 +67,12 @@ ns_garbage_collect() {
Materials::iterator mi;
for (mi = _materials.begin(); mi != _materials.end(); ++mi) {
const Material *mat = (*mi);
if (mat->get_ref_count() == 1) {
const Material *mat1 = (*mi).first;
Material *mat2 = (*mi).second;
if ((*mat1) != (*mat2) || mat2->get_ref_count() == 1) {
if (gobj_cat.is_debug()) {
gobj_cat.debug()
<< "Releasing " << *mat << "\n";
<< "Releasing " << *mat1 << "\n";
}
++num_released;
} else {
@ -83,9 +94,10 @@ ns_list_contents(ostream &out) const {
out << _materials.size() << " materials:\n";
Materials::const_iterator mi;
for (mi = _materials.begin(); mi != _materials.end(); ++mi) {
const Material *mat = (*mi);
out << " " << *mat
<< " (count = " << mat->get_ref_count() << ")\n";
const Material *mat1 = (*mi).first;
Material *mat2 = (*mi).second;
out << " " << *mat1
<< " (count = " << mat2->get_ref_count() << ")\n";
}
}

View File

@ -40,15 +40,14 @@
// The idea is to create a temporary Material
// representing the lighting state you want to apply,
// then call get_material(), passing in your temporary
// Material. The return value will be a constant
// Material object that should be modified (because it
// is now shared among many different geometries), that
// is the same as the temporary Material pointer you
// supplied but may be a different pointer.
// Material. The return value will either be a new
// Material object, or it may be the the same object you
// supplied; in either case, it will have the same
// value.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA MaterialPool {
PUBLISHED:
INLINE static const Material *get_material(const CPT(Material) &temp);
INLINE static Material *get_material(Material *temp);
INLINE static int garbage_collect();
INLINE static void list_contents(ostream &out);
static void write(ostream &out);
@ -56,14 +55,19 @@ PUBLISHED:
private:
INLINE MaterialPool();
const Material *ns_get_material(const CPT(Material) &temp);
Material *ns_get_material(Material *temp);
int ns_garbage_collect();
void ns_list_contents(ostream &out) const;
static MaterialPool *get_ptr();
static MaterialPool *_global_ptr;
typedef pset< CPT(Material), indirect_compare_to<const Material *> > Materials;
// We store a map of CPT(Material) to PT(Material). These are two
// equivalent structures, but different pointers. The first pointer
// never leaves this class. If the second pointer changes value,
// we'll notice it and return a new one.
typedef pmap< CPT(Material), PT(Material), indirect_compare_to<const Material *> > Materials;
Materials _materials;
};

View File

@ -55,6 +55,7 @@
fogAttrib.I fogAttrib.h \
geomNode.I geomNode.h \
geomTransformer.I geomTransformer.h \
internalNameCollection.I internalNameCollection.h \
lensNode.I lensNode.h \
light.I light.h \
lightAttrib.I lightAttrib.h \
@ -67,6 +68,7 @@
loaderOptions.I loaderOptions.h \
lodNode.I lodNode.h \
materialAttrib.I materialAttrib.h \
materialCollection.I materialCollection.h \
modelNode.I modelNode.h \
modelPool.I modelPool.h \
modelRoot.I modelRoot.h \
@ -161,6 +163,7 @@
fogAttrib.cxx \
geomNode.cxx \
geomTransformer.cxx \
internalNameCollection.cxx \
lensNode.cxx \
light.cxx \
lightAttrib.cxx \
@ -173,6 +176,7 @@
loaderOptions.cxx \
lodNode.cxx \
materialAttrib.cxx \
materialCollection.cxx \
modelNode.cxx \
modelPool.cxx \
modelRoot.cxx \
@ -261,6 +265,7 @@
fogAttrib.I fogAttrib.h \
geomNode.I geomNode.h \
geomTransformer.I geomTransformer.h \
internalNameCollection.I internalNameCollection.h \
lensNode.I lensNode.h \
light.I light.h \
lightAttrib.I lightAttrib.h \
@ -273,6 +278,7 @@
loaderOptions.I loaderOptions.h \
lodNode.I lodNode.h \
materialAttrib.I materialAttrib.h \
materialCollection.I materialCollection.h \
modelNode.I modelNode.h \
modelPool.I modelPool.h \
modelRoot.I modelRoot.h \

View File

@ -526,10 +526,10 @@ munge_texcoord_light_vector(const CullTraverser *traverser) {
// Determine the names of the tangent and binormal columns
// associated with the stage's texcoord name.
CPT(InternalName) tangent_name = InternalName::get_tangent_name(source_name);
CPT(InternalName) binormal_name = InternalName::get_binormal_name(source_name);
PT(InternalName) tangent_name = InternalName::get_tangent_name(source_name);
PT(InternalName) binormal_name = InternalName::get_binormal_name(source_name);
CPT(InternalName) texcoord_name = stage->get_texcoord_name();
PT(InternalName) texcoord_name = stage->get_texcoord_name();
if (_munged_data->has_column(tangent_name) &&
_munged_data->has_column(binormal_name)) {

View File

@ -249,7 +249,7 @@ apply_attribs_to_vertices(const AccumulatedAttribs &attribs, int attrib_types,
int num_stages = tma->get_num_stages();
for (int i = 0; i < num_stages; i++) {
TextureStage *stage = tma->get_stage(i);
const InternalName *name = stage->get_texcoord_name();
InternalName *name = stage->get_texcoord_name();
if (get_name_count(name_count, name) > 1) {
// We can't transform these texcoords, since the name is
// used by more than one active stage.

View File

@ -152,7 +152,7 @@ transform_vertices(GeomNode *node, const LMatrix4f &mat) {
////////////////////////////////////////////////////////////////////
bool GeomTransformer::
transform_texcoords(Geom *geom, const InternalName *from_name,
const InternalName *to_name, const LMatrix4f &mat) {
InternalName *to_name, const LMatrix4f &mat) {
PStatTimer timer(apply_texcoord_collector);
nassertr(geom != (Geom *)NULL, false);
@ -212,7 +212,7 @@ transform_texcoords(Geom *geom, const InternalName *from_name,
////////////////////////////////////////////////////////////////////
bool GeomTransformer::
transform_texcoords(GeomNode *node, const InternalName *from_name,
const InternalName *to_name, const LMatrix4f &mat) {
InternalName *to_name, const LMatrix4f &mat) {
bool any_changed = false;
GeomNode::CDWriter cdata(node->_cycler);

View File

@ -58,11 +58,9 @@ public:
bool transform_vertices(GeomNode *node, const LMatrix4f &mat);
bool transform_texcoords(Geom *geom, const InternalName *from_name,
const InternalName *to_name,
const LMatrix4f &mat);
InternalName *to_name, const LMatrix4f &mat);
bool transform_texcoords(GeomNode *node, const InternalName *from_name,
const InternalName *to_name,
const LMatrix4f &mat);
InternalName *to_name, const LMatrix4f &mat);
bool set_color(Geom *geom, const Colorf &color);
bool set_color(GeomNode *node, const Colorf &color);

View File

@ -0,0 +1,27 @@
// Filename: internalNameCollection.I
// Created by: drose (16Mar02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE InternalNameCollection::
~InternalNameCollection() {
}

View File

@ -0,0 +1,263 @@
// Filename: internalNameCollection.cxx
// Created by: drose (16Mar02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "internalNameCollection.h"
#include "indent.h"
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
InternalNameCollection::
InternalNameCollection() {
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
InternalNameCollection::
InternalNameCollection(const InternalNameCollection &copy) :
_names(copy._names)
{
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::Copy Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void InternalNameCollection::
operator = (const InternalNameCollection &copy) {
_names = copy._names;
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::add_name
// Access: Published
// Description: Adds a new InternalName to the collection.
////////////////////////////////////////////////////////////////////
void InternalNameCollection::
add_name(InternalName *name) {
// If the pointer to our internal array is shared by any other
// InternalNameCollections, we have to copy the array now so we won't
// inadvertently modify any of our brethren InternalNameCollection
// objects.
if (_names.get_ref_count() > 1) {
InternalNames old_names = _names;
_names = InternalNames::empty_array(0);
_names.v() = old_names.v();
}
_names.push_back(name);
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::remove_name
// Access: Published
// Description: Removes the indicated InternalName from the collection.
// Returns true if the name was removed, false if it was
// not a member of the collection.
////////////////////////////////////////////////////////////////////
bool InternalNameCollection::
remove_name(InternalName *name) {
int name_index = -1;
for (int i = 0; name_index == -1 && i < (int)_names.size(); i++) {
if (_names[i] == name) {
name_index = i;
}
}
if (name_index == -1) {
// The indicated name was not a member of the collection.
return false;
}
// If the pointer to our internal array is shared by any other
// InternalNameCollections, we have to copy the array now so we won't
// inadvertently modify any of our brethren InternalNameCollection
// objects.
if (_names.get_ref_count() > 1) {
InternalNames old_names = _names;
_names = InternalNames::empty_array(0);
_names.v() = old_names.v();
}
_names.erase(_names.begin() + name_index);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::add_names_from
// Access: Published
// Description: Adds all the InternalNames indicated in the other
// collection to this name. The other names are simply
// appended to the end of the names in this list;
// duplicates are not automatically removed.
////////////////////////////////////////////////////////////////////
void InternalNameCollection::
add_names_from(const InternalNameCollection &other) {
int other_num_names = other.get_num_names();
for (int i = 0; i < other_num_names; i++) {
add_name(other.get_name(i));
}
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::remove_names_from
// Access: Published
// Description: Removes from this collection all of the InternalNames
// listed in the other collection.
////////////////////////////////////////////////////////////////////
void InternalNameCollection::
remove_names_from(const InternalNameCollection &other) {
InternalNames new_names;
int num_names = get_num_names();
for (int i = 0; i < num_names; i++) {
PT(InternalName) name = get_name(i);
if (!other.has_name(name)) {
new_names.push_back(name);
}
}
_names = new_names;
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::remove_duplicate_names
// Access: Published
// Description: Removes any duplicate entries of the same InternalNames
// on this collection. If a InternalName appears multiple
// times, the first appearance is retained; subsequent
// appearances are removed.
////////////////////////////////////////////////////////////////////
void InternalNameCollection::
remove_duplicate_names() {
InternalNames new_names;
int num_names = get_num_names();
for (int i = 0; i < num_names; i++) {
PT(InternalName) name = get_name(i);
bool duplicated = false;
for (int j = 0; j < i && !duplicated; j++) {
duplicated = (name == get_name(j));
}
if (!duplicated) {
new_names.push_back(name);
}
}
_names = new_names;
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::has_name
// Access: Published
// Description: Returns true if the indicated InternalName appears in
// this collection, false otherwise.
////////////////////////////////////////////////////////////////////
bool InternalNameCollection::
has_name(InternalName *name) const {
for (int i = 0; i < get_num_names(); i++) {
if (name == get_name(i)) {
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::clear
// Access: Published
// Description: Removes all InternalNames from the collection.
////////////////////////////////////////////////////////////////////
void InternalNameCollection::
clear() {
_names.clear();
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::get_num_names
// Access: Published
// Description: Returns the number of InternalNames in the collection.
////////////////////////////////////////////////////////////////////
int InternalNameCollection::
get_num_names() const {
return _names.size();
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::get_name
// Access: Published
// Description: Returns the nth InternalName in the collection.
////////////////////////////////////////////////////////////////////
InternalName *InternalNameCollection::
get_name(int index) const {
nassertr(index >= 0 && index < (int)_names.size(), NULL);
return _names[index];
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::operator []
// Access: Published
// Description: Returns the nth InternalName in the collection. This is
// the same as get_name(), but it may be a more
// convenient way to access it.
////////////////////////////////////////////////////////////////////
InternalName *InternalNameCollection::
operator [] (int index) const {
nassertr(index >= 0 && index < (int)_names.size(), NULL);
return _names[index];
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::output
// Access: Published
// Description: Writes a brief one-line description of the
// InternalNameCollection to the indicated output stream.
////////////////////////////////////////////////////////////////////
void InternalNameCollection::
output(ostream &out) const {
if (get_num_names() == 1) {
out << "1 InternalName";
} else {
out << get_num_names() << " InternalNames";
}
}
////////////////////////////////////////////////////////////////////
// Function: InternalNameCollection::write
// Access: Published
// Description: Writes a complete multi-line description of the
// InternalNameCollection to the indicated output stream.
////////////////////////////////////////////////////////////////////
void InternalNameCollection::
write(ostream &out, int indent_level) const {
for (int i = 0; i < get_num_names(); i++) {
indent(out, indent_level) << *get_name(i) << "\n";
}
}

View File

@ -0,0 +1,66 @@
// Filename: internalNameCollection.h
// Created by: drose (16Mar02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef INTERNALNAMECOLLECTION_H
#define INTERNALNAMECOLLECTION_H
#include "pandabase.h"
#include "pointerToArray.h"
#include "internalName.h"
////////////////////////////////////////////////////////////////////
// Class : InternalNameCollection
// Description :
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA InternalNameCollection {
PUBLISHED:
InternalNameCollection();
InternalNameCollection(const InternalNameCollection &copy);
void operator = (const InternalNameCollection &copy);
INLINE ~InternalNameCollection();
void add_name(InternalName *name);
bool remove_name(InternalName *name);
void add_names_from(const InternalNameCollection &other);
void remove_names_from(const InternalNameCollection &other);
void remove_duplicate_names();
bool has_name(InternalName *name) const;
void clear();
int get_num_names() const;
InternalName *get_name(int index) const;
InternalName *operator [] (int index) const;
void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
private:
typedef PTA(PT(InternalName)) InternalNames;
InternalNames _names;
};
INLINE ostream &operator << (ostream &out, const InternalNameCollection &col) {
col.output(out);
return out;
}
#include "internalNameCollection.I"
#endif

View File

@ -46,7 +46,7 @@ is_off() const {
// returns the material that is associated. Otherwise,
// return NULL.
////////////////////////////////////////////////////////////////////
INLINE const Material *MaterialAttrib::
INLINE Material *MaterialAttrib::
get_material() const {
return _material;
}

View File

@ -33,7 +33,7 @@ TypeHandle MaterialAttrib::_type_handle;
// rendering the indicated material onto geometry.
////////////////////////////////////////////////////////////////////
CPT(RenderAttrib) MaterialAttrib::
make(const Material *material) {
make(Material *material) {
MaterialAttrib *attrib = new MaterialAttrib;
attrib->_material = material;
return return_new(attrib);

View File

@ -28,7 +28,7 @@
// Class : MaterialAttrib
// Description : Indicates which, if any, material should be applied
// to geometry. The material is used primarily to
// control lighting effects, and isn't necessarily (or
// control lighting effects, and isn't necessary (or
// useful) in the absence of lighting.
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA MaterialAttrib : public RenderAttrib {
@ -36,11 +36,11 @@ private:
INLINE MaterialAttrib();
PUBLISHED:
static CPT(RenderAttrib) make(const Material *material);
static CPT(RenderAttrib) make(Material *material);
static CPT(RenderAttrib) make_off();
INLINE bool is_off() const;
INLINE const Material *get_material() const;
INLINE Material *get_material() const;
public:
virtual void output(ostream &out) const;
@ -51,7 +51,7 @@ protected:
virtual RenderAttrib *make_default_impl() const;
private:
CPT(Material) _material;
PT(Material) _material;
public:
static void register_with_read_factory();

View File

@ -0,0 +1,27 @@
// Filename: materialCollection.I
// Created by: drose (16Mar02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::Destructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
INLINE MaterialCollection::
~MaterialCollection() {
}

View File

@ -0,0 +1,282 @@
// Filename: materialCollection.cxx
// Created by: drose (16Mar02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#include "materialCollection.h"
#include "indent.h"
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
MaterialCollection::
MaterialCollection() {
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::Copy Constructor
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
MaterialCollection::
MaterialCollection(const MaterialCollection &copy) :
_materials(copy._materials)
{
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::Copy Assignment Operator
// Access: Published
// Description:
////////////////////////////////////////////////////////////////////
void MaterialCollection::
operator = (const MaterialCollection &copy) {
_materials = copy._materials;
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::add_material
// Access: Published
// Description: Adds a new Material to the collection.
////////////////////////////////////////////////////////////////////
void MaterialCollection::
add_material(Material *node_material) {
// If the pointer to our internal array is shared by any other
// MaterialCollections, we have to copy the array now so we won't
// inadvertently modify any of our brethren MaterialCollection
// objects.
if (_materials.get_ref_count() > 1) {
Materials old_materials = _materials;
_materials = Materials::empty_array(0);
_materials.v() = old_materials.v();
}
_materials.push_back(node_material);
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::remove_material
// Access: Published
// Description: Removes the indicated Material from the collection.
// Returns true if the material was removed, false if it was
// not a member of the collection.
////////////////////////////////////////////////////////////////////
bool MaterialCollection::
remove_material(Material *node_material) {
int material_index = -1;
for (int i = 0; material_index == -1 && i < (int)_materials.size(); i++) {
if (_materials[i] == node_material) {
material_index = i;
}
}
if (material_index == -1) {
// The indicated material was not a member of the collection.
return false;
}
// If the pointer to our internal array is shared by any other
// MaterialCollections, we have to copy the array now so we won't
// inadvertently modify any of our brethren MaterialCollection
// objects.
if (_materials.get_ref_count() > 1) {
Materials old_materials = _materials;
_materials = Materials::empty_array(0);
_materials.v() = old_materials.v();
}
_materials.erase(_materials.begin() + material_index);
return true;
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::add_materials_from
// Access: Published
// Description: Adds all the Materials indicated in the other
// collection to this material. The other materials are simply
// appended to the end of the materials in this list;
// duplicates are not automatically removed.
////////////////////////////////////////////////////////////////////
void MaterialCollection::
add_materials_from(const MaterialCollection &other) {
int other_num_materials = other.get_num_materials();
for (int i = 0; i < other_num_materials; i++) {
add_material(other.get_material(i));
}
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::remove_materials_from
// Access: Published
// Description: Removes from this collection all of the Materials
// listed in the other collection.
////////////////////////////////////////////////////////////////////
void MaterialCollection::
remove_materials_from(const MaterialCollection &other) {
Materials new_materials;
int num_materials = get_num_materials();
for (int i = 0; i < num_materials; i++) {
PT(Material) material = get_material(i);
if (!other.has_material(material)) {
new_materials.push_back(material);
}
}
_materials = new_materials;
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::remove_duplicate_materials
// Access: Published
// Description: Removes any duplicate entries of the same Materials
// on this collection. If a Material appears multiple
// times, the first appearance is retained; subsequent
// appearances are removed.
////////////////////////////////////////////////////////////////////
void MaterialCollection::
remove_duplicate_materials() {
Materials new_materials;
int num_materials = get_num_materials();
for (int i = 0; i < num_materials; i++) {
PT(Material) material = get_material(i);
bool duplicated = false;
for (int j = 0; j < i && !duplicated; j++) {
duplicated = (material == get_material(j));
}
if (!duplicated) {
new_materials.push_back(material);
}
}
_materials = new_materials;
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::has_material
// Access: Published
// Description: Returns true if the indicated Material appears in
// this collection, false otherwise.
////////////////////////////////////////////////////////////////////
bool MaterialCollection::
has_material(Material *material) const {
for (int i = 0; i < get_num_materials(); i++) {
if (material == get_material(i)) {
return true;
}
}
return false;
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::clear
// Access: Published
// Description: Removes all Materials from the collection.
////////////////////////////////////////////////////////////////////
void MaterialCollection::
clear() {
_materials.clear();
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::find_material
// Access: Published
// Description: Returns the material in the collection with the
// indicated name, if any, or NULL if no material has
// that name.
////////////////////////////////////////////////////////////////////
Material *MaterialCollection::
find_material(const string &name) const {
int num_materials = get_num_materials();
for (int i = 0; i < num_materials; i++) {
Material *material = get_material(i);
if (material->get_name() == name) {
return material;
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::get_num_materials
// Access: Published
// Description: Returns the number of Materials in the collection.
////////////////////////////////////////////////////////////////////
int MaterialCollection::
get_num_materials() const {
return _materials.size();
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::get_material
// Access: Published
// Description: Returns the nth Material in the collection.
////////////////////////////////////////////////////////////////////
Material *MaterialCollection::
get_material(int index) const {
nassertr(index >= 0 && index < (int)_materials.size(), NULL);
return _materials[index];
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::operator []
// Access: Published
// Description: Returns the nth Material in the collection. This is
// the same as get_material(), but it may be a more
// convenient way to access it.
////////////////////////////////////////////////////////////////////
Material *MaterialCollection::
operator [] (int index) const {
nassertr(index >= 0 && index < (int)_materials.size(), NULL);
return _materials[index];
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::output
// Access: Published
// Description: Writes a brief one-line description of the
// MaterialCollection to the indicated output stream.
////////////////////////////////////////////////////////////////////
void MaterialCollection::
output(ostream &out) const {
if (get_num_materials() == 1) {
out << "1 Material";
} else {
out << get_num_materials() << " Materials";
}
}
////////////////////////////////////////////////////////////////////
// Function: MaterialCollection::write
// Access: Published
// Description: Writes a complete multi-line description of the
// MaterialCollection to the indicated output stream.
////////////////////////////////////////////////////////////////////
void MaterialCollection::
write(ostream &out, int indent_level) const {
for (int i = 0; i < get_num_materials(); i++) {
indent(out, indent_level) << *get_material(i) << "\n";
}
}

View File

@ -0,0 +1,68 @@
// Filename: materialCollection.h
// Created by: drose (16Mar02)
//
////////////////////////////////////////////////////////////////////
//
// PANDA 3D SOFTWARE
// Copyright (c) 2001 - 2004, Disney Enterprises, Inc. All rights reserved
//
// All use of this software is subject to the terms of the Panda 3d
// Software license. You should have received a copy of this license
// along with this source code; you will also find a current copy of
// the license at http://etc.cmu.edu/panda3d/docs/license/ .
//
// To contact the maintainers of this program write to
// panda3d-general@lists.sourceforge.net .
//
////////////////////////////////////////////////////////////////////
#ifndef MATERIALCOLLECTION_H
#define MATERIALCOLLECTION_H
#include "pandabase.h"
#include "pointerToArray.h"
#include "material.h"
////////////////////////////////////////////////////////////////////
// Class : MaterialCollection
// Description :
////////////////////////////////////////////////////////////////////
class EXPCL_PANDA MaterialCollection {
PUBLISHED:
MaterialCollection();
MaterialCollection(const MaterialCollection &copy);
void operator = (const MaterialCollection &copy);
INLINE ~MaterialCollection();
void add_material(Material *node_material);
bool remove_material(Material *node_material);
void add_materials_from(const MaterialCollection &other);
void remove_materials_from(const MaterialCollection &other);
void remove_duplicate_materials();
bool has_material(Material *material) const;
void clear();
Material *find_material(const string &name) const;
int get_num_materials() const;
Material *get_material(int index) const;
Material *operator [] (int index) const;
void output(ostream &out) const;
void write(ostream &out, int indent_level = 0) const;
private:
typedef PTA(PT(Material)) Materials;
Materials _materials;
};
INLINE ostream &operator << (ostream &out, const MaterialCollection &col) {
col.output(out);
return out;
}
#include "materialCollection.I"
#endif

View File

@ -20,6 +20,7 @@
#include "nodePathCollection.h"
#include "findApproxPath.h"
#include "findApproxLevelEntry.h"
#include "internalNameCollection.h"
#include "config_pgraph.h"
#include "colorAttrib.h"
#include "colorScaleAttrib.h"
@ -28,6 +29,7 @@
#include "texMatrixAttrib.h"
#include "texGenAttrib.h"
#include "materialAttrib.h"
#include "materialCollection.h"
#include "lightAttrib.h"
#include "clipPlaneAttrib.h"
#include "polylightEffect.h"
@ -3866,6 +3868,113 @@ has_vertex_column(const InternalName *name) const {
return r_has_vertex_column(node(), name);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::find_all_vertex_columns
// Access: Published
// Description: Returns a list of all vertex array columns stored on
// some geometry found at this node level and below.
////////////////////////////////////////////////////////////////////
InternalNameCollection NodePath::
find_all_vertex_columns() const {
nassertr_always(!is_empty(), InternalNameCollection());
InternalNames vertex_columns;
r_find_all_vertex_columns(node(), vertex_columns);
InternalNameCollection tc;
InternalNames::iterator ti;
for (ti = vertex_columns.begin(); ti != vertex_columns.end(); ++ti) {
tc.add_name(*ti);
}
return tc;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::find_all_vertex_columns
// Access: Published
// Description: Returns a list of all vertex array columns stored on
// some geometry found at this node level and below that
// match the indicated name (which may contain wildcard
// characters).
////////////////////////////////////////////////////////////////////
InternalNameCollection NodePath::
find_all_vertex_columns(const string &name) const {
nassertr_always(!is_empty(), InternalNameCollection());
InternalNames vertex_columns;
r_find_all_vertex_columns(node(), vertex_columns);
GlobPattern glob(name);
InternalNameCollection tc;
InternalNames::iterator ti;
for (ti = vertex_columns.begin(); ti != vertex_columns.end(); ++ti) {
InternalName *name = (*ti);
if (glob.matches(name->get_name())) {
tc.add_name(name);
}
}
return tc;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::find_all_texcoords
// Access: Published
// Description: Returns a list of all texture coordinate sets used by
// any geometry at this node level and below.
////////////////////////////////////////////////////////////////////
InternalNameCollection NodePath::
find_all_texcoords() const {
nassertr_always(!is_empty(), InternalNameCollection());
InternalNames vertex_columns;
r_find_all_vertex_columns(node(), vertex_columns);
CPT(InternalName) texcoord_name = InternalName::get_texcoord();
InternalNameCollection tc;
InternalNames::iterator ti;
for (ti = vertex_columns.begin(); ti != vertex_columns.end(); ++ti) {
if ((*ti)->get_top() == texcoord_name) {
tc.add_name(*ti);
}
}
return tc;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::find_all_texcoords
// Access: Published
// Description: Returns a list of all texture coordinate sets used by
// any geometry at this node level and below that match
// the indicated name (which may contain wildcard
// characters).
////////////////////////////////////////////////////////////////////
InternalNameCollection NodePath::
find_all_texcoords(const string &name) const {
nassertr_always(!is_empty(), InternalNameCollection());
InternalNames vertex_columns;
r_find_all_vertex_columns(node(), vertex_columns);
GlobPattern glob(name);
CPT(InternalName) texcoord_name = InternalName::get_texcoord();
InternalNameCollection tc;
InternalNames::iterator ti;
for (ti = vertex_columns.begin(); ti != vertex_columns.end(); ++ti) {
InternalName *name = (*ti);
if (name->get_top() == texcoord_name) {
// This is a texture coordinate name. Figure out the basename
// of the texture coordinates.
int index = name->find_ancestor("texcoord");
nassertr(index != -1, InternalNameCollection());
string net_basename = name->get_net_basename(index - 1);
if (glob.matches(net_basename)) {
tc.add_name(name);
}
}
}
return tc;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::find_texture
// Access: Published
@ -4041,6 +4150,67 @@ find_all_texture_stages(const string &name) const {
return tc;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::find_material
// Access: Published
// Description: Returns the first material found applied to geometry
// at this node or below that matches the indicated name
// (which may contain wildcards). Returns the material
// if it is found, or NULL if it is not.
////////////////////////////////////////////////////////////////////
Material *NodePath::
find_material(const string &name) const {
nassertr_always(!is_empty(), NULL);
GlobPattern glob(name);
return r_find_material(node(), get_net_state(), glob);
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::find_all_materials
// Access: Published
// Description: Returns a list of a materials applied to geometry at
// this node and below.
////////////////////////////////////////////////////////////////////
MaterialCollection NodePath::
find_all_materials() const {
nassertr_always(!is_empty(), MaterialCollection());
Materials materials;
r_find_all_materials(node(), get_net_state(), materials);
MaterialCollection tc;
Materials::iterator ti;
for (ti = materials.begin(); ti != materials.end(); ++ti) {
tc.add_material(*ti);
}
return tc;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::find_all_materials
// Access: Published
// Description: Returns a list of a materials applied to geometry at
// this node and below that match the indicated name
// (which may contain wildcard characters).
////////////////////////////////////////////////////////////////////
MaterialCollection NodePath::
find_all_materials(const string &name) const {
nassertr_always(!is_empty(), MaterialCollection());
Materials materials;
r_find_all_materials(node(), get_net_state(), materials);
GlobPattern glob(name);
MaterialCollection tc;
Materials::iterator ti;
for (ti = materials.begin(); ti != materials.end(); ++ti) {
Material *material = (*ti);
if (glob.matches(material->get_name())) {
tc.add_material(material);
}
}
return tc;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::set_material
// Access: Published
@ -4115,10 +4285,8 @@ has_material() const {
// applied to the geometry at or below this level, as
// another material at a higher or lower level may
// override.
//
// This function returns a copy of the given material,
// to allow changes, if desired. Once changes are made,
// they should be reapplied via set_material().
// See also find_material().
////////////////////////////////////////////////////////////////////
PT(Material) NodePath::
get_material() const {
@ -4127,7 +4295,7 @@ get_material() const {
node()->get_attrib(MaterialAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
const MaterialAttrib *ma = DCAST(MaterialAttrib, attrib);
return new Material(*ma->get_material());
return ma->get_material();
}
return NULL;
@ -5801,6 +5969,43 @@ r_has_vertex_column(PandaNode *node, const InternalName *name) const {
return false;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::r_find_all_vertex_columns
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
r_find_all_vertex_columns(PandaNode *node,
NodePath::InternalNames &vertex_columns) const {
if (node->is_geom_node()) {
GeomNode *gnode;
DCAST_INTO_V(gnode, node);
int num_geoms = gnode->get_num_geoms();
for (int i = 0; i < num_geoms; ++i) {
const Geom *geom = gnode->get_geom(i);
const GeomVertexFormat *format = geom->get_vertex_data()->get_format();
int num_arrays = format->get_num_arrays();
for (int j = 0; j < num_arrays; ++j) {
const GeomVertexArrayFormat *array = format->get_array(j);
int num_columns = array->get_num_columns();
for (int k = 0; k < num_columns; ++k) {
const GeomVertexColumn *column = array->get_column(k);
vertex_columns.insert(column->get_name());
}
}
}
}
// Now consider children.
PandaNode::Children cr = node->get_children();
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
PandaNode *child = cr.get_child(i);
r_find_all_vertex_columns(child, vertex_columns);
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::r_find_texture
// Access: Private
@ -6133,6 +6338,96 @@ r_unify_texture_stages(PandaNode *node, TextureStage *stage) {
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::r_find_material
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
Material *NodePath::
r_find_material(PandaNode *node, const RenderState *state,
const GlobPattern &glob) const {
if (node->is_geom_node()) {
GeomNode *gnode;
DCAST_INTO_R(gnode, node, NULL);
int num_geoms = gnode->get_num_geoms();
for (int i = 0; i < num_geoms; i++) {
CPT(RenderState) geom_state =
state->compose(gnode->get_geom_state(i));
// Look for a MaterialAttrib on the state.
const RenderAttrib *attrib =
geom_state->get_attrib(MaterialAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
const MaterialAttrib *ta = DCAST(MaterialAttrib, attrib);
if (!ta->is_off()) {
Material *material = ta->get_material();
if (material != (Material *)NULL) {
return material;
}
}
}
}
}
// Now consider children.
PandaNode::Children cr = node->get_children();
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
PandaNode *child = cr.get_child(i);
CPT(RenderState) next_state = state->compose(child->get_state());
Material *result = r_find_material(child, next_state, glob);
if (result != (Material *)NULL) {
return result;
}
}
return NULL;
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::r_find_all_materials
// Access: Private
// Description:
////////////////////////////////////////////////////////////////////
void NodePath::
r_find_all_materials(PandaNode *node, const RenderState *state,
NodePath::Materials &materials) const {
if (node->is_geom_node()) {
GeomNode *gnode;
DCAST_INTO_V(gnode, node);
int num_geoms = gnode->get_num_geoms();
for (int i = 0; i < num_geoms; i++) {
CPT(RenderState) geom_state =
state->compose(gnode->get_geom_state(i));
// Look for a MaterialAttrib on the state.
const RenderAttrib *attrib =
geom_state->get_attrib(MaterialAttrib::get_class_type());
if (attrib != (const RenderAttrib *)NULL) {
const MaterialAttrib *ta = DCAST(MaterialAttrib, attrib);
if (!ta->is_off()) {
Material *material = ta->get_material();
if (material != (Material *)NULL) {
materials.insert(material);
}
}
}
}
}
// Now consider children.
PandaNode::Children cr = node->get_children();
int num_children = cr.get_num_children();
for (int i = 0; i < num_children; i++) {
PandaNode *child = cr.get_child(i);
CPT(RenderState) next_state = state->compose(child->get_state());
r_find_all_materials(child, next_state, materials);
}
}
////////////////////////////////////////////////////////////////////
// Function: NodePath::r_prepare_scene
// Access: Private

View File

@ -37,11 +37,13 @@ class FindApproxPath;
class FindApproxLevelEntry;
class Light;
class PolylightNode;
class InternalNameCollection;
class Texture;
class TextureStage;
class TextureCollection;
class TextureStageCollection;
class Material;
class MaterialCollection;
class Fog;
class GlobPattern;
class PreparedGraphicsObjects;
@ -648,6 +650,10 @@ PUBLISHED:
INLINE bool has_texcoord(const string &texcoord_name) const;
bool has_vertex_column(const InternalName *name) const;
InternalNameCollection find_all_vertex_columns() const;
InternalNameCollection find_all_vertex_columns(const string &name) const;
InternalNameCollection find_all_texcoords() const;
InternalNameCollection find_all_texcoords(const string &name) const;
Texture *find_texture(const string &name) const;
Texture *find_texture(TextureStage *stage) const;
@ -661,6 +667,10 @@ PUBLISHED:
void unify_texture_stages(TextureStage *stage);
Material *find_material(const string &name) const;
MaterialCollection find_all_materials() const;
MaterialCollection find_all_materials(const string &name) const;
void set_material(Material *tex, int priority = 0);
void set_material_off(int priority = 0);
void clear_material();
@ -823,7 +833,10 @@ private:
CollideMask and_mask, CollideMask or_mask,
TypeHandle node_type);
typedef phash_set<InternalName *, pointer_hash> InternalNames;
bool r_has_vertex_column(PandaNode *node, const InternalName *name) const;
void r_find_all_vertex_columns(PandaNode *node,
InternalNames &vertex_columns) const;
typedef phash_set<Texture *, pointer_hash> Textures;
Texture *r_find_texture(PandaNode *node, const RenderState *state,
@ -842,6 +855,12 @@ private:
void r_unify_texture_stages(PandaNode *node, TextureStage *stage);
typedef phash_set<Material *, pointer_hash> Materials;
Material *r_find_material(PandaNode *node, const RenderState *state,
const GlobPattern &glob) const;
void r_find_all_materials(PandaNode *node, const RenderState *state,
Materials &materials) const;
void r_prepare_scene(PandaNode *node, const RenderState *state,
PreparedGraphicsObjects *prepared_objects);

View File

@ -1,3 +1,4 @@
#include "internalNameCollection.cxx"
#include "lensNode.cxx"
#include "light.cxx"
#include "lightAttrib.cxx"
@ -10,6 +11,7 @@
#include "loaderOptions.cxx"
#include "lodNode.cxx"
#include "materialAttrib.cxx"
#include "materialCollection.cxx"
#include "modelNode.cxx"
#include "modelPool.cxx"
#include "modelRoot.cxx"

View File

@ -35,12 +35,13 @@ static const unsigned short _bam_major_ver = 5;
// Bumped to major version 4 on 4/10/02 to store new scene graph.
// Bumped to major version 5 on 5/6/05 for new Geom implementation.
static const unsigned short _bam_minor_ver = 5;
static const unsigned short _bam_minor_ver = 6;
// Bumped to minor version 1 on 7/14/05 to add TextureStage::_saved_result.
// Bumped to minor version 2 on 7/21/05 to add TransformState::is_2d.
// Bumped to minor version 3 on 8/25/05 to add ModelNode::_preserve_attributes.
// Bumped to minor version 4 on 9/27/05 to make SequenceNode inherit from AnimInterface.
// Bumped to minor version 5 on 12/22/05 to add Texture::_border_color.
// Bumped to minor version 6 on 1/14/06 to add Material::_name.
#endif