private List <Vector3> GetPreviousClosestPositionsForRayCast(BoundBase characterBound, float timeInterval, MovableEntity characterEntity)
        {
            Vector3 velocityToPreviousPosition = characterEntity.Velocity * (-timeInterval);

            Vector3 boundOrigin = characterBound.GetOrigin();
            Vector3 boundMax    = characterBound.GetMax();
            Vector3 boundMin    = characterBound.GetMin();

            boundMax    += velocityToPreviousPosition;
            boundMin    += velocityToPreviousPosition;
            boundOrigin += velocityToPreviousPosition;


            FRay[] rays = new FRay[9]
            {
                new FRay(new Vector3(boundMax.X, boundMax.Y, boundMax.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMax.X, boundMax.Y, boundMin.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMax.X, boundMin.Y, boundMax.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMax.X, boundMin.Y, boundMin.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMin.X, boundMax.Y, boundMax.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMin.X, boundMax.Y, boundMin.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMin.X, boundMin.Y, boundMax.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMin.X, boundMin.Y, boundMin.Z), characterEntity.Velocity),
                new FRay(boundOrigin, characterEntity.Velocity)
            };

            return(GetRayCastPositionsOnCharacterBoundByVelocity(rays, characterBound, boundMax, boundMin, boundOrigin));
        }
        private List <Vector3> GetPreviousFreeFallBottomPositionsForRayCast(BoundBase characterBound, MovableEntity characterEntity)
        {
            Vector3 boundOrigin = characterBound.GetOrigin();
            Vector3 boundMax    = characterBound.GetMax();
            Vector3 boundMin    = characterBound.GetMin();

            Vector3 velocityToPreviousPosition = BodyMechanics.GetFreeFallVelocity(characterEntity.Velocity);

            boundMax    -= velocityToPreviousPosition;
            boundMin    -= velocityToPreviousPosition;
            boundOrigin -= velocityToPreviousPosition;


            FRay[] rays = new FRay[9]
            {
                new FRay(new Vector3(boundMax.X, boundMax.Y, boundMax.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMax.X, boundMax.Y, boundMin.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMax.X, boundMin.Y, boundMax.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMax.X, boundMin.Y, boundMin.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMin.X, boundMax.Y, boundMax.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMin.X, boundMax.Y, boundMin.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMin.X, boundMin.Y, boundMax.Z), characterEntity.Velocity),
                new FRay(new Vector3(boundMin.X, boundMin.Y, boundMin.Z), characterEntity.Velocity),
                new FRay(boundOrigin, characterEntity.Velocity)
            };

            return(GetRayCastPositionsOnCharacterBoundByVelocity(rays, characterBound, boundMax, boundMin, boundOrigin));
        }
        private RayCastOutputData GetClosestRayCastResult(FRay ray, List <BoundBase> collidedBounds)
        {
            float     resultShortestDistance = -1.0f;
            BoundBase resultBound            = null;

            // DO RAY CAST IN ALL COLLIDED BOUNDING BOXES
            for (Int32 i = 0; i < collidedBounds.Count; i++)
            {
                float localIntersectionDistance = 0.0f;
                BoundBase.BoundType boundType   = collidedBounds[i].GetBoundType();
                if ((boundType & BoundBase.BoundType.AABB) == BoundBase.BoundType.AABB)
                {
                    localIntersectionDistance = GeometryMath.Intersection_RayAABB(ray, collidedBounds[i] as AABB);
                }
                else if ((boundType & BoundBase.BoundType.OBB) == BoundBase.BoundType.OBB)
                {
                    localIntersectionDistance = GeometryMath.Intersection_RayOBB(ray, collidedBounds[i] as OBB);
                }

                if (resultShortestDistance <= -1.0f || (localIntersectionDistance > 0.0f && localIntersectionDistance < resultShortestDistance))
                {
                    resultShortestDistance = localIntersectionDistance;
                    resultBound            = collidedBounds[i];
                }
            }

            Vector3 intersectionPosition = ray.GetPositionInTime(resultShortestDistance);

            return(new RayCastOutputData(ray, resultBound, resultShortestDistance, intersectionPosition));
        }
        private List <Vector3> GetRayCastPositionsOnCharacterBoundByVelocity(FRay[] insideCastRays, BoundBase characterBound, Vector3 boundMax, Vector3 boundMin, Vector3 boundOrigin)
        {
            List <Vector3> rayCastPositions = new List <Vector3>();

            for (Int32 i = 0; i < insideCastRays.Length; i++)
            {
                FRay  ray = insideCastRays[i];
                float localIntersectionDistance = -1.0f;
                BoundBase.BoundType boundType   = characterBound.GetBoundType();
                if ((boundType & BoundBase.BoundType.AABB) == BoundBase.BoundType.AABB)
                {
                    localIntersectionDistance = GeometryMath.Intersection_RayAABBExt(ray, boundMax, boundMin);
                }
                else if ((boundType & BoundBase.BoundType.OBB) == BoundBase.BoundType.OBB)
                {
                    localIntersectionDistance = GeometryMath.Intersection_RayOBBExt(ray, (characterBound as OBB).GetTangetX(), (characterBound as OBB).GetTangetY(),
                                                                                    (characterBound as OBB).GetTangetZ(), boundOrigin, (characterBound as OBB).GetExtent());
                }

                if (localIntersectionDistance > -1.0f)
                {
                    Vector3 intersectionPosition = ray.GetPositionInTime(localIntersectionDistance);
                    rayCastPositions.Add(new Vector3(intersectionPosition));
                }
            }
            return(rayCastPositions);
        }
        private void ProcessNoCollisionAtState_Move(MovableEntity character)
        {
            Vector3 boundMin = character.GetCharacterCollisionBound().GetMin();
            Vector3 origin   = character.GetCharacterCollisionBound().GetOrigin();

            // Ray cast from middle height position to avoid miss ray casting
            Vector3 rayCastStartPosition = new Vector3(origin);

            FRay  rayDown = new FRay(rayCastStartPosition, -GameWorld.GetWorldInstance().GetLevel().Camera.GetLocalSpaceUpVector());
            float intersectionDistance = LandscapeRayIntersection.Intersection_TerrainRay(GameWorld.GetWorldInstance().GetLevel().Terrain.GetData(), rayDown);

            // Subtract length of bound extent from middle height position
            float boundExtent = origin.Y - boundMin.Y;
            float actualIntersectionDistance = intersectionDistance - boundExtent;

            // Character is in free fall, next position will be calculated in next tick
            if (intersectionDistance < 0.0f || RAYCAST_INTERSECTION_FAR(BodyMechanics.GetFreeFallDistanceInVelocity(character.Velocity), actualIntersectionDistance))
            {
                character.ActorState = BehaviorState.FREE_FALLING;
            }

            // Check if character can reach that height
            else
            {  // Character could be elevated on terrain
                Vector3 CharacterNewPosition = rayDown.GetPositionInTime(intersectionDistance);
                CharacterNewPosition.Y += character.GetCharacterCollisionBound().GetExtent().Y;
                character.SetPosition(CharacterNewPosition);
                character.ActorState = BehaviorState.IDLE;
            }


            // Push current position to stack
            character.pushPosition();
        }
