Пример #1
0
        /// <summary>
        /// CollDetectSphereStaticMeshOverlap
        /// </summary>
        /// <param name="oldSphere"></param>
        /// <param name="newSphere"></param>
        /// <param name="mesh"></param>
        /// <param name="info"></param>
        /// <param name="collTolerance"></param>
        /// <param name="collisionFunctor"></param>
        public static void CollDetectSphereStaticMeshOverlap(BoundingSphere oldSphere, BoundingSphere newSphere,
                                                             TriangleMesh mesh, CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
            Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

            float sphereTolR  = collTolerance + newSphere.Radius;
            float sphereTolR2 = sphereTolR * sphereTolR;

            unsafe
            {
#if USE_STACKALLOC
                SmallCollPointInfo *collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
                int *potentialTriangles     = stackalloc int[MaxLocalStackTris];
                {
                    {
#else
                SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                fixed(SmallCollPointInfo *collPts = collPtArray)
                {
                    int[] potTriArray = IntStackAlloc();
                    fixed(int *potentialTriangles = potTriArray)
                    {
#endif
                        int numCollPts = 0;

                        Vector3 collNormal = Vector3.Zero;

                        BoundingBox bb = BoundingBoxHelper.InitialBox;
                        BoundingBoxHelper.AddSphere(newSphere, ref bb);
                        int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                        // Deano : get the spheres centers in triangle mesh space
                        Vector3 newSphereCen = Vector3.Transform(newSphere.Center, mesh.InverseTransformMatrix);
                        Vector3 oldSphereCen = Vector3.Transform(oldSphere.Center, mesh.InverseTransformMatrix);

                        for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                        {
                            IndexedTriangle meshTriangle = mesh.GetTriangle(potentialTriangles[iTriangle]);
                            float           distToCentre = meshTriangle.Plane.DotCoordinate(newSphereCen);

                            // BEN-BUG-FIX: Replaced 0.0f with -sphereTolR.
                            if (distToCentre < -sphereTolR || distToCentre > sphereTolR)
                            {
                                continue;
                            }

                            int i0, i1, i2;
                            meshTriangle.GetVertexIndices(out i0, out i1, out i2);

                            Triangle triangle = new Triangle(mesh.GetVertex(i0), mesh.GetVertex(i1), mesh.GetVertex(i2));

                            float s, t;
                            float newD2 = Distance.PointTriangleDistanceSq(out s, out t, newSphereCen, triangle);

                            if (newD2 < sphereTolR2)
                            {
                                // have overlap - but actually report the old intersection
                                float oldD2 = Distance.PointTriangleDistanceSq(out s, out t, oldSphereCen, triangle);
                                float dist  = (float)System.Math.Sqrt((float)oldD2);
                                float depth = oldSphere.Radius - dist;

                                Vector3 triPointSTNorm = oldSphereCen - triangle.GetPoint(s, t);
                                JiggleMath.NormalizeSafe(ref triPointSTNorm);

                                Vector3 collisionN = (dist > float.Epsilon) ? triPointSTNorm : triangle.Normal;

                                // since impulse get applied at the old position
                                Vector3 pt = oldSphere.Center - oldSphere.Radius * collisionN;

                                if (numCollPts < MaxLocalStackSCPI)
                                {
                                    // BEN-OPTIMISATION: Reuse existing collPts.
                                    collPts[numCollPts].R0 = pt - body0Pos;
                                    collPts[numCollPts].R1 = pt - body1Pos;
                                    collPts[numCollPts++].InitialPenetration = depth;
                                }
                                collNormal += collisionN;
                            }
                        }

                        if (numCollPts > 0)
                        {
                            JiggleMath.NormalizeSafe(ref collNormal);
                            collisionFunctor.CollisionNotify(ref info, ref collNormal, collPts, numCollPts);
                        }
#if USE_STACKALLOC
                    }
                }
#else
                        FreeStackAlloc(potTriArray);
                    }

                    FreeStackAlloc(collPtArray);
                }
#endif
            }
        }
Пример #2
0
        private static Geometry ConvertAssimpMeshToGeometry(Ai.Mesh aiMesh, Ai.Material material, Dictionary <string, NodeInfo> nodeLookup, ref int nextBoneIndex, Dictionary <int, List <int> > nodeToBoneIndices, List <Matrix4x4> boneInverseBindMatrices, ref Matrix4x4 nodeWorldTransform, ref Matrix4x4 nodeInverseWorldTransform, List <Vector3> transformedVertices, SceneConverterOptions options)
        {
            if (!aiMesh.HasVertices)
            {
                throw new Exception("Assimp mesh has no vertices");
            }

            var geometry = new Geometry();
            var geometryTransformedVertices = new Vector3[aiMesh.VertexCount];

            geometry.Vertices = aiMesh.Vertices
                                .Select(x => new Vector3(x.X, x.Y, x.Z))
                                .ToArray();

            for (int i = 0; i < geometry.Vertices.Length; i++)
            {
                geometryTransformedVertices[i] = Vector3.Transform(geometry.Vertices[i], nodeWorldTransform);
            }

            transformedVertices.AddRange(geometryTransformedVertices);

            if (aiMesh.HasNormals)
            {
                geometry.Normals = aiMesh.Normals
                                   .Select(x => new Vector3(x.X, x.Y, x.Z))
                                   .ToArray();
            }

            if (aiMesh.HasTextureCoords(0))
            {
                geometry.TexCoordsChannel0 = aiMesh.TextureCoordinateChannels[0]
                                             .Select(x => new Vector2(x.X, x.Y))
                                             .ToArray();
            }

            if (aiMesh.HasTextureCoords(1))
            {
                geometry.TexCoordsChannel1 = aiMesh.TextureCoordinateChannels[1]
                                             .Select(x => new Vector2(x.X, x.Y))
                                             .ToArray();
            }

            if (aiMesh.HasTextureCoords(2))
            {
                geometry.TexCoordsChannel2 = aiMesh.TextureCoordinateChannels[2]
                                             .Select(x => new Vector2(x.X, x.Y))
                                             .ToArray();
            }

            if (aiMesh.HasVertexColors(0))
            {
                geometry.ColorChannel0 = aiMesh.VertexColorChannels[0]
                                         .Select(x => ( uint )(( byte )(x.B * 255f) | ( byte )(x.G * 255f) << 8 | ( byte )(x.R * 255f) << 16 | ( byte )(x.A * 255f) << 24))
                                         .ToArray();
            }
            else if (options.GenerateVertexColors)
            {
                geometry.ColorChannel0 = new uint[geometry.VertexCount];
                for (int i = 0; i < geometry.ColorChannel0.Length; i++)
                {
                    geometry.ColorChannel0[i] = 0xFFFFFFFF;
                }
            }

            if (aiMesh.HasVertexColors(1))
            {
                geometry.ColorChannel1 = aiMesh.VertexColorChannels[1]
                                         .Select(x => ( uint )(( byte )(x.B * 255f) | ( byte )(x.G * 255f) << 8 | ( byte )(x.R * 255f) << 16 | ( byte )(x.A * 255f) << 24))
                                         .ToArray();
            }

            if (aiMesh.HasFaces)
            {
                geometry.TriangleIndexType = aiMesh.VertexCount <= ushort.MaxValue ? TriangleIndexType.UInt16 : TriangleIndexType.UInt32;
                geometry.Triangles         = aiMesh.Faces
                                             .Select(x => new Triangle(( uint )x.Indices[0], ( uint )x.Indices[1], ( uint )x.Indices[2]))
                                             .ToArray();
            }

            if (aiMesh.HasBones)
            {
                geometry.VertexWeights = new VertexWeight[geometry.VertexCount];
                for (int i = 0; i < geometry.VertexWeights.Length; i++)
                {
                    geometry.VertexWeights[i].Indices = new byte[4];
                    geometry.VertexWeights[i].Weights = new float[4];
                }

                var vertexWeightCounts = new int[geometry.VertexCount];

                for (var i = 0; i < aiMesh.Bones.Count; i++)
                {
                    var aiMeshBone = aiMesh.Bones[i];

                    // Find node index for the bone
                    var boneLookupData = nodeLookup[AssimpConverterCommon.UnescapeName(aiMeshBone.Name)];
                    int nodeIndex      = boneLookupData.Index;

                    // Calculate inverse bind matrix
                    var boneNode   = boneLookupData.Node;
                    var bindMatrix = boneNode.WorldTransform * nodeInverseWorldTransform;

                    if (options.ConvertSkinToZUp)
                    {
                        bindMatrix *= YToZUpMatrix;
                    }

                    Matrix4x4.Invert(bindMatrix, out var inverseBindMatrix);

                    // Get bone index
                    int boneIndex;
                    if (!nodeToBoneIndices.TryGetValue(nodeIndex, out var boneIndices))
                    {
                        // No entry for the node was found, so we add a new one
                        boneIndex = nextBoneIndex++;
                        nodeToBoneIndices.Add(nodeIndex, new List <int>()
                        {
                            boneIndex
                        });
                        boneInverseBindMatrices.Add(inverseBindMatrix);
                    }
                    else
                    {
                        // Entry for the node was found
                        // Try to find the bone index based on whether the inverse bind matrix matches
                        boneIndex = -1;
                        foreach (int index in boneIndices)
                        {
                            if (boneInverseBindMatrices[index].Equals(inverseBindMatrix))
                            {
                                boneIndex = index;
                            }
                        }

                        if (boneIndex == -1)
                        {
                            // None matching inverse bind matrix was found, so we add a new entry
                            boneIndex = nextBoneIndex++;
                            nodeToBoneIndices[nodeIndex].Add(boneIndex);
                            boneInverseBindMatrices.Add(inverseBindMatrix);
                        }
                    }

                    foreach (var aiVertexWeight in aiMeshBone.VertexWeights)
                    {
                        int vertexWeightCount = vertexWeightCounts[aiVertexWeight.VertexID]++;

                        geometry.VertexWeights[aiVertexWeight.VertexID].Indices[vertexWeightCount] = ( byte )boneIndex;
                        geometry.VertexWeights[aiVertexWeight.VertexID].Weights[vertexWeightCount] = aiVertexWeight.Weight;
                    }
                }
            }

            geometry.MaterialName   = AssimpConverterCommon.UnescapeName(material.Name);
            geometry.BoundingBox    = BoundingBox.Calculate(geometry.Vertices);
            geometry.BoundingSphere = BoundingSphere.Calculate(geometry.BoundingBox.Value, geometry.Vertices);
            geometry.Flags         |= GeometryFlags.Flag80000000;

            return(geometry);
        }
