Overhauled UV-handling in order to have better support for multiple UV sets, I hope

This commit is contained in:
rdb 2009-03-12 07:42:03 +00:00
parent 64a8ebfb02
commit 07d83f7a9c
3 changed files with 87 additions and 37 deletions

View File

@ -63,11 +63,15 @@ void DaeMaterials::add_material_instance(const FCDMaterialInstance* instance) {
for (size_t vib = 0; vib < instance->GetVertexInputBindingCount(); ++vib) {
const FCDMaterialInstanceBindVertexInput* mivib = instance->GetVertexInputBinding(vib);
assert(mivib != NULL);
PT(DaeVertexInputBinding) bvi = new DaeVertexInputBinding();
bvi->_input_semantic = mivib->inputSemantic;
bvi->_input_set = mivib->inputSet;
#if FCOLLADA_VERSION >= 0x00030005
_materials[semantic]->_uvsets[mivib->inputSet] = *mivib->semantic;
bvi->_semantic = *mivib->semantic;
#else
_materials[semantic]->_uvsets[mivib->inputSet] = FROM_FSTRING(mivib->semantic);
bvi->_semantic = FROM_FSTRING(mivib->semantic);
#endif
_materials[semantic]->_uvsets.push_back(bvi);
}
// Handle the material stuff
@ -81,13 +85,13 @@ void DaeMaterials::add_material_instance(const FCDMaterialInstance* instance) {
// Grab the common profile effect
const FCDEffectStandard* effect_common = (FCDEffectStandard *)effect->FindProfile(FUDaeProfileType::COMMON);
if (effect_common == NULL) {
daeegg_cat.debug() << "Ignoring effect referenced by material with semantic " << semantic
daeegg_cat.info() << "Ignoring effect referenced by material with semantic " << semantic
<< " because it has no common profile" << endl;
} else {
daeegg_cat.spam() << "Processing effect, material semantic is " << semantic << endl;
// Set the material parameters
egg_material->set_amb(TO_COLOR(effect_common->GetAmbientColor()));
////TODO: find a better way for transparency
////We already process transparency using blend modes
//LVecBase4f diffuse = TO_COLOR(effect_common->GetDiffuseColor());
//diffuse.set_w(diffuse.get_w() * (1.0f - effect_common->GetOpacity()));
//egg_material->set_diff(diffuse);
@ -149,11 +153,8 @@ process_texture_bucket(const string semantic, const FCDEffectStandard* effect_co
// Find a set of UV coordinates
const FCDEffectParameterInt* uvset = effect_common->GetTexture(bucket, tx)->GetSet();
if (uvset != NULL) {
if (_materials[semantic]->_uvsets.count(uvset->GetValue()) == 0) {
daeegg_cat.warning() << "Texture references a nonexisting UV coordinate set!" << endl;
} else {
egg_texture->set_uv_name(_materials[semantic]->_uvsets[uvset->GetValue()]);
}
daeegg_cat.debug() << "Texture has uv name '" << FROM_FSTRING(uvset->GetSemantic()) << "'\n";
egg_texture->set_uv_name(FROM_FSTRING(uvset->GetSemantic()));
}
// Apply sampler stuff
if (sampler != NULL) {
@ -243,14 +244,34 @@ apply_to(const string semantic, const PT(EggGroup) to) {
////////////////////////////////////////////////////////////////////
// Function: DaeMaterials::get_uvset_name
// Access: Public
// Description: Returns the name of the uvset with the specified
// FCollada input set, or an empty string if the given
// material has no input set.
// Description: Returns the semantic of the uvset with the
// specified input set, or an empty string if the
// given material has no input set.
////////////////////////////////////////////////////////////////////
const string DaeMaterials::
get_uvset_name(const string semantic, int32 input_set) {
if (_materials.count(semantic) > 0 && _materials[semantic]->_uvsets.count(input_set)) {
return _materials[semantic]->_uvsets[input_set];
get_uvset_name(const string semantic, FUDaeGeometryInput::Semantic input_semantic, int32 input_set) {
if (_materials.count(semantic) > 0) {
if (input_set == -1 && _materials[semantic]->_uvsets.size() == 1) {
return _materials[semantic]->_uvsets[0]->_semantic;
} else {
for (int i = 0; i < _materials[semantic]->_uvsets.size(); ++i) {
if (_materials[semantic]->_uvsets[i]->_input_set == input_set &&
_materials[semantic]->_uvsets[i]->_input_semantic == input_semantic) {
return _materials[semantic]->_uvsets[i]->_semantic;
}
}
// If we can't find it, let's look again, but don't care for the
// input_semantic this time. The reason for this is that some tools
// export textangents and texbinormals bound to a uvset with input
// semantic TEXCOORD.
for (int i = 0; i < _materials[semantic]->_uvsets.size(); ++i) {
if (_materials[semantic]->_uvsets[i]->_input_set == input_set) {
daeegg_cat.info() << "Using uv set with non-matching input semantic\n";
return _materials[semantic]->_uvsets[i]->_semantic;
}
}
daeegg_cat.warning() << "No uv set binding found for input set " << input_set << "\n";
}
}
return "";
}
@ -387,6 +408,22 @@ convert_blend(FCDEffectStandard::TransparencyMode mode, Colorf transparent, doub
blend->_operand_a = EggGroup::BO_one;
}
}
if (blend->_operand_b == EggGroup::BO_constant_color) {
if ((blend->_color[0] == 0) && (blend->_color[1] == 0) && (blend->_color[2] == 0) && (blend->_color[3] == 0)) {
blend->_operand_b = EggGroup::BO_zero;
}
if ((blend->_color[0] == 1) && (blend->_color[1] == 1) && (blend->_color[2] == 1) && (blend->_color[3] == 1)) {
blend->_operand_b = EggGroup::BO_one;
}
}
if (blend->_operand_a == EggGroup::BO_one_minus_constant_color) {
if ((blend->_color[0] == 0) && (blend->_color[1] == 0) && (blend->_color[2] == 0) && (blend->_color[3] == 0)) {
blend->_operand_a = EggGroup::BO_one;
}
if ((blend->_color[0] == 1) && (blend->_color[1] == 1) && (blend->_color[2] == 1) && (blend->_color[3] == 1)) {
blend->_operand_a = EggGroup::BO_zero;
}
}
if (blend->_operand_b == EggGroup::BO_one_minus_constant_color) {
if ((blend->_color[0] == 0) && (blend->_color[1] == 0) && (blend->_color[2] == 0) && (blend->_color[3] == 0)) {
blend->_operand_b = EggGroup::BO_one;

View File

@ -46,7 +46,7 @@ public:
void add_material_instance(const FCDMaterialInstance* instance);
void apply_to(const string semantic, const PT(EggPrimitive) to);
void apply_to(const string semantic, const PT(EggGroup) to);
const string get_uvset_name(const string semantic, int32 input_set);
const string get_uvset_name(const string semantic, FUDaeGeometryInput::Semantic input_semantic, int32 input_set);
static EggTexture::TextureType convert_texture_type(const FCDEffectParameterSampler::SamplerType orig_type);
static EggTexture::WrapMode convert_wrap_mode(const FUDaeTextureWrapMode::WrapMode orig_mode);
@ -61,12 +61,19 @@ private:
EggGroup::BlendOperand _operand_b;
};
// Holds information to bind texcoord inputs to textures.
struct DaeVertexInputBinding : public ReferenceCount {
int32 _input_set;
FUDaeGeometryInput::Semantic _input_semantic;
string _semantic;
};
// Holds stuff for an individual material.
struct DaeMaterial : public ReferenceCount {
pvector<PT_EggTexture> _egg_textures;
PT_EggMaterial _egg_material;
bool _double_sided;
pmap<int32, string> _uvsets;
pvector<PT(DaeVertexInputBinding)> _uvsets;
PT(DaeBlendSettings) _blend;
};

View File

@ -362,10 +362,21 @@ void DAEToEggConverter::process_mesh(PT(EggGroup) parent, const FCDGeometryMesh*
const FCDGeometryPolygonsInput* tinput = polygons->FindInput(FUDaeGeometryInput::TEXTANGENT);
const uint32* tindices;
if (tinput != NULL) tindices = tinput->GetIndices();
// Get a name for potential texture coordinate sets
string uvsetname ("");
// Get a name for potential coordinate sets
string tcsetname ("");
if (materials != NULL && tcinput != NULL) {
uvsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), tcinput->GetSet());
daeegg_cat.debug() << "Assigning texcoord set " << tcinput->GetSet() << " to semantic " << FROM_FSTRING(polygons->GetMaterialSemantic()) << "\n";
tcsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), FUDaeGeometryInput::TEXCOORD, tcinput->GetSet());
}
string tbsetname ("");
if (materials != NULL && binput != NULL) {
daeegg_cat.debug() << "Assigning texbinormal set " << binput->GetSet() << " to semantic " << FROM_FSTRING(polygons->GetMaterialSemantic()) << "\n";
tbsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), FUDaeGeometryInput::TEXBINORMAL, binput->GetSet());
}
string ttsetname ("");
if (materials != NULL && tinput != NULL) {
daeegg_cat.debug() << "Assigning textangent set " << tinput->GetSet() << " to semantic " << FROM_FSTRING(polygons->GetMaterialSemantic()) << "\n";
ttsetname = materials->get_uvset_name(FROM_FSTRING(polygons->GetMaterialSemantic()), FUDaeGeometryInput::TEXTANGENT, tinput->GetSet());
}
// Loop through the indices and add the vertices.
for (size_t ix = 0; ix < pinput->GetIndexCount(); ++ix) {
@ -383,9 +394,9 @@ void DAEToEggConverter::process_mesh(PT(EggGroup) parent, const FCDGeometryMesh*
assert(tcsource->GetStride() == 2 || tcsource->GetStride() == 3);
data = &tcsource->GetData()[tcindices[ix]*tcsource->GetStride()];
if (tcsource->GetStride() == 2) {
vertex->set_uv(uvsetname, LPoint2d(data[0], data[1]));
vertex->set_uv(tcsetname, LPoint2d(data[0], data[1]));
} else {
vertex->set_uvw(uvsetname, LPoint3d(data[0], data[1], data[2]));
vertex->set_uvw(tcsetname, LPoint3d(data[0], data[1], data[2]));
}
}
// Process the color
@ -396,28 +407,23 @@ void DAEToEggConverter::process_mesh(PT(EggGroup) parent, const FCDGeometryMesh*
}
// Possibly add a UV object
if ((bsource != NULL && binput != NULL) || (tsource != NULL && tinput != NULL)) {
PT(EggVertexUV) vertex_uv;
if (tcsource != NULL && tcinput != NULL) {
assert(tcsource->GetStride() == 2 || tcsource->GetStride() == 3);
data = &tcsource->GetData()[tcindices[ix]*tcsource->GetStride()];
if (tcsource->GetStride() == 2) {
vertex_uv = new EggVertexUV(uvsetname, TexCoordd(data[0], data[1]));
} else {
vertex_uv = new EggVertexUV(uvsetname, TexCoord3d(data[0], data[1], data[2]));
}
} else {
vertex_uv = new EggVertexUV(uvsetname, TexCoordd());
}
vertex->set_uv_obj(vertex_uv);
if (bsource != NULL && binput != NULL) {
assert(bsource->GetStride() == 3);
data = &bsource->GetData()[bindices[ix]*3];
vertex_uv->set_binormal(LVecBase3d(data[0], data[1], data[2]));
PT(EggVertexUV) uv_obj = vertex->modify_uv_obj(tbsetname);
if (uv_obj == NULL) {
uv_obj = new EggVertexUV(tbsetname, TexCoordd());
}
uv_obj->set_binormal(LVecBase3d(data[0], data[1], data[2]));
}
if (tsource != NULL && tinput != NULL) {
assert(tsource->GetStride() == 3);
data = &tsource->GetData()[tindices[ix]*3];
vertex_uv->set_tangent(LVecBase3d(data[0], data[1], data[2]));
PT(EggVertexUV) uv_obj = vertex->modify_uv_obj(ttsetname);
if (uv_obj == NULL) {
uv_obj = new EggVertexUV(ttsetname, TexCoordd());
}
uv_obj->set_tangent(LVecBase3d(data[0], data[1], data[2]));
}
}
vertex->transform(parent->get_node_to_vertex());