示例#1
0
		// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
		// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
		public void RayTest(Vector3 rayFromWorld, Vector3 rayToWorld, RayResultCallback resultCallback)
		{
			Matrix rayFromTrans, rayToTrans;

			rayFromTrans = Matrix.Identity;
			rayFromTrans.Translation = rayFromWorld;

			rayToTrans = Matrix.Identity;
			rayToTrans.Translation = rayToWorld;

			// brute force go over all objects. Once there is a broadphase, use that, or
			// add a raycast against aabb first.

			foreach (CollisionObject collisionObject in _collisionObjects)
			{
				//RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
				Vector3 collisionObjectAabbMin, collisionObjectAabbMax;
				collisionObject.CollisionShape.GetAabb(collisionObject.WorldTransform, out collisionObjectAabbMin, out collisionObjectAabbMax);

				float hitLambda = 1f; //could use resultCallback.m_closestHitFraction, but needs testing
				Vector3 hitNormal = new Vector3();
				
				//if (MathHelper.TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, collisionObjectAabbMin, collisionObjectAabbMax))
				if (MathHelper.RayAabb(rayFromWorld, rayToWorld, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal))
				{
					RayTestSingle(rayFromTrans, rayToTrans,
						collisionObject, collisionObject.CollisionShape,
							 collisionObject.WorldTransform, resultCallback);

				}
			}
		}
示例#2
0
        // rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
        // This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
        public void RayTest(Vector3 rayFromWorld, Vector3 rayToWorld, RayResultCallback resultCallback)
        {
            Matrix rayFromTrans, rayToTrans;

            rayFromTrans             = Matrix.Identity;
            rayFromTrans.Translation = rayFromWorld;

            rayToTrans             = Matrix.Identity;
            rayToTrans.Translation = rayToWorld;

            // brute force go over all objects. Once there is a broadphase, use that, or
            // add a raycast against aabb first.

            foreach (CollisionObject collisionObject in _collisionObjects)
            {
                //RigidcollisionObject* collisionObject = ctrl->GetRigidcollisionObject();
                Vector3 collisionObjectAabbMin, collisionObjectAabbMax;
                collisionObject.CollisionShape.GetAabb(collisionObject.WorldTransform, out collisionObjectAabbMin, out collisionObjectAabbMax);

                float   hitLambda = 1f;               //could use resultCallback.m_closestHitFraction, but needs testing
                Vector3 hitNormal = new Vector3();

                //if (MathHelper.TestAabbAgainstAabb2(rayAabbMin, rayAabbMax, collisionObjectAabbMin, collisionObjectAabbMax))
                if (MathHelper.RayAabb(rayFromWorld, rayToWorld, collisionObjectAabbMin, collisionObjectAabbMax, hitLambda, hitNormal))
                {
                    RayTestSingle(rayFromTrans, rayToTrans,
                                  collisionObject, collisionObject.CollisionShape,
                                  collisionObject.WorldTransform, resultCallback);
                }
            }
        }