Пример #3
0
        /// <summary>
        /// Update the camera parameters.
        /// </summary>
        protected virtual void UpdateCamera()
        {
            // Capture/release mouse when the button is pressed/released
            if (Input.IsMouseButtonPressed(MouseButton.Right))
            {
                Input.LockMousePosition();
            }
            else if (Input.IsMouseButtonReleased(MouseButton.Right))
            {
                Input.UnlockMousePosition();
            }

            // Update rotation according to mouse deltas
            var rotationDelta = Vector2.Zero;

            if (Input.IsMouseButtonDown(MouseButton.Right))
            {
                rotationDelta = Input.MouseDelta;
            }

            var doubleTapped = false;

            foreach (var gestureEvent in Input.GestureEvents)
            {
                switch (gestureEvent.Type)
                {
                case GestureType.Drag:
                {
                    var drag = (GestureEventDrag)gestureEvent;
                    rotationDelta = drag.DeltaTranslation;
                }
                break;

                case GestureType.Flick:
                    break;

                case GestureType.LongPress:
                    break;

                case GestureType.Composite:
                    break;

                case GestureType.Tap:
                {
                    doubleTapped = true;
                }
                break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }

            // Change rotation only if changed at least once (try to keep original one)
            if (rotationDelta != Vector2.Zero)
            {
                applyRotation = true;
            }

            // Compute translation speed according to framerate and modifiers
            var translationSpeed = MoveSpeed * (float)Game.UpdateTime.Elapsed.TotalSeconds;

            var oldPitch = Pitch;

            // Take shortest path
            var deltaPitch = desiredPitch - Pitch;
            var deltaYaw   = (desiredYaw - Yaw) % MathUtil.TwoPi;

            if (deltaYaw < 0)
            {
                deltaYaw += MathUtil.TwoPi;
            }
            if (deltaYaw > MathUtil.Pi)
            {
                deltaYaw -= MathUtil.TwoPi;
            }
            desiredYaw = Yaw + deltaYaw;

            // Perform orientation transition
            var rotationAdaptation = (float)Game.UpdateTime.Elapsed.TotalSeconds * RotationAdaptationSpeed;

            Yaw   = Math.Abs(deltaYaw) < rotationAdaptation ? desiredYaw : Yaw + rotationAdaptation * Math.Sign(deltaYaw);
            Pitch = Math.Abs(deltaPitch) < rotationAdaptation ? desiredPitch : Pitch + rotationAdaptation * Math.Sign(deltaPitch);

            desiredYaw   = Yaw -= 1.333f * rotationDelta.X * RotationSpeed; // we want to rotate faster Horizontally and Vertically
            desiredPitch = Pitch = MathUtil.Clamp(Pitch - rotationDelta.Y * RotationSpeed, -MathUtil.PiOverTwo, MathUtil.PiOverTwo);

            if (!RotationOnly)
            {
                // Compute base vectors for camera movement
                var rotation = Matrix.RotationYawPitchRoll(Yaw, Pitch, 0);
                var forward  = Vector3.TransformNormal(ForwardVector, rotation);
                var up       = Vector3.TransformNormal(UpVector, rotation);
                var right    = Vector3.Cross(forward, up);

                // Update camera move: Dolly (WADS model/arrow keys)
                var movePosition = Vector3.Zero;
                if (Input.IsKeyDown(Keys.A) || Input.IsKeyDown(Keys.Left))
                {
                    movePosition += -right;
                }
                if (Input.IsKeyDown(Keys.D) || Input.IsKeyDown(Keys.Right))
                {
                    movePosition += right;
                }
                if (Input.IsKeyDown(Keys.S) || Input.IsKeyDown(Keys.Down))
                {
                    movePosition += Component.Projection == CameraProjectionMode.Perspective ? -forward : -up;
                }
                if (Input.IsKeyDown(Keys.W) || Input.IsKeyDown(Keys.Up) || doubleTapped)
                {
                    movePosition += Component.Projection == CameraProjectionMode.Perspective ? forward : up;
                }
                if (Input.IsKeyDown(Keys.Q))
                {
                    movePosition += Component.Projection == CameraProjectionMode.Perspective ? -up : -forward;
                }
                if (Input.IsKeyDown(Keys.E))
                {
                    movePosition += Component.Projection == CameraProjectionMode.Perspective ? up : forward;
                }

                position += (Vector3.Normalize(movePosition) * translationSpeed);

                if (doubleTapped)
                {
                    desiredPitch = Pitch = oldPitch;
                    desiredYaw   = Yaw;

                    forward = -Vector3.Transform(ForwardVector, Quaternion.RotationYawPitchRoll(Yaw, Pitch, 0));
                    var projectedForward = Vector3.Normalize(new Vector3(forward.X, 0, forward.Z));
                    position -= projectedForward * translationSpeed * MouseMoveSpeedFactor;
                }
            }

            // Update the camera view matrix
            UpdateViewMatrix();
        }
Пример #4
0
        /// <summary>
        /// CollDetectSphereStaticMeshSweep
        /// </summary>
        /// <param name="oldSphere"></param>
        /// <param name="newSphere"></param>
        /// <param name="mesh"></param>
        /// <param name="info"></param>
        /// <param name="collTolerance"></param>
        /// <param name="collisionFunctor"></param>
        internal static void CollDetectSphereStaticMeshSweep(BoundingSphere oldSphere, BoundingSphere newSphere, TriangleMesh mesh,
                                                             CollDetectInfo info, float collTolerance, CollisionFunctor collisionFunctor)
        {
            // really use a swept test - or overlap?
            Vector3 delta = newSphere.Center - oldSphere.Center;

            if (delta.LengthSquared < (0.25f * newSphere.Radius * newSphere.Radius))
            {
                CollDetectSphereStaticMeshOverlap(oldSphere, newSphere, mesh, info, collTolerance, collisionFunctor);
            }
            else
            {
                Vector3 body0Pos = (info.Skin0.Owner != null) ? info.Skin0.Owner.OldPosition : Vector3.Zero;
                Vector3 body1Pos = (info.Skin1.Owner != null) ? info.Skin1.Owner.OldPosition : Vector3.Zero;

                float sphereTolR = collTolerance + oldSphere.Radius;
                float sphereToR2 = sphereTolR * sphereTolR;

                Vector3 collNormal = Vector3.Zero;

                BoundingBox bb = BoundingBoxHelper.InitialBox;
                BoundingBoxHelper.AddSphere(oldSphere, ref bb);
                BoundingBoxHelper.AddSphere(newSphere, ref bb);

                // get the spheres centers in triangle mesh space
                Vector3 newSphereCen = Vector3.Transform(newSphere.Center, mesh.InverseTransformMatrix);
                Vector3 oldSphereCen = Vector3.Transform(oldSphere.Center, mesh.InverseTransformMatrix);

                unsafe
                {
#if USE_STACKALLOC
                    SmallCollPointInfo *collPts = stackalloc SmallCollPointInfo[MaxLocalStackSCPI];
                    int *potentialTriangles     = stackalloc int[MaxLocalStackTris];
                    {
                        {
#else
                    SmallCollPointInfo[] collPtArray = SCPIStackAlloc();
                    fixed(SmallCollPointInfo *collPts = collPtArray)
                    {
                        int[] potTriArray = IntStackAlloc();
                        fixed(int *potentialTriangles = potTriArray)
                        {
#endif
                            int numCollPts = 0;

                            int numTriangles = mesh.GetTrianglesIntersectingtAABox(potentialTriangles, MaxLocalStackTris, ref bb);

                            for (int iTriangle = 0; iTriangle < numTriangles; ++iTriangle)
                            {
                                // first test the old sphere for being on the wrong side
                                IndexedTriangle meshTriangle    = mesh.GetTriangle(potentialTriangles[iTriangle]);
                                float           distToCentreOld = meshTriangle.Plane.DotCoordinate(oldSphereCen);
                                if (distToCentreOld <= 0.0f)
                                {
                                    continue;
                                }
                                // now test the new sphere for being clear

                                float distToCentreNew = meshTriangle.Plane.DotCoordinate(newSphereCen);
                                if (distToCentreNew > sphereTolR)
                                {
                                    continue;
                                }

                                int i0, i1, i2;
                                meshTriangle.GetVertexIndices(out i0, out i1, out i2);

                                Triangle triangle = new Triangle(mesh.GetVertex(i0), mesh.GetVertex(i1), mesh.GetVertex(i2));

                                // If the old sphere is intersecting, just use that result
                                float s, t;
                                float d2 = Distance.PointTriangleDistanceSq(out s, out t, oldSphereCen, triangle);

                                if (d2 < sphereToR2)
                                {
                                    float   dist      = (float)System.Math.Sqrt(d2);
                                    float   depth     = oldSphere.Radius - dist;
                                    Vector3 triangleN = triangle.Normal;
                                    Vector3 normSafe  = oldSphereCen - triangle.GetPoint(s, t);

                                    JiggleMath.NormalizeSafe(ref normSafe);

                                    Vector3 collisionN = (dist > float.Epsilon) ? normSafe : triangleN;
                                    // since impulse gets applied at the old position
                                    Vector3 pt = oldSphere.Center - oldSphere.Radius * collisionN;
                                    if (numCollPts < MaxLocalStackSCPI)
                                    {
                                        // BEN-OPTIMISATION: Reuse existing collPts.
                                        collPts[numCollPts].R0 = pt - body0Pos;
                                        collPts[numCollPts].R1 = pt - body1Pos;
                                        collPts[numCollPts++].InitialPenetration = depth;
                                    }
                                    collNormal += collisionN;
                                }
                                else if (distToCentreNew < distToCentreOld)
                                {
                                    // old sphere is not intersecting - do a sweep, but only if the sphere is moving into the
                                    // triangle
                                    Vector3 pt, N; // CHECK THIS
                                    float   depth;
                                    if (Intersection.SweptSphereTriangleIntersection(out pt, out N, out depth, oldSphere, newSphere, triangle,
                                                                                     distToCentreOld, distToCentreNew, Intersection.EdgesToTest.EdgeAll, Intersection.CornersToTest.CornerAll))
                                    {
                                        // collision point etc must be relative to the old position because that's
                                        //where the impulses are applied
                                        float   dist      = (float)System.Math.Sqrt(d2);
                                        float   depth2    = oldSphere.Radius - dist;
                                        Vector3 triangleN = triangle.Normal;
                                        Vector3 normSafe  = oldSphereCen - triangle.GetPoint(s, t);
                                        JiggleMath.NormalizeSafe(ref normSafe);
                                        Vector3 collisionN = (dist > JiggleMath.Epsilon) ? normSafe : triangleN;
                                        // since impulse gets applied at the old position
                                        Vector3 pt2 = oldSphere.Center - oldSphere.Radius * collisionN;
                                        if (numCollPts < MaxLocalStackSCPI)
                                        {
                                            // BEN-OPTIMISATION: Reuse existing collPts.
                                            collPts[numCollPts].R0 = pt2 - body0Pos;
                                            collPts[numCollPts].R1 = pt2 - body1Pos;
                                            collPts[numCollPts++].InitialPenetration = depth;
                                        }
                                        collNormal += collisionN;
                                    }
                                }
                            }
                            if (numCollPts > 0)
                            {
                                JiggleMath.NormalizeSafe(ref collNormal);
                                collisionFunctor.CollisionNotify(ref info, ref collNormal, collPts, numCollPts);
                            }
                        }

#if USE_STACKALLOC
                    }
                }
#else
                        FreeStackAlloc(potTriArray);
                    }

                    FreeStackAlloc(collPtArray);
                }
#endif
            }
        }
Пример #5
0
        protected void moveShips(float timeElapsed)
        {
            if (timeElapsed <= 0f)
            {
                return;
            }

            // make the target drone move from side to side
            localTime += timeElapsed;
            Vector3 pos = targetDrone.Pos;

            pos.Z           = 30f * (float)Math.Sin(localTime);
            targetDrone.Pos = pos;

            // make the vandal ship orbit missile target
            Vector3 desiredPos;
            Vector3 desiredDir;
            float   angle          = localTime * 0.5f;
            float   desiredXOffset = 100f * (float)Math.Cos(angle);
            float   desiredYOffset = 20f * (float)Math.Sin(angle * 0.77f);
            float   desiredZOffset = 80f * (float)Math.Sin(angle * 0.88f);
            Vector3 desiredOffset  = new Vector3(desiredXOffset, desiredYOffset, desiredZOffset);

            var target = getTargetObject();

            if (missileLauncher != MissileLaunchers.VandalShip || target == null || target == vandalShip)
            {
                desiredPos = new Vector3(100f, 0f, 0f);
                desiredDir = -Vector3.UnitX;
            }
            else if (target == main3dScene.ActiveCamera)
            {
                desiredPos = main3dScene.ActiveCamera.Pos + -main3dScene.ActiveCamera.Dir * 300f;
                Quaternion cameraOrient = OpenTKHelper.neededRotation(Vector3.UnitZ, -main3dScene.ActiveCamera.Up);
                desiredPos += Vector3.Transform(desiredOffset * 0.1f, cameraOrient);
                desiredDir  = (target.Pos - vandalShip.Pos).Normalized();
            }
            else
            {
                //float desiredZOffset = 5f * (float)Math.Sin(angle + 0.2f);
                desiredPos = target.Pos + desiredOffset;
                desiredDir = (target.Pos - vandalShip.Pos).Normalized();
            }

            Vector3     desiredMotion = desiredPos - vandalShip.Pos;
            const float vel           = 100f;
            float       displacement  = vel * timeElapsed;
            Vector3     vandalNewPos;

            if (displacement > desiredMotion.LengthFast)
            {
                vandalNewPos = desiredPos;
            }
            else
            {
                vandalNewPos = vandalShip.Pos + desiredMotion.Normalized() * displacement;
            }

            vandalVelocity = (vandalNewPos - vandalShip.Pos) / timeElapsed;
            vandalShip.Pos = vandalNewPos;

            Quaternion vandalOrient = OpenTKHelper.neededRotation(Vector3.UnitZ, desiredDir);

            vandalShip.Orient(desiredDir, Vector3.Transform(Vector3.UnitY, vandalOrient));
        }
Пример #6
0
 public bool MouseIsIn(Vector3 m)
 {
     Vector3 mm = m.Transform (transformationsInverse);
     return Bounds.ContainsOrIsEqual (new Point<float> (mm.X, mm.Y));
 }
Пример #7
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            //Update the form collection
            FormCollection.Update(gameTime);

            KeyboardState keybState = Keyboard.GetState();

            if (keybState.IsKeyDown(Keys.LeftShift) || keybState.IsKeyDown(Keys.RightShift))
            {
                //il giro in 4 secondi => PI/2 al secondo
                float rads = (float)(gameTime.ElapsedGameTime.TotalSeconds * (Math.PI / 2));

                if (keybState.IsKeyDown(Keys.A))
                {
                    StatusCurrent.DirectionalLight0Direction =
                        Vector3.Transform(StatusCurrent.DirectionalLight0Direction, Matrix.CreateRotationY(rads));
                }
                if (keybState.IsKeyDown(Keys.D))
                {
                    StatusCurrent.DirectionalLight0Direction =
                        Vector3.Transform(StatusCurrent.DirectionalLight0Direction, Matrix.CreateRotationY(-rads));
                }

                if (keybState.IsKeyDown(Keys.W))
                {
                    StatusCurrent.DirectionalLight0Direction =
                        Vector3.Transform(StatusCurrent.DirectionalLight0Direction, Matrix.CreateRotationX(rads));
                }
                if (keybState.IsKeyDown(Keys.S))
                {
                    StatusCurrent.DirectionalLight0Direction =
                        Vector3.Transform(StatusCurrent.DirectionalLight0Direction, Matrix.CreateRotationX(-rads));
                }
            }
            if (keybState.IsKeyDown(Keys.LeftShift) || keybState.IsKeyDown(Keys.RightShift))
            {
                //il giro in 4 secondi => PI/2 al secondo
                float rads = (float)(gameTime.ElapsedGameTime.TotalSeconds * (Math.PI / 2));

                if (keybState.IsKeyDown(Keys.A))
                {
                    StatusCurrent.DirectionalLight0Direction =
                        Vector3.Transform(StatusCurrent.DirectionalLight0Direction, Matrix.CreateRotationY(rads));
                }
                if (keybState.IsKeyDown(Keys.D))
                {
                    StatusCurrent.DirectionalLight0Direction =
                        Vector3.Transform(StatusCurrent.DirectionalLight0Direction, Matrix.CreateRotationY(-rads));
                }

                if (keybState.IsKeyDown(Keys.W))
                {
                    StatusCurrent.DirectionalLight0Direction =
                        Vector3.Transform(StatusCurrent.DirectionalLight0Direction, Matrix.CreateRotationX(rads));
                }
                if (keybState.IsKeyDown(Keys.S))
                {
                    StatusCurrent.DirectionalLight0Direction =
                        Vector3.Transform(StatusCurrent.DirectionalLight0Direction, Matrix.CreateRotationX(-rads));
                }
            }
            else
            {
                if (keybState.IsKeyDown(Keys.F1))
                {
                    StatusCurrent.TransparentSide = TraspSide.InFrontOfWhite;
                }
                if (keybState.IsKeyDown(Keys.F2))
                {
                    StatusCurrent.TransparentSide = TraspSide.RightOfWhite;
                }
                if (keybState.IsKeyDown(Keys.F3))
                {
                    StatusCurrent.TransparentSide = TraspSide.InFrontOfBlack;
                }
                if (keybState.IsKeyDown(Keys.F4))
                {
                    StatusCurrent.TransparentSide = TraspSide.RightOfBlack;
                }
                //if (keybState.IsKeyDown(Keys.F11))
                //    StatusCurrent.AlphaTransparency = false;
                //if (keybState.IsKeyDown(Keys.F12))
                //    StatusCurrent.AlphaTransparency = true;
            }

            //Matrix.cre

            base.Update(gameTime);
        }
