Overhauled UV-handling in order to have better support for multiple UV sets, I hope
This commit is contained in:
parent
64a8ebfb02
commit
07d83f7a9c
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -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());
|
||||
|
|
|
|||
Loading…
Reference in New Issue