Esempio n. 6
0
        private BindingVector3 Raycast(FRay ray, WCamera camera)
        {
            BindingVector3        selected_vec            = null;
            List <BindingVector3> vecs_to_raycast         = GetCameraVectorProperties();
            List <Tuple <float, BindingVector3> > results = new List <Tuple <float, BindingVector3> >();

            foreach (BindingVector3 bv in vecs_to_raycast)
            {
                FPlane plane = new FPlane(ray.Direction.Normalized(), bv.BackingVector);

                float dist = float.MaxValue;
                plane.RayIntersectsPlane(ray, out dist);

                Vector3 plane_intersect_point          = camera.Transform.Position + (plane.Normal * dist);
                float   distance_from_billboard_center = (plane_intersect_point - bv.BackingVector).Length;

                if (distance_from_billboard_center < 50.0f)
                {
                    float point_dist = (camera.Transform.Position - bv.BackingVector).Length;
                    results.Add(new Tuple <float, BindingVector3>(point_dist, bv));
                }
            }

            results.Sort(delegate(Tuple <float, BindingVector3> x, Tuple <float, BindingVector3> y)
            {
                return(x.Item1.CompareTo(y.Item1));
            });

            if (results.Count > 0)
            {
                selected_vec = results[0].Item2;
            }

            return(selected_vec);
        }
Esempio n. 7
0
        private CollisionTriangle Raycast(FRay ray)
        {
            if (World.Map == null || ActiveCollisionMesh == null)
            {
                return(null);
            }

            CollisionTriangle closestResult   = null;
            float             closestDistance = float.MaxValue;

            foreach (var tri in ActiveCollisionMesh.Triangles)
            {
                float dist = float.MaxValue;

                if (WMath.RayIntersectsTriangle(ray, tri.Vertices[1], tri.Vertices[0], tri.Vertices[2], true, out dist))
                {
                    if (dist < closestDistance)
                    {
                        closestDistance = dist;
                        closestResult   = tri;
                    }
                }
            }

            return(closestResult);
        }
