mirror of
https://github.com/panda3d/panda3d.git
synced 2025-10-03 10:22:45 -04:00
multitexture support
This commit is contained in:
parent
c7c639797e
commit
afe7b4b829
@ -26,6 +26,7 @@
|
||||
#include "eggTable.h"
|
||||
#include "eggPrimitive.h"
|
||||
#include "eggVertex.h"
|
||||
#include "eggVertexUV.h"
|
||||
#include "eggMorphList.h"
|
||||
#include "eggSAnimData.h"
|
||||
#include "indirectCompareNames.h"
|
||||
@ -347,6 +348,7 @@ scan_for_morphs(EggNode *egg_node, int model_index,
|
||||
EggVertex *vertex = (*vi);
|
||||
|
||||
add_morph_back_pointers(vertex, vertex, model_index, char_data);
|
||||
add_morph_back_pointers_vertex(vertex, vertex, model_index, char_data);
|
||||
|
||||
EggMorphVertexList::const_iterator mvi;
|
||||
for (mvi = vertex->_dxyzs.begin();
|
||||
@ -424,14 +426,6 @@ add_morph_back_pointers(EggAttributes *attrib, EggObject *egg_object,
|
||||
char_data->make_slider(morph.get_name())->add_back_pointer(model_index, egg_object);
|
||||
}
|
||||
|
||||
EggMorphTexCoordList::const_iterator mti;
|
||||
for (mti = attrib->_duvs.begin();
|
||||
mti != attrib->_duvs.end();
|
||||
++mti) {
|
||||
const EggMorphTexCoord &morph = (*mti);
|
||||
char_data->make_slider(morph.get_name())->add_back_pointer(model_index, egg_object);
|
||||
}
|
||||
|
||||
EggMorphColorList::const_iterator mci;
|
||||
for (mci = attrib->_drgbas.begin();
|
||||
mci != attrib->_drgbas.end();
|
||||
@ -441,6 +435,28 @@ add_morph_back_pointers(EggAttributes *attrib, EggObject *egg_object,
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCharacterCollection::add_morph_back_pointers_vertex
|
||||
// Access: Private
|
||||
// Description: Adds the back pointers for the kinds of morphs we
|
||||
// might find in an EggVertex object.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void EggCharacterCollection::
|
||||
add_morph_back_pointers_vertex(EggVertex *vertex, EggObject *egg_object,
|
||||
int model_index, EggCharacterData *char_data) {
|
||||
EggVertex::const_uv_iterator ui;
|
||||
for (ui = vertex->uv_begin(); ui != vertex->uv_end(); ++ui) {
|
||||
EggVertexUV *vert_uv = (*ui);
|
||||
EggMorphTexCoordList::const_iterator mti;
|
||||
for (mti = vert_uv->_duvs.begin();
|
||||
mti != vert_uv->_duvs.end();
|
||||
++mti) {
|
||||
const EggMorphTexCoord &morph = (*mti);
|
||||
char_data->make_slider(morph.get_name())->add_back_pointer(model_index, egg_object);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: EggCharacterCollection::match_egg_nodes
|
||||
// Access: Private
|
||||
|
@ -92,6 +92,8 @@ private:
|
||||
|
||||
void add_morph_back_pointers(EggAttributes *attrib, EggObject *egg_object,
|
||||
int model_index, EggCharacterData *char_data);
|
||||
void add_morph_back_pointers_vertex(EggVertex *vertex, EggObject *egg_object,
|
||||
int model_index, EggCharacterData *char_data);
|
||||
|
||||
// The _top_egg_nodes member is only used temporarily, when adding
|
||||
// each pre-existing egg file to the structure for the first time.
|
||||
|
@ -131,8 +131,8 @@ from_egg(EggFile *egg_file, EggData *data, EggTexture *egg_tex) {
|
||||
|
||||
get_uv_range(_egg_data, pal->_remap_uv);
|
||||
|
||||
_wrap_u = egg_tex->determine_wrap_u();
|
||||
_wrap_v = egg_tex->determine_wrap_v();
|
||||
_wrap_u = _egg_tex->determine_wrap_u();
|
||||
_wrap_v = _egg_tex->determine_wrap_v();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -450,8 +450,10 @@ update_egg() {
|
||||
|
||||
// Finally, go back and actually adjust the UV's to match what we
|
||||
// claimed they could be.
|
||||
if (_egg_tex->get_tex_gen() == EggTexture::TG_unspecified) {
|
||||
update_uv_range(_egg_data, pal->_remap_uv);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureReference::apply_properties_to_source
|
||||
@ -550,12 +552,15 @@ write(ostream &out, int indent_level) const {
|
||||
// the texture in a palette); they will actually be
|
||||
// applied when update_uv_range(), below, is called
|
||||
// later.
|
||||
//
|
||||
// The return value is true if the search should
|
||||
// continue, or false if it should abort prematurely.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureReference::
|
||||
bool TextureReference::
|
||||
get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) {
|
||||
if (group->is_of_type(EggGroup::get_class_type())) {
|
||||
EggGroup *egg_group;
|
||||
DCAST_INTO_V(egg_group, group);
|
||||
DCAST_INTO_R(egg_group, group, false);
|
||||
|
||||
if (egg_group->get_dart_type() != EggGroup::DT_none) {
|
||||
// If it's a character, we might change the kind of remapping we
|
||||
@ -572,7 +577,7 @@ get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) {
|
||||
EggNode *child = (*ci);
|
||||
if (child->is_of_type(EggNurbsSurface::get_class_type())) {
|
||||
EggNurbsSurface *nurbs = DCAST(EggNurbsSurface, child);
|
||||
if (nurbs->has_texture() && nurbs->get_texture() == _egg_tex) {
|
||||
if (nurbs->has_texture(_egg_tex)) {
|
||||
// Here's a NURBS surface that references the texture. Unlike
|
||||
// other kinds of geometries, NURBS don't store UV's; they're
|
||||
// implicit in the surface. NURBS UV's will always run in the
|
||||
@ -585,26 +590,30 @@ get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) {
|
||||
// up the group UV's is so we can consider adjusting them
|
||||
// later). Instead, we just accumulate the NURBS UV's
|
||||
// directly into our total.
|
||||
|
||||
static const int num_nurbs_uvs = 4;
|
||||
static TexCoordd nurbs_uvs[num_nurbs_uvs] = {
|
||||
TexCoordd(0.0, 0.0),
|
||||
TexCoordd(0.0, 1.0),
|
||||
TexCoordd(1.0, 1.0),
|
||||
TexCoordd(1.0, 0.0)
|
||||
};
|
||||
|
||||
for (int i = 0; i < num_nurbs_uvs; i++) {
|
||||
TexCoordd uv = nurbs_uvs[i] * _tex_mat;
|
||||
collect_uv(_any_uvs, _min_uv, _max_uv, uv, uv);
|
||||
}
|
||||
collect_nominal_uv_range();
|
||||
}
|
||||
|
||||
} else if (child->is_of_type(EggPrimitive::get_class_type())) {
|
||||
EggPrimitive *geom = DCAST(EggPrimitive, child);
|
||||
if (geom->has_texture() && geom->get_texture() == _egg_tex) {
|
||||
if (geom->has_texture(_egg_tex)) {
|
||||
// Here's a piece of geometry that references this texture.
|
||||
// Walk through its vertices and get its UV's.
|
||||
|
||||
if (_egg_tex->get_tex_gen() != EggTexture::TG_unspecified) {
|
||||
// If the texture has a TexGen mode, we don't check the UV
|
||||
// range on the model, since that doesn't matter. Instead,
|
||||
// we assume the texture is used in the range (0, 0) - (1,
|
||||
// 1), which will be true for a sphere map, although the
|
||||
// effective range is a little less clear for the
|
||||
// TG_world_position and similar modes.
|
||||
collect_nominal_uv_range();
|
||||
|
||||
// In fact, now we can return, having found at least one
|
||||
// model that references the texture; there's no need to
|
||||
// search further.
|
||||
return false;
|
||||
|
||||
} else {
|
||||
TexCoordd geom_min_uv, geom_max_uv;
|
||||
|
||||
if (get_geom_uvs(geom, geom_min_uv, geom_max_uv)) {
|
||||
@ -617,10 +626,13 @@ get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) {
|
||||
geom_min_uv, geom_max_uv);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else if (child->is_of_type(EggGroupNode::get_class_type())) {
|
||||
EggGroupNode *cg = DCAST(EggGroupNode, child);
|
||||
get_uv_range(cg, remap);
|
||||
if (!get_uv_range(cg, remap)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -632,6 +644,8 @@ get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) {
|
||||
}
|
||||
collect_uv(_any_uvs, _min_uv, _max_uv, group_min_uv, group_max_uv);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
@ -666,7 +680,7 @@ update_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) {
|
||||
} else if (child->is_of_type(EggPrimitive::get_class_type())) {
|
||||
if (remap != Palettizer::RU_never) {
|
||||
EggPrimitive *geom = DCAST(EggPrimitive, child);
|
||||
if (geom->has_texture() && geom->get_texture() == _egg_tex) {
|
||||
if (geom->has_texture(_egg_tex)) {
|
||||
TexCoordd geom_min_uv, geom_max_uv;
|
||||
|
||||
if (get_geom_uvs(geom, geom_min_uv, geom_max_uv)) {
|
||||
@ -698,7 +712,7 @@ update_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) {
|
||||
EggNode *child = (*ci);
|
||||
if (child->is_of_type(EggPrimitive::get_class_type())) {
|
||||
EggPrimitive *geom = DCAST(EggPrimitive, child);
|
||||
if (geom->has_texture() && geom->get_texture() == _egg_tex) {
|
||||
if (geom->has_texture(_egg_tex)) {
|
||||
translate_geom_uvs(geom, trans);
|
||||
}
|
||||
}
|
||||
@ -717,13 +731,14 @@ update_uv_range(EggGroupNode *group, Palettizer::RemapUV remap) {
|
||||
bool TextureReference::
|
||||
get_geom_uvs(EggPrimitive *geom,
|
||||
TexCoordd &geom_min_uv, TexCoordd &geom_max_uv) {
|
||||
string uv_name = _egg_tex->get_uv_name();
|
||||
bool geom_any_uvs = false;
|
||||
|
||||
EggPrimitive::iterator pi;
|
||||
for (pi = geom->begin(); pi != geom->end(); ++pi) {
|
||||
EggVertex *vtx = (*pi);
|
||||
if (vtx->has_uv()) {
|
||||
TexCoordd uv = vtx->get_uv() * _tex_mat;
|
||||
if (vtx->has_uv(uv_name)) {
|
||||
TexCoordd uv = vtx->get_uv(uv_name) * _tex_mat;
|
||||
collect_uv(geom_any_uvs, geom_min_uv, geom_max_uv, uv, uv);
|
||||
}
|
||||
}
|
||||
@ -739,12 +754,14 @@ get_geom_uvs(EggPrimitive *geom,
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureReference::
|
||||
translate_geom_uvs(EggPrimitive *geom, const TexCoordd &trans) const {
|
||||
string uv_name = _egg_tex->get_uv_name();
|
||||
|
||||
EggPrimitive::iterator pi;
|
||||
for (pi = geom->begin(); pi != geom->end(); ++pi) {
|
||||
EggVertex *vtx = (*pi);
|
||||
if (vtx->has_uv()) {
|
||||
if (vtx->has_uv(uv_name)) {
|
||||
EggVertex vtx_copy(*vtx);
|
||||
vtx_copy.set_uv(vtx_copy.get_uv() + trans);
|
||||
vtx_copy.set_uv(uv_name, vtx_copy.get_uv(uv_name) + trans);
|
||||
EggVertex *new_vtx = vtx->get_pool()->create_unique_vertex(vtx_copy);
|
||||
|
||||
if (new_vtx->gref_size() != vtx->gref_size()) {
|
||||
@ -756,6 +773,28 @@ translate_geom_uvs(EggPrimitive *geom, const TexCoordd &trans) const {
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureReference::collect_nominal_uv_range
|
||||
// Access: Private
|
||||
// Description: Updates _any_uvs, _min_uv, and _max_uv with the range
|
||||
// (0, 0) - (1, 1), adjusted by the texture matrix.
|
||||
////////////////////////////////////////////////////////////////////
|
||||
void TextureReference::
|
||||
collect_nominal_uv_range() {
|
||||
static const int num_nurbs_uvs = 4;
|
||||
static TexCoordd nurbs_uvs[num_nurbs_uvs] = {
|
||||
TexCoordd(0.0, 0.0),
|
||||
TexCoordd(0.0, 1.0),
|
||||
TexCoordd(1.0, 1.0),
|
||||
TexCoordd(1.0, 0.0)
|
||||
};
|
||||
|
||||
for (int i = 0; i < num_nurbs_uvs; i++) {
|
||||
TexCoordd uv = nurbs_uvs[i] * _tex_mat;
|
||||
collect_uv(_any_uvs, _min_uv, _max_uv, uv, uv);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////
|
||||
// Function: TextureReference::collect_uv
|
||||
// Access: Private, Static
|
||||
|
@ -80,12 +80,13 @@ public:
|
||||
void write(ostream &out, int indent_level = 0) const;
|
||||
|
||||
private:
|
||||
void get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap);
|
||||
bool get_uv_range(EggGroupNode *group, Palettizer::RemapUV remap);
|
||||
void update_uv_range(EggGroupNode *group, Palettizer::RemapUV remap);
|
||||
|
||||
bool get_geom_uvs(EggPrimitive *geom,
|
||||
TexCoordd &geom_min_uv, TexCoordd &geom_max_uv);
|
||||
void translate_geom_uvs(EggPrimitive *geom, const TexCoordd &trans) const;
|
||||
void collect_nominal_uv_range();
|
||||
static void collect_uv(bool &any_uvs, TexCoordd &min_uv, TexCoordd &max_uv,
|
||||
const TexCoordd &got_min_uv,
|
||||
const TexCoordd &got_max_uv);
|
||||
|
Loading…
x
Reference in New Issue
Block a user