private bool FindRealPoint(ref Matrix transform)
        {
            /* Look for the real height of the step.
             * Move a bit along the ground-collision direction, horizontally,
             * and vertically use 0 and the max step height. */
            Vector3 minTargetPoint = new Vector3(_stepLocal.X, 0, _stepLocal.Z);

            minTargetPoint *= 1 + _stepSearchOvershoot / minTargetPoint.Length;
            // As above: we are using capsule lowest point, rather than ground
            minTargetPoint.Y -= _originHeight;

            Vector3 maxTargetPoint = minTargetPoint;

            maxTargetPoint.Y += _controller.MaxStepHeight + _stepSearchOvershoot;
            minTargetPoint    = Vector3.TransformCoordinate(minTargetPoint, transform);
            maxTargetPoint    = Vector3.TransformCoordinate(maxTargetPoint, transform);

            _closestRay.Setup(ref maxTargetPoint, ref minTargetPoint);
            _world.RayTest(maxTargetPoint, minTargetPoint, _closestRay);
            if (!_closestRay.HasHit)
            {
                return(false);
            }

            if ((1 - _closestRay.ClosestHitFraction) < 0.0001f)
            {
                // Almost at the minimum point, can walk normally
                return(false);
            }

            RealPosWorld = _closestRay.HitPointWorld;
            return(true);
        }
예제 #2
0
    public static CollisionObject ScreenPointToRay(Camera cam, Vector3 inputScreenCoords, CollisionFilterGroups rayFilterGroup, CollisionFilterGroups rayFilterMask)
    {
        /* Returns the first CollisionObject the ray hits.
         * Requires as Input:
         * - Camera cam, UnityCamera from which the ray should be cast, e.g. Camera.main
         * - Vector3 inputScreenCoords, the screenpoint through which the ray should be cast. E.g. mousepointer Input.mousePosition
         * - CollisionFilterGroups rayFilterGroup, of which FilterGroup the ray belongs to
         * - CollisionFilterGroups rayFilterMask, which FilterMask the ray has (to map to other Objects FilterGroups
         * Be aware the Bulletphysics probably needs Group/Mask to match in both ways, i.e. Ray needs to collide with otherObj, as otherObj needs to collide with Ray.
         * To get all Ray hits, see commented out Callback AllHitsRayResultCallback below.
         * First version. Adapt to your needs. Refer to Bulletphysics.org for info. Make Pull Request to Phong BulletUnity with improvements.*/

        CollisionWorld collisionWorld = BPhysicsWorld.Get().world;

        BulletSharp.Math.Vector3 rayFrom = cam.transform.position.ToBullet();
        BulletSharp.Math.Vector3 rayTo   = cam.ScreenToWorldPoint(new Vector3(inputScreenCoords.x, inputScreenCoords.y, cam.farClipPlane)).ToBullet();

        BulletSharp.ClosestRayResultCallback rayCallBack = new BulletSharp.ClosestRayResultCallback(ref rayFrom, ref rayTo);
        rayCallBack.CollisionFilterGroup = (short)rayFilterGroup;
        rayCallBack.CollisionFilterMask  = (short)rayFilterMask;
        //BulletSharp.AllHitsRayResultCallback rayCallBack = new BulletSharp.AllHitsRayResultCallback(rayFrom, rayTo);

        //Debug.Log("Casting ray from: " + rayFrom + " to: " + rayTo);
        collisionWorld.RayTest(rayFrom, rayTo, rayCallBack);

        closestRayResultReturnObj = null;
        if (rayCallBack.HasHit)
        {
            //Debug.Log("rayCallBack " + rayCallBack.GetType() + " had a hit: " + rayCallBack.CollisionObject.UserObject + " / of type: " + rayCallBack.CollisionObject.UserObject.GetType());
            closestRayResultReturnObj = rayCallBack.CollisionObject;
        }

        rayCallBack.Dispose();
        return(closestRayResultReturnObj);
    }