Пример #8
0
        public void Update(float currentTime, ElapsedTime elapsedTime)
        {
            windDisplacementX = viewer.Simulator.Weather.WindSpeedMpS.X * 0.25f;
            windDisplacementZ = viewer.Simulator.Weather.WindSpeedMpS.Y * 0.25f;

            var velocity = WorldPosition.Location - LastWorldPosition.Location;

            velocity.X += (WorldPosition.TileX - LastWorldPosition.TileX) * 2048;
            velocity.Z += (WorldPosition.TileZ - LastWorldPosition.TileZ) * 2048;
            velocity.Z *= -1;
            velocity   /= elapsedTime.ClockSeconds;
            LastWorldPosition.Location = WorldPosition.Location;
            LastWorldPosition.TileX    = WorldPosition.TileX;
            LastWorldPosition.TileZ    = WorldPosition.TileZ;

            RetireActiveParticles(currentTime);
            FreeRetiredParticles();

            if (ParticlesPerSecond < 0.1)
            {
                TimeParticlesLastEmitted = currentTime;
            }

            var numToBeEmitted  = (int)((currentTime - TimeParticlesLastEmitted) * ParticlesPerSecond);
            var numCanBeEmitted = GetCountFreeParticles();
            var numToEmit       = Math.Min(numToBeEmitted, numCanBeEmitted);

            if (numToEmit > 0)
            {
                var rotation = WorldPosition.XNAMatrix;
                rotation.Translation = Vector3.Zero;

                var position = Vector3.Transform(EmitterData.XNALocation, rotation) + WorldPosition.XNAMatrix.Translation;
                var globalInitialVelocity = Vector3.Transform(XNAInitialVelocity, rotation) + velocity;
                // TODO: This should only be rotated about the Y axis and not get fully rotated.
                var globalTargetVelocity = Vector3.Transform(XNATargetVelocity, rotation);

                var time = TimeParticlesLastEmitted;

                for (var i = 0; i < numToEmit; i++)
                {
                    time += 1 / ParticlesPerSecond;

                    var particle     = (FirstFreeParticle + 1) % MaxParticles;
                    var vertex       = particle * VerticiesPerParticle;
                    var texture      = Viewer.Random.Next(16); // Randomizes emissions.
                    var color_Random = new Color((float)ParticleColor.R / 255f, (float)ParticleColor.G / 255f, (float)ParticleColor.B / 255f, (float)Viewer.Random.NextDouble());

                    // Initial velocity varies in X and Z only.
                    var initialVelocity = globalInitialVelocity;
                    initialVelocity.X += (float)(Viewer.Random.NextDouble() - 0.5f) * ParticleEmitterViewer.InitialSpreadRate;
                    initialVelocity.Z += (float)(Viewer.Random.NextDouble() - 0.5f) * ParticleEmitterViewer.InitialSpreadRate;

                    // Target/final velocity vaies in X, Y and Z.
                    var targetVelocity = globalTargetVelocity;
                    targetVelocity.X += Noise.Generate(time + PerlinStart[0]) * ParticleEmitterViewer.SpreadRate;
                    targetVelocity.Y += Noise.Generate(time + PerlinStart[1]) * ParticleEmitterViewer.SpreadRate;
                    targetVelocity.Z += Noise.Generate(time + PerlinStart[2]) * ParticleEmitterViewer.SpreadRate;

                    // Add wind speed
                    targetVelocity.X += windDisplacementX;
                    targetVelocity.Z += windDisplacementZ;

                    // ActionDuration is variable too.
                    var duration = ParticleDuration * (1 + Noise.Generate(time + PerlinStart[3]) * ParticleEmitterViewer.DurationVariation);

                    for (var j = 0; j < VerticiesPerParticle; j++)
                    {
                        Vertices[vertex + j].StartPosition_StartTime   = new Vector4(position, time);
                        Vertices[vertex + j].InitialVelocity_EndTime   = new Vector4(initialVelocity, time + duration);
                        Vertices[vertex + j].TargetVelocity_TargetTime = new Vector4(targetVelocity, ParticleEmitterViewer.DecelerationTime);
                        Vertices[vertex + j].TileXY_Vertex_ID          = new Vector4(WorldPosition.TileX, WorldPosition.TileZ, j, texture);
                        Vertices[vertex + j].Color_Random = color_Random;
                    }

                    FirstFreeParticle = particle;
                }

                TimeParticlesLastEmitted = time;
            }
        }
        protected override void DoRender()
        {
            // Early exit
            if (Lights.Count == 0)
            {
                return;
            }

            // Retrieve device context
            var context = this.DeviceManager.Direct3DContext;

            // backup existing context state
            int       oldStencilRef = 0;
            RawColor4 oldBlendFactor;
            int       oldSampleMaskRef;

            using (var oldVertexLayout = context.InputAssembler.InputLayout)
                using (var oldPixelShader = context.PixelShader.Get())
                    using (var oldVertexShader = context.VertexShader.Get())
                        using (var oldBlendState = context.OutputMerger.GetBlendState(out oldBlendFactor, out oldSampleMaskRef))
                            using (var oldDepthState = context.OutputMerger.GetDepthStencilState(out oldStencilRef))
                                using (var oldRSState = context.Rasterizer.State)
                                {
                                    // Assign shader resources - TODO: create array in CreateDeviceDependentResources instead
                                    context.PixelShader.SetShaderResources(0, gbuffer.SRVs.ToArray().Concat(new[] { gbuffer.DSSRV }).ToArray());

                                    // Assign the additive blend state
                                    context.OutputMerger.BlendState = blendStateAdd;

                                    // Retrieve camera parameters
                                    SharpDX.FrustumCameraParams cameraParams = Frustum.GetCameraParams();

                                    // For each configured light
                                    for (var i = 0; i < Lights.Count; i++)
                                    {
                                        PerLight light = Lights[i];

                                        PixelShader shader = null; // Assign shader
                                        if (light.Type == LightType.Ambient)
                                        {
                                            shader = psAmbientLight;
                                        }
                                        else if (light.Type == LightType.Directional)
                                        {
                                            shader = psDirectionalLight;
                                        }
                                        else if (light.Type == LightType.Point)
                                        {
                                            shader = psPointLight;
                                        }
                                        //else if (light.Type == LightType.Spot)
                                        //    shader = psSpotLight;

                                        // Update the perLight constant buffer
                                        // Calculate view space position (for frustum checks)
                                        Vector3 lightDir     = Vector3.Normalize(Lights[i].Direction);
                                        Vector4 viewSpaceDir = Vector3.Transform(lightDir, PerObject.View);
                                        light.Direction = new Vector3(viewSpaceDir.X, viewSpaceDir.Y, viewSpaceDir.Z);
                                        Vector4 viewSpacePos = Vector3.Transform(Lights[i].Position, PerObject.View);
                                        light.Position = new Vector3(viewSpacePos.X, viewSpacePos.Y, viewSpacePos.Z);

                                        context.UpdateSubresource(ref light, perLightBuffer);
                                        context.PixelShader.SetConstantBuffer(4, perLightBuffer);

                                        light.Position  = Lights[i].Position;
                                        light.Direction = Lights[i].Direction;

                                        // Check if the light should be considered full screen
                                        bool isFullScreen = light.Type == LightType.Directional ||
                                                            light.Type == LightType.Ambient;
                                        if (!isFullScreen)
                                        {
                                            isFullScreen = (cameraParams.ZNear > viewSpacePos.Z - light.Range &&
                                                            cameraParams.ZFar < viewSpacePos.Z + light.Range);
                                        }
                                        if (isFullScreen)
                                        {
                                            context.OutputMerger.DepthStencilState = depthDisabled;
                                            // Use SAQuad
                                            saQuad.ShaderResources = null;
                                            saQuad.Shader          = shader;
                                            saQuad.Render();
                                        }
                                        else // Render volume
                                        {
                                            context.PixelShader.Set(shader);
                                            context.VertexShader.Set(vertexShader);

                                            Matrix world = Matrix.Identity;

                                            MeshRenderer volume = null;;
                                            switch (light.Type)
                                            {
                                            case LightType.Point:
                                                // Prepare world matrix
                                                // Ensure no abrupt light edges with +50%
                                                world.ScaleVector = Vector3.One * light.Range * 1.5f;
                                                volume            = pointLightVolume;
                                                break;

                                            /* TODO: Spot light support
                                             * case LightType.Spot:
                                             *  // Determine rotation!
                                             *  var D = Vector3.Normalize(light.Direction);
                                             *  var s1 = Vector3.Cross(D, Vector3.UnitZ);
                                             *  var s2 = Vector3.Cross(D, Vector3.UnitY);
                                             *  Vector3 S;
                                             *  if (s1.LengthSquared() > s2.LengthSquared())
                                             *      S = s1;
                                             *  else
                                             *      S = s2;
                                             *  var U = Vector3.Cross(D, S);
                                             *  Matrix rotate = Matrix.Identity;
                                             *  rotate.Forward = D;
                                             *  rotate.Down = U;
                                             *  rotate.Left = S;
                                             *
                                             *  float scaleZ = light.Range;
                                             *  // Need to Abs - if negative it will invert our model and result in incorrect normals
                                             *  float scaleXY = light.Range * Math.Abs((float)Math.Tan(Math.Acos(light.SpotOuterCosine*2)/2));
                                             *
                                             *  world.ScaleVector = new Vector3(scaleXY, scaleXY, scaleZ);
                                             *  world *= rotate;
                                             *  volume = spotLightVolume;
                                             *  break;
                                             * */
                                            default:
                                                continue;
                                            }
                                            world.TranslationVector = light.Position;
                                            volume.World            = world;
                                            // Transpose the PerObject matrices
                                            var transposed = PerObject;
                                            transposed.World = volume.World;
                                            transposed.WorldViewProjection = volume.World * PerObject.ViewProjection;
                                            transposed.Transpose();
                                            context.UpdateSubresource(ref transposed, PerObjectBuffer);

                                            if (cameraParams.ZFar < viewSpacePos.Z + light.Range)
                                            {
                                                // Cull the back face and only render where there is something
                                                // behind the front face.
                                                context.Rasterizer.State = rsCullBack;
                                                context.OutputMerger.DepthStencilState = depthLessThan;
                                            }
                                            else
                                            {
                                                // Cull front faces and only render where there is something
                                                // before the back face.
                                                context.Rasterizer.State = rsCullFront;
                                                context.OutputMerger.DepthStencilState = depthGreaterThan;
                                            }
                                            volume.Render();

                                            // Show the light volumes for debugging
                                            if (Debug > 0)
                                            {
                                                if (Debug == 1)
                                                {
                                                    context.OutputMerger.SetDepthStencilState(depthGreaterThan);
                                                }
                                                else
                                                {
                                                    context.OutputMerger.SetDepthStencilState(depthLessThan);
                                                }
                                                context.PixelShader.Set(psDebugLight);
                                                context.Rasterizer.State = rsWireframe;
                                                volume.Render();
                                            }
                                        }
                                    }

                                    // Reset pixel shader resources (all to null)
                                    context.PixelShader.SetShaderResources(0, new ShaderResourceView[gbuffer.SRVs.Count + 1]);

                                    // Restore context states
                                    context.PixelShader.Set(oldPixelShader);
                                    context.VertexShader.Set(oldVertexShader);
                                    context.InputAssembler.InputLayout = oldVertexLayout;
                                    context.OutputMerger.SetBlendState(oldBlendState, oldBlendFactor, oldSampleMaskRef);
                                    context.OutputMerger.SetDepthStencilState(oldDepthState, oldStencilRef);
                                    context.Rasterizer.State = oldRSState;
                                }
        }
