public override float AddSingleResult(LocalRayResult rayResult,bool normalInWorldSpace) { if (rayResult.m_collisionObject == m_me) return 1.0f; return base.AddSingleResult (rayResult, normalInWorldSpace); }
public override float ReportHit(ref Vector3 hitNormalLocal, float hitFraction, int partId, int triangleIndex) { LocalShapeInfo shapeInfo = new LocalShapeInfo(); shapeInfo.m_shapePart = partId; shapeInfo.m_triangleIndex = triangleIndex; Vector3 hitNormalWorld = Vector3.TransformNormal(hitNormalLocal,m_colObjWorldTransform); LocalRayResult rayResult = new LocalRayResult (m_collisionObject, shapeInfo, ref hitNormalWorld, hitFraction); bool normalInWorldSpace = true; return m_resultCallback.AddSingleResult(rayResult, normalInWorldSpace); }
public override float AddSingleResult(LocalRayResult rayResult,bool normalInWorldSpace) { //caller already does the filter on the m_closestHitFraction //btAssert(rayResult.m_hitFraction <= m_closestHitFraction); m_closestHitFraction = rayResult.m_hitFraction; m_collisionObject = rayResult.m_collisionObject; if (normalInWorldSpace) { m_hitNormalWorld = rayResult.m_hitNormalLocal; } else { ///need to transform normal into worldspace m_hitNormalWorld = Vector3.TransformNormal(rayResult.m_hitNormalLocal,m_collisionObject.GetWorldTransform()); } m_hitPointWorld = MathUtil.Interpolate3(ref m_rayFromWorld,ref m_rayToWorld,rayResult.m_hitFraction); return rayResult.m_hitFraction; }
public abstract float AddSingleResult(LocalRayResult rayResult,bool normalInWorldSpace);
public virtual void RayTestSingle(ref Matrix rayFromTrans,ref Matrix rayToTrans, CollisionObject collisionObject, CollisionShape collisionShape, ref Matrix colObjWorldTransform, RayResultCallback resultCallback) { SphereShape pointShape = new SphereShape(0.0f); pointShape.Margin = 0f; ConvexShape castShape = pointShape; if (collisionShape.IsConvex()) { // BT_PROFILE("rayTestConvex"); CastResult castResult = new CastResult(); castResult.m_fraction = resultCallback.m_closestHitFraction; ConvexShape convexShape = (ConvexShape)collisionShape; VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver(); //#define USE_SUBSIMPLEX_CONVEX_CAST 1 //#ifdef USE_SUBSIMPLEX_CONVEX_CAST // FIXME - MAN - convexcat here seems to make big difference to forklift. SubSimplexConvexCast convexCaster = new SubSimplexConvexCast(castShape, convexShape, simplexSolver); //GjkConvexCast convexCaster = new GjkConvexCast(castShape, convexShape, simplexSolver); //#else //btGjkConvexCast convexCaster(castShape,convexShape,&simplexSolver); //btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0); //#endif //#USE_SUBSIMPLEX_CONVEX_CAST if (convexCaster.CalcTimeOfImpact(ref rayFromTrans,ref rayToTrans,ref colObjWorldTransform,ref colObjWorldTransform,castResult)) { //add hit if (castResult.m_normal.LengthSquared() > 0.0001f) { if (castResult.m_fraction < resultCallback.m_closestHitFraction) { //if (resultCallback.m_closestHitFraction != 1f) //{ // int ibreak = 0; // convexCaster.calcTimeOfImpact(ref rayFromTrans, ref rayToTrans, ref colObjWorldTransform, ref colObjWorldTransform, castResult); //} //#ifdef USE_SUBSIMPLEX_CONVEX_CAST //rotate normal into worldspace castResult.m_normal = Vector3.TransformNormal(castResult.m_normal,rayFromTrans); //#endif //USE_SUBSIMPLEX_CONVEX_CAST castResult.m_normal.Normalize(); LocalRayResult localRayResult = new LocalRayResult( collisionObject, null, ref castResult.m_normal, castResult.m_fraction ); bool normalInWorldSpace = true; resultCallback.AddSingleResult(localRayResult, normalInWorldSpace); } } } castResult.Cleanup(); } else { if (collisionShape.IsConcave()) { // BT_PROFILE("rayTestConcave"); if (collisionShape.ShapeType==BroadphaseNativeTypes.TRIANGLE_MESH_SHAPE_PROXYTYPE && collisionShape is BvhTriangleMeshShape) { ///optimized version for btBvhTriangleMeshShape BvhTriangleMeshShape triangleMesh = (BvhTriangleMeshShape)collisionShape; Matrix worldTocollisionObject = Matrix.Invert(colObjWorldTransform); Vector3 rayFromLocal = Vector3.Transform(rayFromTrans.Translation,worldTocollisionObject); Vector3 rayToLocal = Vector3.Transform(rayToTrans.Translation,worldTocollisionObject); Matrix transform = Matrix.Identity; BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(ref rayFromLocal,ref rayToLocal, resultCallback,collisionObject,triangleMesh,ref transform); rcb.m_hitFraction = resultCallback.m_closestHitFraction; triangleMesh.PerformRaycast(rcb,ref rayFromLocal,ref rayToLocal); rcb.Cleanup(); } else { //generic (slower) case ConcaveShape concaveShape = (ConcaveShape)collisionShape; Matrix worldTocollisionObject = Matrix.Invert(colObjWorldTransform); Vector3 rayFromLocal = Vector3.Transform(rayFromTrans.Translation,worldTocollisionObject); Vector3 rayToLocal = Vector3.Transform(rayToTrans.Translation,worldTocollisionObject); //ConvexCast::CastResult Matrix transform = Matrix.Identity; BridgeTriangleConcaveRaycastCallback rcb = new BridgeTriangleConcaveRaycastCallback(ref rayFromLocal, ref rayToLocal, resultCallback, collisionObject, concaveShape,ref transform); rcb.m_hitFraction = resultCallback.m_closestHitFraction; Vector3 rayAabbMinLocal = rayFromLocal; MathUtil.VectorMin(ref rayToLocal,ref rayAabbMinLocal); Vector3 rayAabbMaxLocal = rayFromLocal; MathUtil.VectorMax(ref rayToLocal,ref rayAabbMaxLocal); concaveShape.ProcessAllTriangles(rcb,ref rayAabbMinLocal,ref rayAabbMaxLocal); rcb.Cleanup(); } } else { // BT_PROFILE("rayTestCompound"); ///@todo: use AABB tree or other BVH acceleration structure, see btDbvt if (collisionShape.IsCompound()) { CompoundShape compoundShape = (CompoundShape)(collisionShape); int i=0; for (i=0;i<compoundShape.GetNumChildShapes();i++) { Matrix childTrans = compoundShape.GetChildTransform(i); CollisionShape childCollisionShape = compoundShape.GetChildShape(i); Matrix childWorldTrans = MathUtil.BulletMatrixMultiply(colObjWorldTransform,childTrans) ; // replace collision shape so that callback can determine the triangle CollisionShape saveCollisionShape = collisionObject.GetCollisionShape(); collisionObject.InternalSetTemporaryCollisionShape((CollisionShape)childCollisionShape); LocalInfoAdder2 my_cb = new LocalInfoAdder2(i, resultCallback); my_cb.m_closestHitFraction = resultCallback.m_closestHitFraction; RayTestSingle(ref rayFromTrans,ref rayToTrans, collisionObject, childCollisionShape, ref childWorldTrans, my_cb); // restore collisionObject.InternalSetTemporaryCollisionShape(saveCollisionShape); my_cb.cleanup(); } } } } }