示例#3
0
		// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
		// In a future implementation, we consider moving the ray test as a virtual method in CollisionShape.
		// This allows more customization.
		public static void RayTestSingle(Matrix rayFromTrans, Matrix rayToTrans,
						  CollisionObject collisionObject,
						  CollisionShape collisionShape,
						  Matrix colObjWorldTransform,
						  RayResultCallback resultCallback)
		{
			SphereShape pointShape=new SphereShape(0.0f);

			if (collisionShape.IsConvex)
			{
				CastResult castResult = new CastResult();
				castResult.Fraction = 1f;//??

				ConvexShape convexShape = collisionShape as ConvexShape;
				VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
				SubsimplexConvexCast convexCaster = new SubsimplexConvexCast(pointShape, convexShape, simplexSolver);
				//GjkConvexCast	convexCaster(&pointShape,convexShape,&simplexSolver);
				//ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);

				if (convexCaster.CalcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult))
				{
					//add hit
					if (castResult.Normal.LengthSquared() > 0.0001f)
					{
						castResult.Normal.Normalize();
						if (castResult.Fraction < resultCallback.ClosestHitFraction)
						{

							CollisionWorld.LocalRayResult localRayResult = new LocalRayResult
								(
									collisionObject,
									new LocalShapeInfo(),
									castResult.Normal,
									castResult.Fraction
								);

							resultCallback.AddSingleResult(localRayResult);
						}
					}
				}
				else
				{
					if (collisionShape.IsConcave)
					{

						TriangleMeshShape triangleMesh = collisionShape as TriangleMeshShape;

						Matrix worldTocollisionObject = MathHelper.InvertMatrix(colObjWorldTransform);

						Vector3 rayFromLocal = Vector3.TransformNormal(rayFromTrans.Translation, worldTocollisionObject);
						Vector3 rayToLocal = Vector3.TransformNormal(rayToTrans.Translation, worldTocollisionObject);

						BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(rayFromLocal, rayToLocal, resultCallback, collisionObject, triangleMesh);
						rcb.HitFraction = resultCallback.ClosestHitFraction;

						Vector3 rayAabbMinLocal = rayFromLocal;
						MathHelper.SetMin(ref rayAabbMinLocal, rayToLocal);
						Vector3 rayAabbMaxLocal = rayFromLocal;
						MathHelper.SetMax(ref rayAabbMaxLocal, rayToLocal);

						triangleMesh.ProcessAllTriangles(rcb, rayAabbMinLocal, rayAabbMaxLocal);
					}
					else
					{
						//todo: use AABB tree or other BVH acceleration structure!
						if (collisionShape.IsCompound)
						{
							CompoundShape compoundShape = collisionShape as CompoundShape;
							for (int i = 0; i < compoundShape.ChildShapeCount; i++)
							{
								Matrix childTrans = compoundShape.GetChildTransform(i);
								CollisionShape childCollisionShape = compoundShape.GetChildShape(i);
								Matrix childWorldTrans = colObjWorldTransform * childTrans;
								RayTestSingle(rayFromTrans, rayToTrans,
									collisionObject,
									childCollisionShape,
									childWorldTrans,
									resultCallback);
							}
						}
					}
				}
			}
		}
示例#4
0
 public unsafe static void RayTest(this CollisionWorld obj, ref OpenTK.Vector3 rayFromWorld, ref OpenTK.Vector3 rayToWorld, RayResultCallback resultCallback)
 {
     fixed(OpenTK.Vector3 *rayFromWorldPtr = &rayFromWorld)
     {
         fixed(OpenTK.Vector3 *rayToWorldPtr = &rayToWorld)
         {
             obj.RayTest(ref *(BulletSharp.Math.Vector3 *)rayFromWorldPtr, ref *(BulletSharp.Math.Vector3 *)rayToWorldPtr, resultCallback);
         }
     }
 }
示例#5
0
        //!@}


        //! virtual method for ray collision
        public virtual void RayTest(ref IndexedVector3 rayFrom, ref IndexedVector3 rayTo, RayResultCallback resultCallback)
        {
        }
示例#6
0
		public LocalInfoAdder2 (int i, RayResultCallback user)
		{ 
			m_i = i;
			m_userCallback = user;
		}
示例#7
0
			internal void Initialize( ref btVector3 rayFromWorld, ref btVector3 rayToWorld, btCollisionWorld world, RayResultCallback resultCallback )
			{
				m_rayFromWorld = ( rayFromWorld );
				m_rayToWorld = ( rayToWorld );
				m_world = ( world );
				m_resultCallback = ( resultCallback );
				m_rayFromTrans.setIdentity();
				m_rayFromTrans.setOrigin( ref m_rayFromWorld );
				m_rayToTrans.setIdentity();
				m_rayToTrans.setOrigin( ref m_rayToWorld );

				btVector3 rayDir = ( rayToWorld - rayFromWorld );

				rayDir.normalize();
				///what about division by zero? -. just set rayDirection[i] to INF/BT_LARGE_FLOAT
				m_rayDirectionInverse[0] = rayDir[0] == btScalar.BT_ZERO ? (double)( btScalar.BT_LARGE_FLOAT ) : (double)( 1.0 ) / rayDir[0];
				m_rayDirectionInverse[1] = rayDir[1] == btScalar.BT_ZERO ? (double)( btScalar.BT_LARGE_FLOAT ) : (double)( 1.0 ) / rayDir[1];
				m_rayDirectionInverse[2] = rayDir[2] == btScalar.BT_ZERO ? (double)( btScalar.BT_LARGE_FLOAT ) : (double)( 1.0 ) / rayDir[2];
				m_signs[0] = m_rayDirectionInverse[0] < 0.0 ? 1U : 0;
				m_signs[1] = m_rayDirectionInverse[1] < 0.0 ? 1U : 0;
				m_signs[2] = m_rayDirectionInverse[2] < 0.0 ? 1U : 0;
				m_lambda_max = rayDir.dot( m_rayToWorld - m_rayFromWorld );
			}