Пример #10
0
 public virtual void DebugDraw(ref Matrix drawMatrix)
 {
     if (MyDebugDrawSettings.ENABLE_DEBUG_DRAW)
     {
         if (MyDebugDrawSettings.DEBUG_DRAW_NAVMESHES != MyWEMDebugDrawMode.NONE)
         {
             this.m_mesh.DebugDraw(ref drawMatrix, MyDebugDrawSettings.DEBUG_DRAW_NAVMESHES);
             this.m_mesh.CustomDebugDrawFaces(ref drawMatrix, MyDebugDrawSettings.DEBUG_DRAW_NAVMESHES, obj => (obj as MyNavigationTriangle).Index.ToString());
         }
         if (MyFakes.DEBUG_DRAW_FUNNEL)
         {
             List <Vector3> .Enumerator enumerator;
             MyRenderProxy.DebugDrawSphere(Vector3.Transform(this.m_vertex, (Matrix)drawMatrix), 0.05f, Color.Yellow.ToVector3(), 1f, false, false, true, false);
             MyRenderProxy.DebugDrawSphere(Vector3.Transform(this.m_vertex + this.m_normal, (Matrix)drawMatrix), 0.05f, Color.Orange.ToVector3(), 1f, false, false, true, false);
             MyRenderProxy.DebugDrawSphere(Vector3.Transform(this.m_left, (Matrix)drawMatrix), 0.05f, Color.Red.ToVector3(), 1f, false, false, true, false);
             Color green = Color.Green;
             MyRenderProxy.DebugDrawSphere(Vector3.Transform(this.m_right, (Matrix)drawMatrix), 0.05f, green.ToVector3(), 1f, false, false, true, false);
             using (enumerator = m_debugPointsLeft.GetEnumerator())
             {
                 while (enumerator.MoveNext())
                 {
                     green = Color.Red;
                     MyRenderProxy.DebugDrawSphere(Vector3.Transform(enumerator.Current, (Matrix)drawMatrix), 0.03f, green.ToVector3(), 1f, false, false, true, false);
                 }
             }
             using (enumerator = m_debugPointsRight.GetEnumerator())
             {
                 while (enumerator.MoveNext())
                 {
                     green = Color.Green;
                     MyRenderProxy.DebugDrawSphere(Vector3.Transform(enumerator.Current, (Matrix)drawMatrix), 0.04f, green.ToVector3(), 1f, false, false, true, false);
                 }
             }
             Vector3?nullable = null;
             if (m_path != null)
             {
                 using (enumerator = m_path.GetEnumerator())
                 {
                     while (enumerator.MoveNext())
                     {
                         Vector3 vector = Vector3.Transform(enumerator.Current, (Matrix)drawMatrix);
                         MyRenderProxy.DebugDrawSphere(vector + (Vector3.Up * 0.2f), 0.02f, Color.Orange.ToVector3(), 1f, false, false, true, false);
                         if (nullable != null)
                         {
                             MyRenderProxy.DebugDrawLine3D(nullable.Value + (Vector3.Up * 0.2f), vector + (Vector3.Up * 0.2f), Color.Orange, Color.Orange, true, false);
                         }
                         nullable = new Vector3?(vector);
                     }
                 }
             }
             nullable = null;
             if (m_path2 != null)
             {
                 using (enumerator = m_path2.GetEnumerator())
                 {
                     while (enumerator.MoveNext())
                     {
                         Vector3 vector2 = Vector3.Transform(enumerator.Current, (Matrix)drawMatrix);
                         if (nullable != null)
                         {
                             MyRenderProxy.DebugDrawLine3D(nullable.Value + (Vector3.Up * 0.1f), vector2 + (Vector3.Up * 0.1f), Color.Violet, Color.Violet, true, false);
                         }
                         nullable = new Vector3?(vector2);
                     }
                 }
             }
             if (m_debugFunnel.Count > 0)
             {
                 FunnelState local2  = m_debugFunnel[m_debugFunnelIdx % m_debugFunnel.Count];
                 Vector3     vector3 = Vector3.Transform(local2.Apex, (Matrix)drawMatrix);
                 Vector3     vector4 = vector3 + ((Vector3.Transform(local2.Left, (Matrix)drawMatrix) - vector3) * 10f);
                 Vector3     vector5 = vector3 + ((Vector3.Transform(local2.Right, (Matrix)drawMatrix) - vector3) * 10f);
                 Color       cyan    = Color.Cyan;
                 MyRenderProxy.DebugDrawLine3D(vector3 + (Vector3.Up * 0.1f), vector4 + (Vector3.Up * 0.1f), cyan, cyan, true, false);
                 MyRenderProxy.DebugDrawLine3D(vector3 + (Vector3.Up * 0.1f), vector5 + (Vector3.Up * 0.1f), cyan, cyan, true, false);
             }
         }
     }
 }