Esempio n. 8
0
        public bool Raycast(FRay ray, out float hitDistance, bool returnFirstHit = false)
        {
            // Raycast against the bounding box of the entire mesh first to see if we can save ourself a bunch of time.
            bool hitsAABB = WMath.RayIntersectsAABB(ray, BoundingBox.Min, BoundingBox.Max, out hitDistance);

            if (!hitsAABB)
            {
                return(false);
            }

            // Okay, they've intersected with our big bounding box, so now we'll trace against individual mesh bounding box.
            // However, if they've applied skinning data to the meshes then these bounding boxes are no longer valid, so this
            // optimization step only counts if they're not applying any skinning.
            bool canSkipShapeTriangles = m_currentBoneAnimation == null;
            bool rayDidHit             = false;

            foreach (var shape in SHP1Tag.Shapes)
            {
                if (canSkipShapeTriangles)
                {
                    hitsAABB = WMath.RayIntersectsAABB(ray, shape.BoundingBox.Min, shape.BoundingBox.Max, out hitDistance);

                    // If we didn't intersect with this shape, just go onto the next one.
                    if (!hitsAABB)
                    {
                        continue;
                    }
                }

                // We either intersected with this shape's AABB or they have skinning data applied (and thus we can't skip it),
                // thus, we're going to test against every (skinned!) triangle in this shape.
                bool hitTriangle = false;
                var  vertexList  = shape.OverrideVertPos.Count > 0 ? shape.OverrideVertPos : shape.VertexData.Position;

                for (int i = 0; i < shape.Indexes.Count; i += 3)
                {
                    float triHitDist;
                    hitTriangle = WMath.RayIntersectsTriangle(ray, vertexList[shape.Indexes[i]], vertexList[shape.Indexes[i + 1]], vertexList[shape.Indexes[i + 2]], true, out triHitDist);

                    // If we hit this triangle and we're OK to just return the first hit on the model, then we can early out.
                    if (hitTriangle && returnFirstHit)
                    {
                        hitDistance = triHitDist;
                        return(true);
                    }

                    // Otherwise, we need to test to see if this hit is closer than the previous hit.
                    if (hitTriangle)
                    {
                        if (triHitDist < hitDistance)
                        {
                            hitDistance = triHitDist;
                        }
                        rayDidHit = true;
                    }
                }
            }

            return(rayDidHit);
        }
Esempio n. 9
0
        private WDOMNode Raycast(FRay ray)
        {
            if (World.Map == null)
            {
                return(null);
            }

            WDOMNode closestResult   = null;
            float    closestDistance = float.MaxValue;

            foreach (var scene in World.Map.SceneList)
            {
                var allActors = scene.GetChildrenOfType <VisibleDOMNode>();

                foreach (VisibleDOMNode actorNode in allActors)
                {
                    if (!actorNode.ShouldBeRendered())
                    {
                        continue;
                    }
                    float intersectDistance;
                    bool  hitActor = actorNode.Raycast(ray, out intersectDistance);
                    if (hitActor)
                    {
                        if (intersectDistance >= 0 && intersectDistance < closestDistance)
                        {
                            closestDistance = intersectDistance;
                            closestResult   = actorNode;
                        }
                    }
                }
            }

            return(closestResult);
        }
 public RayCastOutputData(FRay ray, BoundBase boundBase, float shortestDistance, Vector3 intersectionPosition)
 {
     parentRay                 = ray;
     collidedBound             = boundBase;
     this.shortestDistance     = shortestDistance;
     this.intersectionPosition = intersectionPosition;
 }
        private void ProcessNoCollisionAtState_FreeFalling(MovableEntity character)
        {
            if (character.Velocity.LengthSquared > 0)
            {
                Vector3 boundMin = character.GetCharacterCollisionBound().GetMin();
                // Raycast from bottom height point
                Vector3 rayCastStartPosition = new Vector3(character.GetCharacterCollisionBound().GetOrigin());
                rayCastStartPosition.Y = boundMin.Y;

                FRay  ray = new FRay(rayCastStartPosition, character.Velocity);
                float intersectionDistance = LandscapeRayIntersection.Intersection_TerrainRay(GameWorld.GetWorldInstance().GetLevel().Terrain.GetData(), ray);

                // Character is still in free fall, just update position
                if (intersectionDistance < 0.0f || RAYCAST_INTERSECTION_FAR(BodyMechanics.GetFreeFallDistanceInVelocity(character.Velocity), intersectionDistance))
                {
                    character.SetPosition(BodyMechanics.UpdateFreeFallPosition(character.ComponentTranslation, character.Velocity));
                }

                // Character could be elevated on terrain
                else
                {
                    Vector3 CharacterNewPosition = ray.GetPositionInTime(intersectionDistance);
                    CharacterNewPosition.Y += character.GetCharacterCollisionBound().GetExtent().Y;
                    character.SetPosition(CharacterNewPosition);
                    character.ActorState = BehaviorState.IDLE;
                }
            }

            character.pushPosition();
        }
