Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp')
-rw-r--r--extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp186
1 files changed, 186 insertions, 0 deletions
diff --git a/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp
new file mode 100644
index 00000000000..21baabfb864
--- /dev/null
+++ b/extern/bullet/Bullet/NarrowPhaseCollision/ContinuousConvexCollision.cpp
@@ -0,0 +1,186 @@
+/*
+ * Copyright (c) 2005 Erwin Coumans http://www.erwincoumans.com
+ *
+ * Permission to use, copy, modify, distribute and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies.
+ * Erwin Coumans makes no representations about the suitability
+ * of this software for any purpose.
+ * It is provided "as is" without express or implied warranty.
+*/
+
+#include "ContinuousConvexCollision.h"
+#include "CollisionShapes/ConvexShape.h"
+#include "CollisionShapes/MinkowskiSumShape.h"
+#include "NarrowPhaseCollision/SimplexSolverInterface.h"
+#include "SimdTransformUtil.h"
+#include "CollisionShapes/SphereShape.h"
+
+#include "GjkPairDetector.h"
+#include "PointCollector.h"
+
+
+
+ContinuousConvexCollision::ContinuousConvexCollision ( ConvexShape* convexA,ConvexShape* convexB,SimplexSolverInterface* simplexSolver, ConvexPenetrationDepthSolver* penetrationDepthSolver)
+:m_simplexSolver(simplexSolver),
+m_penetrationDepthSolver(penetrationDepthSolver),
+m_convexA(convexA),m_convexB(convexB)
+{
+}
+
+/// This maximum should not be necessary. It allows for untested/degenerate cases in production code.
+/// You don't want your game ever to lock-up.
+#define MAX_ITERATIONS 1000
+
+bool ContinuousConvexCollision::calcTimeOfImpact(
+ const SimdTransform& fromA,
+ const SimdTransform& toA,
+ const SimdTransform& fromB,
+ const SimdTransform& toB,
+ CastResult& result)
+{
+
+ m_simplexSolver->reset();
+
+ /// compute linear and angular velocity for this interval, to interpolate
+ SimdVector3 linVelA,angVelA,linVelB,angVelB;
+ SimdTransformUtil::CalculateVelocity(fromA,toA,1.f,linVelA,angVelA);
+ SimdTransformUtil::CalculateVelocity(fromB,toB,1.f,linVelB,angVelB);
+
+ SimdScalar boundingRadiusA = m_convexA->GetAngularMotionDisc();
+ SimdScalar boundingRadiusB = m_convexB->GetAngularMotionDisc();
+
+ SimdScalar maxAngularProjectedVelocity = angVelA.length() * boundingRadiusA + angVelB.length() * boundingRadiusB;
+
+ float radius = 0.001f;
+
+ SimdScalar lambda = 0.f;
+ SimdVector3 v(1,0,0);
+
+ int maxIter = MAX_ITERATIONS;
+
+ SimdVector3 n;
+ n.setValue(0.f,0.f,0.f);
+ bool hasResult = false;
+ SimdVector3 c;
+
+ float lastLambda = lambda;
+ float epsilon = 0.001f;
+
+ int numIter = 0;
+ //first solution, using GJK
+
+
+ SimdTransform identityTrans;
+ identityTrans.setIdentity();
+
+ SphereShape raySphere(0.0f);
+ raySphere.SetMargin(0.f);
+
+
+// result.DrawCoordSystem(sphereTr);
+
+ PointCollector pointCollector1;
+
+ {
+
+ GjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
+ GjkPairDetector::ClosestPointInput input;
+ input.m_transformA = fromA;
+ input.m_transformB = fromB;
+ gjk.GetClosestPoints(input,pointCollector1);
+
+ hasResult = pointCollector1.m_hasResult;
+ c = pointCollector1.m_pointInWorld;
+ }
+
+ if (hasResult)
+ {
+ SimdScalar dist;
+ dist = pointCollector1.m_distance;
+ n = pointCollector1.m_normalOnBInWorld;
+
+ //not close enough
+ while (dist > radius)
+ {
+ numIter++;
+ if (numIter > maxIter)
+ return false; //todo: report a failure
+
+ float dLambda = 0.f;
+
+ //calculate safe moving fraction from distance / (linear+rotational velocity)
+
+ //float clippedDist = GEN_min(angularConservativeRadius,dist);
+ float clippedDist = dist;
+
+ float projectedLinearVelocity = (linVelB-linVelA).dot(n);
+
+ dLambda = dist / (projectedLinearVelocity+ maxAngularProjectedVelocity);
+
+ lambda = lambda + dLambda;
+
+ //todo: next check with relative epsilon
+ if (lambda <= lastLambda)
+ break;
+ lastLambda = lambda;
+
+ if (lambda > 1.f)
+ return false;
+
+ //interpolate to next lambda
+ SimdTransform interpolatedTransA,interpolatedTransB,relativeTrans;
+
+ SimdTransformUtil::IntegrateTransform(fromA,linVelA,angVelA,lambda,interpolatedTransA);
+ SimdTransformUtil::IntegrateTransform(fromB,linVelB,angVelB,lambda,interpolatedTransB);
+ relativeTrans = interpolatedTransB.inverseTimes(interpolatedTransA);
+
+ result.DebugDraw( lambda );
+
+ PointCollector pointCollector;
+ GjkPairDetector gjk(m_convexA,m_convexB,m_simplexSolver,m_penetrationDepthSolver);
+ GjkPairDetector::ClosestPointInput input;
+ input.m_transformA = interpolatedTransA;
+ input.m_transformB = interpolatedTransB;
+ gjk.GetClosestPoints(input,pointCollector);
+ if (pointCollector.m_hasResult)
+ {
+ if (pointCollector.m_distance < 0.f)
+ {
+ //degenerate ?!
+ result.m_fraction = lastLambda;
+ result.m_normal = n;
+ return true;
+ }
+ c = pointCollector.m_pointInWorld;
+
+ dist = pointCollector.m_distance;
+ } else
+ {
+ //??
+ return false;
+ }
+
+ }
+
+ result.m_fraction = lambda;
+ result.m_normal = n;
+ return true;
+ }
+
+ return false;
+
+/*
+//todo:
+ //if movement away from normal, discard result
+ SimdVector3 move = transBLocalTo.getOrigin() - transBLocalFrom.getOrigin();
+ if (result.m_fraction < 1.f)
+ {
+ if (move.dot(result.m_normal) <= 0.f)
+ {
+ }
+ }
+*/
+
+}
+