Пример #11
0
 public void Transform(Matrix transform)
 {
     this.Center      = Vector3.Transform(this.Center, transform);
     this.Orientation = Quaternion.CreateFromRotationMatrix(transform);
 }
Пример #12
0
Файл: Map.cs Проект: MyEyes/BGJ5
        public int CreateShadowGeometry(Vector2 pos, Rectangle viewSpace, VertexBuffer shadowVB)
        {
            Vector2   center   = pos;
            Rectangle drawRect = viewSpace;
            //Calculate minimal and maximal tile index to consider for shadow calculation
            int minX = (int)((pos.X - drawRect.Width / 2) / TileSize);

            minX = minX >= 0 ? minX : 0;
            int minY = (int)((pos.Y - drawRect.Height / 2) / TileSize);

            minY = minY >= 0 ? minY : 0;
            int maxX = (drawRect.Width + drawRect.X) / TileSize + 1;

            maxX = maxX < _tiles[1].GetLength(0) ? maxX : _tiles[1].GetLength(0);
            int maxY = (drawRect.Height + drawRect.Y) / TileSize + 1;

            maxY = maxY < _tiles[1].GetLength(1) ? maxY : _tiles[1].GetLength(1);
            //Count vertices to make sure we fit everything into our vertex buffer
            int vertexCount = 0;

            //Iterate over all tiles we need to consider, this method is slower than using a BSP tree or something
            //But it is sufficient for this game
            //48,24
            for (int x = minX; x < maxX; x++)
            {
                for (int y = minY; y < maxY; y++)
                {
                    //Check if there's a tile here and wether we have drawn this rect already
                    if (_tiles[1][x, y] != null)
                    {
                        //Set up helper values
                        //Offset for the diagonal of the rectangle
                        Vector2 tileSizeVec = Vector2.Zero; // new Vector2(_tiles[1][x, y].Geometry.BoundingRect.Width * 0.5f, _tiles[1][x, y].Geometry.BoundingRect.Height * 0.5f);
                        //mid point of the rectangle, this way we can directly compute the corners over the diagonals
                        Vector2 midPoint = Vector2.Zero;    // new Vector2(_tiles[1][x, y].Geometry.BoundingRect.Center.X, _tiles[1][x, y].Geometry.BoundingRect.Center.Y);
                        //vector from light source to rectangles center to calculate which edges are facing away from light source

                        tileSizeVec = new Vector2(_tiles[1][x, y].TargetRect.Width * 0.5f, _tiles[1][x, y].TargetRect.Height * 0.5f);
                        midPoint    = new Vector2(_tiles[1][x, y].TargetRect.Center.X, _tiles[1][x, y].TargetRect.Center.Y);

                        Vector3 diff = new Vector3(midPoint - center, 0);
                        Vector3 edge1, edge2, edge3, edge4;
                        //Find a sensible order for the 4 edges, sort them so that if you only take the first 3 edges the left out side is closest to the center of the rectangle
                        //This simplifies the shadow geometry calculation a lot
                        //Note: This seems like a lot of code, but it's just 2 branches and 4 vector 3 creators

                        /*        2*                         3*
                         *
                         *
                         *
                         *
                         *        1*                         4*
                         *                      x
                         *
                         * diff.X/tileSizeVec.X > diff.Y/tileSizeVec.Y
                         */

                        float depth = 0.5f;
                        if (diff.X * tileSizeVec.Y > diff.Y * tileSizeVec.X)
                        {
                            if (diff.X * tileSizeVec.Y > -diff.Y * tileSizeVec.X)
                            {
                                edge1 = new Vector3(midPoint + new Vector2(-tileSizeVec.X, -tileSizeVec.Y), depth); //1
                                edge2 = new Vector3(midPoint + new Vector2(tileSizeVec.X, -tileSizeVec.Y), depth);  //2
                                edge3 = new Vector3(midPoint + new Vector2(tileSizeVec.X, tileSizeVec.Y), depth);   //3
                                edge4 = new Vector3(midPoint + new Vector2(-tileSizeVec.X, tileSizeVec.Y), depth);  //4
                            }
                            else
                            {
                                edge1 = new Vector3(midPoint + new Vector2(-tileSizeVec.X, tileSizeVec.Y), depth);  //4
                                edge2 = new Vector3(midPoint + new Vector2(-tileSizeVec.X, -tileSizeVec.Y), depth); //1
                                edge3 = new Vector3(midPoint + new Vector2(tileSizeVec.X, -tileSizeVec.Y), depth);  //2
                                edge4 = new Vector3(midPoint + new Vector2(tileSizeVec.X, tileSizeVec.Y), depth);   //3
                            }
                        }
                        else
                        {
                            if (diff.X * tileSizeVec.Y > -diff.Y * tileSizeVec.X)
                            {
                                edge1 = new Vector3(midPoint + new Vector2(tileSizeVec.X, -tileSizeVec.Y), depth);  //2
                                edge2 = new Vector3(midPoint + new Vector2(tileSizeVec.X, tileSizeVec.Y), depth);   //3
                                edge3 = new Vector3(midPoint + new Vector2(-tileSizeVec.X, tileSizeVec.Y), depth);  //4
                                edge4 = new Vector3(midPoint + new Vector2(-tileSizeVec.X, -tileSizeVec.Y), depth); //1
                            }
                            else
                            {
                                edge1 = new Vector3(midPoint + new Vector2(tileSizeVec.X, tileSizeVec.Y), depth);   //3
                                edge2 = new Vector3(midPoint + new Vector2(-tileSizeVec.X, tileSizeVec.Y), depth);  //4
                                edge3 = new Vector3(midPoint + new Vector2(-tileSizeVec.X, -tileSizeVec.Y), depth); //1
                                edge4 = new Vector3(midPoint + new Vector2(tileSizeVec.X, -tileSizeVec.Y), depth);  //2
                            }
                        }
                        Vector3 dir1;
                        Vector3 dir2;
                        //Calculate some (not accurate) stretch value to make sure the shadow geometry does not end mid screen
                        //We definitely draw way too much, but everything outside of the screen barely costs fillrate
                        float stretch = tileSizeVec.X * tileSizeVec.Y * 200;

                        //Check which of the 3 interesting sides are facing away from the light center and write appropriate
                        //Geometry into the dynamic vertex buffer
                        if (vertexCount < shadowVB.VertexCount)// && Vector3.Dot((edge1 + edge2) / 2 - new Vector3(center, 0), new Vector3(-(edge2 - edge1).Y, (edge2 - edge1).X, 0)) < 0)
                        {
                            dir1 = edge1 - new Vector3(center, depth);
                            dir1.Normalize();
                            dir2 = edge2 - new Vector3(center, depth);
                            dir2.Normalize();
                            //Some basic math basically we put in 2 triangles
                            //The idea is this, you draw a straight line from the center of the light to the corners and elongate that line
                            //until it is out of the screen, this way with the 2 corner points you get a trapezoid
                            //this trapezoid is your geometry, so you split it into 2 triangles and send them into the VBO
                            shadowVB.SetData <VertexPositionColor>(vertexCount * VertexPositionColor.VertexDeclaration.VertexStride, new VertexPositionColor[] {
                                new VertexPositionColor(edge1 + dir1 * stretch, Color.White),
                                new VertexPositionColor(edge1 + Vector3.Transform(dir1, Lightmap.rotateRight) * stretch, Color.Black),
                                new VertexPositionColor(edge2 + Vector3.Transform(dir2, Lightmap.rotateLeft) * stretch, Color.Black),
                                new VertexPositionColor(edge2 + dir2 * stretch, Color.White),
                                new VertexPositionColor(edge1, Color.Black),
                                new VertexPositionColor(edge2, Color.Black)
                            },
                                                                   0, 6, VertexPositionColor.VertexDeclaration.VertexStride);
                            vertexCount += 6;
                        }

                        //This is the backwards facing side, which will always be facing away, so we only need to check that the geometry fits
                        if (vertexCount < shadowVB.VertexCount)// && Vector3.Dot((edge2+edge3)/2 - new Vector3(center, 0), new Vector3(-(edge3 - edge2).Y, (edge3 - edge2).X, 0)) < 0)
                        {
                            dir1 = edge2 - new Vector3(center, depth);
                            dir1.Normalize();
                            dir2 = edge3 - new Vector3(center, depth);
                            dir2.Normalize();
                            shadowVB.SetData <VertexPositionColor>(vertexCount * VertexPositionColor.VertexDeclaration.VertexStride, new VertexPositionColor[] {
                                new VertexPositionColor(edge2 + dir1 * stretch, Color.White),
                                new VertexPositionColor(edge2 + Vector3.Transform(dir1, Lightmap.rotateRight) * stretch, Color.Black),
                                new VertexPositionColor(edge3 + Vector3.Transform(dir2, Lightmap.rotateLeft) * stretch, Color.Black),
                                new VertexPositionColor(edge3 + dir2 * stretch, Color.White),
                                new VertexPositionColor(edge2, Color.Black),
                                new VertexPositionColor(edge3, Color.Black)
                            },
                                                                   0, 6, VertexPositionColor.VertexDeclaration.VertexStride);
                            vertexCount += 6;
                        }
                        else
                        {
                        }

                        if (vertexCount < shadowVB.VertexCount)// && Vector3.Dot((edge3 + edge4) / 2 - new Vector3(center, 0), new Vector3(-(edge4 - edge3).Y, (edge4 - edge3).X, 0)) < 0)
                        {
                            dir1 = edge3 - new Vector3(center, depth);
                            dir1.Normalize();
                            dir2 = edge4 - new Vector3(center, depth);
                            dir2.Normalize();
                            shadowVB.SetData <VertexPositionColor>(vertexCount * VertexPositionColor.VertexDeclaration.VertexStride, new VertexPositionColor[] {
                                new VertexPositionColor(edge3 + dir1 * stretch, Color.White),
                                new VertexPositionColor(edge3 + Vector3.Transform(dir1, Lightmap.rotateRight) * stretch, Color.Black),
                                new VertexPositionColor(edge4 + Vector3.Transform(dir2, Lightmap.rotateLeft) * stretch, Color.Black),
                                new VertexPositionColor(edge4 + dir2 * stretch, Color.White),
                                new VertexPositionColor(edge3, Color.Black),
                                new VertexPositionColor(edge4, Color.Black),
                            },
                                                                   0, 6, VertexPositionColor.VertexDeclaration.VertexStride);
                            vertexCount += 6;
                        }
                        if (vertexCount < shadowVB.VertexCount)// && Vector3.Dot((edge4 + edge1) / 2 - new Vector3(center, 0), new Vector3(-(edge1 - edge4).Y, (edge1 - edge4).X, 0)) < 0)
                        {
                            dir1 = edge4 - new Vector3(center, depth);
                            dir1.Normalize();
                            dir2 = edge1 - new Vector3(center, depth);
                            dir2.Normalize();
                            shadowVB.SetData <VertexPositionColor>(vertexCount * VertexPositionColor.VertexDeclaration.VertexStride, new VertexPositionColor[] {
                                new VertexPositionColor(edge4 + dir1 * stretch, Color.White),
                                new VertexPositionColor(edge4 + Vector3.Transform(dir1, Lightmap.rotateRight) * stretch, Color.Black),
                                new VertexPositionColor(edge1 + Vector3.Transform(dir2, Lightmap.rotateLeft) * stretch, Color.Black),
                                new VertexPositionColor(edge1 + dir2 * stretch, Color.White),
                                new VertexPositionColor(edge4, Color.Black),
                                new VertexPositionColor(edge1, Color.Black),
                            },
                                                                   0, 6, VertexPositionColor.VertexDeclaration.VertexStride);
                            vertexCount += 6;
                        }
                    }
                }
            }
            return(vertexCount);
        }
        private new void FixSnapTransformationBase6()
        {
            Debug.Assert(CopiedGrids.Count > 0);
            if (CopiedGrids.Count == 0)
            {
                return;
            }

            var hitGrid = m_hitEntity as MyCubeGrid;

            if (hitGrid == null)
            {
                return;
            }

            // Fix rotation of the first pasted grid
            Matrix hitGridRotation  = hitGrid.WorldMatrix.GetOrientation();
            Matrix firstRotation    = PreviewGrids[0].WorldMatrix.GetOrientation();
            Matrix newFirstRotation = Matrix.AlignRotationToAxes(ref firstRotation, ref hitGridRotation);
            Matrix rotationDelta    = Matrix.Invert(firstRotation) * newFirstRotation;

            foreach (var grid in PreviewGrids)
            {
                Matrix rotation = grid.WorldMatrix.GetOrientation();
                rotation = rotation * rotationDelta;
                Matrix rotationInv = Matrix.Invert(rotation);

                Vector3D position = m_pastePosition;

                MatrixD newWorld = MatrixD.CreateWorld(position, rotation.Forward, rotation.Up);
                Debug.Assert(newWorld.GetOrientation().IsRotation());
                grid.PositionComp.SetWorldMatrix(newWorld);
            }

            bool smallOnLargeGrid = hitGrid.GridSizeEnum == MyCubeSize.Large && PreviewGrids[0].GridSizeEnum == MyCubeSize.Small;

            if (smallOnLargeGrid)
            {
                Vector3 pasteOffset = TransformLargeGridHitCoordToSmallGrid(m_hitPos, hitGrid.PositionComp.WorldMatrixNormalizedInv, hitGrid.GridSize);
                m_pastePosition = hitGrid.GridIntegerToWorld(pasteOffset);
            }
            else
            {
                // Find a collision-free position for the first paste grid along the raycast normal
                Vector3I collisionTestStep        = Vector3I.Round(m_hitNormal);
                Vector3I pasteOffset              = hitGrid.WorldToGridInteger(m_pastePosition);
                Vector3I previewGridMin           = PreviewGrids[0].Min;
                Vector3I previewGridMax           = PreviewGrids[0].Max;
                Vector3I previewGridSize          = previewGridMax - previewGridMin + Vector3I.One;
                Vector3D previewGridSizeInWorld   = Vector3D.TransformNormal((Vector3D)previewGridSize, PreviewGrids[0].WorldMatrix);
                Vector3I previewGridSizeInHitGrid = Vector3I.Abs(Vector3I.Round(Vector3D.TransformNormal(previewGridSizeInWorld, hitGrid.PositionComp.WorldMatrixNormalizedInv)));

                int attemptsCount = Math.Abs(Vector3I.Dot(ref collisionTestStep, ref previewGridSizeInHitGrid));
                Debug.Assert(attemptsCount > 0);
                int i;

                for (i = 0; i < attemptsCount; ++i)
                {
                    if (hitGrid.CanMergeCubes(PreviewGrids[0], pasteOffset))
                    {
                        break;
                    }
                    pasteOffset += collisionTestStep;
                }

                if (i == attemptsCount)
                {
                    pasteOffset = hitGrid.WorldToGridInteger(m_pastePosition);
                }

                m_pastePosition = hitGrid.GridIntegerToWorld(pasteOffset);
            }

            // Move all the grids according to the collision-free position of the first one
            for (int i = 0; i < PreviewGrids.Count; ++i)
            {
                var     grid   = PreviewGrids[i];
                MatrixD matrix = grid.WorldMatrix;
                matrix.Translation = m_pastePosition + Vector3.Transform(m_copiedGridOffsets[i], rotationDelta);
                grid.PositionComp.SetWorldMatrix(matrix);
            }

            if (MyDebugDrawSettings.DEBUG_DRAW_COPY_PASTE)
            {
                MyRenderProxy.DebugDrawLine3D(m_hitPos, m_hitPos + m_hitNormal, Color.Red, Color.Green, false);
            }
        }