Esempio n. 12
0
        public static float Intersection_RayOBBExt(FRay ray, Vector3 RotationX, Vector3 RotationY, Vector3 RotationZ, Vector3 Origin, Vector3 Extent)
        {
            Vector3 p = Origin - ray.StartPosition;

            // Project obb tangent vectors on ray direction
            Vector3 f = new Vector3(
                ProjectVectorOnNormalizedVector(RotationX, ray.Direction),
                ProjectVectorOnNormalizedVector(RotationY, ray.Direction),
                ProjectVectorOnNormalizedVector(RotationZ, ray.Direction)
                );

            // Project tangent vectors on p
            Vector3 e = new Vector3(
                ProjectVectorOnNormalizedVector(RotationX, p),
                ProjectVectorOnNormalizedVector(RotationY, p),
                ProjectVectorOnNormalizedVector(RotationZ, p)
                );


            float[] tparameter = new float[6];
            for (Int32 i = 0; i < 3; i++)
            {
                if (CMP(f[i], 0) > 0)
                {
                    if (-e[i] - Extent[i] > 0 || -e[i] + Extent[i] < 0)
                    {
                        return(-1);
                    }
                    f[i] = 0.00001f;
                }

                tparameter[i * 2]     = (e[i] + Extent[i]) / f[i]; // min
                tparameter[i * 2 + 1] = (e[i] - Extent[i]) / f[i]; // max
            }

            float tmin = Math.Max(
                Math.Max(Math.Min(tparameter[0], tparameter[1]), Math.Min(tparameter[2], tparameter[3])),
                Math.Min(tparameter[4], tparameter[5]));

            float tmax = System.Math.Min(
                System.Math.Min(System.Math.Max(tparameter[0], tparameter[1]), System.Math.Max(tparameter[2], tparameter[3])),
                System.Math.Max(tparameter[4], tparameter[5]));

            // If OBB is behind the origin of the ray or if ray doesn't intersect OBB
            if (tmax < 0 || tmin > tmax)
            {
                return(-1);
            }

            // If origin of ray is inside the OBB
            if (tmin < 0.0f)
            {
                return(tmax);
            }

            // Intersection point
            return(tmin);
        }
Esempio n. 13
0
        public static Vector3 GetIntersectionRayPlane(FPlane plane, FRay ray)
        {
            Vector3 result;
            Vector3 planeNormal = new Vector3(plane.X, plane.Y, plane.Z);
            float   timeParam   = (plane.D + (Vector3.Dot(planeNormal, ray.StartPosition))) / Vector3.Dot(planeNormal, ray.Direction);

            result = ray.StartPosition + ray.Direction * timeParam;
            return(result);
        }
Esempio n. 14
0
        public void Update(WSceneView view)
        {
            UpdateSelectionGizmo(view);

            // If we have a gizmo and we're transforming it, don't check for selection change.
            if (TransformGizmo != null && TransformGizmo.IsTransforming)
            {
                return;
            }
            if (WInput.GetMouseButtonDown(0) && !WInput.GetMouseButton(1))
            {
                FRay mouseRay   = view.ProjectScreenToWorld(WInput.MousePosition);
                var  addedActor = Raycast(mouseRay);

                // Check the behaviour of this click to determine appropriate selection modification behaviour.
                // Click w/o Modifiers = Clear Selection, add result to selection
                // Click /w Ctrl = Toggle Selection State
                // Click /w Shift = Add to Selection
                bool ctrlPressed  = WInput.GetKey(Key.LeftCtrl) || WInput.GetKey(Key.RightCtrl);
                bool shiftPressed = WInput.GetKey(Key.LeftShift) || WInput.GetKey(Key.RightShift);

                if (!ctrlPressed & !shiftPressed)
                {
                    EditorSelection.ClearSelection();
                    if (addedActor != null)
                    {
                        EditorSelection.AddToSelection(addedActor);
                    }
                }
                else if (addedActor != null && (ctrlPressed && !shiftPressed))
                {
                    if (addedActor.IsSelected)
                    {
                        EditorSelection.RemoveFromSelection(addedActor);
                    }
                    else
                    {
                        EditorSelection.AddToSelection(addedActor);
                    }
                }
                else if (addedActor != null && shiftPressed)
                {
                    if (!EditorSelection.SelectedObjects.Contains(addedActor))
                    {
                        EditorSelection.AddToSelection(addedActor);
                    }
                }

                UpdateGizmoTransform();
            }

            // Add our gizmo to the renderer this frame.
            ((IRenderable)TransformGizmo).AddToRenderer(view);
        }
Esempio n. 15
0
        private Vector3 GetTopBottomIntersectionPoint(Vector3 A, FPlane cbPlane, FPlane incidentPlane)
        {
            Vector3 result;
            Vector3 acNormal       = new Vector3(incidentPlane.X, incidentPlane.Y, incidentPlane.Z);
            Vector3 acRayDirection = Vector3.Cross(acNormal, RightVector);

            Vector3 cbNormal = new Vector3(cbPlane.X, cbPlane.Y, cbPlane.Z);

            // if ac ray is opposite directed - invert it's direction
            acRayDirection *= Vector3.Dot(cbNormal, acRayDirection) > 0.0 ? 1 : -1;
            FRay acRay = new FRay(A, acRayDirection);

            result = GeometryMath.GetIntersectionRayPlane(cbPlane, acRay);
            return(result);
        }
