TriangleMeshShape.cpp 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. //
  2. // Urho3D Engine
  3. // Copyright (c) 2008-2012 Lasse Öörni
  4. //
  5. // Permission is hereby granted, free of charge, to any person obtaining a copy
  6. // of this software and associated documentation files (the "Software"), to deal
  7. // in the Software without restriction, including without limitation the rights
  8. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  9. // copies of the Software, and to permit persons to whom the Software is
  10. // furnished to do so, subject to the following conditions:
  11. //
  12. // The above copyright notice and this permission notice shall be included in
  13. // all copies or substantial portions of the Software.
  14. //
  15. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  16. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  17. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  18. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  19. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  20. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  21. // THE SOFTWARE.
  22. //
  23. #include "Precompiled.h"
  24. #include "Context.h"
  25. #include "Model.h"
  26. #include "Node.h"
  27. #include "PhysicsUtils.h"
  28. #include "PhysicsWorld.h"
  29. #include "ResourceCache.h"
  30. #include "TriangleMeshShape.h"
  31. #include <BulletCollision/CollisionShapes/btScaledBvhTriangleMeshShape.h>
  32. #include <stdio.h>
  33. OBJECTTYPESTATIC(TriangleMeshShape);
  34. TriangleMeshShape::TriangleMeshShape(Context* context) :
  35. CollisionShape(context),
  36. size_(Vector3::ONE),
  37. lodLevel_(0)
  38. {
  39. }
  40. TriangleMeshShape::~TriangleMeshShape()
  41. {
  42. delete shape_;
  43. shape_ = 0;
  44. geometry_.Reset();
  45. if (physicsWorld_)
  46. physicsWorld_->CleanupGeometryCache();
  47. }
  48. void TriangleMeshShape::RegisterObject(Context* context)
  49. {
  50. context->RegisterFactory<TriangleMeshShape>();
  51. ACCESSOR_ATTRIBUTE(TriangleMeshShape, VAR_RESOURCEREF, "Model", GetModelAttr, SetModelAttr, ResourceRef, ResourceRef(Model::GetTypeStatic()), AM_DEFAULT);
  52. ATTRIBUTE(TriangleMeshShape, VAR_INT, "LOD Level", lodLevel_, 0, AM_DEFAULT);
  53. ATTRIBUTE(TriangleMeshShape, VAR_VECTOR3, "Offset Position", position_, Vector3::ZERO, AM_DEFAULT);
  54. ATTRIBUTE(TriangleMeshShape, VAR_QUATERNION, "Offset Rotation", rotation_, Quaternion::IDENTITY, AM_DEFAULT);
  55. ATTRIBUTE(TriangleMeshShape, VAR_VECTOR3, "Size", size_, Vector3::ONE, AM_DEFAULT);
  56. }
  57. void TriangleMeshShape::SetModel(Model* model)
  58. {
  59. if (model != model_)
  60. {
  61. model_ = model;
  62. UpdateCollisionShape();
  63. NotifyRigidBody();
  64. }
  65. }
  66. void TriangleMeshShape::SetLodLevel(unsigned lodLevel)
  67. {
  68. if (lodLevel != lodLevel_)
  69. {
  70. lodLevel_ = lodLevel;
  71. UpdateCollisionShape();
  72. NotifyRigidBody();
  73. }
  74. }
  75. void TriangleMeshShape::SetSize(const Vector3& size)
  76. {
  77. if (size != size_)
  78. {
  79. size_ = size;
  80. UpdateCollisionShape();
  81. NotifyRigidBody();
  82. }
  83. }
  84. Model* TriangleMeshShape::GetModel() const
  85. {
  86. return model_;
  87. }
  88. void TriangleMeshShape::SetModelAttr(ResourceRef value)
  89. {
  90. ResourceCache* cache = GetSubsystem<ResourceCache>();
  91. model_ = cache->GetResource<Model>(value.id_);
  92. dirty_ = true;
  93. }
  94. ResourceRef TriangleMeshShape::GetModelAttr() const
  95. {
  96. return GetResourceRef(model_, Model::GetTypeStatic());
  97. }
  98. void TriangleMeshShape::UpdateCollisionShape()
  99. {
  100. if (node_)
  101. {
  102. delete shape_;
  103. shape_ = 0;
  104. if (model_ && physicsWorld_)
  105. {
  106. char sizeText[CONVERSION_BUFFER_LENGTH];
  107. sprintf(sizeText, "%.3f%.3f%.3f", size_.x_, size_.y_, size_.z_);
  108. // Check the geometry cache
  109. String id = model_->GetName() + "_" + String(lodLevel_) + "_" + String(sizeText);
  110. Map<String, SharedPtr<TriangleMeshData> >& cache = physicsWorld_->GetTriangleMeshCache();
  111. Map<String, SharedPtr<TriangleMeshData> >::Iterator j = cache.Find(id);
  112. if (j != cache.End())
  113. geometry_ = j->second_;
  114. else
  115. {
  116. geometry_ = new TriangleMeshData(model_, lodLevel_, size_);
  117. cache[id] = geometry_;
  118. }
  119. shape_ = new btScaledBvhTriangleMeshShape(geometry_->shape_, ToBtVector3(node_->GetWorldScale()));
  120. }
  121. else
  122. geometry_.Reset();
  123. if (physicsWorld_)
  124. physicsWorld_->CleanupGeometryCache();
  125. }
  126. }