Пример #14
0
 public static Vector3 operator *(QT Q, Vector3 v) =>
 Vector3.Transform(v, Q.q);
Пример #15
0
        public static void Test(
            Entity entity1, object[] boundingVolumes1, ref Matrix worldTransform1, ref Vector3 translation1, ref Quaternion rotation1, ref Vector3 scale1,
            Entity entity2, object[] boundingVolumes2, ref Matrix worldTransform2, ref Vector3 translation2, ref Quaternion rotation2, ref Vector3 scale2,
            bool needAllContacts, ref Contact contact
            )
        {
            Debug.Assert(scale1.X == scale1.Y && scale1.Y == scale1.Z);
            Debug.Assert(scale2.X == scale2.Y && scale2.Y == scale2.Z);

            for (int i = 0; i < boundingVolumes1.Length; ++i)
            {
                Sphere3 sphere1 = (Sphere3)boundingVolumes1[i];

                for (int j = 0; j < boundingVolumes2.Length; ++j)
                {
                    Cylinder3 cylinder2 = (Cylinder3)boundingVolumes2[j];

                    Vector3 center1 = Vector3.Transform(sphere1.Center, worldTransform1);
                    float   radius1 = scale1.X * sphere1.Radius;
                    Vector3 top2    = Vector3.Transform(cylinder2.Top, worldTransform2);
                    Vector3 bottom2 = Vector3.Transform(cylinder2.Bottom, worldTransform2);
                    float   radius2 = scale2.X * cylinder2.Radius;

                    // sphere is on same level as the cylinder
                    if (center1.Y <= top2.Y &&
                        center1.Y >= bottom2.Y)
                    {
                        // distance between the two
                        Vector3 diff = top2 - center1;
                        diff.Y = 0; // we are only interested in horizontal distance
                        float collisionLengthSquared = (radius2 + radius1) * (radius2 + radius1);
                        if (diff.LengthSquared() < collisionLengthSquared)
                        {
                            diff.Normalize();
                            Vector3 point = center1 + diff * radius1;
                            contact.AddContactPoint(ref point, ref diff);
                        }
                    }
                    // above cylinder...
                    else if (center1.Y > top2.Y)
                    {
                        if (center1.Y - radius1 < top2.Y)
                        {
                            // project to top cylinder 'plane'
                            Vector3 projected = center1;
                            projected.Y = top2.Y;

                            Vector3 toProjected = projected - top2;
                            if (toProjected.LengthSquared() < radius2 * radius2)
                            {
                                Vector3 normal = -Vector3.UnitY;
                                contact.AddContactPoint(ref projected, ref normal);
                            }
                            else
                            {
                                toProjected.Normalize();
                                Vector3 nearestPoint = top2 + toProjected * radius2;
                                Vector3 diff         = nearestPoint - center1;
                                if (diff.LengthSquared() < radius1 * radius1)
                                {
                                    Vector3 normal = -Vector3.UnitY;
                                    contact.AddContactPoint(ref nearestPoint, ref normal);
                                }
                            }
                        }
                    }
                    // below cylinder
                    else if (center1.Y < bottom2.Y)
                    {
                        if (center1.Y + radius1 < bottom2.Y)
                        {
                            // project to bottom cylinder 'plane'
                            Vector3 projected = center1;
                            projected.Y = bottom2.Y;

                            Vector3 toProjected = projected - bottom2;
                            if (toProjected.LengthSquared() < radius2 * radius2)
                            {
                                Vector3 normal = Vector3.UnitY;
                                contact.AddContactPoint(ref projected, ref normal);
                            }
                            else
                            {
                                toProjected.Normalize();
                                Vector3 nearestPoint = bottom2 + toProjected * radius2;
                                Vector3 diff         = nearestPoint - center1;
                                if (diff.LengthSquared() < radius1 * radius1)
                                {
                                    Vector3 normal = Vector3.UnitY;
                                    contact.AddContactPoint(ref nearestPoint, ref normal);
                                }
                            }
                        }
                    }
                    else
                    {
                        // we covered all cases...
                        Debug.Assert(false);
                    }
                }
            }
        }