예제 #3
0
        public void cast(CollisionWorld cw)
        {
#if USE_BT_CLOCK
            frame_timer.reset();
#endif //USE_BT_CLOCK

#if BATCH_RAYCASTER
            if (gBatchRaycaster == null)
            {
                return;
            }

            gBatchRaycaster.clearRays();
            for (int i = 0; i < NUMRAYS_IN_BAR; i++)
            {
                gBatchRaycaster.addRay(source[i], dest[i]);
            }
            gBatchRaycaster.performBatchRaycast();
            for (int i = 0; i < gBatchRaycaster.getNumRays(); i++)
            {
                const SpuRaycastTaskWorkUnitOut& outResult = (*gBatchRaycaster)[i];
                hit[i].setInterpolate3(source[i], dest[i], outResult.hitFraction);
                normal[i] = outResult.hitNormal;
                normal[i] = normal[i].Normalize();
            }
#else
            for (int i = 0; i < NUMRAYS_IN_BAR; i++)
            {
                ClosestRayResultCallback cb = new ClosestRayResultCallback(source[i], dest[i]);

                cw.RayTest(ref source[i], ref dest[i], cb);
                if (cb.HasHit())
                {
                    hit[i]    = cb.m_hitPointWorld;
                    normal[i] = cb.m_hitNormalWorld;
                    normal[i] = IndexedVector3.Normalize(normal[i]);
                }
                else
                {
                    hit[i]    = dest[i];
                    normal[i] = new IndexedVector3(1.0f, 0.0f, 0.0f);
                }
            }
#if USE_BT_CLOCK
            ms += frame_timer.getTimeMilliseconds();
#endif //USE_BT_CLOCK
            frame_counter++;
            if (frame_counter > 50)
            {
                min_ms  = ms < min_ms ? ms : min_ms;
                max_ms  = ms > max_ms ? ms : max_ms;
                sum_ms += ms;
                sum_ms_samples++;
                float mean_ms = (float)sum_ms / (float)sum_ms_samples;
                //printf("%d rays in %d ms %d %d %f\n", NUMRAYS_IN_BAR * frame_counter, ms, min_ms, max_ms, mean_ms);
                ms            = 0;
                frame_counter = 0;
            }
#endif
        }
예제 #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
        public void Cast(CollisionWorld cw)
        {
#if BATCH_RAYCASTER
            if (!gBatchRaycaster)
            {
                return;
            }

            gBatchRaycaster->clearRays();
            for (int i = 0; i < NUMRAYS_IN_BAR; i++)
            {
                gBatchRaycaster->addRay(source[i], dest[i]);
            }
            gBatchRaycaster->performBatchRaycast();
            for (int i = 0; i < gBatchRaycaster->getNumRays(); i++)
            {
                const SpuRaycastTaskWorkUnitOut& out = (*gBatchRaycaster)[i];
                hit[i].setInterpolate3(source[i], dest[i], out.HitFraction);
                normal[i] = out.hitNormal;
                normal[i].Normalize();
            }
#else
            for (int i = 0; i < NUMRAYS_IN_BAR; i++)
            {
                using (var cb = new CollisionWorld.ClosestRayResultCallback(ref source[i], ref dest[i]))
                {
                    cw.RayTest(ref source[i], ref dest[i], cb);
                    if (cb.HasHit)
                    {
                        hit[i]    = cb.HitPointWorld;
                        normal[i] = cb.HitNormalWorld;
                        normal[i].Normalize();
                    }
                    else
                    {
                        hit[i]    = dest[i];
                        normal[i] = new Vector3(1.0f, 0.0f, 0.0f);
                    }
                }
            }

            frame_counter++;
            if (frame_counter > 50)
            {
                min_ms  = ms < min_ms ? ms : min_ms;
                max_ms  = ms > max_ms ? ms : max_ms;
                sum_ms += ms;
                sum_ms_samples++;
                float mean_ms = (float)sum_ms / (float)sum_ms_samples;
                Console.WriteLine("{0} rays in {1} ms {2} {3} {4}", NUMRAYS_IN_BAR * frame_counter, ms, min_ms, max_ms, mean_ms);
                ms            = 0;
                frame_counter = 0;
            }
#endif
        }