示例#8
0
 public void RayTestRef(ref Vector3 rayFromWorld, ref Vector3 rayToWorld, RayResultCallback resultCallback)
 {
     btGhostObject_rayTest(_native, ref rayFromWorld, ref rayToWorld, resultCallback._native);
 }
示例#9
0
		/// rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
		/// In a future implementation, we consider moving the ray test as a virtual method in btCollisionShape.
		/// This allows more customization.
		public static void rayTestSingle( ref btTransform rayFromTrans, ref btTransform rayToTrans,
											btCollisionObject collisionObject,
											btCollisionShape collisionShape,
											ref btTransform colObjWorldTransform,
											RayResultCallback resultCallback )
		{
			//btCollisionObjectWrapper colObWrap = BulletGlobals.CollisionObjectWrapperPool.Get();
			//colObWrap.Initialize( null, collisionShape, collisionObject, ref colObjWorldTransform, -1, -1 );
			rayTestSingleInternal( ref rayFromTrans, ref rayToTrans, collisionShape, collisionObject
				, ref colObjWorldTransform, resultCallback );
			//BulletGlobals.CollisionObjectWrapperPool.Free( colObWrap );
		}
示例#10
0
		public static void rayTestSingleInternal( ref btTransform rayFromTrans, ref btTransform rayToTrans,
												btCollisionShape collisionShape,
												btCollisionObject collisionObject,
												ref btTransform useTransform,
												RayResultCallback resultCallback )
		{
			btSphereShape pointShape = BulletGlobals.SphereShapePool.Get();
			pointShape.Initialize( btScalar.BT_ZERO );
			pointShape.setMargin( 0f );
			btConvexShape castShape = pointShape;
			//btCollisionShape collisionShape = collisionObjectWrap.getCollisionShape();
			btTransform colObjWorldTransform = useTransform;// collisionObjectWrap.m_worldTransform;

			if( collisionShape.isConvex() )
			{
				//		CProfileSample sample = new CProfileSample("rayTestConvex");
				btConvexCast.CastResult castResult = new btConvexCast.CastResult();

				castResult.m_fraction = resultCallback.m_closestHitFraction;

				btConvexShape convexShape = (btConvexShape)collisionShape;
				btVoronoiSimplexSolver simplexSolver = BulletGlobals.VoronoiSimplexSolverPool.Get();
				//new btVoronoiSimplexSolver();
				btSubsimplexConvexCast subSimplexConvexCaster = BulletGlobals.SubSimplexConvexCastPool.Get();
				subSimplexConvexCaster.Initialize( castShape, convexShape, simplexSolver );

				btGjkConvexCast gjkConvexCaster = BulletGlobals.GjkConvexCastPool.Get();
				gjkConvexCaster.Initialize( castShape, convexShape, simplexSolver );
				BulletGlobals.SubSimplexConvexCastPool.Free( subSimplexConvexCaster );
				BulletGlobals.VoronoiSimplexSolverPool.Free( simplexSolver );

				//btContinuousConvexCollision convexCaster(castShape,convexShape,&simplexSolver,0);

				btConvexCast convexCasterPtr = null;
				//use kF_UseSubSimplexConvexCastRaytest by default
				if( ( resultCallback.m_flags & (uint)btTriangleRaycastCallback.EFlags.kF_UseGjkConvexCastRaytest ) != 0 )
					convexCasterPtr = gjkConvexCaster;
				else
					convexCasterPtr = subSimplexConvexCaster;

				btConvexCast convexCaster = convexCasterPtr;

				if( convexCaster.calcTimeOfImpact( ref rayFromTrans, ref rayToTrans
					, ref useTransform/*collisionObjectWrap.m_worldTransform*/
					, ref useTransform/*collisionObjectWrap.m_worldTransform*/
					, castResult ) )
				{
					//add hit
					if( castResult.m_normal.length2() > (double)( 0.0001 ) )
					{
						if( castResult.m_fraction < resultCallback.m_closestHitFraction )
						{
							//todo: figure out what this is about. When is rayFromTest.getBasis() not identity?
#if USE_SUBSIMPLEX_CONVEX_CAST
							//rotate normal into worldspace
							castResult.m_normal = rayFromTrans.getBasis()  castResult.m_normal;
#endif //USE_SUBSIMPLEX_CONVEX_CAST

							castResult.m_normal.normalize();
							LocalRayResult localRayResult = new LocalRayResult
								(
								collisionObject,
								null,
								castResult.m_normal,
								castResult.m_fraction
								);

							bool normalInWorldSpace = true;
							resultCallback.addSingleResult( localRayResult, normalInWorldSpace );

						}
					}
				}
				BulletGlobals.GjkConvexCastPool.Free( gjkConvexCaster );
			}
			else
			{
				if( collisionShape.isConcave() )
				{
					btTransform worldTocollisionObject; colObjWorldTransform.inverse( out worldTocollisionObject );
					btVector3 tmp;
					rayFromTrans.getOrigin( out tmp );
					btVector3 rayFromLocal; worldTocollisionObject.Apply( ref tmp, out rayFromLocal );
					rayToTrans.getOrigin( out tmp );
					btVector3 rayToLocal; worldTocollisionObject.Apply( ref tmp, out rayToLocal );

					//			CProfileSample sample = new CProfileSample("rayTestConcave");
#if SUPPORT_TRIANGLE_MESH
					if( collisionShape.getShapeType() == BroadphaseNativeTypes.TRIANGLE_MESH_SHAPE_PROXYTYPE )
					{
						///optimized version for btBvhTriangleMeshShape
						btBvhTriangleMeshShape triangleMesh = (btBvhTriangleMeshShape)collisionShape;

						BridgeTriangleRaycastCallback rcb( rayFromLocal, rayToLocal,&resultCallback, collisionObjectWrap.getCollisionObject(), triangleMesh, colObjWorldTransform);
						rcb.m_hitFraction = resultCallback.m_closestHitFraction;
						triangleMesh.performRaycast( &rcb, rayFromLocal, rayToLocal );
					}
					else
#endif
					{
						//generic (slower) case
						btConcaveShape concaveShape = (btConcaveShape)collisionShape;

						//ConvexCast::CastResult


						BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback( ref rayFromLocal, ref rayToLocal, resultCallback
							, collisionObject, concaveShape, ref colObjWorldTransform );
						rcb.m_hitFraction = resultCallback.m_closestHitFraction;

						btVector3 rayAabbMinLocal = rayFromLocal;
						rayAabbMinLocal.setMin( ref rayToLocal );
						btVector3 rayAabbMaxLocal = rayFromLocal;
						rayAabbMaxLocal.setMax( ref rayToLocal );

						concaveShape.processAllTriangles( rcb, ref rayAabbMinLocal, ref rayAabbMaxLocal );
					}
				}
				else
				{
					//			CProfileSample sample = new CProfileSample("rayTestCompound");
					if( collisionShape.isCompound() )
					{

						btCompoundShape compoundShape = (btCompoundShape)( collisionShape );
						btDbvt dbvt = compoundShape.getDynamicAabbTree();


						RayTester rayCB = new RayTester(
									collisionObject,
									compoundShape,
									ref colObjWorldTransform,
									ref rayFromTrans,
									ref rayToTrans,
									resultCallback );
#if !DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
						if( dbvt != null )
						{
							btTransform tmp;
							colObjWorldTransform.inverseTimes( ref rayFromTrans, out tmp );
							btVector3 localRayFrom; tmp.getOrigin( out localRayFrom );
							colObjWorldTransform.inverseTimes( ref rayToTrans, out tmp );
							btVector3 localRayTo; tmp.getOrigin( out localRayTo );
							btDbvt.rayTest( dbvt.m_root, ref localRayFrom, ref localRayTo, rayCB );
						}
						else
#endif //DISABLE_DBVT_COMPOUNDSHAPE_RAYCAST_ACCELERATION
						{
							for( int i = 0, n = compoundShape.getNumChildShapes(); i < n; ++i )
							{
								rayCB.Process( i );
							}
						}
					}
				}
			}
			BulletGlobals.SphereShapePool.Free( pointShape );
		}