Пример #16
0
        public void ProcessKinectCommands(InputManager inputManager)
        {
            inputManager.GameState.KinectVideoColors = kinectHandler.ColorImage;
            if (inputManager.GameState.IsKinectActive)
            {
                inputManager.GameState.IsInputActive = false;

                if (kinectHandler.Gesture == "TurnLeft")
                {
                    // Rotate left.
                    inputManager.GameState.IsInputActive    = true;
                    inputManager.GameState.AvatarYRotation += inputManager.GameState.TurningSpeed / 2;
                }

                if (kinectHandler.Gesture == "TurnRight")
                {
                    // Rotate right.
                    inputManager.GameState.IsInputActive    = true;
                    inputManager.GameState.AvatarYRotation -= inputManager.GameState.TurningSpeed / 2;
                }
                if (kinectHandler.Gesture == "MoveForward")
                {
                    inputManager.GameState.IsInputActive = true;
                    Matrix  forwardMovement = Matrix.CreateRotationY(inputManager.GameState.AvatarYRotation);
                    Vector3 v = new Vector3(0, 0, -inputManager.GameState.MovingSpeed);
                    v = Vector3.Transform(v, forwardMovement);
                    Vector3 avatarPosition = inputManager.GameState.AvatarPosition;
                    avatarPosition.Z += v.Z;
                    avatarPosition.X += v.X;
                    inputManager.GameState.AvatarPosition = avatarPosition;
                    //Console.WriteLine ("Avatar Postion:{0}", avatarPosition.ToString ());
                }
                if (kinectHandler.Gesture == "MoveBackward")
                {
                    inputManager.GameState.IsInputActive = true;
                    Matrix  forwardMovement = Matrix.CreateRotationY(inputManager.GameState.AvatarYRotation);
                    Vector3 v = new Vector3(0, 0, inputManager.GameState.MovingSpeed);
                    v = Vector3.Transform(v, forwardMovement);
                    Vector3 avatarPosition = inputManager.GameState.AvatarPosition;
                    avatarPosition.Z += v.Z;
                    avatarPosition.X += v.X;
                    inputManager.GameState.AvatarPosition = avatarPosition;
                }
                //if (kinectHandler.Gesture == "Swipe Up")
                //    {
                //    inputManager.GameState.IsInputActive = true;
                //    Matrix forwardMovement = Matrix.CreateRotationY (inputManager.GameState.AvatarYRotation);
                //    Vector3 v = new Vector3 (0, inputManager.GameState.MovingSpeed, 0);
                //    v = Vector3.Transform (v, forwardMovement);
                //    Vector3 avatarPosition = inputManager.GameState.AvatarPosition;
                //    avatarPosition.Y += v.Y;

                //    inputManager.GameState.AvatarPosition = avatarPosition;
                //    }

                //if (kinectHandler.Gesture == "Swipe Down")
                //    {
                //    inputManager.GameState.IsInputActive = true;
                //    Matrix forwardMovement = Matrix.CreateRotationY (inputManager.GameState.AvatarYRotation);
                //    Vector3 v = new Vector3 (0, -inputManager.GameState.MovingSpeed, 0);
                //    v = Vector3.Transform (v, forwardMovement);
                //    Vector3 avatarPosition = inputManager.GameState.AvatarPosition;
                //    avatarPosition.Y += v.Y;
                //    inputManager.GameState.AvatarPosition = avatarPosition;
                //    }

                //if (kinectHandler.Gesture == "Zoom In")
                //    {
                //    inputManager.GameState.CameraState += 1;
                //    inputManager.GameState.CameraState %= 3;
                //    }



                if (kinectHandler.Gesture == "Clear")
                {
                    inputManager.GameState.IsInputActive = false;
                    if (inputManager.GameState.ShowInfo)
                    {
                        inputManager.GameState.ShowInfo = false;
                    }
                    if (inputManager.GameState.ShowCursor)
                    {
                        inputManager.GameState.ShowCursor = false;
                    }
                }

                if (kinectHandler.Gesture == "Select")
                {
                    // Console.WriteLine (inputManager.GameState.ShowCursor);
                    if (inputManager.GameState.ShowCursor)
                    {
                        inputManager.GameState.ShowInfo = true;
                    }
                }

                if (kinectHandler.Gesture == "Wave Right")
                {
                    inputManager.GameState.ShowCursor = true;
                }

                if (inputManager.GameState.ShowCursor)
                {
                    inputManager.GameState.CursorScreenLocation = new Vector2(kinectHandler.ScaledRightHand.Position.X, kinectHandler.ScaledRightHand.Position.Y);
                }
            }
        }
Пример #17
0
        public override void Update(GameTime gameTime)
        {
            curMouse = Mouse.GetState();
            curKeys  = Keyboard.GetState();

            if (Game.IsActive)
            {
                if (curMouse.ScrollWheelValue < prevMouse.ScrollWheelValue)
                {
                    zoom *= 1.2f;
                }
                else if (curMouse.ScrollWheelValue > prevMouse.ScrollWheelValue)
                {
                    zoom /= 1.2f;
                }
                if (zoom < minZoom)
                {
                    zoom = minZoom;
                }
                if (zoom > maxZoom)
                {
                    zoom = maxZoom;
                }


                int w = Game.GraphicsDevice.Viewport.Width / 2;
                int h = Game.GraphicsDevice.Viewport.Height / 2;

                float dx = curMouse.X - w;
                float dy = curMouse.Y - h;
                Mouse.SetPosition(w, h);

                yaw   -= dx * .005f;
                pitch -= dy * .005f;
                if (pitch > 0)
                {
                    pitch = 0;
                }
                else if (pitch < -MathHelper.PiOver2)
                {
                    pitch = -MathHelper.PiOver2;
                }

                rot             = Matrix.CreateRotationX(pitch) * Matrix.CreateRotationY(yaw);
                rotatedTarget   = Vector3.Transform(new Vector3(0, 0, -1), rot);
                rotatedUpVector = Vector3.Transform(new Vector3(0, 1, 0), rot);

                distanceFromTarget = 20 * zoom;
                target             = physicalData.Position + headOffset;
                position           = target + rot.Backward * distanceFromTarget;
                view = Matrix.CreateLookAt(position, target, rotatedUpVector);

                physicalData.Orientation = Quaternion.CreateFromYawPitchRoll(yaw, 0, 0);
            }

            int i = 0;

            foreach (Entity e in lightPoleEntities)
            {
                if (i < lightPositions.Length)
                {
                    lightPositions[i++] = e.Position + e.OrientationMatrix.Up * 4;
                }
            }
            while (i < lightPositions.Length)
            {
                lightPositions[i++] = inactiveLightPos;
            }

            prevMouse = curMouse;
            prevKeys  = curKeys;
        }
