|
|
@@ -297,6 +297,23 @@ void PhysicsController::removeRigidBody(PhysicsRigidBody* rigidBody)
|
|
|
break;
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+ // Find the rigid body's collision shape and release the rigid body's reference to it.
|
|
|
+ for (unsigned int i = 0; i < _shapes.size(); i++)
|
|
|
+ {
|
|
|
+ if (_shapes[i]->_shape == rigidBody->_shape)
|
|
|
+ {
|
|
|
+ if (_shapes[i]->getRefCount() == 1)
|
|
|
+ {
|
|
|
+ _shapes[i]->release();
|
|
|
+ _shapes.erase(_shapes.begin() + i);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ _shapes[i]->release();
|
|
|
+
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
PhysicsRigidBody* PhysicsController::getRigidBody(const btCollisionObject* collisionObject)
|
|
|
@@ -314,8 +331,24 @@ PhysicsRigidBody* PhysicsController::getRigidBody(const btCollisionObject* colli
|
|
|
btCollisionShape* PhysicsController::createBox(const Vector3& min, const Vector3& max, const btVector3& scale)
|
|
|
{
|
|
|
btVector3 halfExtents(scale.x() * 0.5 * abs(max.x - min.x), scale.y() * 0.5 * abs(max.y - min.y), scale.z() * 0.5 * abs(max.z - min.z));
|
|
|
+
|
|
|
+ // Return the box shape from the cache if it already exists.
|
|
|
+ for (unsigned int i = 0; i < _shapes.size(); i++)
|
|
|
+ {
|
|
|
+ if (_shapes[i]->_shape->getShapeType() == BOX_SHAPE_PROXYTYPE)
|
|
|
+ {
|
|
|
+ btBoxShape* box = static_cast<btBoxShape*>(_shapes[i]->_shape);
|
|
|
+ if (box->getHalfExtentsWithMargin() == halfExtents)
|
|
|
+ {
|
|
|
+ _shapes[i]->addRef();
|
|
|
+ return box;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create the box shape and add it to the cache.
|
|
|
btBoxShape* box = bullet_new<btBoxShape>(halfExtents);
|
|
|
- _shapes.push_back(box);
|
|
|
+ _shapes.push_back(new PhysicsCollisionShape(box));
|
|
|
|
|
|
return box;
|
|
|
}
|
|
|
@@ -330,8 +363,23 @@ btCollisionShape* PhysicsController::createSphere(float radius, const btVector3&
|
|
|
if (uniformScale < scale.z())
|
|
|
uniformScale = scale.z();
|
|
|
|
|
|
+ // Return the sphere shape from the cache if it already exists.
|
|
|
+ for (unsigned int i = 0; i < _shapes.size(); i++)
|
|
|
+ {
|
|
|
+ if (_shapes[i]->_shape->getShapeType() == SPHERE_SHAPE_PROXYTYPE)
|
|
|
+ {
|
|
|
+ btSphereShape* sphere = static_cast<btSphereShape*>(_shapes[i]->_shape);
|
|
|
+ if (sphere->getRadius() == uniformScale * radius)
|
|
|
+ {
|
|
|
+ _shapes[i]->addRef();
|
|
|
+ return sphere;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ // Create the sphere shape and add it to the cache.
|
|
|
btSphereShape* sphere = bullet_new<btSphereShape>(uniformScale * radius);
|
|
|
- _shapes.push_back(sphere);
|
|
|
+ _shapes.push_back(new PhysicsCollisionShape(sphere));
|
|
|
|
|
|
return sphere;
|
|
|
}
|
|
|
@@ -431,7 +479,7 @@ btCollisionShape* PhysicsController::createMesh(PhysicsRigidBody* body)
|
|
|
}
|
|
|
|
|
|
btBvhTriangleMeshShape* shape = bullet_new<btBvhTriangleMeshShape>(meshInterface, true);
|
|
|
- _shapes.push_back(shape);
|
|
|
+ _shapes.push_back(new PhysicsCollisionShape(shape));
|
|
|
|
|
|
return shape;
|
|
|
}
|
|
|
@@ -480,103 +528,87 @@ void PhysicsController::removeConstraint(PhysicsConstraint* constraint)
|
|
|
|
|
|
PhysicsController::DebugDrawer::DebugDrawer()
|
|
|
: _mode(btIDebugDraw::DBG_DrawAabb | btIDebugDraw::DBG_DrawConstraintLimits | btIDebugDraw::DBG_DrawConstraints |
|
|
|
- btIDebugDraw::DBG_DrawContactPoints | btIDebugDraw::DBG_DrawWireframe), _effect(NULL), _positionAttrib(0), _colorAttrib(0),
|
|
|
- _viewProjectionMatrixUniform(NULL), _viewProjection(NULL), _vertexData(NULL), _vertexCount(0), _vertexDataSize(0)
|
|
|
+ btIDebugDraw::DBG_DrawContactPoints | btIDebugDraw::DBG_DrawWireframe), _viewProjection(NULL), _meshBatch(NULL)
|
|
|
{
|
|
|
- // Unused
|
|
|
+ // Vertex shader for drawing colored lines.
|
|
|
+ const char* vs_str =
|
|
|
+ {
|
|
|
+ "uniform mat4 u_viewProjectionMatrix;\n"
|
|
|
+ "attribute vec4 a_position;\n"
|
|
|
+ "attribute vec4 a_color;\n"
|
|
|
+ "varying vec4 v_color;\n"
|
|
|
+ "void main(void) {\n"
|
|
|
+ " v_color = a_color;\n"
|
|
|
+ " gl_Position = u_viewProjectionMatrix * a_position;\n"
|
|
|
+ "}"
|
|
|
+ };
|
|
|
+
|
|
|
+ // Fragment shader for drawing colored lines.
|
|
|
+ const char* fs_str =
|
|
|
+ {
|
|
|
+ #ifdef OPENGL_ES
|
|
|
+ "precision highp float;\n"
|
|
|
+ #endif
|
|
|
+ "varying vec4 v_color;\n"
|
|
|
+ "void main(void) {\n"
|
|
|
+ " gl_FragColor = v_color;\n"
|
|
|
+ "}"
|
|
|
+ };
|
|
|
+
|
|
|
+ Effect* effect = Effect::createFromSource(vs_str, fs_str);
|
|
|
+ Material* material = Material::create(effect);
|
|
|
+
|
|
|
+ VertexFormat::Element elements[] =
|
|
|
+ {
|
|
|
+ VertexFormat::Element(VertexFormat::POSITION, 3),
|
|
|
+ VertexFormat::Element(VertexFormat::COLOR, 4),
|
|
|
+ };
|
|
|
+ _meshBatch = MeshBatch::create(VertexFormat(elements, 2), Mesh::LINES, material, false);
|
|
|
+
|
|
|
+ SAFE_RELEASE(material);
|
|
|
+ SAFE_RELEASE(effect);
|
|
|
}
|
|
|
|
|
|
PhysicsController::DebugDrawer::~DebugDrawer()
|
|
|
{
|
|
|
- SAFE_RELEASE(_effect);
|
|
|
- SAFE_DELETE_ARRAY(_vertexData);
|
|
|
+ SAFE_DELETE(_meshBatch);
|
|
|
}
|
|
|
|
|
|
void PhysicsController::DebugDrawer::begin(const Matrix& viewProjection)
|
|
|
{
|
|
|
_viewProjection = &viewProjection;
|
|
|
- _vertexCount = 0;
|
|
|
+ _meshBatch->begin();
|
|
|
}
|
|
|
|
|
|
void PhysicsController::DebugDrawer::end()
|
|
|
{
|
|
|
- // Lazy load the effect for drawing.
|
|
|
- if (!_effect)
|
|
|
- {
|
|
|
- // Vertex shader for drawing colored lines.
|
|
|
- const char* vs_str =
|
|
|
- {
|
|
|
- "uniform mat4 u_viewProjectionMatrix;\n"
|
|
|
- "attribute vec4 a_position;\n"
|
|
|
- "attribute vec4 a_color;\n"
|
|
|
- "varying vec4 v_color;\n"
|
|
|
- "void main(void) {\n"
|
|
|
- " v_color = a_color;\n"
|
|
|
- " gl_Position = u_viewProjectionMatrix * a_position;\n"
|
|
|
- "}"
|
|
|
- };
|
|
|
-
|
|
|
- // Fragment shader for drawing colored lines.
|
|
|
- const char* fs_str =
|
|
|
- {
|
|
|
- #ifdef OPENGL_ES
|
|
|
- "precision highp float;\n"
|
|
|
- #endif
|
|
|
- "varying vec4 v_color;\n"
|
|
|
- "void main(void) {\n"
|
|
|
- " gl_FragColor = v_color;\n"
|
|
|
- "}"
|
|
|
- };
|
|
|
-
|
|
|
- _effect = Effect::createFromSource(vs_str, fs_str);
|
|
|
- _positionAttrib = _effect->getVertexAttribute("a_position");
|
|
|
- _colorAttrib = _effect->getVertexAttribute("a_color");
|
|
|
- _viewProjectionMatrixUniform = _effect->getUniform("u_viewProjectionMatrix");
|
|
|
- }
|
|
|
-
|
|
|
- // Bind the effect and set the vertex attributes.
|
|
|
- _effect->bind();
|
|
|
- GL_ASSERT( glEnableVertexAttribArray(_positionAttrib) );
|
|
|
- GL_ASSERT( glEnableVertexAttribArray(_colorAttrib) );
|
|
|
- GL_ASSERT( glVertexAttribPointer(_positionAttrib, 3, GL_FLOAT, GL_FALSE, sizeof(float) * 7, _vertexData) );
|
|
|
- GL_ASSERT( glVertexAttribPointer(_colorAttrib, 4, GL_FLOAT, GL_FALSE, sizeof(float) * 7, &_vertexData[3]) );
|
|
|
-
|
|
|
- // Set the camera's view projection matrix and draw.
|
|
|
- _effect->setValue( _viewProjectionMatrixUniform, _viewProjection);
|
|
|
- GL_ASSERT( glDrawArrays(GL_LINES, 0, _vertexCount / 7) );
|
|
|
+ _meshBatch->getMaterial()->getParameter("u_viewProjectionMatrix")->setValue(_viewProjection);
|
|
|
+ _meshBatch->draw();
|
|
|
+ _meshBatch->end();
|
|
|
}
|
|
|
|
|
|
void PhysicsController::DebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& fromColor, const btVector3& toColor)
|
|
|
{
|
|
|
- // Allocate extra space in the vertex data batch if it is needed.
|
|
|
- if (_vertexDataSize - _vertexCount < 14)
|
|
|
- {
|
|
|
- if (_vertexDataSize > 0)
|
|
|
- {
|
|
|
- unsigned int newVertexDataSize = _vertexDataSize * 2;
|
|
|
- float* newVertexData = new float[newVertexDataSize];
|
|
|
- memcpy(newVertexData, _vertexData, _vertexDataSize * sizeof(float));
|
|
|
- SAFE_DELETE_ARRAY(_vertexData);
|
|
|
- _vertexData = newVertexData;
|
|
|
- _vertexDataSize = newVertexDataSize;
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- _vertexDataSize = INITIAL_CAPACITY;
|
|
|
- _vertexData = new float[_vertexDataSize];
|
|
|
- }
|
|
|
- }
|
|
|
+ static DebugDrawer::DebugVertex fromVertex, toVertex;
|
|
|
|
|
|
- // Create the vertex data for the line and copy it into the batch.
|
|
|
- float vertexData[] =
|
|
|
- {
|
|
|
- from.getX(), from.getY(), from.getZ(),
|
|
|
- fromColor.getX(), fromColor.getY(), fromColor.getZ(), 1.0f,
|
|
|
- to.getX(), to.getY(), to.getZ(),
|
|
|
- toColor.getX(), toColor.getY(), toColor.getZ(), 1.0f
|
|
|
- };
|
|
|
- memcpy(&_vertexData[_vertexCount], vertexData, sizeof(float) * 14);
|
|
|
- _vertexCount += 14;
|
|
|
+ fromVertex.x = from.getX();
|
|
|
+ fromVertex.y = from.getY();
|
|
|
+ fromVertex.z = from.getZ();
|
|
|
+ fromVertex.r = fromColor.getX();
|
|
|
+ fromVertex.g = fromColor.getY();
|
|
|
+ fromVertex.b = fromColor.getZ();
|
|
|
+ fromVertex.a = 1.0f;
|
|
|
+
|
|
|
+ toVertex.x = to.getX();
|
|
|
+ toVertex.y = to.getY();
|
|
|
+ toVertex.z = to.getZ();
|
|
|
+ toVertex.r = toColor.getX();
|
|
|
+ toVertex.g = toColor.getY();
|
|
|
+ toVertex.b = toColor.getZ();
|
|
|
+ toVertex.a = 1.0f;
|
|
|
+
|
|
|
+ _meshBatch->add(&fromVertex, 1);
|
|
|
+ _meshBatch->add(&toVertex, 1);
|
|
|
}
|
|
|
|
|
|
void PhysicsController::DebugDrawer::drawLine(const btVector3& from, const btVector3& to, const btVector3& color)
|