Esempio n. 16
0
        public void Update(WSceneView view)
        {
            if (WInput.GetMouseButton(0) && !WInput.GetMouseButton(1))
            {
                FRay mouseRay   = view.ProjectScreenToWorld(WInput.MousePosition);
                var  addedActor = Raycast(mouseRay);

                // Check the behaviour of this click to determine appropriate selection modification behaviour.
                // Click w/o Modifiers = Clear Selection, add result to selection
                // Click /w Ctrl = Toggle Selection State
                // Click /w Shift = Add to Selection
                bool ctrlPressed  = WInput.GetKey(Key.LeftCtrl) || WInput.GetKey(Key.RightCtrl);
                bool shiftPressed = WInput.GetKey(Key.LeftShift) || WInput.GetKey(Key.RightShift);

                if (ctrlPressed && !WInput.GetMouseButtonDown(0))
                {
                    return;
                }

                if (!ctrlPressed & !shiftPressed)
                {
                    ClearSelection();
                    if (addedActor != null)
                    {
                        AddTriangleToSelection(addedActor);
                    }
                }
                else if (addedActor != null && (ctrlPressed && !shiftPressed))
                {
                    if (addedActor.IsSelected)
                    {
                        RemoveTriangleFromSelection(addedActor);
                    }
                    else
                    {
                        AddTriangleToSelection(addedActor);
                    }
                }
                else if (addedActor != null && shiftPressed)
                {
                    if (!EditorSelection.SelectedObjects.Contains(addedActor))
                    {
                        AddTriangleToSelection(addedActor);
                    }
                }
            }
        }
Esempio n. 17
0
        public static float Intersection_RayAABB(FRay ray, AABB aabb)
        {
            Vector3 max = aabb.GetMax();
            Vector3 min = aabb.GetMin();

            Vector3 rayDirection = ray.Direction;

            // safety check to avoid zero division
            rayDirection.X = System.Math.Abs(rayDirection.X) < 0.00005f ? 0.00005f : rayDirection.X;
            rayDirection.Y = System.Math.Abs(rayDirection.Y) < 0.00005f ? 0.00005f : rayDirection.Y;
            rayDirection.Z = System.Math.Abs(rayDirection.Z) < 0.00005f ? 0.00005f : rayDirection.Z;

            // find time of getting to each bounding box position
            float t1 = (min.X - ray.StartPosition.X) / rayDirection.X;
            float t2 = (max.X - ray.StartPosition.X) / rayDirection.X;
            float t3 = (min.Y - ray.StartPosition.Y) / rayDirection.Y;
            float t4 = (max.Y - ray.StartPosition.Y) / rayDirection.Y;
            float t5 = (min.Z - ray.StartPosition.Z) / rayDirection.Z;
            float t6 = (max.Z - ray.StartPosition.Z) / rayDirection.Z;

            // find minimal from max values
            float tmax = System.Math.Min(
                System.Math.Min(System.Math.Max(t1, t2), System.Math.Max(t3, t4)),
                System.Math.Max(t5, t6));
            // find maximal from min values
            float tmin = System.Math.Max(
                System.Math.Max(System.Math.Min(t1, t2), System.Math.Min(t3, t4)),
                System.Math.Min(t5, t6));

            // If AABB is behind the origin of the ray or if ray doesn't intersect AABB
            if (tmax < 0 || tmin > tmax)
            {
                return(-1);
            }

            // If origin of ray is inside the AABB
            if (tmin < 0.0f)
            {
                return(tmax);
            }

            // Intersection point
            return(tmin);
        }
        private List <Vector3> GetCurrentMiddlePositionsForRayCast(BoundBase characterBound, MovableEntity characterEntity)
        {
            Vector3 boundOrigin = characterBound.GetOrigin();
            Vector3 boundMax    = characterBound.GetMax();
            Vector3 boundMin    = characterBound.GetMin();

            Vector3 tangentY = -characterBound.GetTangetY();

            FRay[] rays = new FRay[5]
            {
                new FRay(boundOrigin, tangentY),
                new FRay(new Vector3(boundMax.X, boundOrigin.Y, boundMax.Z), tangentY),
                new FRay(new Vector3(boundMax.X, boundOrigin.Y, boundMin.Z), tangentY),
                new FRay(new Vector3(boundMin.X, boundOrigin.Y, boundMin.Z), tangentY),
                new FRay(new Vector3(boundMin.X, boundOrigin.Y, boundMax.Z), tangentY),
            };

            return(GetClosestPositionsForRayCast(rays, characterBound, boundMax, boundMin, boundOrigin, boundOrigin.Y));
        }
Esempio n. 19
0
        public static Vector3 getIntersectionPoint(Landscape terrain, FRay ray) //Binary search
        {
            Vector3 endPoint    = getEndPoint(ray);
            Vector3 startPoint  = ray.StartPosition;
            Vector3 middlePoint = new Vector3(0);

            for (Int32 i = 0; i < RECURSION_COUNT; i++)
            {
                middlePoint = endPoint - (endPoint - startPoint) / 2; // Divide by two
                if (isUnderTerrain(terrain, middlePoint))             //If height of landscape is beyond point
                {
                    endPoint = middlePoint;
                }
                else
                {
                    startPoint = middlePoint; //If height of landscape is under middlePoint
                }
            }
            return(middlePoint);
        }
