add NodePath::find_material(), find_all_texcoords(), etc. Make Material be directly modifiable.
This commit is contained in:
parent
28321721ac
commit
cf01ef9cd6
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -57,25 +57,25 @@ class EXPCL_PANDA GeomVertexArrayFormat : public TypedWritableReferenceCount, pu
|
|||
PUBLISHED:
|
||||
GeomVertexArrayFormat();
|
||||
GeomVertexArrayFormat(const GeomVertexArrayFormat ©);
|
||||
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 ©);
|
||||
~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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 ©);
|
||||
void operator = (const GeomVertexColumn ©);
|
||||
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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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()) {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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 ©) {
|
||||
Material(const Material ©) : Namable(copy) {
|
||||
operator = (copy);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ TypeHandle Material::_type_handle;
|
|||
////////////////////////////////////////////////////////////////////
|
||||
void Material::
|
||||
operator = (const Material ©) {
|
||||
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 ¶ms) {
|
|||
// 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);
|
||||
|
|
|
|||
|
|
@ -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 ©);
|
||||
void operator = (const Material ©);
|
||||
INLINE ~Material();
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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";
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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 \
|
||||
|
|
|
|||
|
|
@ -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)) {
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
}
|
||||
|
|
@ -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 ©) :
|
||||
_names(copy._names)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: InternalNameCollection::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void InternalNameCollection::
|
||||
operator = (const InternalNameCollection ©) {
|
||||
_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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
void operator = (const InternalNameCollection ©);
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
}
|
||||
|
|
@ -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 ©) :
|
||||
_materials(copy._materials)
|
||||
{
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: MaterialCollection::Copy Assignment Operator
|
||||
// Access: Published
|
||||
// Description:
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void MaterialCollection::
|
||||
operator = (const MaterialCollection ©) {
|
||||
_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";
|
||||
}
|
||||
}
|
||||
|
|
@ -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 ©);
|
||||
void operator = (const MaterialCollection ©);
|
||||
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
|
||||
|
||||
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in New Issue