Пример #18
0
        private void animate()
        {
            Animation.Sequence sequence = new Animation.Sequence();

            bool originalCanPause = false;

            sequence.Add(new Animation.Execute(delegate()
            {
                Entity p = PlayerFactory.Instance;
                if (p != null)
                {
                    p.Get <Model>("FirstPersonModel").Enabled.Value = false;
                    p.Get <Model>("Model").Enabled.Value            = false;
                    p.Get <CameraController>().Enabled.Value        = false;
                    p.Get <FPSInput>().Enabled.Value       = false;
                    p.Get <UIRenderer>("UI").Enabled.Value = false;
                    AkSoundEngine.PostEvent(AK.EVENTS.STOP_PLAYER_BREATHING_SOFT, p);
                }
                CameraStop.CinematicActive.Value = true;
                originalCanPause = this.main.Menu.CanPause;
#if !DEVELOPMENT
                this.main.Menu.CanPause.Value = false;
#endif
            }));

            sequence.Add(new Animation.Set <Matrix>(this.main.Camera.RotationMatrix, Matrix.CreateFromQuaternion(this.Entity.Get <Transform>().Quaternion)));
            sequence.Add(new Animation.Set <Vector3>(this.main.Camera.Position, Vector3.Transform(new Vector3(0, 0, this.Offset), this.Entity.Get <Transform>().Matrix)));

            Animation.Ease.EaseType lastEase = Animation.Ease.EaseType.None;
            BSpline spline        = null;
            Entity  current       = this.Entity;
            float   totalDuration = 0.0f;
            while (current != null)
            {
                CameraStop currentStop      = current.Get <CameraStop>();
                Transform  currentTransform = current.Get <Transform>();

                Entity     next     = currentStop.Next.Value.Target;
                CameraStop nextStop = next == null ? null : next.Get <CameraStop>();

                if (!lastEase.BlendsInto(currentStop.Blend) || next == null)
                {
                    if (spline != null)
                    {
                        spline.Add(currentTransform.Position, currentTransform.Quaternion, currentStop.Offset, currentStop.FieldOfView);
                    }
                    spline = new BSpline();
                }

                float currentTime = spline.Duration;
                spline.Duration += currentStop.Duration;
                totalDuration   += currentStop.Duration;

                if (currentStop.Blend != Animation.Ease.EaseType.None && next != null)
                {
                    BSpline currentSpline = spline;
                    currentSpline.Add(currentTransform.Position, currentTransform.Quaternion, currentStop.Offset, currentStop.FieldOfView);
                    Transform nextTransform = next.Get <Transform>();
                    sequence.Add
                    (
                        new Animation.Ease
                        (
                            new Animation.Custom
                            (
                                delegate(float x)
                    {
                        float lerpValue                       = (currentTime + x * currentStop.Duration) / currentSpline.Duration;
                        BSpline.ControlPoint point            = currentSpline.Evaluate(lerpValue);
                        Matrix rotationMatrix                 = Matrix.CreateFromQuaternion(point.Orientation);
                        this.main.Camera.FieldOfView.Value    = MathHelper.Clamp(point.FieldOfView, 0.01f, (float)Math.PI * 0.99f);
                        this.main.Camera.RotationMatrix.Value = rotationMatrix;
                        Matrix m = rotationMatrix * Matrix.CreateTranslation(point.Position);
                        this.main.Camera.Position.Value = Vector3.Transform(new Vector3(0, 0, point.Offset), m);
                    },
                                currentStop.Duration
                            ),
                            currentStop.Blend
                        )
                    );
                }
                else
                {
                    sequence.Add
                    (
                        new Animation.Custom
                        (
                            delegate(float x)
                    {
                        this.main.Camera.RotationMatrix.Value = Matrix.CreateFromQuaternion(currentTransform.Quaternion);
                        this.main.Camera.Position.Value       = Vector3.Transform(new Vector3(0, 0, currentStop.Offset), currentTransform.Matrix);
                        this.main.Camera.FieldOfView.Value    = MathHelper.ToRadians(currentStop.FieldOfView);
                    },
                            currentStop.Duration
                        )
                    );
                }

                sequence.Add(new Animation.Execute(currentStop.OnDone));

                lastEase = currentStop.Blend;
                current  = next;
            }

            Action done = delegate()
            {
                Entity p = PlayerFactory.Instance;
                if (p != null)
                {
                    p.Get <Model>("FirstPersonModel").Enabled.Value = true;
                    p.Get <Model>("Model").Enabled.Value            = true;
                    p.Get <CameraController>().Enabled.Value        = true;
                    p.Get <FPSInput>().Enabled.Value       = true;
                    p.Get <UIRenderer>("UI").Enabled.Value = true;
                }
                this.main.Camera.FieldOfView.Value = this.main.Settings.FieldOfView;
                CameraStop.CinematicActive.Value   = false;
                this.main.Menu.CanPause.Value      = originalCanPause;
            };

            Animation anim;
            if (PlayerFactory.Instance != null && totalDuration > 0.0f)             // Fade in and out
            {
                anim = new Animation
                       (
                    new Animation.Vector3MoveTo(this.main.Renderer.Tint, Vector3.Zero, 0.5f),
                    new Animation.Parallel(sequence, new Animation.Vector3MoveTo(this.main.Renderer.Tint, Vector3.One, 0.5f)),
                    new Animation.Vector3MoveTo(this.main.Renderer.Tint, Vector3.Zero, 0.5f),
                    new Animation.Execute(done),
                    new Animation.Vector3MoveTo(this.main.Renderer.Tint, Vector3.One, 0.5f)
                       );
            }
            else
            {
                // Just do it
                anim = new Animation
                       (
                    sequence,
                    new Animation.Execute(done)
                       );
            }
            anim.EnabledWhenPaused = false;
            WorldFactory.Instance.Add(anim);
        }
Пример #19
0
 public Vector3 GetForward()
 {
     return(Vector3.Transform(Vector3.Backward, Rotation));
 }
Пример #20
0
 /// <summary>
 /// Transforms a specified Vector3 by a specified transformation matrix in homogeneous space
 /// </summary>
 /// <param name="v">the vector to be transformed</param>
 /// <param name="m">the transformation matrix</param>
 /// <returns>a specified vector transformed by a specified transformation matrix in homogeneous space</returns>
 public static Vector4 Transform(Vector3 v, Matrix4x4 m)
 {
     return v.Transform(m);
 }
Пример #21
0
 public Vector3 GetRight()
 {
     return(Vector3.Transform(Vector3.Right, Rotation));
 }
Пример #22
0
 bool testProximity(int n)
 {
     Piece p = Neighbours [n];
     if (p == null)
         return false;
     if (Angle != p.Angle)
         return false;
     cDelta = Bounds.Center - p.Bounds.Center;
     cDelta = cDelta.Transform (Matrix4.CreateRotationZ (Angle));
     if (
         Math.Abs (Dx - p.Dx-cDelta.X) < puzzle.TolerancePlacementPieces &&
         Math.Abs (Dy - p.Dy-cDelta.Y) < puzzle.TolerancePlacementPieces)
         return true;
     return false;
 }
Пример #23
0
        /// <summary>
        /// Gets the intersection between the box and the ray.
        /// </summary>
        /// <param name="ray">Ray to test against the box.</param>
        /// <param name="transform">Transform of the shape.</param>
        /// <param name="maximumLength">Maximum distance to travel in units of the direction vector's length.</param>
        /// <param name="hit">Hit data for the raycast, if any.</param>
        /// <returns>Whether or not the ray hit the target.</returns>
        public override bool RayTest(ref Ray ray, ref RigidTransform transform, float maximumLength, out RayHit hit)
        {
            hit = new RayHit();

            Quaternion conjugate;

            Quaternion.Conjugate(ref transform.Orientation, out conjugate);
            Vector3 localOrigin;

            Vector3.Subtract(ref ray.Position, ref transform.Position, out localOrigin);
            Vector3.Transform(ref localOrigin, ref conjugate, out localOrigin);
            Vector3 localDirection;

            Vector3.Transform(ref ray.Direction, ref conjugate, out localDirection);
            Vector3 normal = Toolbox.ZeroVector;
            float   temp, tmin = 0, tmax = maximumLength;

            if (Math.Abs(localDirection.X) < Toolbox.Epsilon && (localOrigin.X < -halfWidth || localOrigin.X > halfWidth))
            {
                return(false);
            }
            float inverseDirection = 1 / localDirection.X;
            float t1         = (-halfWidth - localOrigin.X) * inverseDirection;
            float t2         = (halfWidth - localOrigin.X) * inverseDirection;
            var   tempNormal = new Vector3(-1, 0, 0);

            if (t1 > t2)
            {
                temp        = t1;
                t1          = t2;
                t2          = temp;
                tempNormal *= -1;
            }
            temp = tmin;
            tmin = Math.Max(tmin, t1);
            if (temp != tmin)
            {
                normal = tempNormal;
            }
            tmax = Math.Min(tmax, t2);
            if (tmin > tmax)
            {
                return(false);
            }
            if (Math.Abs(localDirection.Y) < Toolbox.Epsilon && (localOrigin.Y < -halfHeight || localOrigin.Y > halfHeight))
            {
                return(false);
            }
            inverseDirection = 1 / localDirection.Y;
            t1         = (-halfHeight - localOrigin.Y) * inverseDirection;
            t2         = (halfHeight - localOrigin.Y) * inverseDirection;
            tempNormal = new Vector3(0, -1, 0);
            if (t1 > t2)
            {
                temp        = t1;
                t1          = t2;
                t2          = temp;
                tempNormal *= -1;
            }
            temp = tmin;
            tmin = Math.Max(tmin, t1);
            if (temp != tmin)
            {
                normal = tempNormal;
            }
            tmax = Math.Min(tmax, t2);
            if (tmin > tmax)
            {
                return(false);
            }
            if (Math.Abs(localDirection.Z) < Toolbox.Epsilon && (localOrigin.Z < -halfLength || localOrigin.Z > halfLength))
            {
                return(false);
            }
            inverseDirection = 1 / localDirection.Z;
            t1         = (-halfLength - localOrigin.Z) * inverseDirection;
            t2         = (halfLength - localOrigin.Z) * inverseDirection;
            tempNormal = new Vector3(0, 0, -1);
            if (t1 > t2)
            {
                temp        = t1;
                t1          = t2;
                t2          = temp;
                tempNormal *= -1;
            }
            temp = tmin;
            tmin = Math.Max(tmin, t1);
            if (temp != tmin)
            {
                normal = tempNormal;
            }
            tmax = Math.Min(tmax, t2);
            if (tmin > tmax)
            {
                return(false);
            }
            hit.T = tmin;
            Vector3.Multiply(ref ray.Direction, tmin, out hit.Location);
            Vector3.Add(ref hit.Location, ref ray.Position, out hit.Location);
            Vector3.Transform(ref normal, ref transform.Orientation, out normal);
            hit.Normal = normal;
            return(true);
        }