Esempio n. 20
0
        public static float Intersection_TerrainRay(Landscape terrain, FRay ray)
        {
            float t = -1.0f;

            if (terrain != null)
            {
                Vector3 P = getIntersectionPoint(terrain, ray);

                if (GeometryMath.CMP(ray.Direction.X, 0.0f) <= 0.0f && GeometryMath.CMP(P.X, 0.0f) <= 0.0f)
                {
                    t = (P.X - ray.StartPosition.X) / ray.Direction.X;
                }
                else if (GeometryMath.CMP(ray.Direction.Y, 0.0f) <= 0.0f && GeometryMath.CMP(P.Y, 0.0f) <= 0.0f)
                {
                    t = (P.Y - ray.StartPosition.Y) / ray.Direction.Y;
                }
                else if (GeometryMath.CMP(ray.Direction.Z, 0.0f) <= 0.0f && GeometryMath.CMP(P.Z, 0.0f) <= 0.0f)
                {
                    t = (P.Z - ray.StartPosition.Z) / ray.Direction.Z;
                }
            }
            return(t);
        }
Esempio n. 21
0
        public bool Raycast(FRay ray, out float hitDistance, bool returnFirstHit = false)
        {
            // Raycast against the bounding box of the entire mesh first to see if we can save ourself a bunch of time.
            bool hitsAABB = WMath.RayIntersectsAABB(ray, BoundingBox.Min, BoundingBox.Max, out hitDistance);

            if (!hitsAABB)
            {
                return(false);
            }

            // Okay, they've intersected with our big bounding box, so now we'll trace against individual mesh bounding box.
            // However, if they've applied skinning data to the meshes then these bounding boxes are no longer valid, so this
            // optimization step only counts if they're not applying any skinning.
            bool canSkipShapeTriangles = m_currentBoneAnimation == null;
            bool rayDidHit             = false;

            foreach (var shape in SHP1Tag.Shapes)
            {
                if (canSkipShapeTriangles)
                {
                    hitsAABB = WMath.RayIntersectsAABB(ray, shape.BoundingBox.Min, shape.BoundingBox.Max, out hitDistance);

                    // If we didn't intersect with this shape, just go onto the next one.
                    if (!hitsAABB)
                    {
                        continue;
                    }
                }

                // We either intersected with this shape's AABB or they have skinning data applied (and thus we can't skip it),
                // thus, we're going to test against every (skinned!) triangle in this shape.
                bool hitTriangle = false;

                /*foreach (SHP1.Packet pak in shape.MatrixGroups)
                 * {
                 *  List<Vector3> vertexList = new List<Vector3>();
                 *
                 *  for (int i = 0; i < pak.Indexes.Count; i++)
                 *  {
                 *      Matrix4 cur_mat = DRW1Tag.Matrices[pak.MatrixDataTable.MatrixTable[pak.VertexData.PositionMatrixIndexes[i]]];
                 *      vertexList.Add(Vector3.Transform(pak.VertexData.Position[i], cur_mat));
                 *  }
                 *
                 *  for (int i = 0; i < pak.Indexes.Count; i += 3)
                 *  {
                 *      float triHitDist;
                 *      hitTriangle = WMath.RayIntersectsTriangle(ray, vertexList[pak.Indexes[i]], vertexList[pak.Indexes[i + 1]], vertexList[pak.Indexes[i + 2]], true, out triHitDist);
                 *
                 *      // If we hit this triangle and we're OK to just return the first hit on the model, then we can early out.
                 *      if (hitTriangle && returnFirstHit)
                 *      {
                 *          hitDistance = triHitDist;
                 *          Console.WriteLine($"{Name}:{hitDistance}");
                 *          return true;
                 *      }
                 *
                 *      // Otherwise, we need to test to see if this hit is closer than the previous hit.
                 *      if (hitTriangle)
                 *      {
                 *          if (triHitDist < hitDistance)
                 *              hitDistance = triHitDist;
                 *          rayDidHit = true;
                 *      }
                 *  }
                 * }*/
            }

            return(rayDidHit);
        }
Esempio n. 22
0
 private static Vector3 getEndPoint(FRay ray)
 {
     return(ray.GetPositionInTime(RAY_DISTANCE));
 }
Esempio n. 23
0
        private float GetCollisionDistanceFromCamera()
        {
            if (World.Map == null)
            {
                return(-1);
            }

            List <WCollisionMesh> meshes;

            if (World.Map.FocusedScene is WStage)
            {
                // If a stage is selected, raycast against the collision meshes for all rooms that are loaded.
                meshes = new List <WCollisionMesh>();
                foreach (var scene in World.Map.SceneList)
                {
                    meshes.AddRange(scene.GetChildrenOfType <WCollisionMesh>());
                }
            }
            else
            {
                // If a room is selected, raycast against the collision mesh for only that room.
                meshes = World.Map.FocusedScene.GetChildrenOfType <WCollisionMesh>();
            }

            if (meshes.Count == 0)
            {
                return(-1);
            }

            WCamera camera = World.GetFocusedSceneView().ViewCamera;

            Vector3 dir = Vector3.Transform(new Vector3(0.0f, 0.0f, -1.0f), camera.Transform.Rotation);

            dir.Normalize();
            FRay ray = new FRay(camera.Transform.Position, dir);

            CollisionTriangle closestResult   = null;
            float             closestDistance = float.MaxValue;

            foreach (var mesh in meshes)
            {
                foreach (var tri in mesh.Triangles)
                {
                    float dist = float.MaxValue;

                    if (WMath.RayIntersectsTriangle(ray, tri.Vertices[1], tri.Vertices[0], tri.Vertices[2], true, out dist))
                    {
                        if (dist < closestDistance)
                        {
                            closestDistance = dist;
                            closestResult   = tri;
                        }
                    }
                }
            }

            if (closestResult == null)
            {
                return(-1.0f);
            }

            return(closestDistance);
        }
