233 lines
9.2 KiB
C++
233 lines
9.2 KiB
C++
/********************************************************************************
|
|
* ReactPhysics3D physics library, http://www.reactphysics3d.com *
|
|
* Copyright (c) 2010-2018 Daniel Chappuis *
|
|
*********************************************************************************
|
|
* *
|
|
* This software is provided 'as-is', without any express or implied warranty. *
|
|
* In no event will the authors be held liable for any damages arising from the *
|
|
* use of this software. *
|
|
* *
|
|
* Permission is granted to anyone to use this software for any purpose, *
|
|
* including commercial applications, and to alter it and redistribute it *
|
|
* freely, subject to the following restrictions: *
|
|
* *
|
|
* 1. The origin of this software must not be misrepresented; you must not claim *
|
|
* that you wrote the original software. If you use this software in a *
|
|
* product, an acknowledgment in the product documentation would be *
|
|
* appreciated but is not required. *
|
|
* *
|
|
* 2. Altered source versions must be plainly marked as such, and must not be *
|
|
* misrepresented as being the original software. *
|
|
* *
|
|
* 3. This notice may not be removed or altered from any source distribution. *
|
|
* *
|
|
********************************************************************************/
|
|
|
|
// Libraries
|
|
#include "ProxyShape.h"
|
|
#include "utils/Logger.h"
|
|
#include "collision/RaycastInfo.h"
|
|
#include "memory/MemoryManager.h"
|
|
#include "engine/CollisionWorld.h"
|
|
|
|
using namespace reactphysics3d;
|
|
|
|
// Constructor
|
|
/**
|
|
* @param body Pointer to the parent body
|
|
* @param shape Pointer to the collision shape
|
|
* @param transform Transformation from collision shape local-space to body local-space
|
|
* @param mass Mass of the collision shape (in kilograms)
|
|
*/
|
|
ProxyShape::ProxyShape(Entity entity, CollisionBody* body, MemoryManager& memoryManager)
|
|
:mMemoryManager(memoryManager), mEntity(entity), mBody(body),
|
|
mUserData(nullptr) {
|
|
|
|
}
|
|
|
|
// Destructor
|
|
ProxyShape::~ProxyShape() {
|
|
|
|
}
|
|
|
|
// Return the mass of the collision shape
|
|
/**
|
|
* @return Mass of the collision shape (in kilograms)
|
|
*/
|
|
decimal ProxyShape::getMass() const {
|
|
return mBody->mWorld.mProxyShapesComponents.getMass(mEntity);
|
|
}
|
|
|
|
|
|
// Return true if a point is inside the collision shape
|
|
/**
|
|
* @param worldPoint Point to test in world-space coordinates
|
|
* @return True if the point is inside the collision shape
|
|
*/
|
|
bool ProxyShape::testPointInside(const Vector3& worldPoint) {
|
|
const Transform localToWorld = mBody->mWorld.mTransformComponents.getTransform(mBody->getEntity()) *
|
|
mBody->mWorld.mProxyShapesComponents.getLocalToBodyTransform(mEntity);
|
|
const Vector3 localPoint = localToWorld.getInverse() * worldPoint;
|
|
const CollisionShape* collisionShape = mBody->mWorld.mProxyShapesComponents.getCollisionShape(mEntity);
|
|
return collisionShape->testPointInside(localPoint, this);
|
|
}
|
|
|
|
// Set the collision category bits
|
|
/**
|
|
* @param collisionCategoryBits The collision category bits mask of the proxy shape
|
|
*/
|
|
void ProxyShape::setCollisionCategoryBits(unsigned short collisionCategoryBits) {
|
|
|
|
mBody->mWorld.mProxyShapesComponents.setCollisionCategoryBits(mEntity, collisionCategoryBits);
|
|
|
|
int broadPhaseId = mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(mEntity);
|
|
|
|
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
|
|
"ProxyShape " + std::to_string(broadPhaseId) + ": Set collisionCategoryBits=" +
|
|
std::to_string(collisionCategoryBits));
|
|
}
|
|
|
|
// Set the collision bits mask
|
|
/**
|
|
* @param collideWithMaskBits The bits mask that specifies with which collision category this shape will collide
|
|
*/
|
|
void ProxyShape::setCollideWithMaskBits(unsigned short collideWithMaskBits) {
|
|
|
|
mBody->mWorld.mProxyShapesComponents.setCollideWithMaskBits(mEntity, collideWithMaskBits);
|
|
|
|
int broadPhaseId = mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(mEntity);
|
|
|
|
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
|
|
"ProxyShape " + std::to_string(broadPhaseId) + ": Set collideWithMaskBits=" +
|
|
std::to_string(collideWithMaskBits));
|
|
}
|
|
|
|
// Set the local to parent body transform
|
|
void ProxyShape::setLocalToBodyTransform(const Transform& transform) {
|
|
|
|
//mLocalToBodyTransform = transform;
|
|
mBody->mWorld.mProxyShapesComponents.setLocalToBodyTransform(mEntity, transform);
|
|
|
|
mBody->setIsSleeping(false);
|
|
|
|
// Notify the body that the proxy shape has to be updated in the broad-phase
|
|
mBody->updateProxyShapeInBroadPhase(this, true);
|
|
|
|
int broadPhaseId = mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(mEntity);
|
|
|
|
RP3D_LOG(mLogger, Logger::Level::Information, Logger::Category::ProxyShape,
|
|
"ProxyShape " + std::to_string(broadPhaseId) + ": Set localToBodyTransform=" +
|
|
transform.to_string());
|
|
}
|
|
|
|
// Return the AABB of the proxy shape in world-space
|
|
/**
|
|
* @return The AABB of the proxy shape in world-space
|
|
*/
|
|
const AABB ProxyShape::getWorldAABB() const {
|
|
AABB aabb;
|
|
CollisionShape* collisionShape = mBody->mWorld.mProxyShapesComponents.getCollisionShape(mEntity);
|
|
collisionShape->computeAABB(aabb, getLocalToWorldTransform());
|
|
return aabb;
|
|
}
|
|
|
|
// Return the collision shape
|
|
/**
|
|
* @return Pointer to the internal collision shape
|
|
*/
|
|
const CollisionShape* ProxyShape::getCollisionShape() const {
|
|
return mBody->mWorld.mProxyShapesComponents.getCollisionShape(mEntity);
|
|
}
|
|
|
|
// Return the collision shape
|
|
/**
|
|
* @return Pointer to the internal collision shape
|
|
*/
|
|
CollisionShape* ProxyShape::getCollisionShape() {
|
|
return mBody->mWorld.mProxyShapesComponents.getCollisionShape(mEntity);
|
|
}
|
|
|
|
// Return the broad-phase id
|
|
int ProxyShape::getBroadPhaseId() const {
|
|
return mBody->mWorld.mProxyShapesComponents.getBroadPhaseId(mEntity);
|
|
}
|
|
|
|
// Return the local to parent body transform
|
|
/**
|
|
* @return The transformation that transforms the local-space of the collision shape
|
|
* to the local-space of the parent body
|
|
*/
|
|
const Transform& ProxyShape::getLocalToBodyTransform() const {
|
|
return mBody->mWorld.mProxyShapesComponents.getLocalToBodyTransform(mEntity);
|
|
}
|
|
|
|
// Raycast method with feedback information
|
|
/**
|
|
* @param ray Ray to use for the raycasting
|
|
* @param[out] raycastInfo Result of the raycasting that is valid only if the
|
|
* methods returned true
|
|
* @return True if the ray hits the collision shape
|
|
*/
|
|
bool ProxyShape::raycast(const Ray& ray, RaycastInfo& raycastInfo) {
|
|
|
|
// If the corresponding body is not active, it cannot be hit by rays
|
|
if (!mBody->isActive()) return false;
|
|
|
|
// Convert the ray into the local-space of the collision shape
|
|
const Transform localToWorldTransform = getLocalToWorldTransform();
|
|
const Transform worldToLocalTransform = localToWorldTransform.getInverse();
|
|
Ray rayLocal(worldToLocalTransform * ray.point1,
|
|
worldToLocalTransform * ray.point2,
|
|
ray.maxFraction);
|
|
|
|
const CollisionShape* collisionShape = mBody->mWorld.mProxyShapesComponents.getCollisionShape(mEntity);
|
|
bool isHit = collisionShape->raycast(rayLocal, raycastInfo, this, mMemoryManager.getPoolAllocator());
|
|
|
|
// Convert the raycast info into world-space
|
|
raycastInfo.worldPoint = localToWorldTransform * raycastInfo.worldPoint;
|
|
raycastInfo.worldNormal = localToWorldTransform.getOrientation() * raycastInfo.worldNormal;
|
|
raycastInfo.worldNormal.normalize();
|
|
|
|
return isHit;
|
|
}
|
|
|
|
// Return the collision category bits
|
|
/**
|
|
* @return The collision category bits mask of the proxy shape
|
|
*/
|
|
unsigned short ProxyShape::getCollisionCategoryBits() const {
|
|
return mBody->mWorld.mProxyShapesComponents.getCollisionCategoryBits(mEntity);
|
|
}
|
|
|
|
// Return the collision bits mask
|
|
/**
|
|
* @return The bits mask that specifies with which collision category this shape will collide
|
|
*/
|
|
unsigned short ProxyShape::getCollideWithMaskBits() const {
|
|
return mBody->mWorld.mProxyShapesComponents.getCollideWithMaskBits(mEntity);
|
|
}
|
|
|
|
// Return the local to world transform
|
|
/**
|
|
* @return The transformation that transforms the local-space of the collision
|
|
* shape to the world-space
|
|
*/
|
|
const Transform ProxyShape::getLocalToWorldTransform() const {
|
|
return mBody->mWorld.mTransformComponents.getTransform(mBody->getEntity()) *
|
|
mBody->mWorld.mProxyShapesComponents.getLocalToBodyTransform(mEntity);
|
|
}
|
|
|
|
#ifdef IS_PROFILING_ACTIVE
|
|
|
|
// Set the profiler
|
|
void ProxyShape::setProfiler(Profiler* profiler) {
|
|
|
|
mProfiler = profiler;
|
|
|
|
CollisionShape* collisionShape = mBody->mWorld.mProxyShapesComponents.getCollisionShape(mEntity);
|
|
collisionShape->setProfiler(profiler);
|
|
}
|
|
|
|
#endif
|
|
|