示例#11
0
			internal RayTester( btCollisionObject collisionObject,
					btCompoundShape compoundShape,
					ref btTransform colObjWorldTransform,
					ref btTransform rayFromTrans,
					ref btTransform rayToTrans,
					RayResultCallback resultCallback )
			{
				m_collisionObject = ( collisionObject );
				m_compoundShape = ( compoundShape );
				m_colObjWorldTransform = ( colObjWorldTransform );
				m_rayFromTrans = ( rayFromTrans );
				m_rayToTrans = ( rayToTrans );
				m_resultCallback = ( resultCallback );

			}
示例#12
0
			internal LocalInfoAdder2( int i, RayResultCallback user )
			{
				m_userCallback = ( user ); m_i = ( i );
				m_closestHitFraction = m_userCallback.m_closestHitFraction;
				m_flags = m_userCallback.m_flags;
			}
示例#13
0
 internal static global::System.Runtime.InteropServices.HandleRef getCPtr(RayResultCallback obj)
 {
     return((obj == null) ? new global::System.Runtime.InteropServices.HandleRef(null, global::System.IntPtr.Zero) : obj.swigCPtr);
 }
示例#14
0
 public void RayTest(ref IndexedVector3 rayFromWorld, ref IndexedVector3 rayToWorld, RayResultCallback resultCallback)
 {
     int ibreak = 0;
 }