Esempio n. 24
0
        private void UpdateSelectionGizmo(WSceneView view)
        {
            if (!TransformGizmo.Enabled && EditorSelection.SelectedObjects.Count > 0)
            {
                // Show the Transform Gizmo.
                TransformGizmo.Enabled = true;
                UpdateGizmoTransform();
                // m_transformGizmo.SetPosition(m_selectionList[0].Transform.Position);
                // m_transformGizmo.SetLocalRotation(m_selectionList[0].Transform.Rotation);
            }
            else if (TransformGizmo.Enabled && EditorSelection.SelectedObjects.Count == 0)
            {
                // Hide the Transform Gizmo.
                TransformGizmo.Enabled = false;
            }

            if (!TransformGizmo.Enabled)
            {
                return;
            }

            if (WInput.GetKeyDown(Key.Q) && !WInput.GetMouseButton(1))
            {
                TransformGizmo.SetMode(FTransformMode.None);
            }
            if (WInput.GetKeyDown(Key.W) && !WInput.GetMouseButton(1))
            {
                TransformGizmo.SetMode(FTransformMode.Translation);
            }
            if (WInput.GetKeyDown(Key.E) && !WInput.GetMouseButton(1))
            {
                TransformGizmo.SetMode(FTransformMode.Rotation);
            }
            if (WInput.GetKeyDown(Key.R) && !WInput.GetMouseButton(1))
            {
                TransformGizmo.SetMode(FTransformMode.Scale);
            }

            if (WInput.GetKeyDown(Key.OemOpenBrackets))
            {
                TransformGizmo.DecrementSize();
            }

            if (WInput.GetKeyDown(Key.OemCloseBrackets))
            {
                TransformGizmo.IncrementSize();
            }

            if (WInput.GetKeyDown(Key.OemTilde))
            {
                if (TransformGizmo.TransformSpace == FTransformSpace.World)
                {
                    TransformGizmo.SetTransformSpace(FTransformSpace.Local);
                }
                else
                {
                    TransformGizmo.SetTransformSpace(FTransformSpace.World);
                }

                UpdateGizmoTransform();
            }

            if (WInput.GetMouseButtonDown(0))
            {
                FRay mouseRay = view.ProjectScreenToWorld(WInput.MousePosition);
                if (TransformGizmo.CheckSelectedAxes(mouseRay))
                {
                    TransformGizmo.StartTransform();
                }
            }

            if (WInput.GetMouseButtonUp(0))
            {
                if (TransformGizmo.IsTransforming)
                {
                    // When we end let go of the gizmo, we want to make one last action which specifies that it is done,
                    // so that the next gizmo move doesn't merge with the previous.
                    WUndoCommand undoAction = CreateUndoActionForGizmo(true);
                    if (undoAction != null)
                    {
                        BroadcastUndoEventGenerated(undoAction);
                    }

                    TransformGizmo.EndTransform();
                }
            }

            if (TransformGizmo.IsTransforming)
            {
                FRay mouseRay = view.ProjectScreenToWorld(WInput.MousePosition);
                if (TransformGizmo.TransformFromInput(mouseRay, view))
                {
                    WUndoCommand undoAction = CreateUndoActionForGizmo(false);
                    if (undoAction != null)
                    {
                        BroadcastUndoEventGenerated(undoAction);
                    }
                }
            }

            TransformGizmo.UpdateForSceneView(view);
        }
        private void ProcessCollisionAtState_FreeFalling(MovableEntity character, Entity collidedEntity, List <BoundBase> collidedBounds)
        {
            switch (GetEntityType(collidedEntity))
            {
            // If character collided another character during free fall because of forward velocity
            case EntityType.MOVABLE_ENTITY:
            {
                // Restore previous position and set velocity to fall
                character.popPosition();
                character.Velocity = -GameWorld.GetWorldInstance().GetLevel().Camera.GetLocalSpaceUpVector();
                break;
            }

            // If character is in free falling but has encountered some collisions with bounds
            case EntityType.STATIC_ENTITY:
            {
                List <Vector3> previousRayCastPositions = GetPreviousFreeFallBottomPositionsForRayCast(character.GetCharacterCollisionBound(), character);
                List <FRay>    listOfRays = new List <FRay>();
                for (Int32 i = 0; i < previousRayCastPositions.Count; i++)
                {
                    listOfRays.Add(new FRay(previousRayCastPositions[i], character.Velocity));
                }

                FRay rayFromMiddleBottom = listOfRays.First();

                // Necessary data for subsequent calculations
                RayCastOutputData rayCastOutputData           = null;
                float             terrainIntersectionDistance = LandscapeRayIntersection.Intersection_TerrainRay(GameWorld.GetWorldInstance().GetLevel().Terrain.GetData(), rayFromMiddleBottom);

                bool bTerrainIntersection = !(terrainIntersectionDistance < 0.0f ||
                                              RAYCAST_INTERSECTION_FAR(BodyMechanics.GetFreeFallDistanceInVelocity(character.Velocity), terrainIntersectionDistance));

                // No terrain intersection - check intersection with bounds
                if (!bTerrainIntersection)
                {
                    rayCastOutputData = GetClosestRayCastResultFromMultipleRayCast(listOfRays, collidedBounds, character);

                    // Ray collided with one of the bounds, check angle of that plane, if can elevate on it - do it
                    if (RAYCAST_COLLIDED(rayCastOutputData.shortestDistance))
                    {
                        Vector3 normalToCollidedPlane = rayCastOutputData.collidedBound.GetNormalToIntersectedPosition(rayCastOutputData.intersectionPosition);
                        // Character can step on this surface
                        if (REACHABLE_INCLINE(normalToCollidedPlane))
                        {
                            Vector3 BoundOrigin          = character.GetCharacterCollisionBound().GetOrigin();
                            Vector3 NewCharacterPosition = new Vector3(BoundOrigin.X, rayCastOutputData.intersectionPosition.Y + character.GetCharacterCollisionBound().GetExtent().Y,
                                                                       BoundOrigin.Z);
                            character.SetPosition(NewCharacterPosition);
                            character.pushPosition();
                            character.ActorState = BehaviorState.IDLE;
                        }
                        // If normal is down directed or too up directed - character can't step on this surface - return to previous position and set velocity to down
                        else
                        {
                            // This is quick fix
                            character.ActorState = BehaviorState.MOVE;
                            character.popPosition();
                            character.Velocity = -GameWorld.GetWorldInstance().GetLevel().Camera.GetLocalSpaceUpVector();
                        }
                    }
                    // No ray collision, but bound collision exists, bound position is unknown - return to previous position and set velocity to down
                    else
                    {
                        character.popPosition();
                        character.Velocity = -GameWorld.GetWorldInstance().GetLevel().Camera.GetLocalSpaceUpVector();
                    }
                }
                // Character could be elevated on terrain
                else
                {
                    Vector3 CharacterNewPosition = rayFromMiddleBottom.GetPositionInTime(terrainIntersectionDistance);
                    CharacterNewPosition.Y += character.GetCharacterCollisionBound().GetExtent().Y;
                    character.SetPosition(CharacterNewPosition);
                    character.ActorState = BehaviorState.IDLE;
                    character.pushPosition();
                }

                break;
            }
            }
        }
