| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2009, Google Inc. | 2 * Copyright 2009, Google Inc. |
| 3 * All rights reserved. | 3 * All rights reserved. |
| 4 * | 4 * |
| 5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
| 6 * modification, are permitted provided that the following conditions are | 6 * modification, are permitted provided that the following conditions are |
| 7 * met: | 7 * met: |
| 8 * | 8 * |
| 9 * * Redistributions of source code must retain the above copyright | 9 * * Redistributions of source code must retain the above copyright |
| 10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 29 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 30 */ | 30 */ |
| 31 | 31 |
| 32 | 32 |
| 33 // This file contains functions for importing COLLADA files into O3D. | 33 // This file contains functions for importing COLLADA files into O3D. |
| 34 #include "import/cross/precompile.h" | 34 #include "import/cross/precompile.h" |
| 35 | 35 |
| 36 #include "base/file_path.h" | 36 #include "base/file_path.h" |
| 37 #include "base/file_util.h" | 37 #include "base/file_util.h" |
| 38 #include "base/string_util.h" | 38 #include "base/string_util.h" |
| 39 #include "core/cross/class_manager.h" |
| 39 #include "core/cross/curve.h" | 40 #include "core/cross/curve.h" |
| 40 #include "core/cross/error.h" | 41 #include "core/cross/error.h" |
| 41 #include "core/cross/function.h" | 42 #include "core/cross/function.h" |
| 42 #include "core/cross/ierror_status.h" | 43 #include "core/cross/ierror_status.h" |
| 43 #include "core/cross/math_utilities.h" | 44 #include "core/cross/math_utilities.h" |
| 44 #include "core/cross/matrix4_axis_rotation.h" | 45 #include "core/cross/matrix4_axis_rotation.h" |
| 45 #include "core/cross/matrix4_composition.h" | 46 #include "core/cross/matrix4_composition.h" |
| 46 #include "core/cross/matrix4_scale.h" | 47 #include "core/cross/matrix4_scale.h" |
| 47 #include "core/cross/matrix4_translation.h" | 48 #include "core/cross/matrix4_translation.h" |
| 48 #include "core/cross/pack.h" | 49 #include "core/cross/pack.h" |
| 49 #include "core/cross/param_operation.h" | 50 #include "core/cross/param_operation.h" |
| 50 #include "core/cross/primitive.h" | 51 #include "core/cross/primitive.h" |
| 51 #include "core/cross/skin.h" | 52 #include "core/cross/skin.h" |
| 52 #include "core/cross/stream.h" | 53 #include "core/cross/stream.h" |
| 53 #include "import/cross/collada.h" | 54 #include "import/cross/collada.h" |
| 54 #include "import/cross/collada_conditioner.h" | 55 #include "import/cross/collada_conditioner.h" |
| 55 #include "import/cross/collada_zip_archive.h" | 56 #include "import/cross/collada_zip_archive.h" |
| 57 #include "import/cross/destination_buffer.h" |
| 56 #include "utils/cross/file_path_utils.h" | 58 #include "utils/cross/file_path_utils.h" |
| 57 | 59 |
| 58 #define COLLADA_NAMESPACE "collada" | 60 #define COLLADA_NAMESPACE "collada" |
| 59 #define COLLADA_NAMESPACE_SEPARATOR "." | 61 #define COLLADA_NAMESPACE_SEPARATOR "." |
| 60 | 62 |
| 61 // Macro to provide a uniform prefix for all string constants created by | 63 // Macro to provide a uniform prefix for all string constants created by |
| 62 // COLLADA. | 64 // COLLADA. |
| 63 #define COLLADA_STRING_CONSTANT(value) \ | 65 #define COLLADA_STRING_CONSTANT(value) \ |
| 64 (COLLADA_NAMESPACE COLLADA_NAMESPACE_SEPARATOR value) | 66 (COLLADA_NAMESPACE COLLADA_NAMESPACE_SEPARATOR value) |
| 65 | 67 |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 140 Transform* parent, | 142 Transform* parent, |
| 141 ParamFloat* animation_input, | 143 ParamFloat* animation_input, |
| 142 const Options& options) { | 144 const Options& options) { |
| 143 return Collada::Import(pack, | 145 return Collada::Import(pack, |
| 144 UTF8ToFilePath(filename), | 146 UTF8ToFilePath(filename), |
| 145 parent, | 147 parent, |
| 146 animation_input, | 148 animation_input, |
| 147 options); | 149 options); |
| 148 } | 150 } |
| 149 | 151 |
| 152 void Collada::Init(ServiceLocator* service_locator) { |
| 153 ClassManager* class_manager= |
| 154 service_locator->GetService<o3d::ClassManager>(); |
| 155 class_manager->AddTypedClass<DestinationBuffer>(); |
| 156 } |
| 157 |
| 150 // Parameters: | 158 // Parameters: |
| 151 // pack: The pack into which the scene objects will be placed. | 159 // pack: The pack into which the scene objects will be placed. |
| 152 // Returns true on success. | 160 // Returns true on success. |
| 153 Collada::Collada(Pack* pack, const Options& options) | 161 Collada::Collada(Pack* pack, const Options& options) |
| 154 : service_locator_(pack->service_locator()), | 162 : service_locator_(pack->service_locator()), |
| 155 pack_(pack), | 163 pack_(pack), |
| 156 options_(options), | 164 options_(options), |
| 157 dummy_effect_(NULL), | 165 dummy_effect_(NULL), |
| 158 dummy_material_(NULL), | 166 dummy_material_(NULL), |
| 159 instance_root_(NULL), | 167 instance_root_(NULL), |
| (...skipping 224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 384 LOG_ASSERT(entity); | 392 LOG_ASSERT(entity); |
| 385 LOG_ASSERT(entity->GetType() == FCDEntity::MATERIAL); | 393 LOG_ASSERT(entity->GetType() == FCDEntity::MATERIAL); |
| 386 FCDMaterial* collada_material = down_cast<FCDMaterial*>(entity); | 394 FCDMaterial* collada_material = down_cast<FCDMaterial*>(entity); |
| 387 BuildMaterial(doc, collada_material); | 395 BuildMaterial(doc, collada_material); |
| 388 } | 396 } |
| 389 | 397 |
| 390 // Import the scene objects, starting at the root. | 398 // Import the scene objects, starting at the root. |
| 391 FCDSceneNode* scene = doc->GetVisualSceneInstance(); | 399 FCDSceneNode* scene = doc->GetVisualSceneInstance(); |
| 392 if (scene) { | 400 if (scene) { |
| 393 instance_root_ = CreateInstanceTree(scene); | 401 instance_root_ = CreateInstanceTree(scene); |
| 394 ImportTree(instance_root_, parent, animation_input); | 402 if (ImportTree(instance_root_, parent, animation_input)) { |
| 395 ImportTreeInstances(doc, instance_root_); | 403 if (ImportTreeInstances(doc, instance_root_)) { |
| 404 status = true; |
| 405 } |
| 406 } |
| 396 delete instance_root_; | 407 delete instance_root_; |
| 397 instance_root_ = NULL; | 408 instance_root_ = NULL; |
| 398 status = true; | |
| 399 } | 409 } |
| 400 } | 410 } |
| 401 } | 411 } |
| 402 return status; | 412 return status; |
| 403 } | 413 } |
| 404 | 414 |
| 405 namespace { | 415 namespace { |
| 406 | 416 |
| 407 Curve::Infinity ConvertInfinity(FUDaeInfinity::Infinity infinity) { | 417 Curve::Infinity ConvertInfinity(FUDaeInfinity::Infinity infinity) { |
| 408 switch (infinity) { | 418 switch (infinity) { |
| (...skipping 380 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 789 } | 799 } |
| 790 | 800 |
| 791 // Recursively imports a tree of nodes from FCollada, rooted at the | 801 // Recursively imports a tree of nodes from FCollada, rooted at the |
| 792 // given node, into the O3D scene. | 802 // given node, into the O3D scene. |
| 793 // Parameters: | 803 // Parameters: |
| 794 // instance: The root NodeInstance from which to import. | 804 // instance: The root NodeInstance from which to import. |
| 795 // parent_transform: The parent Transform under which the tree will be placed. | 805 // parent_transform: The parent Transform under which the tree will be placed. |
| 796 // animation_input: The float parameter used as the input to the animation | 806 // animation_input: The float parameter used as the input to the animation |
| 797 // (if present). This is usually time. This can be null | 807 // (if present). This is usually time. This can be null |
| 798 // if there is no animation. | 808 // if there is no animation. |
| 799 void Collada::ImportTree(NodeInstance *instance, | 809 bool Collada::ImportTree(NodeInstance *instance, |
| 800 Transform* parent_transform, | 810 Transform* parent_transform, |
| 801 ParamFloat* animation_input) { | 811 ParamFloat* animation_input) { |
| 802 FCDSceneNode *node = instance->node(); | 812 FCDSceneNode *node = instance->node(); |
| 803 Transform* transform = BuildTransform(node, parent_transform, | 813 Transform* transform = BuildTransform(node, parent_transform, |
| 804 animation_input); | 814 animation_input); |
| 805 instance->set_transform(transform); | 815 instance->set_transform(transform); |
| 806 | 816 |
| 807 // recursively import the rest of the nodes in the tree | 817 // recursively import the rest of the nodes in the tree |
| 808 const NodeInstance::NodeInstanceList &children = instance->children(); | 818 const NodeInstance::NodeInstanceList &children = instance->children(); |
| 809 for (size_t i = 0; i < children.size(); ++i) { | 819 for (size_t i = 0; i < children.size(); ++i) { |
| 810 ImportTree(children[i], transform, animation_input); | 820 if (!ImportTree(children[i], transform, animation_input)) { |
| 821 return false; |
| 822 } |
| 811 } | 823 } |
| 824 return true; |
| 812 } | 825 } |
| 813 | 826 |
| 814 void Collada::ImportTreeInstances(FCDocument* doc, | 827 bool Collada::ImportTreeInstances(FCDocument* doc, |
| 815 NodeInstance *node_instance) { | 828 NodeInstance *node_instance) { |
| 816 FCDSceneNode *node = node_instance->node(); | 829 FCDSceneNode *node = node_instance->node(); |
| 817 // recursively import the rest of the nodes in the tree | 830 // recursively import the rest of the nodes in the tree |
| 818 const NodeInstance::NodeInstanceList &children = node_instance->children(); | 831 const NodeInstance::NodeInstanceList &children = node_instance->children(); |
| 819 for (size_t i = 0; i < children.size(); ++i) { | 832 for (size_t i = 0; i < children.size(); ++i) { |
| 820 ImportTreeInstances(doc, children[i]); | 833 if (!ImportTreeInstances(doc, children[i])) { |
| 834 return false; |
| 835 } |
| 821 } | 836 } |
| 822 | 837 |
| 823 Transform* transform = node_instance->transform(); | 838 Transform* transform = node_instance->transform(); |
| 824 for (size_t i = 0; i < node->GetInstanceCount(); ++i) { | 839 for (size_t i = 0; i < node->GetInstanceCount(); ++i) { |
| 825 FCDEntityInstance* instance = node->GetInstance(i); | 840 FCDEntityInstance* instance = node->GetInstance(i); |
| 826 FCDCamera* camera(NULL); | 841 FCDCamera* camera(NULL); |
| 827 FCDGeometryInstance* geom_instance(NULL); | 842 FCDGeometryInstance* geom_instance(NULL); |
| 828 | 843 |
| 829 LOG_ASSERT(instance != 0); | 844 LOG_ASSERT(instance != 0); |
| 830 // Import each node based on what kind of entity it is | 845 // Import each node based on what kind of entity it is |
| 831 // TODO(o3d): add more entity types as they are supported | 846 // TODO(o3d): add more entity types as they are supported |
| 832 switch (instance->GetEntityType()) { | 847 switch (instance->GetEntityType()) { |
| 833 case FCDEntity::CAMERA: | 848 case FCDEntity::CAMERA: |
| 834 // camera entity | 849 // camera entity |
| 835 camera = down_cast<FCDCamera*>(instance->GetEntity()); | 850 camera = down_cast<FCDCamera*>(instance->GetEntity()); |
| 836 BuildCamera(doc, camera, transform, node); | 851 BuildCamera(doc, camera, transform, node); |
| 837 break; | 852 break; |
| 838 case FCDEntity::GEOMETRY: { | 853 case FCDEntity::GEOMETRY: { |
| 839 // geometry entity | 854 // geometry entity |
| 840 geom_instance = static_cast<FCDGeometryInstance*>(instance); | 855 geom_instance = static_cast<FCDGeometryInstance*>(instance); |
| 841 Shape* shape = GetShape(doc, geom_instance); | 856 Shape* shape = GetShape(doc, geom_instance); |
| 842 if (shape) { | 857 if (shape) { |
| 843 transform->AddShape(shape); | 858 transform->AddShape(shape); |
| 844 } | 859 } |
| 845 break; | 860 break; |
| 846 } | 861 } |
| 847 case FCDEntity::CONTROLLER: { | 862 case FCDEntity::CONTROLLER: { |
| 848 FCDControllerInstance* controller_instance = | 863 FCDControllerInstance* controller_instance = |
| 849 static_cast<FCDControllerInstance*> (instance); | 864 static_cast<FCDControllerInstance*> (instance); |
| 850 Shape* shape = GetSkinnedShape(doc, controller_instance, node_instance); | 865 FCDController* controller = |
| 851 if (shape) { | 866 static_cast<FCDController*>(controller_instance->GetEntity()); |
| 852 transform->AddShape(shape); | 867 if (controller) { |
| 868 if (controller->IsSkin()) { |
| 869 Shape* shape = GetSkinnedShape(doc, |
| 870 controller_instance, |
| 871 node_instance); |
| 872 if (shape) { |
| 873 transform->AddShape(shape); |
| 874 } else { |
| 875 return false; |
| 876 } |
| 877 } |
| 853 } | 878 } |
| 854 break; | 879 break; |
| 855 } | 880 } |
| 856 default: | 881 default: |
| 857 // do nothing | 882 // do nothing |
| 858 break; | 883 break; |
| 859 } | 884 } |
| 860 } | 885 } |
| 886 return true; |
| 861 } | 887 } |
| 862 | 888 |
| 863 // Converts an FCollada vertex attribute semantic into an O3D | 889 // Converts an FCollada vertex attribute semantic into an O3D |
| 864 // vertex attribute semantic. Returns the O3D semantic, or | 890 // vertex attribute semantic. Returns the O3D semantic, or |
| 865 // UNKNOWN_SEMANTIC on failure. | 891 // UNKNOWN_SEMANTIC on failure. |
| 866 static Stream::Semantic C2G3DSemantic(FUDaeGeometryInput::Semantic semantic) { | 892 static Stream::Semantic C2G3DSemantic(FUDaeGeometryInput::Semantic semantic) { |
| 867 switch (semantic) { | 893 switch (semantic) { |
| 868 case FUDaeGeometryInput::POSITION: return Stream::POSITION; | 894 case FUDaeGeometryInput::POSITION: return Stream::POSITION; |
| 869 case FUDaeGeometryInput::VERTEX: return Stream::POSITION; | 895 case FUDaeGeometryInput::VERTEX: return Stream::POSITION; |
| 870 case FUDaeGeometryInput::NORMAL: return Stream::NORMAL; | 896 case FUDaeGeometryInput::NORMAL: return Stream::NORMAL; |
| (...skipping 440 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1311 } | 1337 } |
| 1312 } | 1338 } |
| 1313 } | 1339 } |
| 1314 | 1340 |
| 1315 // There's a BIG assumption here. We assume the first primitive on the shape | 1341 // There's a BIG assumption here. We assume the first primitive on the shape |
| 1316 // has vertex buffers that are shared on all the primitives under this shape | 1342 // has vertex buffers that are shared on all the primitives under this shape |
| 1317 // such that we only need to copy the first primitive's vertex buffers to | 1343 // such that we only need to copy the first primitive's vertex buffers to |
| 1318 // skin everything. This is actually what was BuildShape was doing at the | 1344 // skin everything. This is actually what was BuildShape was doing at the |
| 1319 // time this code was written. | 1345 // time this code was written. |
| 1320 const ElementRefArray& elements = shape->GetElementRefs(); | 1346 const ElementRefArray& elements = shape->GetElementRefs(); |
| 1321 if (elements.empty() || !elements[0]->IsA(Primitive::GetApparentClass())) { | 1347 if (elements.empty()) { |
| 1322 return NULL; | 1348 return NULL; |
| 1323 } | 1349 } |
| 1350 // check that they all use the same StreamBank and are all Primitives |
| 1351 for (unsigned ii = 0; ii < elements.size(); ++ii) { |
| 1352 if (!elements[ii]->IsA(Primitive::GetApparentClass())) { |
| 1353 O3D_ERROR(service_locator_) |
| 1354 << "Element in Shape '" << shape->name() << "' is not a Primitive."; |
| 1355 return NULL; |
| 1356 } |
| 1357 if (down_cast<Primitive*>(elements[ii].Get())->stream_bank() != |
| 1358 down_cast<Primitive*>(elements[0].Get())->stream_bank()) { |
| 1359 O3D_ERROR(service_locator_) |
| 1360 << "More than one StreamBank in Shape '" << shape->name() << "'."; |
| 1361 return NULL; |
| 1362 } |
| 1363 } |
| 1324 Primitive* primitive = down_cast<Primitive*>(elements[0].Get()); | 1364 Primitive* primitive = down_cast<Primitive*>(elements[0].Get()); |
| 1325 | 1365 |
| 1326 String controller_name = WideToUTF8(controller->GetName().c_str()); | 1366 String controller_name = WideToUTF8(controller->GetName().c_str()); |
| 1327 | 1367 |
| 1328 ParamArray* matrices = pack_->Create<ParamArray>(); | 1368 ParamArray* matrices = pack_->Create<ParamArray>(); |
| 1329 Skin* skin = pack_->Create<Skin>(); | 1369 Skin* skin = pack_->Create<Skin>(); |
| 1330 skin->set_name(controller_name); | 1370 skin->set_name(controller_name); |
| 1331 SkinEval* skin_eval = pack_->Create<SkinEval>(); | 1371 SkinEval* skin_eval = pack_->Create<SkinEval>(); |
| 1332 skin_eval->set_name(controller_name); | 1372 skin_eval->set_name(controller_name); |
| 1333 | 1373 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1405 // two issues come up | 1445 // two issues come up |
| 1406 // | 1446 // |
| 1407 // 1) If we serialize that VertexBuffer, POSITION and NORMAL are stored | 1447 // 1) If we serialize that VertexBuffer, POSITION and NORMAL are stored |
| 1408 // twice. Once in the SourceBuffer, again in the VertexBuffer. That's a lot | 1448 // twice. Once in the SourceBuffer, again in the VertexBuffer. That's a lot |
| 1409 // of data to download just to throw it away. | 1449 // of data to download just to throw it away. |
| 1410 // | 1450 // |
| 1411 // 2) If we want to instance the skin we'll need to make a new VertexBuffer | 1451 // 2) If we want to instance the skin we'll need to make a new VertexBuffer |
| 1412 // so we can store the skinned vertices for the second instance. But we'd | 1452 // so we can store the skinned vertices for the second instance. But we'd |
| 1413 // like to share the COLOR and TEXCOORDS. To do that they need to be in | 1453 // like to share the COLOR and TEXCOORDS. To do that they need to be in |
| 1414 // a separate VertexBuffer. | 1454 // a separate VertexBuffer. |
| 1415 StreamBank* stream_bank = primitive->stream_bank(); | 1455 StreamBank* old_stream_bank = primitive->stream_bank(); |
| 1416 SourceBuffer* buffer = pack_->Create<SourceBuffer>(); | 1456 StreamBank* new_stream_bank = pack_->Create<StreamBank>(); |
| 1457 new_stream_bank->set_name(String("skinned_") + old_stream_bank->name()); |
| 1458 Buffer* old_buffer = NULL; |
| 1459 SourceBuffer* source_buffer = pack_->Create<SourceBuffer>(); |
| 1417 VertexBuffer* shared_buffer = pack_->Create<VertexBuffer>(); | 1460 VertexBuffer* shared_buffer = pack_->Create<VertexBuffer>(); |
| 1461 DestinationBuffer* dest_buffer = pack_->Create<DestinationBuffer>(); |
| 1418 const StreamParamVector& source_stream_params = | 1462 const StreamParamVector& source_stream_params = |
| 1419 stream_bank->vertex_stream_params(); | 1463 old_stream_bank->vertex_stream_params(); |
| 1420 std::vector<Field*> new_fields(source_stream_params.size(), NULL); | 1464 std::vector<Field*> source_fields(source_stream_params.size(), NULL); |
| 1465 std::vector<Field*> dest_fields(source_stream_params.size(), NULL); |
| 1421 // first make all the fields. | 1466 // first make all the fields. |
| 1422 for (unsigned ii = 0; ii < source_stream_params.size(); ++ii) { | 1467 for (unsigned ii = 0; ii < source_stream_params.size(); ++ii) { |
| 1423 const Stream& source_stream = source_stream_params[ii]->stream(); | 1468 const Stream& source_stream = source_stream_params[ii]->stream(); |
| 1424 const Field& field = source_stream.field(); | 1469 const Field& field = source_stream.field(); |
| 1470 if (old_buffer == NULL) { |
| 1471 old_buffer = field.buffer(); |
| 1472 } else if (old_buffer != field.buffer()) { |
| 1473 O3D_ERROR(service_locator_) |
| 1474 << "More than 1 buffer used by StreamBank '" |
| 1475 << old_stream_bank->name().c_str() |
| 1476 << "' which the collada importer does not currently support"; |
| 1477 } |
| 1425 bool copied = false; | 1478 bool copied = false; |
| 1426 if (field.IsA(FloatField::GetApparentClass()) && | 1479 if (field.IsA(FloatField::GetApparentClass()) && |
| 1427 (field.num_components() == 3 || | 1480 (field.num_components() == 3 || |
| 1428 field.num_components() == 4)) { | 1481 field.num_components() == 4)) { |
| 1429 switch (source_stream.semantic()) { | 1482 switch (source_stream.semantic()) { |
| 1430 case Stream::POSITION: | 1483 case Stream::POSITION: |
| 1431 case Stream::NORMAL: | 1484 case Stream::NORMAL: |
| 1432 case Stream::BINORMAL: | 1485 case Stream::BINORMAL: |
| 1433 case Stream::TANGENT: { | 1486 case Stream::TANGENT: { |
| 1434 copied = true; | 1487 copied = true; |
| 1435 unsigned num_source_components = field.num_components(); | 1488 unsigned num_source_components = field.num_components(); |
| 1436 unsigned num_source_vertices = source_stream.GetMaxVertices(); | 1489 unsigned num_source_vertices = source_stream.GetMaxVertices(); |
| 1437 if (num_source_vertices != num_vertices) { | 1490 if (num_source_vertices != num_vertices) { |
| 1438 O3D_ERROR(service_locator_) | 1491 O3D_ERROR(service_locator_) |
| 1439 << "Number of vertices in stream_bank '" | 1492 << "Number of vertices in stream_bank '" |
| 1440 << stream_bank->name().c_str() | 1493 << old_stream_bank->name().c_str() |
| 1441 << "' does not equal the number of vertices in the Skin '" | 1494 << "' does not equal the number of vertices in the Skin '" |
| 1442 << skin->name().c_str() << "'"; | 1495 << skin->name().c_str() << "'"; |
| 1443 return NULL; | 1496 return NULL; |
| 1444 } | 1497 } |
| 1445 new_fields[ii] = buffer->CreateField(FloatField::GetApparentClass(), | 1498 source_fields[ii] = source_buffer->CreateField( |
| 1446 num_source_components); | 1499 FloatField::GetApparentClass(), num_source_components); |
| 1500 DCHECK(source_fields[ii]); |
| 1501 dest_fields[ii] = dest_buffer->CreateField( |
| 1502 FloatField::GetApparentClass(), num_source_components); |
| 1503 DCHECK(dest_fields[ii]); |
| 1504 if (!new_stream_bank->SetVertexStream( |
| 1505 source_stream.semantic(), |
| 1506 source_stream.semantic_index(), |
| 1507 dest_fields[ii], |
| 1508 0)) { |
| 1509 O3D_ERROR(service_locator_) |
| 1510 << "could not SetVertexStream on StreamBank '" |
| 1511 << new_stream_bank->name() << "'"; |
| 1512 return NULL; |
| 1513 } |
| 1447 } | 1514 } |
| 1448 } | 1515 } |
| 1449 } | 1516 } |
| 1450 if (!copied) { | 1517 if (!copied) { |
| 1451 // It's a shared field, copy it to the shared buffer. | 1518 // It's a shared field, copy it to the shared buffer. |
| 1452 new_fields[ii] = shared_buffer->CreateField(field.GetClass(), | 1519 source_fields[ii] = shared_buffer->CreateField(field.GetClass(), |
| 1453 field.num_components()); | 1520 field.num_components()); |
| 1521 new_stream_bank->SetVertexStream(source_stream.semantic(), |
| 1522 source_stream.semantic_index(), |
| 1523 source_fields[ii], |
| 1524 0); |
| 1454 } | 1525 } |
| 1455 } | 1526 } |
| 1456 | 1527 |
| 1457 if (!buffer->AllocateElements(num_vertices) || | 1528 if (!source_buffer->AllocateElements(num_vertices) || |
| 1458 !shared_buffer->AllocateElements(num_vertices)) { | 1529 !shared_buffer->AllocateElements(num_vertices) || |
| 1530 !dest_buffer->AllocateElements(num_vertices)) { |
| 1459 O3D_ERROR(service_locator_) | 1531 O3D_ERROR(service_locator_) |
| 1460 << "Failed to allocate destination vertex buffer"; | 1532 << "Failed to allocate destination vertex buffer"; |
| 1461 return NULL; | 1533 return NULL; |
| 1462 } | 1534 } |
| 1463 | 1535 |
| 1464 for (unsigned ii = 0; ii < source_stream_params.size(); ++ii) { | 1536 for (unsigned ii = 0; ii < source_stream_params.size(); ++ii) { |
| 1465 const Stream& source_stream = source_stream_params[ii]->stream(); | 1537 const Stream& source_stream = source_stream_params[ii]->stream(); |
| 1466 const Field& field = source_stream.field(); | 1538 const Field& field = source_stream.field(); |
| 1467 bool copied = false; | 1539 bool copied = false; |
| 1468 if (field.IsA(FloatField::GetApparentClass()) && | 1540 if (field.IsA(FloatField::GetApparentClass()) && |
| 1469 (field.num_components() == 3 || | 1541 (field.num_components() == 3 || |
| 1470 field.num_components() == 4)) { | 1542 field.num_components() == 4)) { |
| 1471 switch (source_stream.semantic()) { | 1543 switch (source_stream.semantic()) { |
| 1472 case Stream::POSITION: | 1544 case Stream::POSITION: |
| 1473 case Stream::NORMAL: | 1545 case Stream::NORMAL: |
| 1474 case Stream::BINORMAL: | 1546 case Stream::BINORMAL: |
| 1475 case Stream::TANGENT: { | 1547 case Stream::TANGENT: { |
| 1476 copied = true; | 1548 copied = true; |
| 1477 unsigned num_source_components = field.num_components(); | 1549 unsigned num_source_components = field.num_components(); |
| 1478 Field* new_field = new_fields[ii]; | 1550 Field* source_field = source_fields[ii]; |
| 1479 | 1551 |
| 1480 std::vector<float> data(num_vertices * num_source_components); | 1552 std::vector<float> data(num_vertices * num_source_components); |
| 1481 field.GetAsFloats(0, &data[0], num_source_components, | 1553 field.GetAsFloats(0, &data[0], num_source_components, |
| 1482 num_vertices); | 1554 num_vertices); |
| 1483 // TODO(o3d): Remove this matrix multiply. I don't think it is | 1555 // TODO(o3d): Remove this matrix multiply. I don't think it is |
| 1484 // needed. | 1556 // needed. |
| 1485 for (unsigned vv = 0; vv < num_vertices; ++vv) { | 1557 for (unsigned vv = 0; vv < num_vertices; ++vv) { |
| 1486 float* values = &data[vv * num_source_components]; | 1558 float* values = &data[vv * num_source_components]; |
| 1487 switch (field.num_components()) { | 1559 switch (field.num_components()) { |
| 1488 case 3: { | 1560 case 3: { |
| (...skipping 20 matching lines...) Expand all Loading... |
| 1509 values[2], | 1581 values[2], |
| 1510 values[3])); | 1582 values[3])); |
| 1511 values[0] = result.getElem(0); | 1583 values[0] = result.getElem(0); |
| 1512 values[1] = result.getElem(1); | 1584 values[1] = result.getElem(1); |
| 1513 values[2] = result.getElem(2); | 1585 values[2] = result.getElem(2); |
| 1514 values[3] = result.getElem(3); | 1586 values[3] = result.getElem(3); |
| 1515 break; | 1587 break; |
| 1516 } | 1588 } |
| 1517 } | 1589 } |
| 1518 } | 1590 } |
| 1519 new_field->SetFromFloats(&data[0], num_source_components, 0, | 1591 source_field->SetFromFloats(&data[0], num_source_components, 0, |
| 1520 num_vertices); | 1592 num_vertices); |
| 1521 // Bind streams | 1593 // Bind streams |
| 1522 skin_eval->SetVertexStream(source_stream.semantic(), | 1594 skin_eval->SetVertexStream(source_stream.semantic(), |
| 1523 source_stream.semantic_index(), | 1595 source_stream.semantic_index(), |
| 1524 new_field, | 1596 source_field, |
| 1525 0); | 1597 0); |
| 1526 stream_bank->BindStream(skin_eval, | 1598 new_stream_bank->BindStream(skin_eval, |
| 1527 source_stream.semantic(), | 1599 source_stream.semantic(), |
| 1528 source_stream.semantic_index()); | 1600 source_stream.semantic_index()); |
| 1529 break; | 1601 break; |
| 1530 } | 1602 } |
| 1531 } | 1603 } |
| 1532 } | 1604 } |
| 1533 if (!copied) { | 1605 if (!copied) { |
| 1534 Field* new_field = new_fields[ii]; | 1606 Field* source_field = source_fields[ii]; |
| 1535 new_field->Copy(field); | 1607 source_field->Copy(field); |
| 1536 field.buffer()->RemoveField(&source_stream.field()); | |
| 1537 stream_bank->SetVertexStream(source_stream.semantic(), | |
| 1538 source_stream.semantic_index(), | |
| 1539 new_field, | |
| 1540 0); | |
| 1541 } | 1608 } |
| 1542 } | 1609 } |
| 1610 |
| 1611 // Set all primitives to use new stream bank. |
| 1612 for (unsigned ii = 0; ii < elements.size(); ++ii) { |
| 1613 down_cast<Primitive*>(elements[ii].Get())->set_stream_bank( |
| 1614 new_stream_bank); |
| 1615 } |
| 1616 pack_->RemoveObject(old_stream_bank); |
| 1617 if (old_buffer) { |
| 1618 source_buffer->set_name(String("source_") + old_buffer->name()); |
| 1619 dest_buffer->set_name(String("skinned_") + old_buffer->name()); |
| 1620 shared_buffer->set_name(String("shared_") + old_buffer->name()); |
| 1621 pack_->RemoveObject(old_buffer); |
| 1622 } |
| 1543 } | 1623 } |
| 1544 return shape; | 1624 return shape; |
| 1545 } | 1625 } |
| 1546 | 1626 |
| 1547 Texture* Collada::BuildTextureFromImage(FCDImage* image) { | 1627 Texture* Collada::BuildTextureFromImage(FCDImage* image) { |
| 1548 const fstring filename = image->GetFilename(); | 1628 const fstring filename = image->GetFilename(); |
| 1549 Texture* tex = textures_[filename.c_str()]; | 1629 Texture* tex = textures_[filename.c_str()]; |
| 1550 if (!tex) { | 1630 if (!tex) { |
| 1551 FilePath file_path = WideToFilePath(filename.c_str()); | 1631 FilePath file_path = WideToFilePath(filename.c_str()); |
| 1552 FilePath uri = file_path; | 1632 FilePath uri = file_path; |
| (...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2760 SetParamFromFCEffectParam(param_object, | 2840 SetParamFromFCEffectParam(param_object, |
| 2761 kMaterialParamNameShininess, | 2841 kMaterialParamNameShininess, |
| 2762 effect_standard->GetShininessParam()); | 2842 effect_standard->GetShininessParam()); |
| 2763 SetParamFromFCEffectParam(param_object, | 2843 SetParamFromFCEffectParam(param_object, |
| 2764 kMaterialParamNameSpecularFactor, | 2844 kMaterialParamNameSpecularFactor, |
| 2765 effect_standard->GetSpecularFactorParam()); | 2845 effect_standard->GetSpecularFactorParam()); |
| 2766 } | 2846 } |
| 2767 } | 2847 } |
| 2768 } | 2848 } |
| 2769 } // namespace o3d | 2849 } // namespace o3d |
| OLD | NEW |