diff options
Diffstat (limited to 'o3d')
-rw-r--r-- | o3d/converter/cross/converter.cc | 72 | ||||
-rw-r--r-- | o3d/converter/cross/converter.h | 12 | ||||
-rw-r--r-- | o3d/converter/cross/converter_main.cc | 21 | ||||
-rw-r--r-- | o3d/import/cross/collada.cc | 86 | ||||
-rw-r--r-- | o3d/import/cross/collada.h | 25 |
5 files changed, 180 insertions, 36 deletions
diff --git a/o3d/converter/cross/converter.cc b/o3d/converter/cross/converter.cc index 981b129..6f50787 100644 --- a/o3d/converter/cross/converter.cc +++ b/o3d/converter/cross/converter.cc @@ -132,6 +132,78 @@ bool Convert(const FilePath& in_filename, pack->RemoveObject(param_object); } + // Mark all Samplers to use tri-linear filtering + if (!options.keep_filters) { + std::vector<Sampler*> samplers = pack->GetByClass<Sampler>(); + for (unsigned ii = 0; ii < samplers.size(); ++ii) { + Sampler* sampler = samplers[ii]; + sampler->set_mag_filter(Sampler::LINEAR); + sampler->set_min_filter(Sampler::LINEAR); + sampler->set_mip_filter(Sampler::LINEAR); + } + } + + // Mark all Materials that are on Primitives that have no normals as constant. + if (!options.keep_materials) { + std::vector<Primitive*> primitives = pack->GetByClass<Primitive>(); + for (unsigned ii = 0; ii < primitives.size(); ++ii) { + Primitive* primitive = primitives[ii]; + StreamBank* stream_bank = primitive->stream_bank(); + if (stream_bank && !stream_bank->GetVertexStream(Stream::NORMAL, 0)) { + Material* material = primitive->material(); + if (material) { + ParamString* lighting_param = material->GetParam<ParamString>( + Collada::kLightingTypeParamName); + if (lighting_param) { + // If the lighting type is lambert, blinn, or phong + // copy the diffuse color to the emissive since that's most likely + // what the user wants to see. + if (lighting_param->value().compare( + Collada::kLightingTypeLambert) == 0 || + lighting_param->value().compare( + Collada::kLightingTypeBlinn) == 0 || + lighting_param->value().compare( + Collada::kLightingTypePhong) == 0) { + // There's 4 cases: (to bad they are not the same names) + // 1) Diffuse -> Emissive + // 2) DiffuseSampler -> Emissive + // 3) Diffuse -> EmissiveSampler + // 4) DiffuseSampler -> EmissiveSampler + ParamFloat4* diffuse_param = material->GetParam<ParamFloat4>( + Collada::kMaterialParamNameDiffuse); + ParamFloat4* emissive_param = material->GetParam<ParamFloat4>( + Collada::kMaterialParamNameEmissive); + ParamSampler* diffuse_sampler_param = + material->GetParam<ParamSampler>( + Collada::kMaterialParamNameDiffuseSampler); + ParamSampler* emissive_sampler_param = + material->GetParam<ParamSampler>( + Collada::kMaterialParamNameEmissive); + Param* source_param = diffuse_param ? + static_cast<Param*>(diffuse_param) : + static_cast<Param*>(diffuse_sampler_param); + Param* destination_param = emissive_param ? + static_cast<Param*>(emissive_param) : + static_cast<Param*>(emissive_sampler_param); + if (!source_param->IsA(destination_param->GetClass())) { + // The params do not match type so we need to make the emissive + // Param the same as the diffuse Param. + material->RemoveParam(destination_param); + destination_param = material->CreateParamByClass( + diffuse_param ? Collada::kMaterialParamNameEmissive : + Collada::kMaterialParamNameEmissiveSampler, + source_param->GetClass()); + DCHECK(destination_param); + } + destination_param->CopyDataFromParam(source_param); + } + lighting_param->set_value(Collada::kLightingTypeConstant); + } + } + } + } + } + // Attempt to open the output file. FILE* out_file = file_util::OpenFile(out_filename, "wb"); if (out_file == NULL) { diff --git a/o3d/converter/cross/converter.h b/o3d/converter/cross/converter.h index 1524493..dd0141c 100644 --- a/o3d/converter/cross/converter.h +++ b/o3d/converter/cross/converter.h @@ -50,7 +50,10 @@ struct Options { : base_path(FilePath::kCurrentDirectory), condition(true), up_axis(0, 0, 0), - pretty_print(false) {} + pretty_print(false), + keep_filters(false), + keep_materials(false) { + } // The path to the "base" of the model path, from which all paths // are made relative. Defaults to the current directory. @@ -68,6 +71,13 @@ struct Options { // pretty-printed (formatted with spaces and newlines) or just // emitted as one huge one-line string. Defaults to false. bool pretty_print; + + // Tells the converter not to set all filters to tri-linear. + bool keep_filters; + + // Tells the converter not to change materials to constant if they are used by + // a mesh that has no normals. + bool keep_materials; }; // Converts the given file for use in O3D. This is done by diff --git a/o3d/converter/cross/converter_main.cc b/o3d/converter/cross/converter_main.cc index 85cc594..650e0b7 100644 --- a/o3d/converter/cross/converter_main.cc +++ b/o3d/converter/cross/converter_main.cc @@ -80,9 +80,24 @@ int CrossMain(int argc, char**argv) { in_filename = o3d::WideToFilePath(values[0]); out_filename = o3d::WideToFilePath(values[1]); } else { - std::cerr << "Usage: " << argv[0] - << " [--no-condition] [--base-path=<path>] [--up-axis=x,y,z]" - << " [--pretty-print] <infile.dae> [ <outfile> ]\n"; + std::cerr << "Usage: " << argv[0] + << " [ options ] <infile.dae> [ <outfile> ]\n"; + std::cerr + << "--no-condition\n" + << " Stops the converter from conditioning shaders.\n" + << "--base-path=<path>\n" + << " Sets the base path for finding textures and other external\n" + << " files.\n" + << "--up-axis=x,y,z\n" + << " Converts the file to have this up axis.\n" + << "--pretty-print\n" + << " Makes the exported JSON easier to read.\n" + << "--keep-filters\n" + << " Stops the converter from forcing all texture samplers to use\n" + << " tri-linear filtering.\n" + << "--keep-materials\n" + << " Stops the converter from changing materials to <constant> if\n" + << " they are used by a mesh that has no normals.\n"; return EXIT_FAILURE; } diff --git a/o3d/import/cross/collada.cc b/o3d/import/cross/collada.cc index 64d39fc..e2041e86 100644 --- a/o3d/import/cross/collada.cc +++ b/o3d/import/cross/collada.cc @@ -66,6 +66,27 @@ namespace o3d { +const char* Collada::kLightingTypeParamName = + COLLADA_STRING_CONSTANT("lightingType"); + +const char* Collada::kLightingTypeConstant = "constant"; +const char* Collada::kLightingTypePhong = "phong"; +const char* Collada::kLightingTypeBlinn = "blinn"; +const char* Collada::kLightingTypeLambert = "lambert"; +const char* Collada::kLightingTypeUnknown = "unknown"; + +const char* Collada::kMaterialParamNameEmissive = "emissive"; +const char* Collada::kMaterialParamNameAmbient = "ambient"; +const char* Collada::kMaterialParamNameDiffuse = "diffuse"; +const char* Collada::kMaterialParamNameSpecular = "specular"; +const char* Collada::kMaterialParamNameShininess = "shininess"; +const char* Collada::kMaterialParamNameSpecularFactor = "specularFactor"; +const char* Collada::kMaterialParamNameEmissiveSampler = "emissiveSampler"; +const char* Collada::kMaterialParamNameAmbientSampler = "ambientSampler"; +const char* Collada::kMaterialParamNameDiffuseSampler = "diffuseSampler"; +const char* Collada::kMaterialParamNameSpecularSampler = "specularSampler"; +const char* Collada::kMaterialParamNameBumpSampler = "bumpSampler"; + class TranslationMap : public FCDGeometryIndexTranslationMap { }; @@ -213,7 +234,7 @@ bool Collada::ImportFile(const FilePath& filename, Transform* parent, } if (!status) { - // TODO: this could probably be the original URI instead of some + // TODO(o3d): this could probably be the original URI instead of some // filename in the temp folder. O3D_ERROR(service_locator_) << "Unable to import: " << FilePathToUTF8(filename).c_str(); @@ -341,7 +362,7 @@ bool Collada::ImportDAEDocument(FCDocument* doc, // materials or models the user put them in the file and might need them // at runtime. // - // TODO: Add option to skip this step if user just wants what's + // TODO(o3d): Add option to skip this step if user just wants what's // actually used by models. The rest of the code already deals with this. FCDImageLibrary* image_library = doc->GetImageLibrary(); for (uint32 i = 0; i < image_library->GetEntityCount(); i++) { @@ -355,7 +376,7 @@ bool Collada::ImportDAEDocument(FCDocument* doc, // Import all the materials in the file. Even if they are not used by // models the user put them in the file and might need them at runtime. // - // TODO: Add option to skip this step if user just wants what's + // TODO(o3d): Add option to skip this step if user just wants what's // actually used by models. The rest of the code already deals with this. FCDMaterialLibrary* material_library = doc->GetMaterialLibrary(); for (uint32 i = 0; i < material_library->GetEntityCount(); i++) { @@ -807,7 +828,7 @@ void Collada::ImportTreeInstances(FCDocument* doc, LOG_ASSERT(instance != 0); // Import each node based on what kind of entity it is - // TODO: add more entity types as they are supported + // TODO(o3d): add more entity types as they are supported switch (instance->GetEntityType()) { case FCDEntity::CAMERA: // camera entity @@ -1021,7 +1042,6 @@ void Collada::BuildCamera(FCDocument* doc, break; } } - } Shape* Collada::GetShape(FCDocument* doc, @@ -1248,7 +1268,7 @@ Shape* Collada::BuildShape(FCDocument* doc, Shape* Collada::BuildSkinnedShape(FCDocument* doc, FCDControllerInstance* instance, NodeInstance *parent_node_instance) { - // TODO: Handle chained controllers. Morph->Skin->... + // TODO(o3d): Handle chained controllers. Morph->Skin->... Shape* shape = NULL; LOG_ASSERT(doc && instance); FCDController* controller = @@ -1460,7 +1480,7 @@ Shape* Collada::BuildSkinnedShape(FCDocument* doc, std::vector<float> data(num_vertices * num_source_components); field.GetAsFloats(0, &data[0], num_source_components, num_vertices); - // TODO: Remove this matrix multiply. I don't think it is + // TODO(o3d): Remove this matrix multiply. I don't think it is // needed. for (unsigned vv = 0; vv < num_vertices; ++vv) { float* values = &data[vv * num_source_components]; @@ -1685,7 +1705,7 @@ bool Collada::SetParamFromFCEffectParam(ParamObject* param_object, SetSamplerStates(sampler, o3d_sampler); } } else if (type == FCDEffectParameter::SURFACE) { - // TODO: This code is here to handle the NV_import profile + // TODO(o3d): This code is here to handle the NV_import profile // exported by Max's DirectX Shader materials, which references // only references texture params (not samplers). Once we move // completely to using samplers and add sampler blocks to our @@ -1740,15 +1760,15 @@ static const char* GetLightingType(FCDEffectStandard* std_profile) { FCDEffectStandard::LightingType type = std_profile->GetLightingType(); switch (type) { case FCDEffectStandard::CONSTANT: - return "constant"; + return Collada::kLightingTypeConstant; case FCDEffectStandard::PHONG: - return "phong"; + return Collada::kLightingTypePhong; case FCDEffectStandard::BLINN: - return "blinn"; + return Collada::kLightingTypeBlinn; case FCDEffectStandard::LAMBERT: - return "lambert"; + return Collada::kLightingTypeLambert; default: - return "unknown"; + return Collada::kLightingTypeUnknown; } } @@ -1807,7 +1827,7 @@ Material* Collada::BuildMaterial(FCDocument* doc, collada_effect->FindProfile(FUDaeProfileType::COMMON)); if (std_profile) { ParamString* type_tag = material->CreateParam<ParamString>( - COLLADA_STRING_CONSTANT("lightingType")); + kLightingTypeParamName); type_tag->set_value(GetLightingType(std_profile)); } } @@ -1838,7 +1858,7 @@ Effect* Collada::GetEffect(FCDocument* doc, FCDEffect* collada_effect) { // the newly-created effect, or NULL or error. Effect* Collada::BuildEffect(FCDocument* doc, FCDEffect* collada_effect) { if (!doc || !collada_effect) return NULL; - // TODO: Remove all of this to be replaced by parsing Collada-FX + // TODO(o3d): Remove all of this to be replaced by parsing Collada-FX // and profile_O3D only. Effect* effect = NULL; FCDEffectProfileFX* profile_fx = FindProfileFX(collada_effect); @@ -1877,7 +1897,9 @@ Effect* Collada::BuildEffect(FCDocument* doc, FCDEffect* collada_effect) { return NULL; } } else { - file_util::ReadFileToString(file_path, &effect_string); + FilePath temp_path = file_path; + GetRelativePathIfPossible(base_path_, temp_path, &temp_path); + file_util::ReadFileToString(temp_path, &effect_string); } } String collada_effect_name = WideToUTF8( @@ -2540,7 +2562,7 @@ static Sampler::FilterType ConvertFilterType( case FUDaeTextureFilterFunction::LINEAR_MIPMAP_NEAREST: case FUDaeTextureFilterFunction::LINEAR_MIPMAP_LINEAR: return Sampler::LINEAR; - // TODO: Once FCollada supports COLLADA v1.5, turn this on: + // TODO(o3d): Once FCollada supports COLLADA v1.5, turn this on: // case FUDaeTextureFilterFunction::ANISOTROPIC: // return Sampler::ANISOTROPIC; case FUDaeTextureFilterFunction::NONE: @@ -2593,7 +2615,7 @@ void Collada::SetSamplerStates(FCDEffectParameterSampler* effect_sampler, FUDaeTextureFilterFunction::FilterFunction mip_filter = effect_sampler->GetMipFilter(); - // TODO: Once FCollada supports COLLADA v1.5, turn this on: + // TODO(o3d): Once FCollada supports COLLADA v1.5, turn this on: // int max_anisotropy = effect_sampler->GetMaxAnisotropy(); o3d_sampler->set_address_mode_u(ConvertSamplerAddressMode(wrap_s)); @@ -2627,7 +2649,7 @@ void Collada::SetSamplerStates(FCDEffectParameterSampler* effect_sampler, o3d_sampler->set_mip_filter(ConvertFilterType(mip_filter, true)); } - // TODO: Once FCollada supports COLLADA v1.5, turn this on: + // TODO(o3d): Once FCollada supports COLLADA v1.5, turn this on: // o3d_sampler->set_max_anisotropy(max_anisotropy); } @@ -2664,7 +2686,7 @@ void Collada::SetParamFromStandardEffectParam( // Sets the values of a ParamObject parameters from a given FCollada material // node. If a corresponding ParamObject parameter is not found, the FCollada // parameter is ignored. -// TODO: Should we ignore params not found? Maybe the user wants those for +// TODO(o3d): Should we ignore params not found? Maybe the user wants those for // things other than rendering. // Parameters: // material: The FCollada material node from which to retrieve values. @@ -2672,7 +2694,7 @@ void Collada::SetParamFromStandardEffectParam( void Collada::SetParamsFromMaterial(FCDMaterial* material, ParamObject* param_object) { size_t pcount = material->GetEffectParameterCount(); - // TODO: This test (for determining if we used the + // TODO(o3d): This test (for determining if we used the // programmable profile or the fixed-func profile) is not very robust. // Remove this once the Material changes are in. if (pcount > 0) { @@ -2707,39 +2729,39 @@ void Collada::SetParamsFromMaterial(FCDMaterial* material, effect->FindProfile(FUDaeProfileType::COMMON))) != NULL) { SetParamFromStandardEffectParam(effect_standard, param_object, - "emissive", - "emissiveSampler", + kMaterialParamNameEmissive, + kMaterialParamNameEmissiveSampler, effect_standard->GetEmissionColorParam(), FUDaeTextureChannel::EMISSION); SetParamFromStandardEffectParam(effect_standard, param_object, - "ambient", - "ambientSampler", + kMaterialParamNameAmbient, + kMaterialParamNameAmbientSampler, effect_standard->GetAmbientColorParam(), FUDaeTextureChannel::AMBIENT); SetParamFromStandardEffectParam(effect_standard, param_object, - "diffuse", - "diffuseSampler", + kMaterialParamNameDiffuse, + kMaterialParamNameDiffuseSampler, effect_standard->GetDiffuseColorParam(), FUDaeTextureChannel::DIFFUSE); SetParamFromStandardEffectParam(effect_standard, param_object, - "specular", - "specularSampler", + kMaterialParamNameSpecular, + kMaterialParamNameSpecularSampler, effect_standard->GetSpecularColorParam(), FUDaeTextureChannel::SPECULAR); SetParamFromStandardEffectParam(effect_standard, param_object, NULL, - "bumpSampler", + kMaterialParamNameBumpSampler, NULL, FUDaeTextureChannel::BUMP); SetParamFromFCEffectParam(param_object, - "shininess", + kMaterialParamNameShininess, effect_standard->GetShininessParam()); SetParamFromFCEffectParam(param_object, - "specularFactor", + kMaterialParamNameSpecularFactor, effect_standard->GetSpecularFactorParam()); } } diff --git a/o3d/import/cross/collada.h b/o3d/import/cross/collada.h index 67538ea..a3aa963 100644 --- a/o3d/import/cross/collada.h +++ b/o3d/import/cross/collada.h @@ -154,6 +154,31 @@ class Collada { FilePath base_path; }; + // Collada Param Names. + // TODO(gman): Remove these as we switch this stuff to JSON + static const char* kLightingTypeParamName; + + // Lighitng Types. + // TODO(gman): Remove these as we switch this stuff to JSON + static const char* kLightingTypeConstant; + static const char* kLightingTypePhong; + static const char* kLightingTypeBlinn; + static const char* kLightingTypeLambert; + static const char* kLightingTypeUnknown; + + // Material Param Names. + static const char* kMaterialParamNameEmissive; + static const char* kMaterialParamNameAmbient; + static const char* kMaterialParamNameDiffuse; + static const char* kMaterialParamNameSpecular; + static const char* kMaterialParamNameShininess; + static const char* kMaterialParamNameSpecularFactor; + static const char* kMaterialParamNameEmissiveSampler; + static const char* kMaterialParamNameAmbientSampler; + static const char* kMaterialParamNameDiffuseSampler; + static const char* kMaterialParamNameSpecularSampler; + static const char* kMaterialParamNameBumpSampler; + // Use this if you need access to data after the import (as the // converter does). Collada(Pack* pack, const Options& options); |