Esempio n. 26
0
        public void Update(WSceneView view)
        {
            m_View = view;
            UpdateSelectionGizmo(view);

            // Add our gizmo to the renderer this frame.
            if (TransformGizmo != null)
            {
                ((IRenderable)TransformGizmo).AddToRenderer(view);
            }

            // If we have a gizmo and we're transforming it, don't check for selection change.
            if (TransformGizmo != null && TransformGizmo.IsTransforming)
            {
                return;
            }
            if (WInput.GetMouseButtonDown(0) && !WInput.GetMouseButton(1) && !m_bOverrideSceneCamera)
            {
                FRay           mouseRay = view.ProjectScreenToWorld(WInput.MousePosition);
                BindingVector3 addedVec = Raycast(mouseRay, view.ViewCamera);

                // Check the behaviour of this click to determine appropriate selection modification behaviour.
                // Click w/o Modifiers = Clear Selection, add result to selection
                // Click /w Ctrl = Toggle Selection State
                // Click /w Shift = Add to Selection
                bool ctrlPressed  = WInput.GetKey(Key.LeftCtrl) || WInput.GetKey(Key.RightCtrl);
                bool shiftPressed = WInput.GetKey(Key.LeftShift) || WInput.GetKey(Key.RightShift);

                // Replace the previous selection with the current selection, if it's valid.
                if (!ctrlPressed & !shiftPressed)
                {
                    EditorSelection.ClearSelection();

                    if (addedVec != null)
                    {
                        EditorSelection.AddToSelection(addedVec);
                    }
                }
                else if (addedVec != null && (ctrlPressed && !shiftPressed))
                {
                    if (EditorSelection.SelectedObjects.Contains(addedVec))
                    {
                        EditorSelection.RemoveFromSelection(addedVec);
                    }
                    else
                    {
                        EditorSelection.AddToSelection(addedVec);
                    }
                }
                else if (addedVec != null && shiftPressed)
                {
                    if (!EditorSelection.SelectedObjects.Contains(addedVec))
                    {
                        EditorSelection.AddToSelection(addedVec);
                    }
                }
            }
            if (m_CopyCameraRequest != null)
            {
                m_CopyCameraRequest.RequestingCut.CopySettingsFromCamera(view.ViewCamera, m_CopyCameraRequest.IsStart);
                m_CopyCameraRequest = null;
            }
            if (WInput.GetMouseButton(1) && m_bOverrideSceneCamera)
            {
                RestoreSceneCamera(view);
            }

            UpdateGizmoTransform();
        }