示例#15
0
		/// rayTest performs a raycast on all objects in the btCollisionWorld, and calls the resultCallback
		/// This allows for several queries: first hit, all hits, any hit, dependent on the value returned by the callback.
		void rayTest( btVector3 rayFromWorld, btVector3 rayToWorld, RayResultCallback resultCallback )
		{
			//CProfileSample sample = new CProfileSample("rayTest");
			/// use the broadphase to accelerate the search for objects, based on their aabb
			/// and for each object with ray-aabb overlap, perform an exact ray test
			btSingleRayCallback rayCB = BulletGlobals.SingleRayCallbackPool.Get();
			rayCB.Initialize( ref rayFromWorld, ref rayToWorld, this, resultCallback );

#if !USE_BRUTEFORCE_RAYBROADPHASE
			m_broadphasePairCache.rayTest( ref rayFromWorld, ref rayToWorld, rayCB );
#else
	for( int i = 0; i < this.getNumCollisionObjects(); i++ )
	{
		rayCB.process( m_collisionObjects[i].getBroadphaseHandle() );
	}
#endif //USE_BRUTEFORCE_RAYBROADPHASE
			BulletGlobals.SingleRayCallbackPool.Free( rayCB );
		}
示例#16
0
 public void RayTest(Vector3 rayFrom, Vector3 rayTo, RayResultCallback resultCallback)
 {
     btGImpactShapeInterface_rayTest(_native, ref rayFrom, ref rayTo, resultCallback._native);
 }
示例#17
0
			internal BridgeTriangleRaycastCallback( ref btVector3 from, ref btVector3 to
				, RayResultCallback resultCallback
				, btCollisionObject collisionObject, btConcaveShape triangleMesh
				, ref btTransform colObjWorldTransform )
						: base( ref from, ref to, (btTriangleRaycastCallback.EFlags)resultCallback.m_flags )
			{
				m_resultCallback = ( resultCallback );
				m_collisionObject = ( collisionObject );
				m_triangleMesh = ( triangleMesh );
				m_colObjWorldTransform = ( colObjWorldTransform );
			}