예제 #6
0
        public RayResult FindEntityOnRay(Ray ray, PhysicsEntity ignore = null)
        {
            RayResult result = new RayResult();

            if (collisionWorld != null)
            {
                BulletSharp.Math.Vector3 start = ray.Origin;
                BulletSharp.Math.Vector3 end   = ray.Origin + ray.Direction;

                ClosestRayResultCallback callback = new ClosestRayResultCallback(ref start, ref end);
                collisionWorld.RayTest(start, end, callback);

                if (callback.HasHit && callback.CollisionObject != ignore.Rigidbody)
                {
                    result.Position = callback.HitPointWorld;
                    result.Normal   = callback.HitNormalWorld;
                    //result.Hit = callback.CollisionObject;
                }
            }
            return(result);
        }
예제 #7
0
        public void Cast(CollisionWorld cw, float frameDelta)
        {
#if BATCH_RAYCASTER
            if (!batchRaycaster)
            {
                return;
            }

            batchRaycaster.ClearRays();
            foreach (var ray in _rays)
            {
                batchRaycaster.AddRay(ray.Source, ray.Destination);
            }
            batchRaycaster.PerformBatchRaycast();
            for (int i = 0; i < batchRaycaster.NumRays; i++)
            {
                const SpuRaycastTaskWorkUnitOut& out = (*batchRaycaster)[i];
                _rays[i].HitPoint.SetInterpolate3(_source[i], _destination[i], out.HitFraction);
                _rays[i].Normal = out.hitNormal;
                _rays[i].Normal.Normalize();
            }
#else
            foreach (var ray in _rays)
            {
                using (var cb = new ClosestRayResultCallback(ref ray.Source, ref ray.Destination))
                {
                    cw.RayTest(ref ray.Source, ref ray.Destination, cb);
                    if (cb.HasHit)
                    {
                        ray.HitPoint = cb.HitPointWorld;
                        ray.Normal   = cb.HitNormalWorld;
                        ray.Normal.Normalize();
                    }
                    else
                    {
                        ray.HitPoint = ray.Destination;
                        ray.Normal   = new Vector3(1.0f, 0.0f, 0.0f);
                    }
                }
            }

            _time += frameDelta;
            _frameCount++;
            if (_frameCount > 50)
            {
                if (_time < _timeMin)
                {
                    _timeMin = _time;
                }
                if (_time > _timeMax)
                {
                    _timeMax = _time;
                }
                _timeTotal += _time;
                _sampleCount++;
                float timeMean = _timeTotal / _sampleCount;
                PrintStats();
                _time       = 0;
                _frameCount = 0;
            }
#endif
        }
예제 #8
0
        new void Update()
        {
            var rayCalback = new KinematicClosestNotMeRayResultCallback(_ghostObject);

            rayCalback.CollisionFilterMask  = (int)CollisionFilleters.Look;
            rayCalback.CollisionFilterGroup = (int)CollisionFilleters.Look;
            //var test1 = Vector3.Cross(new Vector3(-6.84475f, 1.5930859f, 11.550375f) -  camera.GetPos, (camera.GetLook * 10 * -Vector4.UnitZ).Xyz);
            //Console.WriteLine("{0} {1} {2}", camera.GetPos.Convert(), (camera.GetLook * 10 * -Vector4.UnitZ).Xyz.Convert(), test1.Length / (camera.GetLook * 10 * -Vector4.UnitZ).Xyz.Length);
            world.RayTest(camera.GetPos.Convert(), (camera.GetLook * 10 * new Vector4(0, 0, -1, 1)).Xyz.Convert(), rayCalback);
            if (rayCalback.HasHit)
            {
                // Console.WriteLine("Hit ON {0}",rayCalback.HitNormalWorld);
                if (rayCalback.CollisionObject.UserIndex == 1)
                {
                    if (activeObject != rayCalback.CollisionObject)
                    {
                        activeObject = rayCalback.CollisionObject;
                        lookCallback?.Invoke(null);
                        lookCallback = (Action <SceneNode>)activeObject.UserObject;
                    }
                    lookCallback(camera.Node);
                }
            }

            /*
             * else if (activeObject != null)
             * {
             *  //reset look
             *  lookCallback(Vector3.Zero);
             *  lookCallback = null;
             *  activeObject = null;
             * }
             */

            var keyState = GLWindow.gLWindow.KeyboardState;

            if (game.IsFocused && keyState.IsKeyDown(Keys.Up))
            {
                Walk(-Vector3.UnitZ);
            }
            else if (game.IsFocused && keyState.IsKeyDown(Keys.Down))
            {
                Walk(Vector3.UnitZ);
            }
            else if (game.IsFocused && keyState.IsKeyDown(Keys.Left))
            {
                Walk(-Vector3.UnitX);
            }
            else if (game.IsFocused && keyState.IsKeyDown(Keys.Right))
            {
                Walk(Vector3.UnitX);
            }
            else if (game.IsFocused && keyState.IsKeyDown(Keys.Space))
            {
                Jump();
            }
            else
            {
                Stop();
            }

            base.Update();
        }
예제 #9
0
        public void Cast(CollisionWorld cw, float frameDelta)
        {
#if BATCH_RAYCASTER
            if (!gBatchRaycaster)
            {
                return;
            }

            gBatchRaycaster->clearRays();
            for (int i = 0; i < NumRays; i++)
            {
                gBatchRaycaster->addRay(source[i], dest[i]);
            }
            gBatchRaycaster->performBatchRaycast();
            for (int i = 0; i < gBatchRaycaster->getNumRays(); i++)
            {
                const SpuRaycastTaskWorkUnitOut& out = (*gBatchRaycaster)[i];
                _hitPoint[i].setInterpolate3(_source[i], _destination[i], out.HitFraction);
                _normal[i] = out.hitNormal;
                _normal[i].Normalize();
            }
#else
            for (int i = 0; i < NumRays; i++)
            {
                using (var cb = new ClosestRayResultCallback(ref _source[i], ref _destination[i]))
                {
                    cw.RayTest(ref _source[i], ref _destination[i], cb);
                    if (cb.HasHit)
                    {
                        _hitPoint[i] = cb.HitPointWorld;
                        _normal[i]   = cb.HitNormalWorld;
                        _normal[i].Normalize();
                    }
                    else
                    {
                        _hitPoint[i] = _destination[i];
                        _normal[i]   = new Vector3(1.0f, 0.0f, 0.0f);
                    }
                }
            }

            _time += frameDelta;
            _frameCount++;
            if (_frameCount > 50)
            {
                if (_time < _timeMin)
                {
                    _timeMin = _time;
                }
                if (_time > _timeMax)
                {
                    _timeMax = _time;
                }
                _timeTotal += _time;
                _sampleCount++;
                float timeMean = _timeTotal / _sampleCount;
                Console.WriteLine("{0} rays in {1} s, min {2}, max {3}, mean {4}",
                                  NumRays * _frameCount,
                                  _time.ToString("0.000", CultureInfo.InvariantCulture),
                                  _timeMin.ToString("0.000", CultureInfo.InvariantCulture),
                                  _timeMax.ToString("0.000", CultureInfo.InvariantCulture),
                                  timeMean.ToString("0.000", CultureInfo.InvariantCulture));
                _time       = 0;
                _frameCount = 0;
            }
#endif
        }