示例#18
0
 public void RayTest(Vector3 rayFromWorld, Vector3 rayToWorld, RayResultCallback resultCallback)
 {
     btGhostObject_rayTest(Native, ref rayFromWorld, ref rayToWorld, resultCallback.Native);
 }
示例#19
0
        // rayTestSingle performs a raycast call and calls the resultCallback. It is used internally by rayTest.
        // In a future implementation, we consider moving the ray test as a virtual method in CollisionShape.
        // This allows more customization.
        public static void RayTestSingle(Matrix rayFromTrans, Matrix rayToTrans,
                                         CollisionObject collisionObject,
                                         CollisionShape collisionShape,
                                         Matrix colObjWorldTransform,
                                         RayResultCallback resultCallback)
        {
            SphereShape pointShape = new SphereShape(0.0f);

            if (collisionShape.IsConvex)
            {
                CastResult castResult = new CastResult();
                castResult.Fraction = 1f;                //??

                ConvexShape          convexShape   = collisionShape as ConvexShape;
                VoronoiSimplexSolver simplexSolver = new VoronoiSimplexSolver();
                SubsimplexConvexCast convexCaster  = new SubsimplexConvexCast(pointShape, convexShape, simplexSolver);
                //GjkConvexCast	convexCaster(&pointShape,convexShape,&simplexSolver);
                //ContinuousConvexCollision convexCaster(&pointShape,convexShape,&simplexSolver,0);

                if (convexCaster.CalcTimeOfImpact(rayFromTrans, rayToTrans, colObjWorldTransform, colObjWorldTransform, castResult))
                {
                    //add hit
                    if (castResult.Normal.LengthSquared() > 0.0001f)
                    {
                        castResult.Normal.Normalize();
                        if (castResult.Fraction < resultCallback.ClosestHitFraction)
                        {
                            CollisionWorld.LocalRayResult localRayResult = new LocalRayResult
                                                                           (
                                collisionObject,
                                new LocalShapeInfo(),
                                castResult.Normal,
                                castResult.Fraction
                                                                           );

                            resultCallback.AddSingleResult(localRayResult);
                        }
                    }
                }
                else
                {
                    if (collisionShape.IsConcave)
                    {
                        TriangleMeshShape triangleMesh = collisionShape as TriangleMeshShape;

                        Matrix worldTocollisionObject = MathHelper.InvertMatrix(colObjWorldTransform);

                        Vector3 rayFromLocal = Vector3.TransformNormal(rayFromTrans.Translation, worldTocollisionObject);
                        Vector3 rayToLocal   = Vector3.TransformNormal(rayToTrans.Translation, worldTocollisionObject);

                        BridgeTriangleRaycastCallback rcb = new BridgeTriangleRaycastCallback(rayFromLocal, rayToLocal, resultCallback, collisionObject, triangleMesh);
                        rcb.HitFraction = resultCallback.ClosestHitFraction;

                        Vector3 rayAabbMinLocal = rayFromLocal;
                        MathHelper.SetMin(ref rayAabbMinLocal, rayToLocal);
                        Vector3 rayAabbMaxLocal = rayFromLocal;
                        MathHelper.SetMax(ref rayAabbMaxLocal, rayToLocal);

                        triangleMesh.ProcessAllTriangles(rcb, rayAabbMinLocal, rayAabbMaxLocal);
                    }
                    else
                    {
                        //todo: use AABB tree or other BVH acceleration structure!
                        if (collisionShape.IsCompound)
                        {
                            CompoundShape compoundShape = collisionShape as CompoundShape;
                            for (int i = 0; i < compoundShape.ChildShapeCount; i++)
                            {
                                Matrix         childTrans          = compoundShape.GetChildTransform(i);
                                CollisionShape childCollisionShape = compoundShape.GetChildShape(i);
                                Matrix         childWorldTrans     = colObjWorldTransform * childTrans;
                                RayTestSingle(rayFromTrans, rayToTrans,
                                              collisionObject,
                                              childCollisionShape,
                                              childWorldTrans,
                                              resultCallback);
                            }
                        }
                    }
                }
            }
        }