Beispiel #1
0
        public virtual void FreeLookAt(Vector3 targetAbsRef, Vector3 upRelRef)
        {

            //Vector v1 = new Vector3(0, 0, -1);
            //Vector moveV = _staticModel.Position - vector;
            //Vector v2 = moveV.RotateBy(_staticModel.Orientation.W, 0, 1, 0);

            /*Vector forward = lookAt.Normalized();
            Vector right = Vector::Cross(up.Normalized(), forward);
            Vector up = Vector::Cross(forward, right);*/
            Vector3 forward ;
            if (_mainModel.IsChild)
            {
                //Normalizing target and transforming it to local system
                forward = Geometric.Quaternion_Rotate(_mainModel.ParentModel.Orientation.Inverted(), targetAbsRef.Normalized()) - _mainModel.ParentModel.Position;
            }
            else
            {
                //Normalizing target.. local system is the same as world system
                forward = targetAbsRef.Normalized();
            }
            //Normalizing upVector (we are assuming it is expressed in local system)
            Vector3 eye = _mainModel.PositionRelative.Normalized();
            Vector3 up = upRelRef.Normalized();

            //Insert manual imprecision to avoid singularity
            if( Vector3.Dot(forward,up) == 1 )
            {
                forward.X += 0.001f;
                forward.Y += 0.001f;
                forward.Z += 0.001f;
            }

            //float angle = (float)Math.Acos( Vector3.DotProduct(current,targetAbsRef) );
            //Vector3 rotAxis = Vector3.CrossProduct(current, forward).Normalize();
            //Vector3 right = Vector3.CrossProduct(forward, up);

            Matrix4 lookAt_result = Matrix4.LookAt( eye.X, eye.Y, eye.Z, forward.X, forward.Y, forward.Z, up.X, up.Y, up.Z );
            Matrix3 targetRelOrientation_matrix = new Matrix3(lookAt_result);
            Quaternion targetRelOrientation_quaternion = Quaternion.FromMatrix(targetRelOrientation_matrix);

            /*
            Quaternion targetRelOrientation_quaternion = new Quaternion();
            targetRelOrientation_quaternion.W = (float)Math.Sqrt((double)(1.0f + right.X + up.Y + forward.Z)) * 0.5f;
            float w4_recip = 1.0f / (4.0f * targetRelOrientation_quaternion.W);
            targetRelOrientation_quaternion.X = (forward.Y - up.Z) * w4_recip;
            targetRelOrientation_quaternion.Y = (right.Z - forward.X) * w4_recip;
            targetRelOrientation_quaternion.Z = (up.X - right.Y) * w4_recip;
            */

            _mainModel.OrientationRelative = Quaternion.Slerp(_mainModel.OrientationRelative, targetRelOrientation_quaternion, Game.DeltaTime * 0.001f);

        }
Beispiel #2
0
 public Camera(Vector3 pos, Vector3 forward, Vector3 up, float fieldOfView)
 {
   _position = pos;
   _forward = forward.Normalized();
   _up = up.Normalized();
   _fieldOfView = fieldOfView;
 }
Beispiel #3
0
        public void Update(ISteering steering, float frametime)
        {
            Position += Velocity * frametime;

            Velocity += steering.GetLinearAcceleration() * frametime;

            if (Velocity.Length > MaxSpeed)
            {
                Velocity = Velocity.Normalized() * MaxSpeed;
            }
        }
Beispiel #4
0
        public Camera(Vector3 position, Vector3 forward, Vector3 worldUp, float fieldOfView, Size renderSize)
            : base(position)
        {
            this.ReflectionDepth = 5;
            this.forward = forward.Normalized();
            this.right = Util.CrossProduct(worldUp, forward).Normalized();
            this.up = -Util.CrossProduct(right, forward).Normalized();
            this.fieldOfView = fieldOfView;
            this.RenderSize = renderSize;

            RecalculateFieldOfView();
        }
Beispiel #5
0
        public Camera(Vector3 position, Vector3 forward, Vector3 worldUp, float fieldOfView, Size renderSize)
            : base(position)
        {
            this.ReflectionDepth = 5;
            this.forward = forward.Normalized();
            //this.up = up;
            this.right = Vector3.Normalize(Vector3.Cross(worldUp, forward));
            this.up = Vector3.Normalize(-Vector3.Cross(right, forward));
            this.fieldOfView = fieldOfView;
            this.RenderSize = renderSize;

            RecalculateFieldOfView();
        }
        /// <summary>
        /// Constructs a plane with the properties provided
        /// </summary>
        /// <param name="position">The position of the plane's center</param>
        /// <param name="material">The plane's material</param>
        /// <param name="normalDirection">The normal direction of the plane</param>
        /// <param name="cellWidth">The width of a cell in the plane, used for texture coordinate mapping.</param>
        public InfinitePlane(Vector3 position, Material material, Vector3 normalDirection, float cellWidth)
            : base(position, material)
        {
            this.normalDirection = normalDirection.Normalized();
            if (normalDirection == Util.ForwardVector)
            {
                this.uDirection = -Util.RightVector;
            }
            else if (normalDirection == -Util.ForwardVector)
            {
                this.uDirection = Util.RightVector;
            }
            else
            {
                this.uDirection = Util.CrossProduct(normalDirection, Util.ForwardVector).Normalized();
            }

            this.vDirection = -Util.CrossProduct(normalDirection, uDirection).Normalized();
            this.cellWidth = cellWidth;
        }
 /// <summary>
 /// Angle between vectors.
 /// </summary>
 public static float AngleTo(this Vector3 vector, Vector3 other)
 {
     return((float)System.Math.Acos(vector.Normalized().Dot(other.Normalized())));
 }
    private void _MovementControl(float delta)
    {
        Transform camera = ((Camera)GetNode("Camera")).GetGlobalTransform();

        Vector3 charRot   = new Vector3();
        Vector3 direction = new Vector3();
        Vector2 joystick  = new Vector2(Input.GetJoyAxis(0, 0), Input.GetJoyAxis(0, 1));
        bool    isMoving  = false;

        if (joystick.Length() > 0.25)
        {
            direction.x = joystick.x;
            direction.z = joystick.y;
            isMoving    = true;
        }
        else
        {
            if (Input.IsActionPressed("ui_up"))
            {
                direction += -camera.basis[0];
                isMoving   = true;
            }

            if (Input.IsActionPressed("ui_left"))
            {
                direction += camera.basis[2];
                isMoving   = true;
            }

            if (Input.IsActionPressed("ui_right"))
            {
                direction += -camera.basis[2];
                isMoving   = true;
            }

            if (Input.IsActionPressed("ui_down"))
            {
                direction += camera.basis[0];
                isMoving   = true;
            }
        }

        direction.y = 0;
        direction   = direction.Normalized();

        velocity.y += gravity * delta;

        Vector3 hv = new Vector3(velocity.x, 0, velocity.z);

        var newPos = direction * speed;
        var accel  = deAcceleration;

        if (direction.Dot(hv) > 0)
        {
            accel = acceleration;
        }

        hv = hv.LinearInterpolate(newPos, accel * delta);

        velocity.x = hv.x;
        velocity.z = hv.z;

        if (isMoving)
        {
            Spatial node  = (Spatial)GetNode("Mesh");
            float   angle = Mathf.Atan2(hv.z, hv.x);
            charRot   = node.GetRotation();
            charRot.z = angle;
            node.SetRotation(charRot);
        }

        velocity = MoveAndSlide(velocity, new Vector3(0, 1, 0));

        if (IsOnFloor() && Input.IsActionPressed("ui_accept"))
        {
            velocity.y = 10;
        }

        RpcUnreliable("OnMove", GetGlobalTransform().origin, Id, isMoving, charRot);
    }
Beispiel #9
0
 //constructors
 public Camera(Vector3 cameraPos, Vector3 cameraDir, Vector3 cameraUp)
 {
     this.cameraPos = cameraPos;
     this.cameraUp = cameraUp.Normalized();
     this.cameraDir = cameraDir.Normalized();
 }
Beispiel #10
0
 public Ray(Vector3 origin, Vector3 direction)
 {
     Direction = direction.Normalized();
     Origin    = origin;
 }
Beispiel #11
0
        public override void Render()
        {
            int culled = 0;

            foreach (PointLight light in Entity.GetAll <PointLight>())
            {
                if (Entity.Has <Transform>(light.Id))
                {
                    light.CachedPosition = Entity.Get <Transform>(light.Id).Position.Value;
                }
            }
            foreach (Camera cam in Entity.GetAll <Camera>())
            {
                Matrix4 camMatrix = Matrix4.Identity;
                Vector3 camFwd    = Vector3.UnitZ;
                Vector3 camPos    = Vector3.Zero;
                if (Entity.Has <Transform>(cam.Id))
                {
                    Transform camTrans = Entity.Get <Transform>(cam.Id);
                    cam.Begin(camTrans.ViewMatrix);
                    camMatrix = camTrans.ViewMatrix;
                    camFwd    = camTrans.Forward;
                    camPos    = camTrans.Position.Value;
                }
                else
                {
                    cam.Begin(Matrix4.Identity);
                }
                foreach (Renderer r in Entity.GetAll <Renderer>())
                {
                    if ((r.LayerMask.Value & cam.LayerMask.Value) == 0)
                    {
                        continue;                                                 //If the camera and renderer use different layers, don't draw
                    }
                    Matrix4 viewMatrix   = Matrix4.Identity;
                    Matrix4 normalMatrix = Matrix4.Identity;
                    if (Entity.Has <Transform>(r.Id))
                    {
                        Transform t = Entity.Get <Transform>(r.Id);
                        viewMatrix   = t.ViewMatrix;
                        normalMatrix = t.ScalingMatrix * t.RotationMatrix;
                    }
                    if (Entity.Has <MeshFilter>(r.Id))  //If there is a Mesh component, draw that
                    {
                        MeshFilter mf = Entity.Get <MeshFilter>(r.Id);
                        if (mf.Mesh.Value != null)
                        {
                            bool   cull = true;
                            Bounds b    = mf.Mesh.Value.GetBounds();
                            GL.PushMatrix();
                            GL.Translate(b.Min + (b.Max - b.Min) / 2f);
                            //new Sphere(((b.Max - b.Min)/2f).LengthFast).Draw(viewMatrix, normalMatrix, OpenTK.Graphics.Color4.Magenta); //Draw bounding boxes as spheres
                            GL.PopMatrix();
                            foreach (Vector3 corner in b.GetCorners())
                            {
                                Vector3 t    = Vector3.Transform(corner, viewMatrix);
                                Vector3 diff = (t - camPos);
                                if (cam.IsPerspective && diff.LengthFast > cam.ViewDistance.Value)
                                {
                                    continue;                                                                        //Out of viewing range, no need to check against FoV
                                }
                                double angle = Math.Acos(Vector3.Dot(camFwd, diff.Normalized()));                    //Get angle between camera forward direction and direction to bound corner
                                if (cam.IsPerspective && angle < MathHelper.DegreesToRadians(cam.FieldOfView.Value)) //If angle is inside field of view, don't cull
                                {
                                    cull = false;
                                    break;
                                }
                            }
                            if (!cull)
                            {
                                mf.Mesh.Value.Draw(viewMatrix, normalMatrix, mf.Color.Value);
                            }
                            else
                            {
                                culled++;
                            }
                        }
                    }
                    else   //Otherwise, draw an XYZ axis gizmo so we can see where it is
                    {
                        GL.PushMatrix();

                        GL.MultMatrix(ref viewMatrix);
                        GL.Begin(PrimitiveType.Lines);
                        GL.Color3(1f, 0f, 0f);
                        GL.Vertex3(0f, 0f, 0f);
                        GL.Color3(1f, 0f, 0f);
                        GL.Vertex3(1f, 0f, 0f);
                        GL.Color3(0f, 1f, 0f);
                        GL.Vertex3(0f, 0f, 0f);
                        GL.Color3(0f, 1f, 0f);
                        GL.Vertex3(0f, 1f, 0f);
                        GL.Color3(0f, 0f, 1f);
                        GL.Vertex3(0f, 0f, 0f);
                        GL.Color3(0f, 0f, 1f);
                        GL.Vertex3(0f, 0f, 1f);
                        GL.End();
                        GL.PopMatrix();
                    }
                }
                cam.End();
            }
            Debug.AddMsg("Culled: " + culled);
        }
Beispiel #12
0
 public static float Angle(Vector3 A, Vector3 B)
 {
     return(Mathf.Acos(A.Normalized().Dot(B.Normalized())) * Rad2Deg);
 }
Beispiel #13
0
    public override void Update(float delta)
    {
        base.Update(delta);
        Vector3 finalMove = Vector3.Zero;
        Vector3 snapDown  = Vector3.Zero;

        //All things that happen when the player is on the ground
        if (groundColliding)
        {
            //For when the player stops moving.
            if (!controller.inputs.moved)
            {
                if (currentSpeed < .1f)
                {
                    switch (controller.ability.GetCurrentState())
                    {
                    case PlayerState.sprinting:
                    case PlayerState.walking:
                        Stop();
                        SetState(PlayerState.standing);
                        break;

                    case PlayerState.crouch:
                        Stop();
                        break;
                    }
                }
                if (controller.ability.GetCurrentState() != PlayerState.slide)
                {
                    if (currentSpeed < .1f)
                    {
                        currentSpeed = 0;
                    }
                    else
                    {
                        currentSpeed -= currentSpeed * time * PlayerOptions.walkingDeceleration;
                    }
                }
            }
            else //This is what happens when they do move
            {
                //This section is for changing the players state
                if (controller.size.crouched)
                {
                    if (accelerate > 1.1f)
                    {
                        SetState(PlayerState.slide);
                    }
                    else
                    {
                        SetState(PlayerState.crouch);
                    }
                }
                else
                {
                    if (maxSpeed == PlayerOptions.playerMaxWalkingSpeed)
                    {
                        SetState(PlayerState.walking);
                    }
                    else
                    {
                        SetState(PlayerState.sprinting);
                    }
                }
            }

            //Testing whether we need to modify the angle that the player walks
            if (!groundData.colliding || controller.ability.GetNoCollide())
            {
                finalMove += stableMove.Normalized() * currentSpeed * accelerate;
                //This is the mod that allows walking up slopes needs to be zero'd out when not in use
                verticalAddition *= 0;
            }
            else
            {
                //The mod being calculated
                verticalAddition = groundData.normal.Cross(stableMove.Rotated(Vector3.Up, NinetyDegreesToRad)).Normalized();
                finalMove       += verticalAddition * currentSpeed * accelerate;
            }
            //Used primarely quick bursts of speed but drops when on the ground
            horizontalAcc -= horizontalAcc * time * .9f;

            //Universal knockback that only starts to slow when on the ground
            if (knockback.Length() < .1f)
            {
                knockback *= 0;
            }
            else
            {
                knockback -= knockback * time * 2f;
            }

            if (verticalMove.Length() < 0.01f)
            {
                snapDown = Vector3.Down;
            }
        }
        else //No longer on the ground
        {
            //This sets the state to falling up and down so long as the player isnt' wall running or gliding
            if (controller.ability.GetCurrentState() != PlayerState.wallRunning && controller.ability.GetCurrentState() != PlayerState.glide)
            {
                if (verticalMove.y > 0)
                {
                    SetState(PlayerState.fallingUp);
                }
                else
                {
                    SetState(PlayerState.fallingDown);
                }
            }
            //For when the player is in the air and is moving
            finalMove += stableMove * accelerate;

            //Controlling the vertical movement of the player depending on the state they are currently in
            switch (controller.ability.GetCurrentState())
            {
            case PlayerState.wallRunning:
                verticalMove += Vector3.Down * time * PlayerOptions.wallRunningGravity;
                break;

            case PlayerState.glide:
                verticalMove = Vector3.Down * PlayerOptions.glideFallSpeed;
                break;

            default:
                verticalMove += Vector3.Down * time * PlayerOptions.gravity;
                break;
            }
        }
        //Some edge cases where the player is on the ground and gets hit with knockback or something that modifies vertical move
        if (PlayerAreaSensor.GetArea(AreaSensorDirection.Above) && verticalMove.y > 0)
        {
            verticalMove = Vector3.Zero;
        }
        finalMove += horizontalAcc + verticalMove + pushing + knockback;
        //Moves the player finally
        controller.MoveAndSlideWithSnap(finalMove, snapDown, Vector3.Up, true);
        //Will only work if you have a force applying downward to the character?
        if (controller.IsOnFloor() != onFloor)
        {
            onFloor = controller.IsOnFloor();
            controller.GroundChanging(onFloor);
            floorMovement.y = controller.GetFloorVelocity().y;
        }
        if (currentAccelerationTime < PlayerOptions.slideMaxTime)
        {
            currentAccelerationTime += time;
        }
        else
        {
            accelerate = Mathf.Clamp(accelerate - PlayerOptions.slideDeceleration * time, 1, accelerate);
        }
        pushing = Vector3.Zero;
        if (controller.ability.GetCurrentState() != PlayerState.slide)
        {
            if (moved)
            {
                movedBuffer += 1;
                if (movedBuffer > 60f - Engine.GetFramesPerSecond())
                {
                    moved       = false;
                    movedBuffer = 0f;
                }
            }
        }
    }
Beispiel #14
0
 private void GenerateNormal(IVertex vertex, List<IFace> faces)
 {
   var accumulatedNormal = new Vector3();
   foreach (var face in faces)
   {
     accumulatedNormal += GetFaceNormal(face);
   }
   vertex.Normal = accumulatedNormal.Normalized();
 }
Beispiel #15
0
 public Ray(Vector3 origin, Vector3 direction, float estimatedLength)
 {
     Origin = origin;
     Direction = direction.Normalized();
     EstimatedLength = estimatedLength;
 }
Beispiel #16
0
 public void Assign(Vector3 n, Vector3 pos)
 {
     Normal = n.Normalized();
     Dot = Normal.Dot(pos);
 }
Beispiel #17
0
    public override void _PhysicsProcess(float delta)
    {
        if (IsNetworkMaster())
        {
            direction = new Vector3();
            moved     = false;

            if (Input.IsActionPressed("move_forward"))
            {
                direction -= Transform.basis.z;
                if (!characterAnimationPlayer.IsPlaying())
                {
                    characterAnimationPlayer.Play("Running");
                    if (GetTree().NetworkPeer != null)
                    {
                        ObjectBroker.Instance.NetworkService.toServer(new ClientAnimationStateUpdate("Running", false));
                    }
                    moved = true;
                }
            }
            if (Input.IsActionPressed("move_backward"))
            {
                direction += Transform.basis.z;
                if (!characterAnimationPlayer.IsPlaying())
                {
                    characterAnimationPlayer.PlayBackwards("Running");
                    if (GetTree().NetworkPeer != null)
                    {
                        ObjectBroker.Instance.NetworkService.toServer(new ClientAnimationStateUpdate("Running", true));
                    }
                    moved = true;
                }
            }
            if (Input.IsActionPressed("move_left"))
            {
                direction -= Transform.basis.x;
                moved      = true;
            }
            if (Input.IsActionPressed("move_right"))
            {
                direction += Transform.basis.x;
                moved      = true;
            }
            if (Input.IsActionPressed("jump") && IsOnFloor())
            {
                cc.y  = jump;
                moved = true;
            }
            if (Input.IsActionPressed("move_sprint") && IsOnFloor())
            {
                speed = 35;
                moved = true;
            }
            else
            {
                speed = 10;
            }

            direction.y -= gravity * delta;
            cc.y        -= gravity * delta;
            cc           = MoveAndSlide(cc, Vector3.Up, true);

            direction = direction.Normalized();
            velocity  = velocity.LinearInterpolate(direction * speed, acceleration * delta);
            velocity  = MoveAndSlide(velocity, Vector3.Up, true);
            if (GetTree().NetworkPeer != null && (moved || (velocity.Length() > 0)))
            {
                ObjectBroker.Instance.NetworkService.toServer(new ClientPositionUpdate(Translation, Rotation));
            }
        }
    }
Beispiel #18
0
 protected Vector3 SetControlPoint(float gap, Vector3 controlPoint)
 {
     return(controlPoint.Normalized() * gap * 0.7f);
 }
Beispiel #19
0
        public void DoStuff(float timeStep)
        {
            foreach (Rigidbody rb in Entity.GetAll <Rigidbody>())
            {
                if (!Entity.Has <Transform>(rb.Id))
                {
                    continue;
                }
                Transform t = Entity.Get <Transform>(rb.Id);

                foreach (Attractor atr in Entity.GetAll <Attractor>())
                {
                    Vector3 pos    = Vector3.Zero;
                    Vector3 normal = atr.Normal.Value;
                    if (Entity.Has <Transform>(atr.Id))
                    {
                        pos    = Entity.Get <Transform>(atr.Id).Position.Value;
                        normal = Entity.Get <Transform>(atr.Id).ToWorldNormal(normal);
                    }
                    if (atr.Type.Value == Attractor.AttractionType.World)
                    {
                        rb.Velocity.Value += atr.Normal.Value * atr.Acceleration.Value * (atr.UseMass.Value ? rb.Mass.Value : 1f) * timeStep;
                    }
                    else if (atr.Type.Value == Attractor.AttractionType.Point)
                    {
                        Vector3 diff = (t.Position.Value - pos);
                        float   dist = diff.Length;
                        if (dist > 0f)
                        {
                            dist = Math.Max(dist, 1f);
                        }
                        if (dist < 0f)
                        {
                            dist = Math.Min(dist, -1f);
                        }
                        rb.Velocity.Value += diff.Normalized() * (atr.Acceleration.Value * (atr.UseMass.Value ? rb.Mass.Value : 1f) / (dist * dist)) * timeStep;
                        Console.WriteLine(diff.Normalized() * (atr.Acceleration.Value * (atr.UseMass.Value ? rb.Mass.Value : 1f) / (dist * dist)) * timeStep);
                    }
                    else if (atr.Type.Value == Attractor.AttractionType.Plane)
                    {
                        float dist = Vector3.Dot(normal, pos - t.Position.Value);
                        float sign = (dist > 0f ? 1f : 0f);
                        dist = Math.Abs(dist);
                        rb.Velocity.Value += normal * sign * (atr.Acceleration.Value * (atr.UseMass.Value ? rb.Mass.Value : 1f) / (dist * dist)) * timeStep;
                    }
                }

                t.Position.Value += rb.Velocity.Value * timeStep;
                t.Rotation.Value *= Quaternion.FromMatrix(Matrix3.CreateRotationZ(rb.AngularVelocity.Value.Z * timeStep) * Matrix3.CreateRotationX(rb.AngularVelocity.Value.X * timeStep) * Matrix3.CreateRotationY(rb.AngularVelocity.Value.Y * timeStep));

                if (Entity.Has <Constraint>(rb.Id))
                {
                    Constraint c   = Entity.Get <Constraint>(rb.Id);
                    Vector3    pos = t.Position.Value;
                    pos.X            = Math.Max(c.MinPosition.Value.X, Math.Min(c.MaxPosition.Value.X, pos.X));
                    pos.Y            = Math.Max(c.MinPosition.Value.Y, Math.Min(c.MaxPosition.Value.Y, pos.Y));
                    pos.Z            = Math.Max(c.MinPosition.Value.Z, Math.Min(c.MaxPosition.Value.Z, pos.Z));
                    t.Position.Value = pos;
                }
            }
        }
Beispiel #20
0
 // Token: 0x06000139 RID: 313 RVA: 0x000095FE File Offset: 0x000077FE
 public static bool IsParallelTo(this Vector3 vector, Vector3 other, float tolerance = 1E-06f)
 {
     return(Math.Abs(1.0 - (double)Math.Abs(vector.Normalized().Dot(other.Normalized()))) <= (double)tolerance);
 }
Beispiel #21
0
        /// <summary>
        ///
        /// </summary>
        /// <returns></returns>
        private void ProcessMesh(IOScene scene, IOMesh mesh, HSD_JOBJ rootnode)
        {
            HSD_JOBJ parent = rootnode;


            if (mesh.ParentBone != null && _cache.NameToJOBJ.ContainsKey(mesh.ParentBone.Name))
            {
                parent = _cache.NameToJOBJ[mesh.ParentBone.Name];
            }


            HSD_DOBJ root = null;
            HSD_DOBJ prev = null;

            var skeleton = rootnode.BreathFirstList;

            Console.WriteLine("Processing " + mesh.Name);

            bool singleBinded = mesh.Name.Contains("SINGLE");

            foreach (var poly in mesh.Polygons)
            {
                // Skip Empty Polygon
                if (poly.Indicies.Count == 0)
                {
                    continue;
                }


                // convert to triangles
                poly.ToTriangles(mesh);

                if (poly.PrimitiveType != IOPrimitive.TRIANGLE)
                {
                    continue;
                }


                // Generate DOBJ
                HSD_DOBJ dobj = new HSD_DOBJ();

                if (Settings.ImportMeshNames)
                {
                    dobj.ClassName = mesh.Name;
                }

                if (root == null)
                {
                    root = dobj;
                }
                else
                {
                    prev.Next = dobj;
                }
                prev = dobj;


                // generate material
                var material = scene.Materials.Find(e => e.Name == poly.MaterialName);

                dobj.Mobj = GenerateMaterial(material);


                Console.WriteLine(mesh.Name + " " + material?.Name);


                // reflective mobjs do not use uvs
                var hasReflection = false;

                // bump maps need tangents and bitangents
                var hasBump = false;

                // Assess needed attributes based on the material MOBJ
                if (mesh.Name.Contains("REFLECTIVE"))
                {
                    hasReflection = true;
                }

                if (mesh.Name.Contains("BUMP"))
                {
                    hasBump = true;
                }

                if (dobj.Mobj.Textures != null)
                {
                    foreach (var t in dobj.Mobj.Textures.List)
                    {
                        if (t.Flags.HasFlag(TOBJ_FLAGS.COORD_REFLECTION))
                        {
                            hasReflection = true;
                        }
                        if (t.Flags.HasFlag(TOBJ_FLAGS.BUMP))
                        {
                            hasBump = true;
                        }
                    }
                }

                // assess attributes
                List <GXAttribName> Attributes = new List <GXAttribName>();

                if (mesh.HasEnvelopes() && Settings.ImportRigging && !singleBinded)
                {
                    Attributes.Add(GXAttribName.GX_VA_PNMTXIDX);

                    if (hasReflection)
                    {
                        Attributes.Add(GXAttribName.GX_VA_TEX0MTXIDX);
                    }

                    if (hasReflection && dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 1)
                    {
                        Attributes.Add(GXAttribName.GX_VA_TEX1MTXIDX);
                    }
                }


                Attributes.Add(GXAttribName.GX_VA_POS);


                if (hasBump)
                {
                    Attributes.Add(GXAttribName.GX_VA_NBT);
                }
                else
                if (mesh.HasNormals && Settings.ImportNormals)
                {
                    Attributes.Add(GXAttribName.GX_VA_NRM);
                }


                if (mesh.HasColorSet(0) && Settings.ImportVertexColor)
                {
                    Attributes.Add(GXAttribName.GX_VA_CLR0);
                }

                if (mesh.HasColorSet(1) && Settings.ImportVertexColor)
                {
                    Attributes.Add(GXAttribName.GX_VA_CLR1);
                }


                if (mesh.HasUVSet(0) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX0);
                }

                if ((mesh.HasUVSet(1) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 1)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX1);
                }

                if ((mesh.HasUVSet(2) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 2)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX2);
                }

                if ((mesh.HasUVSet(3) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 3)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX3);
                }

                if ((mesh.HasUVSet(4) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 4)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX4);
                }

                if ((mesh.HasUVSet(5) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 5)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX5);
                }

                if ((mesh.HasUVSet(6) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 6)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX6);
                }

                if ((mesh.HasUVSet(7) || (dobj.Mobj.Textures != null && dobj.Mobj.Textures.List.Count > 7)) && !hasReflection)
                {
                    Attributes.Add(GXAttribName.GX_VA_TEX7);
                }


                var vertices   = new List <GX_Vertex>();
                var jobjList   = new List <HSD_JOBJ[]>();
                var weightList = new List <float[]>();

                foreach (var face in poly.Indicies)
                {
                    var v = mesh.Vertices[face];

                    GX_Vertex vertex = new GX_Vertex();

                    var tkvert  = new Vector3(v.Position.X, v.Position.Y, v.Position.Z);
                    var tknrm   = new Vector3(v.Normal.X, v.Normal.Y, v.Normal.Z);
                    var tktan   = new Vector3(v.Tangent.X, v.Tangent.Y, v.Tangent.Z);
                    var tkbitan = new Vector3(v.Binormal.X, v.Binormal.Y, v.Binormal.Z);

                    var parentTransform = _cache.jobjToWorldTransform[parent].Inverted();

                    tkvert  = Vector3.TransformPosition(tkvert, parentTransform);
                    tknrm   = Vector3.TransformNormal(tknrm, parentTransform).Normalized();
                    tktan   = Vector3.TransformNormal(tktan, parentTransform).Normalized();
                    tkbitan = Vector3.TransformNormal(tkbitan, parentTransform).Normalized();


                    if (mesh.HasEnvelopes() && Settings.ImportRigging)
                    {
                        // create weighting lists
                        jobjList.Add(v.Envelope.Weights.Select(e => _cache.NameToJOBJ[e.BoneName]).ToArray());
                        weightList.Add(v.Envelope.Weights.Select(e => e.Weight).ToArray());

                        // indicate enveloped jobjs
                        foreach (var bw in v.Envelope.Weights)
                        {
                            if (!_cache.EnvelopedJOBJs.Contains(_cache.NameToJOBJ[bw.BoneName]))
                            {
                                _cache.EnvelopedJOBJs.Add(_cache.NameToJOBJ[bw.BoneName]);
                            }
                        }

                        // invert single binds
                        if (v.Envelope.Weights.Count == 1)
                        {
                            var inv = _cache.jobjToWorldTransform[_cache.NameToJOBJ[v.Envelope.Weights[0].BoneName]].Inverted();
                            tkvert  = Vector3.TransformPosition(tkvert, inv);
                            tknrm   = Vector3.TransformNormal(tknrm, inv).Normalized();
                            tktan   = Vector3.TransformNormal(tknrm, inv).Normalized();
                            tkbitan = Vector3.TransformNormal(tknrm, inv).Normalized();
                        }
                    }

                    vertex.POS   = GXTranslator.fromVector3(tkvert);
                    vertex.NRM   = GXTranslator.fromVector3(tknrm.Normalized());
                    vertex.TAN   = GXTranslator.fromVector3(tktan);
                    vertex.BITAN = GXTranslator.fromVector3(tkbitan);

                    if (Settings.InvertNormals)
                    {
                        vertex.NRM.X   *= -1;
                        vertex.NRM.Y   *= -1;
                        vertex.NRM.Z   *= -1;
                        vertex.TAN.X   *= -1;
                        vertex.TAN.Y   *= -1;
                        vertex.TAN.Z   *= -1;
                        vertex.BITAN.X *= -1;
                        vertex.BITAN.Y *= -1;
                        vertex.BITAN.Z *= -1;
                    }

                    if (mesh.HasUVSet(0))
                    {
                        vertex.TEX0 = new GXVector2(v.UVs[0].X, v.UVs[0].Y);
                    }

                    if (mesh.HasUVSet(1))
                    {
                        vertex.TEX1 = new GXVector2(v.UVs[1].X, v.UVs[1].Y);
                    }

                    if (mesh.HasUVSet(2))
                    {
                        vertex.TEX2 = new GXVector2(v.UVs[2].X, v.UVs[2].Y);
                    }

                    if (mesh.HasUVSet(3))
                    {
                        vertex.TEX3 = new GXVector2(v.UVs[3].X, v.UVs[3].Y);
                    }

                    if (mesh.HasUVSet(4))
                    {
                        vertex.TEX4 = new GXVector2(v.UVs[4].X, v.UVs[4].Y);
                    }

                    if (mesh.HasUVSet(5))
                    {
                        vertex.TEX5 = new GXVector2(v.UVs[5].X, v.UVs[5].Y);
                    }

                    if (mesh.HasUVSet(6))
                    {
                        vertex.TEX6 = new GXVector2(v.UVs[6].X, v.UVs[6].Y);
                    }

                    if (mesh.HasUVSet(7))
                    {
                        vertex.TEX7 = new GXVector2(v.UVs[7].X, v.UVs[7].Y);
                    }

                    if (mesh.HasColorSet(0))
                    {
                        vertex.CLR0 = new GXColor4(
                            v.Colors[0].X * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[0].Y * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[0].Z * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            Settings.ImportVertexAlpha ? v.Colors[0].W : 1);
                    }

                    if (mesh.HasColorSet(1))
                    {
                        vertex.CLR1 = new GXColor4(
                            v.Colors[1].X * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[1].Y * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            v.Colors[1].Z * (Settings.MultiplyVertexColorBy2 ? 2 : 1),
                            Settings.ImportVertexAlpha ? v.Colors[1].W : 1);
                    }

                    vertices.Add(vertex);
                }


                // generate pobjs
                HSD_POBJ pobj = null;

                if (mesh.HasEnvelopes() && Settings.ImportRigging && !singleBinded)
                {
                    pobj = _cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), jobjList, weightList);
                }
                else
                {
                    pobj = _cache.POBJGen.CreatePOBJsFromTriangleList(vertices, Attributes.ToArray(), null);
                }

                if (singleBinded && jobjList.Count > 0 && jobjList[0].Length > 0)
                {
                    parent = jobjList[0][0];
                }

                if (pobj != null)
                {
                    if (dobj.Pobj == null)
                    {
                        dobj.Pobj = pobj;
                    }
                    else
                    {
                        dobj.Pobj.Add(pobj);
                    }
                }
            }

            if (parent.Dobj == null)
            {
                parent.Dobj = root;
            }
            else
            {
                parent.Dobj.Add(root);
            }
        }
    //Solves for the ik chain
    private void solveIk()
    {
        if (_isRunning)
        {
            //Makes the Targetnode play nice with the skeleton by making it's values local
            Transform targetTransform = new Transform(new Basis(_targetNode.GlobalTransform.basis.Quat() * _targetSkeleton.GlobalTransform.basis.Quat()), _targetSkeleton.ToLocal(_targetNode.GlobalTransform.origin));

            //Resets the bones to the base bones in case there is a bug so that the solver doesn't stay broken
            _targetSkeleton.SetBonePose(_boneIds[0], _boneBasePose[0]);
            _targetSkeleton.SetBonePose(_boneIds[1], _boneBasePose[1]);
            _targetSkeleton.SetBonePose(_boneIds[2], _boneBasePose[2]);

            //Float to get the distance to the target from the root bone Global pose origin
            float targetDistanceSquared = targetTransform.origin.DistanceSquaredTo(LocalPoseToGlobalPose(_boneIds[0], _boneBasePose[0]).origin);

            //Checks whether the bone is in range or not
            if (targetDistanceSquared >= _maxChainLength || targetDistanceSquared <= _minChainLength)             //Out of range Solver
            {
                for (int i = 0; i < 2; i++)
                {
                    //Uses Normal math to point the chain at the target if it is out of range
                    Vector3   boneNormal    = _targetSkeleton.GetBoneGlobalPose(_boneIds[i + 1]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[i]).origin;
                    Vector3   targetNormal  = targetTransform.origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[i]).origin;
                    Transform boneTransform = _targetSkeleton.GetBoneGlobalPose(_boneIds[i]);
                    boneTransform.basis = boneTransform.basis.Rotated(boneNormal.Cross(targetNormal).Normalized(), boneNormal.AngleTo(targetNormal));

                    _targetSkeleton.SetBonePose(_boneIds[i], GlobalPoseToLocalPose(_boneIds[i], boneTransform));
                }
            }
            else             //Solve for Two Bone
            {
                //Makes a target vector based on the target and the root bone
                Vector3 targetVector = targetTransform.origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin;

                //Variable to hold lengths needed for law of cosigns
                float[,] lengths = new float[2, 3];
                //Target Triangle lengths
                lengths[0, 0] = _boneLengths[0];
                lengths[0, 1] = _boneLengths[1];
                lengths[0, 2] = targetVector.Length();

                //Current Triangle Lengths
                lengths[1, 0] = _boneLengths[0];
                lengths[1, 1] = _boneLengths[1];
                lengths[1, 2] = (_targetSkeleton.GetBoneGlobalPose(_boneIds[2]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin).Length();

                //Get Bone Vectors
                Vector3[] boneVector = new Vector3[2];
                boneVector[0] = _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[1]).origin;
                boneVector[1] = _targetSkeleton.GetBoneGlobalPose(_boneIds[2]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[1]).origin;

                //Get angles need for rotation
                float currentBoneAngle = LawOfCosigns(lengths[1, 2], lengths[1, 1], lengths[1, 0]);
                float targetBoneAngle  = LawOfCosigns(lengths[0, 2], lengths[0, 1], lengths[0, 0]);

                //Solve for the inner angle of the elbow bone by subtracting the targetAngle by the elbow's current inner angle
                float angleToRotate = targetBoneAngle - currentBoneAngle;

                //Get elbow axis of upper arm and lower arm
                Vector3 elbowAxis = (boneVector[0].Cross(boneVector[1])).Normalized();

                //Set elbow inner angle of the second bone transform with the elbowAxis
                Transform boneTransform = _targetSkeleton.GetBoneGlobalPose(_boneIds[1]);
                boneTransform.basis = boneTransform.basis.Rotated(elbowAxis, angleToRotate);

                //Set Pose of the elbow with the new transform
                _targetSkeleton.SetBonePose(_boneIds[1], GlobalPoseToLocalPose(_boneIds[1], boneTransform));

                //settings up total chain vector (Vector from the root bone to the tip bone)
                Vector3 chainVector = (_targetSkeleton.GetBoneGlobalPose(_boneIds[2]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin);

                //Get the root bone transform and rotate so that it aligns with the target Vector
                boneTransform       = _targetSkeleton.GetBoneGlobalPose(_boneIds[0]);
                boneTransform.basis = boneTransform.basis.Rotated(chainVector.Cross(targetVector).Normalized(), chainVector.AngleTo(targetVector));

                //Set Shoulder rotation
                _targetSkeleton.SetBonePose(_boneIds[0], GlobalPoseToLocalPose(_boneIds[0], boneTransform));

                //Solve for magnet
                if (_useMagnet)
                {
                    //Find the arm chain normal and use it for the normal of the plane
                    chainVector = (_targetSkeleton.GetBoneGlobalPose(_boneIds[2]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin);
                    Vector3 chainNormal = chainVector.Normalized();
                    Plane   magnetPlane = new Plane(chainNormal, 0);

                    //Project both the magnet and the elbow to said plane and return their positions;
                    Vector3 elbowProject  = magnetPlane.Project(_targetSkeleton.GetBoneGlobalPose(_boneIds[1]).origin - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin);
                    Vector3 magnetProject = magnetPlane.Project(magnetVector - _targetSkeleton.GetBoneGlobalPose(_boneIds[0]).origin);

                    //Find the signed rotation between the positions
                    float rotation = SignedAngle(elbowProject, magnetProject, chainNormal);

                    //Rotate and apply bone rotations
                    boneTransform       = _targetSkeleton.GetBoneGlobalPose(_boneIds[0]);
                    boneTransform.basis = boneTransform.basis.Rotated(chainNormal, rotation);
                    _targetSkeleton.SetBonePose(_boneIds[0], GlobalPoseToLocalPose(_boneIds[0], boneTransform));
                }
            }
            //SetEnd to be target rotation
            Transform endBoneTransform = _targetSkeleton.GetBoneGlobalPose(_boneIds[2]);
            endBoneTransform.basis = new Basis(targetTransform.basis.Quat());
            _targetSkeleton.SetBonePose(_boneIds[2], GlobalPoseToLocalPose(_boneIds[2], endBoneTransform));
        }
    }
Beispiel #23
0
 public static Vector3 Projection(Vector3 projectedVector, Vector3 directionVector)
 {
     var mag = Vector3.Dot(projectedVector, directionVector.Normalized());
     return directionVector * new Vector3(mag);
 }
Beispiel #24
0
    /// <summary>Call this method to update a single track follower on an absolute basis</summary>
    /// <param name="NewTrackPosition">The new absolute track position of the follower</param>
    /// <param name="UpdateWorldCoordinates">Whether to update the world co-ordinates</param>
    /// <param name="AddTrackInaccuracy">Whether to add track innacuracy</param>
    public void UpdateAbsolute(float NewTrackPosition, bool UpdateWorldCoordinates, bool AddTrackInaccuracy)
    {
        if (TrackIndex == 0 && (currentHost.Tracks[0].Elements == null || currentHost.Tracks[TrackIndex].Elements.Length == 0))
        {
            /*
             * Used for displaying trains in Object Viewer
             * As we have no track, just update the Z value with the new pos
             */
            WorldPosition.z = NewTrackPosition;
            return;
        }
        if (!currentHost.Tracks.ContainsKey(TrackIndex) || currentHost.Tracks[TrackIndex].Elements.Length == 0)
        {
            return;
        }
        int i = System.Math.Min(currentHost.Tracks[TrackIndex].Elements.Length - 1, LastTrackElement);

        while (i >= 0)
        {
            if (currentHost.Tracks[TrackIndex].Elements[i].InvalidElement)
            {
                var prevTrackEnded = currentHost.Tracks[TrackIndex].Elements.Select((x, j) => new { Index = j, Element = x }).Take(i + 1).LastOrDefault(x => !x.Element.InvalidElement);

                if (prevTrackEnded == null)
                {
                    break;
                }

                i = prevTrackEnded.Index;

                if (i == 0)
                {
                    break;
                }
            }

            if (NewTrackPosition >= currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition)
            {
                break;
            }
            double       ta = TrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition;
            const double tb = -0.01;
            CheckEvents(i, -1, ta, tb);
            i--;
        }

        if (i >= 0)
        {
            while (i < currentHost.Tracks[TrackIndex].Elements.Length - 1)
            {
                if (currentHost.Tracks[TrackIndex].Elements[i + 1].InvalidElement)
                {
                    var nextTrackStarted = currentHost.Tracks[TrackIndex].Elements.Select((x, j) => new { Index = j, Element = x }).Skip(i + 1).FirstOrDefault(x => !x.Element.InvalidElement);

                    if (nextTrackStarted == null)
                    {
                        break;
                    }

                    i = nextTrackStarted.Index;

                    if (i == currentHost.Tracks[TrackIndex].Elements.Length - 1)
                    {
                        break;
                    }
                }

                if (NewTrackPosition < currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition)
                {
                    break;
                }
                double ta = TrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition;
                double tb = currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition + 0.01;
                CheckEvents(i, 1, ta, tb);
                i++;
            }
        }
        else
        {
            i = 0;
        }

        float da = TrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition;
        float db = NewTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition;

        // track
        if (UpdateWorldCoordinates)
        {
            if (db != 0.0)
            {
                if (currentHost.Tracks[TrackIndex].Elements[i].CurveRadius != 0.0)
                {
                    // curve
                    float   r = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius;
                    float   p = currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.y / Godot.Mathf.Sqrt(currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.x * currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.x + currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.z * currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.z);
                    float   s = db / Godot.Mathf.Sqrt(1.0f + p * p);
                    float   h = s * p;
                    float   b = s / System.Math.Abs(r);
                    float   f = 2.0f * r * r * (1.0f - Godot.Mathf.Cos(b));
                    float   c = (float)System.Math.Sign(db) * Godot.Mathf.Sqrt(f >= 0.0f ? f : 0.0f); // todo math
                    float   a = (float)(0.5f * (double)System.Math.Sign(r) * b);
                    Vector3 D = new Vector3(currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.x, 0.0f, currentHost.Tracks[TrackIndex].Elements[i].WorldDirection.z);
                    D = D.Normalized();
                    D = D.Rotated(Vector3.Down, a);
                    WorldPosition.x = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition.x + c * D.x;
                    WorldPosition.y = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition.y + h;
                    WorldPosition.z = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition.z + c * D.z;
                    D = D.Rotated(Vector3.Down, a);
                    WorldDirection.x = D.x;
                    WorldDirection.y = (float)p;
                    WorldDirection.z = D.z;
                    WorldDirection   = WorldDirection.Normalized();
                    WorldSide        = currentHost.Tracks[TrackIndex].Elements[i].WorldSide;
                    WorldSide        = WorldSide.Rotated(Vector3.Down, 2.0f * a);
                    WorldUp          = WorldDirection.Cross(WorldSide);
                }
                else
                {
                    // straight
                    WorldPosition  = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition + db * currentHost.Tracks[TrackIndex].Elements[i].WorldDirection;
                    WorldDirection = currentHost.Tracks[TrackIndex].Elements[i].WorldDirection;
                    WorldUp        = currentHost.Tracks[TrackIndex].Elements[i].WorldUp;
                    WorldSide      = currentHost.Tracks[TrackIndex].Elements[i].WorldSide;
                    CurveRadius    = 0.0;
                }

                // cant
                if (i < currentHost.Tracks[TrackIndex].Elements.Length - 1)
                {
                    float t = db / (currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition);
                    if (t < 0.0)
                    {
                        t = 0.0f;
                    }
                    else if (t > 1.0)
                    {
                        t = 1.0f;
                    }

                    float t2 = t * t;
                    float t3 = t2 * t;
                    CurveCant =
                        (2.0f * t3 - 3.0f * t2 + 1.0f) * currentHost.Tracks[TrackIndex].Elements[i].CurveCant +
                        (t3 - 2.0f * t2 + t) * currentHost.Tracks[TrackIndex].Elements[i].CurveCantTangent +
                        (-2.0f * t3 + 3.0f * t2) * currentHost.Tracks[TrackIndex].Elements[i + 1].CurveCant +
                        (t3 - t2) * currentHost.Tracks[TrackIndex].Elements[i + 1].CurveCantTangent;
                    CurveRadius = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius;
                }
                else
                {
                    CurveCant = currentHost.Tracks[TrackIndex].Elements[i].CurveCant;
                }
            }
            else
            {
                WorldPosition  = currentHost.Tracks[TrackIndex].Elements[i].WorldPosition;
                WorldDirection = currentHost.Tracks[TrackIndex].Elements[i].WorldDirection;
                WorldUp        = currentHost.Tracks[TrackIndex].Elements[i].WorldUp;
                WorldSide      = currentHost.Tracks[TrackIndex].Elements[i].WorldSide;
                CurveRadius    = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius;
                CurveCant      = currentHost.Tracks[TrackIndex].Elements[i].CurveCant;
            }
        }
        else
        {
            if (db != 0.0)
            {
                CurveRadius = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius != 0.0 ? currentHost.Tracks[TrackIndex].Elements[i].CurveRadius : 0.0;

                if (i < currentHost.Tracks[TrackIndex].Elements.Length - 1)
                {
                    float t = db / (currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition);
                    if (t < 0.0)
                    {
                        t = 0.0f;
                    }
                    else if (t > 1.0)
                    {
                        t = 1.0f;
                    }

                    float t2 = t * t;
                    float t3 = t2 * t;
                    CurveCant =
                        (2.0f * t3 - 3.0f * t2 + 1.0f) * currentHost.Tracks[TrackIndex].Elements[i].CurveCant +
                        (t3 - 2.0f * t2 + t) * currentHost.Tracks[TrackIndex].Elements[i].CurveCantTangent +
                        (-2.0f * t3 + 3.0f * t2) * currentHost.Tracks[TrackIndex].Elements[i + 1].CurveCant +
                        (t3 - t2) * currentHost.Tracks[TrackIndex].Elements[i + 1].CurveCantTangent;
                }
                else
                {
                    CurveCant = currentHost.Tracks[TrackIndex].Elements[i].CurveCant;
                }
            }
            else
            {
                CurveRadius = currentHost.Tracks[TrackIndex].Elements[i].CurveRadius;
                CurveCant   = currentHost.Tracks[TrackIndex].Elements[i].CurveCant;
            }
        }

        AdhesionMultiplier = currentHost.Tracks[TrackIndex].Elements[i].AdhesionMultiplier;
        RainIntensity      = currentHost.Tracks[TrackIndex].Elements[i].RainIntensity;
        SnowIntensity      = currentHost.Tracks[TrackIndex].Elements[i].SnowIntensity;
        //Pitch added for Plugin Data usage
        //Mutliply this by 1000 to get the original value
        Pitch = currentHost.Tracks[TrackIndex].Elements[i].Pitch * 1000;
        // inaccuracy
        if (AddTrackInaccuracy)
        {
            float x, y, c;
            if (i < currentHost.Tracks[TrackIndex].Elements.Length - 1)
            {
                float t = db / (currentHost.Tracks[TrackIndex].Elements[i + 1].StartingTrackPosition - currentHost.Tracks[TrackIndex].Elements[i].StartingTrackPosition);
                if (t < 0.0)
                {
                    t = 0.0f;
                }
                else if (t > 1.0)
                {
                    t = 1.0f;
                }

                float x1, y1, c1;
                float x2, y2, c2;
                currentHost.Tracks[TrackIndex].GetInaccuracies(NewTrackPosition, currentHost.Tracks[TrackIndex].Elements[i].CsvRwAccuracyLevel, out x1, out y1, out c1);
                currentHost.Tracks[TrackIndex].GetInaccuracies(NewTrackPosition, currentHost.Tracks[TrackIndex].Elements[i + 1].CsvRwAccuracyLevel, out x2, out y2, out c2);
                x = (1.0f - t) * x1 + t * x2;
                y = (1.0f - t) * y1 + t * y2;
                c = (1.0f - t) * c1 + t * c2;
            }
            else
            {
                currentHost.Tracks[TrackIndex].GetInaccuracies(NewTrackPosition, currentHost.Tracks[TrackIndex].Elements[i].CsvRwAccuracyLevel, out x, out y, out c);
            }

            WorldPosition += (float)x * WorldSide + (float)y * WorldUp;

            CurveCant          += c;
            CantDueToInaccuracy = c;
        }
        else
        {
            CantDueToInaccuracy = 0.0;
        }

        // events
        CheckEvents(i, System.Math.Sign(db - da), da, db);
        //Update the odometer
        if (TrackPosition != NewTrackPosition)
        {
            //HACK: Reset the odometer if we've moved more than 10m this frame
            if (System.Math.Abs(NewTrackPosition - TrackPosition) > 10)
            {
                Odometer = 0;
            }
            else
            {
                Odometer += NewTrackPosition - TrackPosition;
            }
        }

        // finish
        TrackPosition    = NewTrackPosition;
        LastTrackElement = i;
    }
Beispiel #25
0
 public Ray (Vector3 position, Vector3 direction)
 {
   Position = position;
   Direction = direction.Normalized();
 }
Beispiel #26
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="targetID"></param>
        /// <param name="attackerID"></param>
        /// <param name="damage"></param>
        /// <param name="kickImpulse"></param>
        /// <param name="kickPoint"></param>
        /// <param name="damageType"></param>
        public override bool Damage(uint targetID, uint attackerID, short damage, Vector3 kickImpulse, Vector3 kickPoint, DamageType damageType)
        {
            if (damage <= 0)
            {
                return(false);
            }

            var c = controller;
            var e = Entity;

            c.SupportFinder.ClearSupportData();
            var i = MathConverter.Convert(kickImpulse);
            var p = MathConverter.Convert(kickPoint);

            c.Body.ApplyImpulse(p, i);

            /**************************************************
            *
            *	1. Accumulate damage and emit FX according to
            *	maximum inflicted damage.
            *	Probably we have to add new controller stage
            *	for FX processing (e.g. Update and UpdateFX).
            *
            *	2. Do not scream at each damage.
            *	Screams should not overlap!
            *
            **************************************************/

            //
            //	calc health :
            //
            var health = e.GetItemCount(Inventory.Health);

            health -= damage;

            var dir = kickImpulse.Normalized();

            if (health > 75)
            {
                World.SpawnFX("PlayerPain25", targetID, kickPoint, dir);
            }
            else
            if (health > 50)
            {
                World.SpawnFX("PlayerPain50", targetID, kickPoint, dir);
            }
            else
            if (health > 25)
            {
                World.SpawnFX("PlayerPain75", targetID, kickPoint, dir);
            }
            else
            if (health > 0)
            {
                World.SpawnFX("PlayerPain100", targetID, kickPoint, dir);
            }
            else
            if (health > -25)
            {
                World.SpawnFX("PlayerDeath", targetID, e.Position, dir);
            }
            else
            {
                World.SpawnFX("PlayerDeathMeat", targetID, e.Position, kickImpulse, dir);
            }

            if (health <= 0)
            {
                World.Kill(targetID);
                return(true);
            }

            e.SetItemCount(Inventory.Health, health);

            return(false);
        }
 /// <summary>
 /// Sets the target and current rotation points of the entity to a set of yaw, pitch, and
 /// roll values extracted from a direction vector. The rotation itself occurs in the 
 /// Update method.
 /// </summary>
 /// <param name="direction">A vector representing the direction to face.</param>
 /// <param name="roll">The angle in degrees to rotate to around the Z axis.</param>
 void RotateImmediate(Vector3 direction, float roll)
 {
     Vector3 vec = direction.Normalized();
     float yawDot = Vector3.Dot(vec, Vector3.UnitZ);
     float pitchDot = Vector3.Dot(vec, Vector3.UnitY);
     float yaw = 1.0F / (float)System.Math.Cos(yawDot);
     float pitch = 1.0F / (float)System.Math.Cos(pitchDot);
     _Yaw = yaw;
     _Pitch = pitch;
     _Roll = roll;
     _TargetYaw = yaw;
     _TargetPitch = pitch;
     _TargetRoll = roll;
 }
Beispiel #28
0
    public Vector3 Move(Vector3 Momentum, float Delta, int MaxSlideCount, float MaxAngle, float Snap)
    {
        Vector3 Movement = Momentum * Delta;

        if (Momentum.y <= 0)
        {
            Vector3            OriginalTranslation = Translation;
            var                SnapVec             = new Vector3(0, (-Snap - 0.1f) * Delta, 0);
            KinematicCollision SnapCollision       = MoveAndCollide(SnapVec);
            if (SnapCollision != null && Acos(SnapCollision.Normal.Dot(new Vector3(0, 1, 0))) <= Deg2Rad(MaxAngle))
            {
                float TargetHLength = Movement.Flattened().Length();
                Movement = Movement.Slide(SnapCollision.Normal);
                float NewHLength = Movement.Flattened().Length();
                if (TargetHLength != 0 && NewHLength != 0)                //Protect against division by zero
                {
                    Movement *= TargetHLength / Movement.Flattened().Length();
                }

                OnFloor = true;

                if (Momentum.Flattened().Length() <= 0.5f)
                {
                    Translation = OriginalTranslation;
                    Momentum.y  = 0;                    //On floor so zero out vertical momentum
                    return(Momentum);
                }
            }
            else
            {
                Translation = OriginalTranslation;
                OnFloor     = false;
            }
        }
        else
        {
            OnFloor = false;
        }

        int   SlideCount = 0;
        float Traveled   = 0f;

        while (SlideCount <= MaxSlideCount)
        {
            Movement = Movement.Normalized() * (Movement.Length() - Traveled);
            KinematicCollision Collision = MoveAndCollide(Movement);
            if (Collision == null)
            {
                break;                 //No collision, reached destination
            }
            Traveled += Collision.Travel.Length();
            if (Traveled >= Movement.Length())
            {
                break;                 //Reached destination
            }
            SlideCount += 1;

            Movement = Movement.Slide(Collision.Normal);
            if (Acos(Collision.Normal.Dot(new Vector3(0, 1, 0))) <= Deg2Rad(MaxAngle))
            {
                OnFloor = true;
            }
            else
            {
                Momentum = Momentum.Slide(Collision.Normal);
            }
        }

        if (OnFloor)
        {
            Momentum.y = 0;             //On floor so zero out vertical momentum
        }
        return(Momentum);
    }
Beispiel #29
0
        public void CreateFromPanorama(string file)
        {
            int texSize = 1024;
            var src     = new ImageTexture(file);

            ImageTexture Create(int faceIndex)
            {
                var data = new Byte[texSize * texSize * 3];

                void SetPixel(int u, int v, Color32 color)
                {
                    var p = texSize * 3 * v + u * 3;

                    data[p]     = (byte)(color.r * 255 + 0.5f);
                    data[p + 1] = (byte)(color.g * 255 + 0.5f);
                    data[p + 2] = (byte)(color.b * 255 + 0.5f);
                }

                Vector3[] vDirA = new Vector3[4];
                if (faceIndex == FACE_FRONT)
                {
                    vDirA[0] = new Vector3(-1.0f, -1.0f, -1.0f);
                    vDirA[1] = new Vector3(1.0f, -1.0f, -1.0f);
                    vDirA[2] = new Vector3(-1.0f, 1.0f, -1.0f);
                    vDirA[3] = new Vector3(1.0f, 1.0f, -1.0f);
                }
                else if (faceIndex == FACE_BACK)
                {
                    vDirA[0] = new Vector3(1.0f, -1.0f, 1.0f);
                    vDirA[1] = new Vector3(-1.0f, -1.0f, 1.0f);
                    vDirA[2] = new Vector3(1.0f, 1.0f, 1.0f);
                    vDirA[3] = new Vector3(-1.0f, 1.0f, 1.0f);
                }
                else if (faceIndex == FACE_LEFT)
                {
                    vDirA[0] = new Vector3(1.0f, -1.0f, -1.0f);
                    vDirA[1] = new Vector3(1.0f, -1.0f, 1.0f);
                    vDirA[2] = new Vector3(1.0f, 1.0f, -1.0f);
                    vDirA[3] = new Vector3(1.0f, 1.0f, 1.0f);
                }
                else if (faceIndex == FACE_RIGHT)
                {
                    vDirA[0] = new Vector3(-1.0f, -1.0f, 1.0f);
                    vDirA[1] = new Vector3(-1.0f, -1.0f, -1.0f);
                    vDirA[2] = new Vector3(-1.0f, 1.0f, 1.0f);
                    vDirA[3] = new Vector3(-1.0f, 1.0f, -1.0f);
                }
                else if (faceIndex == FACE_UP)
                {
                    vDirA[0] = new Vector3(-1.0f, 1.0f, -1.0f);
                    vDirA[1] = new Vector3(1.0f, 1.0f, -1.0f);
                    vDirA[2] = new Vector3(-1.0f, 1.0f, 1.0f);
                    vDirA[3] = new Vector3(1.0f, 1.0f, 1.0f);
                }
                else if (faceIndex == FACE_DOWN)
                {
                    vDirA[0] = new Vector3(-1.0f, -1.0f, 1.0f);
                    vDirA[1] = new Vector3(1.0f, -1.0f, 1.0f);
                    vDirA[2] = new Vector3(-1.0f, -1.0f, -1.0f);
                    vDirA[3] = new Vector3(1.0f, -1.0f, -1.0f);
                }

                Vector3 rotDX1 = (vDirA[1] - vDirA[0]) / (float)texSize;
                Vector3 rotDX2 = (vDirA[3] - vDirA[2]) / (float)texSize;

                float dy = 1.0f / (float)texSize;
                float fy = 0.0f;


                for (int y = 0; y < texSize; y++)
                {
                    Vector3 xv1 = vDirA[0];
                    Vector3 xv2 = vDirA[2];
                    for (int x = 0; x < texSize; x++)
                    {
                        Vector3 v = ((xv2 - xv1) * fy) + xv1;
                        v = v.Normalized();
                        SetPixel(x, y, Spherical(v));
                        xv1 += rotDX1;
                        xv2 += rotDX2;
                    }
                    fy += dy;
                }
                return(new ImageTexture(data, texSize, texSize));
            }

            Color32 Spherical(Vector3 vDir)
            {
                float theta       = Mathf.Atan2(vDir.z, vDir.x);
                float phi         = Mathf.Acos(vDir.y);
                var   m_direction = 0;

                theta += m_direction * Mathf.PI / 180.0f;
                while (theta < -Mathf.PI)
                {
                    theta += Mathf.PI + Mathf.PI;
                }
                while (theta > Mathf.PI)
                {
                    theta -= Mathf.PI + Mathf.PI;
                }

                float dx = theta / Mathf.PI;
                float dy = phi / Mathf.PI;

                dx = dx * 0.5f + 0.5f;
                int px = (int)(dx * src.w);

                if (px < 0)
                {
                    px = 0;
                }
                if (px >= src.w)
                {
                    px = src.w - 1;
                }
                int py = (int)(dy * src.w);

                if (py < 0)
                {
                    py = 0;
                }
                if (py >= src.w)
                {
                    py = src.w - 1;
                }
                //Console.WriteLine(px+"-"+ (src.w - py - 1)+"--"+src.w+"-"+py);
                Color32 col = src.GetPixel(px, src.w - py - 1);

                return(col);
            }

            buffer[0] = Create(FACE_FRONT);
            buffer[1] = Create(FACE_UP);
            buffer[2] = Create(FACE_LEFT);
            buffer[3] = Create(FACE_BACK);
            buffer[4] = Create(FACE_DOWN);
            buffer[5] = Create(FACE_RIGHT);

            for (int i = 0; i < 6; i++)
            {
                buffer[i].Save("sky" + i);
            }
        }
Beispiel #30
0
        private RootEntity ParseTmd(BinaryReader reader, string fileTitle)
        {
            var flags = reader.ReadUInt32();

            if (flags != 0 && flags != 1)
            {
                return(null);
            }

            var nObj = reader.ReadUInt32();

            if (nObj == 0 || nObj > Program.MaxTMDObjects)
            {
                return(null);
            }

            var models = new List <ModelEntity>();

            var objBlocks = new ObjBlock[nObj];

            var objOffset = reader.BaseStream.Position;

            for (var o = 0; o < nObj; o++)
            {
                var vertTop      = reader.ReadUInt32();
                var nVert        = reader.ReadUInt32();
                var normalTop    = reader.ReadUInt32();
                var nNormal      = reader.ReadUInt32();
                var primitiveTop = reader.ReadUInt32();
                var nPrimitive   = reader.ReadUInt32();
                var scale        = reader.ReadInt32();

                if (flags == 0)
                {
                    vertTop      += (uint)objOffset;
                    normalTop    += (uint)objOffset;
                    primitiveTop += (uint)objOffset;
                }

                if (nPrimitive > Program.MaxTMDPrimitives)
                {
                    return(null);
                }

                objBlocks[o] = new ObjBlock
                {
                    VertTop      = vertTop,
                    NVert        = nVert,
                    NormalTop    = normalTop,
                    NNormal      = nNormal,
                    PrimitiveTop = primitiveTop,
                    NPrimitive   = nPrimitive,
                    Scale        = scale
                };
            }

            for (uint o = 0; o < objBlocks.Length; o++)
            {
                var objBlock = objBlocks[o];

                var vertices = new Vector3[objBlock.NVert];
                if (Program.IgnoreTmdVersion && objBlock.VertTop < _offset)
                {
                    return(null);
                }
                reader.BaseStream.Seek(objBlock.VertTop, SeekOrigin.Begin);
                for (var v = 0; v < objBlock.NVert; v++)
                {
                    var vx  = reader.ReadInt16();
                    var vy  = reader.ReadInt16();
                    var vz  = reader.ReadInt16();
                    var pad = reader.ReadInt16();
                    if (pad != 0)
                    {
                        if (Program.Debug)
                        {
                            Program.Logger.WriteLine($"Found suspicious pad value of: {pad} at index:{v}");
                        }
                    }
                    var vertex = new Vector3
                    {
                        X = vx,
                        Y = vy,
                        Z = vz
                    };
                    vertices[v] = vertex;
                }

                var normals = new Vector3[objBlock.NNormal];
                if (Program.IgnoreTmdVersion && objBlock.NormalTop < _offset)
                {
                    return(null);
                }
                reader.BaseStream.Seek(objBlock.NormalTop, SeekOrigin.Begin);
                for (var n = 0; n < objBlock.NNormal; n++)
                {
                    var nx  = TMDHelper.ConvertNormal(reader.ReadInt16());
                    var ny  = TMDHelper.ConvertNormal(reader.ReadInt16());
                    var nz  = TMDHelper.ConvertNormal(reader.ReadInt16());
                    var pad = reader.ReadInt16();
                    if (pad != 0)
                    {
                        if (Program.Debug)
                        {
                            Program.Logger.WriteLine($"Found suspicious pad value of: {pad} at index:{n}");
                        }
                    }
                    var normal = new Vector3
                    {
                        X = nx,
                        Y = ny,
                        Z = nz
                    };
                    normals[n] = normal.Normalized();
                }

                var groupedTriangles = new Dictionary <uint, List <Triangle> >();

                reader.BaseStream.Seek(objBlock.PrimitiveTop, SeekOrigin.Begin);
                if (Program.IgnoreTmdVersion && objBlock.PrimitiveTop < _offset)
                {
                    return(null);
                }

                if (Program.Debug)
                {
                    Program.Logger.WriteLine($"Primitive count:{objBlock.NPrimitive} {fileTitle}");
                }
                for (var p = 0; p < objBlock.NPrimitive; p++)
                {
                    var olen            = reader.ReadByte();
                    var ilen            = reader.ReadByte();
                    var flag            = reader.ReadByte();
                    var mode            = reader.ReadByte();
                    var offset          = reader.BaseStream.Position;
                    var packetStructure = TMDHelper.CreateTMDPacketStructure(flag, mode, reader, p);
                    if (packetStructure != null)
                    {
                        TMDHelper.AddTrianglesToGroup(groupedTriangles, packetStructure, delegate(uint index)
                        {
                            if (index >= vertices.Length)
                            {
                                if (Program.IgnoreTmdVersion)
                                {
                                    return(new Vector3(index, 0, 0));
                                }
                                Program.Logger.WriteErrorLine("Vertex index error : " + fileTitle);
                                throw new Exception("Vertex index error: " + fileTitle);
                            }
                            return(vertices[index]);
                        }, delegate(uint index)
                        {
                            if (index >= normals.Length)
                            {
                                if (Program.IgnoreTmdVersion)
                                {
                                    return(new Vector3(index, 0, 0));
                                }
                                Program.Logger.WriteErrorLine("Vertex index error: " + fileTitle);
                                throw new Exception("Vertex index error: " + fileTitle);
                            }
                            return(normals[index]);
                        });
                    }
                    var newOffset = offset + ilen * 4;
                    if (Program.IgnoreTmdVersion && newOffset < _offset)
                    {
                        return(null);
                    }
                    reader.BaseStream.Seek(newOffset, SeekOrigin.Begin);
                }

                foreach (var kvp in groupedTriangles)
                {
                    var triangles = kvp.Value;
                    if (triangles.Count > 0)
                    {
                        var model = new ModelEntity
                        {
                            Triangles   = triangles.ToArray(),
                            TexturePage = kvp.Key,
                            TMDID       = o
                        };
                        models.Add(model);
                    }
                }
            }

            if (models.Count > 0)
            {
                var entity = new RootEntity();
                foreach (var model in models)
                {
                    model.ParentEntity = entity;
                }
                entity.ChildEntities = models.ToArray();
                entity.ComputeBounds();
                return(entity);
            }
            return(null);
        }
 public FPlane(Vector3 normal, Vector3 pointOnPlane)
 {
     Normal = normal.Normalized();
     Distance = -Vector3.Dot(normal, pointOnPlane);
 }
Beispiel #32
0
        public void updateExecution(float timeElapsed)
        {
            if (timeElapsed <= 0f)
            {
                return;
            }

            var mParams = _missile.cluster.parameters;
            var target  = _missile.cluster.target;

            // basic proportional navigation. see wikipedia
            Vector3 Vr    = target.velocity - _missile.velocity;
            Vector3 R     = target.position - _missile.position;
            Vector3 omega = Vector3.Cross(R, Vr) / R.LengthSquared;
            Vector3 latax = mParams.pursuitNavigationGain * Vector3.Cross(Vr, omega);

            if (mParams.pursuitAugmentedPN == true)
            {
                // this code is not tested as there are currently no targets with well defined accelerations
                Vector3 losDir       = R.Normalized();
                float   targetAccLos = Vector3.Dot(target.acceleration, losDir);
                Vector3 targetLatAx  = target.acceleration - targetAccLos * losDir;
                latax += mParams.pursuitNavigationGain * targetLatAx / 2f;
            }
            _missile._lataxDebug = latax;

            // apply latax
            var oldVelMag = _missile.velocity.LengthFast;

            _missile.velocity += latax * timeElapsed;
            float tempVelMag = _missile.velocity.LengthFast;

            if (oldVelMag != 0f)
            {
                float r = tempVelMag / oldVelMag;
                if (r > 1f)
                {
                    _missile.velocity /= r;
                }
            }

            if (mParams.pursuitHitTimeCorrection)
            {
                // apply pursuit hit time correction
                float dist = R.LengthFast;
                if (dist != 0f)
                {
                    Vector3 targetDir        = R / dist;
                    float   v0               = -Vector3.Dot(Vr, targetDir);
                    float   t                = _missile.cluster.timeToHit;
                    float   correctionAccMag = 2f * (dist - v0 * t) / t / t;
                    Vector3 corrAcc          = correctionAccMag * targetDir;
                    _missile.velocity            += corrAcc * timeElapsed;
                    _missile._hitTimeCorrAccDebug = corrAcc;
                }
            }
            else
            {
                // hit time correction inactive. allow accelerating to achieve optimal velocity or forever
                oldVelMag = _missile.velocity.LengthFast;
                float velDelta  = mParams.pursuitMaxAcc * timeElapsed;
                float newVelMag = Math.Min(oldVelMag + velDelta, mParams.pursuitMaxVelocity);
                if (oldVelMag != 0f)
                {
                    _missile.velocity *= (newVelMag / oldVelMag);
                }
            }

            // make visual direction "lean into" velocity
            Vector3 axis;
            float   angle;

            OpenTKHelper.neededRotation(_missile.visualDirection, _missile.velocity.Normalized(),
                                        out axis, out angle);
            float abs = Math.Abs(angle);

            if (abs > mParams.pursuitVisualRotationRate && abs > 0f)
            {
                angle = angle / abs * mParams.pursuitVisualRotationRate;
            }
            Quaternion quat = Quaternion.FromAxisAngle(axis, angle);

            _missile.visualDirection = Vector3.Transform(_missile.visualDirection, quat);
        }
Beispiel #33
0
 public FRay(Vector3 startPosition, Vector3 direction)
 {
     StartPosition = startPosition;
     Direction     = direction.Normalized();
 }
Beispiel #34
0
 public void Normalize()
 {
     Vector3 v1 = new Vector3(-10.5f, 0.2f, 1000.0f);
     Vector3 v2 = new Vector3(-10.5f, 0.2f, 1000.0f);
     v1.Normalize();
     var expectedResult = new Vector3(-0.0104994215f, 0.000199988979f, 0.999944866f);
     Assert.That(expectedResult, Is.EqualTo(v1).Using(Vector3Comparer.Epsilon));
     var normalizedV2 = Vector3.Normalize(v2);
     Assert.That(expectedResult, Is.EqualTo(normalizedV2).Using(Vector3Comparer.Epsilon));
     Assert.That(expectedResult, Is.EqualTo(v2.Normalized()).Using(Vector3Comparer.Epsilon));
     Assert.That(expectedResult, Is.Not.EqualTo(v2).Using(Vector3Comparer.Epsilon));
 }
Beispiel #35
0
        protected void moveShips(float timeElapsed)
        {
            if (timeElapsed <= 0f)
            {
                return;
            }

            // make the target drone move from side to side
            localTime += timeElapsed;
            //localTime += timeElapsed * 0.3f;
            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 angle = localTime * 0.01f;
            #if true
            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);
            #else
            float desiredXOffset = 100f * (float)Math.Cos(angle);
            float desiredYOffset = 100f * (float)Math.Sin(angle);
            float desiredZOffset = 0f;
            #endif

            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.neededRotationQuat(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.neededRotationQuat(Vector3.UnitZ, desiredDir);
            vandalShip.Orient(desiredDir, Vector3.Transform(Vector3.UnitY, vandalOrient));
        }
Beispiel #36
0
        static TriangleIntersection RayIntersectsTriangle(Ray r, Vector3 v0, Vector3 v1, Vector3 v2, Vector3 n0, Vector3 n1, Vector3 n2)
        {
            Vector3 e1, e2, h, s, q;
            float   a, f, u, v;

            e1 = v1 - v0;
            e2 = v2 - v0;

            h = Vector3.Cross(r.dir, e2);
            a = Vector3.Dot(e1, h);


            if (a > -0.00001 && a < 0.00001)
            {
                return(new TriangleIntersection(false));
            }

            f = 1 / a;
            s = r.pos - v0;
            u = f * (Vector3.Dot(s, h));

            if (u < 0.0 || u > 1.0)
            {
                return(new TriangleIntersection(false));
            }

            q = Vector3.Cross(s, e1);
            v = f * Vector3.Dot(r.dir, q);

            if (v < 0.0 || u + v > 1.0)
            {
                return(new TriangleIntersection(false));
            }

            // at this stage we can compute t to find out where
            // the intersection point is on the line
            float t = f * Vector3.Dot(e2, q);

            Vector3 normal = new Vector3();

            if (t <= 0.00001) // ray intersection
            {
                return(new TriangleIntersection(false, t, normal));
            }
            Vector3 p = r.pos + r.dir * t;

            float area;
            float w0, w1, w2;

            area = edgeFunction(v0, v1, v2, 0);
            w0   = edgeFunction(v1, v2, p, 0);
            w1   = edgeFunction(v2, v0, p, 0);
            w2   = edgeFunction(v0, v1, p, 0);
            w0  /= area;
            w1  /= area;
            w2  /= area;
            if (float.IsNaN(w0) || float.IsNaN(w1) || float.IsNaN(w2) || float.IsInfinity(w0) || float.IsInfinity(w1) || float.IsInfinity(w2))
            {
                area = edgeFunction(v0, v1, v2, 1);
                w0   = edgeFunction(v1, v2, p, 1);
                w1   = edgeFunction(v2, v0, p, 1);
                w2   = edgeFunction(v0, v1, p, 1);
                w0  /= area;
                w1  /= area;
                w2  /= area;
                if (float.IsNaN(w0) || float.IsNaN(w1) || float.IsNaN(w2) || float.IsInfinity(w0) || float.IsInfinity(w1) || float.IsInfinity(w2))
                {
                    area = edgeFunction(v0, v1, v2, 2);
                    w0   = edgeFunction(v1, v2, p, 2);
                    w1   = edgeFunction(v2, v0, p, 2);
                    w2   = edgeFunction(v0, v1, p, 2);
                    w0  /= area;
                    w1  /= area;
                    w2  /= area;
                }
            }
            normal[0] = w0 * n0[0] + w1 * n1[0] + w2 * n2[0];
            normal[1] = w0 * n0[1] + w1 * n1[1] + w2 * n2[1];
            normal[2] = w0 * n0[2] + w1 * n1[2] + w2 * n2[2];
            return(new TriangleIntersection(true, t, normal.Normalized()));
        }
Beispiel #37
0
        public static bool CheckAndCleanMeshIssues(ref List <DTriangle> triangle, List <Vector3> vertex, bool removeSmallInvalidTriangles, out string issues)
        {
            const float  kLengthEpsilon         = 0.0001f;
            const float  kDotEpsilon            = 0.99999f;
            const double kUVEpsilon             = 0.000001;
            const double kMaxAreaForAutoRemoval = 0.0003;

            Vector3[] verts = new Vector3[3];

            bool result = false;

            System.Text.StringBuilder builder = new System.Text.StringBuilder();

            List <BadTriangle> badTriangleIndices = new List <BadTriangle>();

            foreach (int triIdx in Enumerable.Range(0, triangle.Count))
            {
                var tri = triangle[triIdx];
                if (tri.vert.Length != 3)
                {
                    builder.AppendFormat("-- Polygon is not 3 verts\n");
                    result = true;
                    badTriangleIndices.Add(new BadTriangle()
                    {
                        index = triIdx, reason = BadTriangleReason.ZeroArea
                    });
                    continue;
                }

                for (int i = 0; i < 3; ++i)
                {
                    verts[i] = vertex[tri.vert[i]];
                }

                Vector3 edge0 = verts[0] - verts[1];
                Vector3 edge1 = verts[2] - verts[1];
                Vector3 edge2 = verts[0] - verts[2];

                bool isZeroAreaTriangle = false;
                bool isBadUVTriangle    = false;

                if (edge0.Length <= kLengthEpsilon)
                {
                    builder.AppendFormat("-- triangle in polygon {3} edge0 is collapsed {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString(), tri.poly_num.ToString());
                    isZeroAreaTriangle = true;
                }
                if (edge1.Length <= kLengthEpsilon)
                {
                    builder.AppendFormat("-- triangle in polygon {3} edge1 is collapsed {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString(), tri.poly_num.ToString());
                    isZeroAreaTriangle = true;
                }
                if (edge2.Length <= kLengthEpsilon)
                {
                    builder.AppendFormat("-- triangle in polygon {3} edge2 is collapsed {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString(), tri.poly_num.ToString());
                    isZeroAreaTriangle = true;
                }

                if (!isZeroAreaTriangle)
                {
                    float edge_dot = Math.Abs(Vector3.Dot(edge0.Normalized(), edge1.Normalized()));
                    if (edge_dot >= kDotEpsilon)
                    {
                        builder.AppendFormat("-- triangle has no area {0} {1} {2}\n", verts[0].ToString(), verts[1].ToString(), verts[2].ToString());
                        isZeroAreaTriangle = true;
                    }
                }

                // Check UVs to make sure there is a gradient
                Vector2 w1 = tri.tex_uv[0];
                Vector2 w2 = tri.tex_uv[1];
                Vector2 w3 = tri.tex_uv[2];
                double  s1 = w2.X - w1.X;
                double  s2 = w3.X - w1.X;
                double  t1 = w2.Y - w1.Y;
                double  t2 = w3.Y - w1.Y;

                double den = (s1 * t2 - s2 * t1);
                if (Math.Abs(den) <= kUVEpsilon)
                {
                    double area = CalculateTriangleArea(edge0, edge1, edge2);
                    if (area <= kMaxAreaForAutoRemoval)
                    {
                        builder.AppendFormat("-- triangle has invalid UVs {0} {1} {2} -- area {3} (REMOVING)\n", w1.ToString(), w2.ToString(), w3.ToString(), area);
                        isZeroAreaTriangle = true;
                    }
                    else
                    {
                        builder.AppendFormat("-- triangle has invalid UVs {0} {1} {2} -- area {3} (FIXING)\n", w1.ToString(), w2.ToString(), w3.ToString(), area);
                        isBadUVTriangle = true;
                    }
                }

                if (isZeroAreaTriangle)
                {
                    result = true;

                    // Calculate the area of the triangle
                    double triangleArea = CalculateTriangleArea(edge0, edge1, edge2);
                    if (triangleArea < kMaxAreaForAutoRemoval)
                    {
                        badTriangleIndices.Add(new BadTriangle()
                        {
                            index = triIdx, reason = BadTriangleReason.ZeroArea
                        });
                    }
                }
                else if (isBadUVTriangle)
                {
                    result = true;
                    badTriangleIndices.Add(new BadTriangle()
                    {
                        index = triIdx, reason = BadTriangleReason.BadUV
                    });
                }
            }

            if (removeSmallInvalidTriangles && badTriangleIndices.Count > 0)
            {
                List <DTriangle> newTriangles = new List <DTriangle>();
                int numRemoved = 0;

                int numBadTriangles = badTriangleIndices.Count;
                int badIndex        = 0;
                foreach (int srcTriIndex in Enumerable.Range(0, triangle.Count))
                {
                    if (badIndex < numBadTriangles && badTriangleIndices[badIndex].index == srcTriIndex)
                    {
                        bool skipThis = false;
                        switch (badTriangleIndices[badIndex++].reason)
                        {
                        case BadTriangleReason.ZeroArea: {
                            skipThis = true;
                        }
                        break;

                        case BadTriangleReason.BadUV: {
                            DTriangle tri = triangle[srcTriIndex];
                            tri.tex_uv[1] = tri.tex_uv[1] + new Vector2(0.1f, 0.1f);
                            tri.tex_uv[2] = tri.tex_uv[2] - new Vector2(0.1f, 0.1f);
                        }
                        break;
                        }
                        if (skipThis)
                        {
                            ++numRemoved;
                            continue;
                        }
                    }

                    newTriangles.Add(triangle[srcTriIndex]);
                }

                triangle = newTriangles;
                builder.AppendFormat("Removed {0} triangles\n", numRemoved);
            }

            issues = builder.ToString();

            return(result);
        }
Beispiel #38
0
        protected override void onClickOculusTrigger(ref VREvent_t vrEvent)
        {
            primaryDeviceIndex = vrEvent.trackedDeviceIndex;
            if (currentState != State.READY || targetPRhObjID == Guid.Empty)
            {
                return;
            }

            pointOnObjRef = new ObjRef(targetPRhObjID);
            //chage to only raycasting to the obj where we draw, if not snap to the origin
            if (!(projectP.X == 0 && projectP.Y == 0 && projectP.Z == 0))
            {
                rayCastingObjs.Clear();
                rayCastingObjs.Add(pointOnObjRef);
            }

            //testing
            Vector3 projectPVR = UtilOld.platformToVRPoint(ref mScene, UtilOld.RhinoToOpenTKPoint(projectP));

            mScene.iPointList.Add(UtilOld.platformToVRPoint(ref mScene, projectPVR)); //not use at the current version, point is VR coordinate
            pointsList.Add(projectP);

            //render edit points in VR
            Geometry.Geometry geo = new Geometry.DrawPointMarker(new Vector3(0, 0, 0));
            Material.Material m   = new Material.SingleColorMaterial(0, 1, 0, 1);
            SceneNode         editPointSN;

            UtilOld.MarkPointVR(ref mScene, projectPVR, ref geo, ref m, out editPointSN);
            pointMarkers.Add(editPointSN);

            //TODO-hide two other design plane
            if (pointMarkers.Count == 1)
            {
                if (pointOnObjRef != null && drawnType == DrawnType.Plane)
                {
                    if (!(projectP.X == 0 && projectP.Y == 0 && projectP.Z == 0))
                    {
                        UtilOld.hideOtherPlanes(ref mScene, pointOnObjRef.Object().Attributes.Name);
                    }
                    computeContourCurve();
                }
                //TODO- how to find the curvePlane on the surface like teapot body, using the normal of first point?
                //do we need to use different ways for patch surface and other generated surface
                else if (pointOnObjRef != null && drawnType == DrawnType.Surface)
                {
                    computeContourCurve();
                }
            }

            if (maxNumPoint == pointMarkers.Count)
            {
                //Assume we always can find a curvePlane sicnce we use a huge tolerance
                NurbsCurve modelcurve = null;
                Brep       modelBrep;
                string     modelName = "";
                if (shapeType == ShapeType.Circle)
                {
                    float  radius = (float)Math.Sqrt(Math.Pow(pointsList[1].X - pointsList[0].X, 2) + Math.Pow(pointsList[1].Y - pointsList[0].Y, 2) + Math.Pow(pointsList[1].Z - pointsList[0].Z, 2));
                    Circle circle = new Rhino.Geometry.Circle(curvePlane, pointsList[0], radius);
                    modelcurve = circle.ToNurbsCurve();
                    modelName  = "Circle";
                }
                else if (shapeType == ShapeType.Rect)
                {
                    Vector3 rectDiagonalV = new Vector3((float)(pointsList[0].X - pointsList[1].X), (float)(pointsList[0].Y - pointsList[1].Y), (float)(pointsList[0].Z - pointsList[1].Z));
                    float   lenDiagonal   = rectDiagonalV.Length;
                    Vector3 rectLeftTop   = new Vector3((float)pointsList[0].X, (float)pointsList[0].Y, (float)pointsList[0].Z) + lenDiagonal * rectDiagonalV.Normalized();
                    Point3d topLeftP      = new Point3d(rectLeftTop.X, rectLeftTop.Y, rectLeftTop.Z);

                    Rectangle3d rect = new Rectangle3d(curvePlane, topLeftP, pointsList[1]);

                    //using top-left cornel and bottom right

                    //Rectangle3d rect = new Rectangle3d(curvePlane, pointsList[0], pointsList[1]);

                    modelcurve = rect.ToNurbsCurve();
                    modelName  = "Rect";
                }

                /*
                 * Brep[] shapes = Brep.CreatePlanarBreps(modelcurve);
                 * modelBrep = shapes[0];
                 * Guid guid = Util.addRhinoObjectSceneNode(ref mScene, ref modelBrep, ref profile_m, modelName, out renderObjSN);
                 */

                //generate new curveOnObj for mvoingPlane cases sicne and move the XYZPlanes to origial positons
                if (drawnType == DrawnType.Plane)
                {
                    Rhino.Geometry.Vector3d newNormal = new Rhino.Geometry.Vector3d();;
                    Point3d newOrigin   = new Point3d();
                    String  planeName   = pointOnObjRef.Object().Attributes.Name;
                    Point3d planeOrigin = pointOnObjRef.Object().Geometry.GetBoundingBox(true).Center;
                    if (planeName.Contains("planeXY"))
                    {
                        newNormal = new Rhino.Geometry.Vector3d(0, 0, 1);
                        newOrigin = new Point3d(0, 0, planeOrigin.Z);
                    }
                    else if (planeName.Contains("planeYZ"))
                    {
                        newNormal = new Rhino.Geometry.Vector3d(1, 0, 0);
                        newOrigin = new Point3d(planeOrigin.X, 0, 0);
                    }
                    else if (planeName.Contains("planeXZ"))
                    {
                        newNormal = new Rhino.Geometry.Vector3d(0, 1, 0);
                        newOrigin = new Point3d(0, planeOrigin.Y, 0);
                    }

                    Plane        newPlane      = new Plane(newOrigin, newNormal);
                    int          size          = 240;
                    PlaneSurface plane_surface = new PlaneSurface(newPlane, new Interval(-size, size), new Interval(-size, size));
                    Brep         newPlaneBrep  = Brep.CreateFromSurface(plane_surface);

                    Guid newPlaneID = UtilOld.addRhinoObject(ref mScene, ref newPlaneBrep, "MoveP");
                    //might be better to use Replace(), just need to be careful about the referece count
                    pointOnObjRef = null;
                    pointOnObjRef = new ObjRef(newPlaneID);

                    modelcurve.SetUserString(CurveData.CurveOnObj.ToString(), newPlaneID.ToString());
                    modelcurve.SetUserString(CurveData.PlaneOrigin.ToString(), newPlane.Origin.ToString());
                    modelcurve.SetUserString(CurveData.PlaneNormal.ToString(), newPlane.Normal.ToString());
                }
                else if (drawnType == DrawnType.Surface)
                {
                    modelcurve.SetUserString(CurveData.CurveOnObj.ToString(), pointOnObjRef.ObjectId.ToString());
                    modelcurve.SetUserString(CurveData.PlaneOrigin.ToString(), curvePlane.Origin.ToString());
                    modelcurve.SetUserString(CurveData.PlaneNormal.ToString(), curvePlane.Normal.ToString());
                }

                mScene.iCurveList.Add(modelcurve);

                //call next interaction in the chain
                afterCurveCount = mScene.iCurveList.Count;
                mScene.pushInteractionFromChain();
                currentState = State.READY;
            }
        }
Beispiel #39
0
        protected override void OnRenderFrame(FrameEventArgs e)
        {
            #region Shader updates

            float renderTime = (float)e.Time; //TODO e.Time accuracy

            Shader.diffuseShaderCompiled.SetUniform("worldTime", worldTime);
            Shader.unlitShaderCompiled.SetUniform("worldTime", worldTime);
            Shader.wireframeShaderCompiled.SetUniform("worldTime", worldTime);
            Shader.collisionShaderCompiled.SetUniform("worldTime", worldTime);
            Shader.hudShaderCompiled.SetUniform("worldTime", worldTime);
            Shader.fboShaderCompiled.SetUniform("worldTime", worldTime);
            Shader.blurShaderCompiled.SetUniform("worldTime", worldTime);
            Shader.crtShaderCompiled.SetUniform("worldTime", worldTime);
            Shader.ditherShaderCompiled.SetUniform("worldTime", worldTime);

            Shader.diffuseShaderCompiled.SetUniform("effects", enableDoppler, enableRelBrightness, enableRelAberration);
            Shader.unlitShaderCompiled.SetUniform("effects", enableDoppler, enableRelBrightness, enableRelAberration);
            Shader.wireframeShaderCompiled.SetUniform("effects", enableDoppler, enableRelBrightness, enableRelAberration);
            Shader.collisionShaderCompiled.SetUniform("effects", enableDoppler, enableRelBrightness, enableRelAberration);

            Vector3 velocityDelta = Camera.Instance.velocity - smoothedVelocity;
            smoothedVelocity += velocityDelta - Vector3.Divide(velocityDelta, (float)Math.Pow(smoothFactor, renderTime)); //TODO: time dilation

            v = smoothedVelocity.Length;
            b = v / c;
            lf = 1f / (float)Math.Sqrt(1.0 - b * b);

            Shader.diffuseShaderCompiled.SetUniform("bW", b);
            Shader.unlitShaderCompiled.SetUniform("bW", b);
            Shader.wireframeShaderCompiled.SetUniform("bW", b);
            Shader.collisionShaderCompiled.SetUniform("bW", b);

            Vector3 vDir = smoothedVelocity.Normalized();

            Shader.diffuseShaderCompiled.SetUniform("vdirW", vDir);
            Shader.unlitShaderCompiled.SetUniform("vdirW", vDir);
            Shader.wireframeShaderCompiled.SetUniform("vdirW", vDir);
            Shader.collisionShaderCompiled.SetUniform("vdirW", vDir);

            Shader.diffuseShaderCompiled.SetUniform("cpos", Camera.Instance.position);
            Shader.unlitShaderCompiled.SetUniform("cpos", Camera.Instance.position);
            Shader.wireframeShaderCompiled.SetUniform("cpos", Camera.Instance.position);
            Shader.collisionShaderCompiled.SetUniform("cpos", Camera.Instance.position);

            Matrix4 cRot = Matrix4.CreateFromQuaternion(Camera.Instance.derivedOrientation);

            Shader.diffuseShaderCompiled.SetUniform("crot", cRot);
            Shader.unlitShaderCompiled.SetUniform("crot", cRot);
            Shader.wireframeShaderCompiled.SetUniform("crot", cRot);
            Shader.collisionShaderCompiled.SetUniform("crot", cRot);

            #endregion
            #region 3D
            #region First FBO pass
            UpdateViewport();

            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();

            // Enable rendering to FBO
            GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, depthRenderbuffer);
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, fboHandle);
            GL.DrawBuffer((DrawBufferMode)FramebufferAttachment.ColorAttachment0Ext);
            GL.PushAttrib(AttribMask.ViewportBit);
            GL.Viewport(0, 0, Width, Height);

            // Clear previous frame
            GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);

            // Geometry render passes
            for(int i = 0; i < amountOfRenderPasses; i++)
            {
                RootNode.Instance.StartRender(i);
            }

            for(int i = 0; i < amountOfRenderPasses; i++)
            {
                if(Camera.Instance.parent == null)
                {
                    Camera.Instance.StartRender(i);
                }
            }

            // Focal depth
            float[] pixelData = new float[1];
            GL.ReadPixels(Width / 2, Height / 2, 1, 1, PixelFormat.DepthComponent, PixelType.Float, pixelData);
            focalDistance = pixelData[0];

            // Restore render settings
            GL.PopAttrib();
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0); // return to visible framebuffer
            GL.DrawBuffer(DrawBufferMode.Back);
            GL.Ext.BindRenderbuffer(RenderbufferTarget.RenderbufferExt, 0);
            GL.Ext.BindFramebuffer(FramebufferTarget.FramebufferExt, 0);

            #endregion
            #region FBO render to back buffer & HUD
            GL.Color4(Color4.White);

            // 2D rendering settings
            GL.DepthMask(false);
            GL.Disable(EnableCap.DepthTest);
            GL.Disable(EnableCap.Lighting);
            GL.Disable(EnableCap.CullFace);

            GL.MatrixMode(MatrixMode.Projection);
            GL.LoadIdentity();
            GL.Ortho(0, ClientRectangle.Width, ClientRectangle.Height, 0, -1, 10);
            GL.MatrixMode(MatrixMode.Modelview);
            GL.LoadIdentity();

            // GFX sader selection
            if(InputManager.IsKeyToggled(Key.Number3))
            {
                if(InputManager.IsKeyToggled(Key.BackSpace))
                {
                    Shader.ssaoShaderCompiled.Enable();
                    Shader.ssaoShaderCompiled.SetUniform("tex", 0);
                    Shader.ssaoShaderCompiled.SetUniform("depthTex", 1);
                    Shader.ssaoShaderCompiled.SetUniform("focalDist", focalDistance);
                }
                else
                {
                    Shader.blurShaderCompiled.Enable();
                    Shader.blurShaderCompiled.SetUniform("tex", 0);
                    Shader.blurShaderCompiled.SetUniform("depthTex", 1);
                    Shader.blurShaderCompiled.SetUniform("focalDist", focalDistance);
                }
                GL.ActiveTexture(TextureUnit.Texture1);
                GL.BindTexture(TextureTarget.Texture2D, depthTexture);
            }
            else
            {
                if(InputManager.IsKeyToggled(Key.Number4))
                {
                    GL.ActiveTexture(TextureUnit.Texture1);
                    GL.BindTexture(TextureTarget.Texture2D, ditherTexture);

                    Shader.ditherShaderCompiled.Enable();
                    Shader.ditherShaderCompiled.SetUniform("tex", 0);
                    Shader.ditherShaderCompiled.SetUniform("ditherTex", 1);
                }
                else
                {
                    GL.ActiveTexture(TextureUnit.Texture1);
                    GL.BindTexture(TextureTarget.Texture2D, depthTexture);

                    Shader.fboShaderCompiled.Enable();
                    Shader.fboShaderCompiled.SetUniform("tex", 0);
                    Shader.fboShaderCompiled.SetUniform("depthTex", 1);
                }
            }

            // Render FBO quad
            GL.ActiveTexture(TextureUnit.Texture0);
            GL.BindTexture(TextureTarget.Texture2D, colorTexture);

            GL.Begin(PrimitiveType.Quads);
            GL.Color4(Color4.White);
            GL.TexCoord2(0, 1); GL.Vertex2(0, 0);
            GL.TexCoord2(0, 0); GL.Vertex2(0, Height);
            GL.TexCoord2(1, 0); GL.Vertex2(Width, Height);
            GL.TexCoord2(1, 1); GL.Vertex2(Width, 0);
            GL.End();

            Shader.hudShaderCompiled.Enable();
            Shader.hudShaderCompiled.SetUniform("tex", 0);

            // HUD render pass
            HudBase.Instance.StartRender();

            // Return to 3D rendering settings
            GL.Color3(Color.White);
            GL.DepthMask(true);
            GL.Enable(EnableCap.DepthTest);
            GL.Enable(EnableCap.Lighting);
            GL.Enable(EnableCap.CullFace);
            #endregion
            #endregion

            // Display the back buffer
            SwapBuffers();
        }
 public static Vector3 smoothNormal(Vector3 vector1, Vector3 vector2, Vector3 vector3, Vector3 vector4)
 {
     return(vector1.Normalized() + vector2.Normalized() + vector3.Normalized() + vector4.Normalized());
 }
        public ParticlesRingGenerator(ParticlesPlaneGenerator planeGenerator,
                                      Vector3 ringCenter, Vector3 up, float ringRadius,
                                      float sectionStart = 0.0f, 
                                      float sectionEnd = (float)(2.0*Math.PI))
        {
            m_ringCenter = ringCenter;
            m_ringZAxis = up.Normalized();
            m_ringRadius = ringRadius;
            m_sectionStart = sectionStart;
            m_sectionEnd = sectionEnd;
            m_planeGenerator = planeGenerator;

            if (Math.Abs(m_ringZAxis.X) < c_eps && Math.Abs(m_ringZAxis.Y) < c_eps) {
                m_ringXAxis = new Vector3(1.0f, 0.0f, 0.0f);
            } else {
                m_ringXAxis = new Vector3(m_ringZAxis.Y, -m_ringZAxis.X, 0.0f);
                m_ringXAxis.Normalize();
            }
            m_ringYAxis = Vector3.Cross(m_ringXAxis, m_ringZAxis);
        }
    //Processes movement
    public void ProcessMovement(float delta)
    {
        //Sets the normal in a variable to calculate the dot product later
        if (GetFloorNormal() != Vector3.Zero)
        {
            Normal_vect = GetFloorNormal();
        }
        else if (Floor_cast.GetCollisionNormal() != Vector3.Zero)
        {
            Normal_vect = Floor_cast.GetCollisionNormal();
        }

        //Sets a redundant check to secure that the character isn't on the ground (and sets a fake normal that is perpendicular to the up vector)
        if (!Floor_cast.IsColliding())
        {
            Normal_vect = Vector3.Forward;
            Floor_dect  = false;
        }
        //Reset the redundant check to true if it detects it touched the floor (and sets a -10 gravity value)
        if (IsOnFloor())
        {
            Floor_dect = true;
            Grav.y     = -10;
        }
        //Sets the velocity of gravity if the check is negative
        if (!Floor_dect)
        {
            Grav.y -= 30.0f * delta;
        }

        //Sets the velocity vector (acceleration coming in the future)
        Velocity_vect = Direction_vect * 20;

        //If the dot product of the normalized normal and the Vector 3 that points downwards is -0.5 < or 0.5 > and the player presed jump (aka space) set a variable to jump and change the gravity
        if ((new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) > 0.5 || new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) < -0.5) && Input.IsActionPressed("Player_jump"))
        {
            Jumping = true;
            Grav.y  = 10;
        }

        //If you were not jumping and you fell from a platform it resets the gravity to 0 for 1 frame
        if (Floor_dect_PFPS && !Floor_dect && !Jumping)
        {
            Grav.y = 0;
        }

        //If you were jumping and you touched the floor it reset jumping to false
        if (!Floor_dect_PFPS && Floor_dect && Jumping)
        {
            Jumping = false;
        }

        //If the dot product of the normalized normal and the Vector 3 that points downwards is not -0.5 < and not 0.5 > or the Vector_velocity isn't 0 or is jumping, it aplies the movement WITH gravity
        if (((!(new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) > 0.5) && !(new Vector3(0, -1, 0).Dot(Normal_vect.Normalized()) < -0.5)) || Velocity_vect != Vector3.Zero) || Jumping)
        {
            MoveAndSlide((Velocity_vect) + Grav, Vector3.Up, true);
        }

        Floor_dect_PFPS = Floor_dect;

        //If you touch the ceiling with a positive y value on gravity and you keep pressing jump you get ""grabed"" on the ceiling, else you bonk
        if (IsOnCeiling() && Grav.y > 0)
        {
            if (Input.IsActionPressed("Player_jump"))
            {
                Grav.y = 2;
            }
            else
            {
                Grav.y = 0;
            }
        }
    }
Beispiel #43
0
 public Ray(Vector3 start, Vector3 direction, float distance)
 {
     this.Origin = start;
     this.Direction = direction.Normalized();
     this.Distance = distance;
 }
Beispiel #44
0
        // Super basic test
        public void ProcessMovement(FPSInput input, float delta)
        {
            _debugSb.Clear();

            ApplyRotations();
            //Console.WriteLine($"Buttons {input.buttons} delta {delta}");
            Vector3 inputDir = new Vector3();

            if (input.isBitOn(FPSInput.BitMoveForward))
            {
                inputDir.z -= 1;
            }
            if (input.isBitOn(FPSInput.BitMoveBackward))
            {
                inputDir.z += 1;
            }
            if (input.isBitOn(FPSInput.BitMoveLeft))
            {
                inputDir.x -= 1;
            }
            if (input.isBitOn(FPSInput.BitMoveRight))
            {
                inputDir.x += 1;
            }

            float mouseMoveX = 0;             // horizontal turn
            float mouseMoveY = 0;             // verticla turn

            if (input.isBitOn(FPSInput.BitLookLeft))
            {
                mouseMoveX += KEYBOARD_TURN_DEGREES_PER_SECOND;
            }
            if (input.isBitOn(FPSInput.BitLookRight))
            {
                mouseMoveX -= KEYBOARD_TURN_DEGREES_PER_SECOND;
            }

            if (input.isBitOn(FPSInput.BitLookUp))
            {
                mouseMoveY += KEYBOARD_TURN_DEGREES_PER_SECOND;
            }
            if (input.isBitOn(FPSInput.BitLookDown))
            {
                mouseMoveY -= KEYBOARD_TURN_DEGREES_PER_SECOND;
            }

            _yaw   += mouseMoveX * delta;
            _pitch += mouseMoveY * delta;

            // convert desired move to world axes
            Transform t       = _body.GlobalTransform;
            Vector3   forward = t.basis.z;
            Vector3   left    = t.basis.x;

            Vector3 runPush = Vector3.Zero;

            runPush.x += forward.x * inputDir.z;
            runPush.z += forward.z * inputDir.z;
            runPush.x += left.x * inputDir.x;
            runPush.z += left.z * inputDir.x;
            runPush    = runPush.Normalized();

            // calculate horizontal move independently.
            Vector3 lastVel    = CalcLastFlatVelocity(_lastMove, _lastDelta);
            Vector3 horizontal = CalcVelocityQuakeStyle(
                lastVel, runPush, MOVE_SPEED, delta, true);

            _velocity.x = horizontal.x;
            _velocity.z = horizontal.z;

            // Apply external push
            Vector3 prevPosition = t.origin;

            // Move!
            _body.MoveAndSlide(_velocity);

            // record move info for next frame
            _lastMove  = _body.GlobalTransform.origin - prevPosition;
            _lastDelta = delta;

            _debugSb.Append($"FPS: {Engine.GetFramesPerSecond()}");
            _debugSb.Append($"Pitch {_pitch}\nyaw {_yaw}\n");
            _debugSb.Append($"Prev delta {_lastDelta}\n");
            _debugSb.Append($"Prev move {_lastMove}\n");
            _debugSb.Append($"Velocity {_velocity}\n");
            _debugSb.Append($"Run push {runPush}\n");
            _debugSb.Append($"Move spd {MOVE_SPEED} accel {MOVE_ACCELERATION}\n");
        }
Beispiel #45
0
            public void update(float timeElapsed)
            {
                _position += _velocity * timeElapsed;
                _timeElapsedTotal += timeElapsed;
                for (int i = 0; i < _delaysRemaining.Length; ++i) {
                    if (_explosionsRemaining > 0 && _delaysRemaining [i] <= 0f) {
                        float intensity = _chainParams.minIntensity
                            + (float)rand.NextDouble() * (_chainParams.maxIntensity - _chainParams.minIntensity);
                        double r = _chainParams.radiusMin
                            + rand.NextDouble() * (_chainParams.radiusMax - _chainParams.radiusMin);
                        double theta = 2.0 * Math.PI * rand.NextDouble();
                        double phi = Math.PI * (rand.NextDouble() - 0.5);
                        double xy = r * Math.Cos(theta);
                        Vector3 radialOffset = new Vector3 (
                            (float)(xy * Math.Cos(theta)),
                            (float)(xy * Math.Sin(theta)),
                            (float)(r * Math.Sin(phi)));

                        Vector3 pos = _position + radialOffset;
                        double spreadVelScale = _chainParams.spreadVelocityMin
                                + rand.NextDouble() * (_chainParams.spreadVelocityMax - _chainParams.spreadVelocityMin);
                        Vector3 vel = _velocity;
                        if (radialOffset.LengthFast > 0f) {
                            var radialDir = radialOffset.Normalized();
                            var radialVelOffset = (float)spreadVelScale * radialDir;
                            pos += radialVelOffset * _timeElapsedTotal;
                            vel += radialVelOffset ;
                        }
                        _em.showExplosion(_chainParams, intensity, pos,  vel);

                        _delaysRemaining [i] = _chainParams.minDelay
                            + (float)rand.NextDouble() * (_chainParams.maxDelay - _chainParams.minDelay);

                        --_explosionsRemaining;
                    }
                    _delaysRemaining [i] -= timeElapsed;
                }
            }
Beispiel #46
0
 private int AddVertex(Vector3 p)
 {
     _points.Add(p.Normalized());
     return(_index++);
 }
Beispiel #47
0
 public Ray(Vector3 origin, Vector3 direction)
 {
     Origin = origin;
     Direction = direction.Normalized();
 }
Beispiel #48
0
        /// <summary>
        /// Returns the distance between the closest points on the segment and the sphere
        /// </summary>
        public static float SegmentSphere(Vector3 segmentA, Vector3 segmentB, Vector3 sphereCenter, float sphereRadius)
        {
            Vector3 segmentAToCenter = sphereCenter - segmentA;
            Vector3 fromAtoB         = segmentB - segmentA;
            float   segmentLength    = fromAtoB.Length();

            if (segmentLength < Geometry.Epsilon)
            {
                return(segmentAToCenter.Length() - sphereRadius);
            }

            Vector3 segmentDirection = fromAtoB.Normalized();
            float   centerProjection = segmentDirection.Dot(segmentAToCenter);

            if (centerProjection + sphereRadius < -Geometry.Epsilon ||
                centerProjection - sphereRadius > segmentLength + Geometry.Epsilon)
            {
                // No intersection
                if (centerProjection < 0)
                {
                    return(segmentAToCenter.Length() - sphereRadius);
                }
                return((sphereCenter - segmentB).Length() - sphereRadius);
            }

            float sqrDistanceToA            = segmentAToCenter.LengthSquared();
            float sqrDistanceToLine         = sqrDistanceToA - centerProjection * centerProjection;
            float sqrDistanceToIntersection = sphereRadius * sphereRadius - sqrDistanceToLine;

            if (sqrDistanceToIntersection < -Geometry.Epsilon)
            {
                // No intersection
                if (centerProjection < -Geometry.Epsilon)
                {
                    return(Mathf.Sqrt(sqrDistanceToA) - sphereRadius);
                }
                if (centerProjection > segmentLength + Geometry.Epsilon)
                {
                    return((sphereCenter - segmentB).Length() - sphereRadius);
                }
                return(Mathf.Sqrt(sqrDistanceToLine) - sphereRadius);
            }

            if (sqrDistanceToIntersection < Geometry.Epsilon)
            {
                if (centerProjection < -Geometry.Epsilon)
                {
                    // No intersection
                    return(Mathf.Sqrt(sqrDistanceToA) - sphereRadius);
                }
                if (centerProjection > segmentLength + Geometry.Epsilon)
                {
                    // No intersection
                    return((sphereCenter - segmentB).Length() - sphereRadius);
                }
                // Point intersection
                return(0);
            }

            // Line intersection
            float distanceToIntersection = Mathf.Sqrt(sqrDistanceToIntersection);
            float distanceA = centerProjection - distanceToIntersection;
            float distanceB = centerProjection + distanceToIntersection;

            bool pointAIsAfterSegmentA  = distanceA > -Geometry.Epsilon;
            bool pointBIsBeforeSegmentB = distanceB < segmentLength + Geometry.Epsilon;

            if (pointAIsAfterSegmentA && pointBIsBeforeSegmentB)
            {
                // Two points intersection
                return(0);
            }
            if (!pointAIsAfterSegmentA && !pointBIsBeforeSegmentB)
            {
                // The segment is inside, but no intersection
                distanceB = -(distanceB - segmentLength);
                return(distanceA > distanceB ? distanceA : distanceB);
            }

            bool pointAIsBeforeSegmentB = distanceA < segmentLength + Geometry.Epsilon;

            if (pointAIsAfterSegmentA && pointAIsBeforeSegmentB)
            {
                // Point A intersection
                return(0);
            }
            bool pointBIsAfterSegmentA = distanceB > -Geometry.Epsilon;

            if (pointBIsAfterSegmentA && pointBIsBeforeSegmentB)
            {
                // Point B intersection
                return(0);
            }

            // No intersection
            if (centerProjection < 0)
            {
                return(Mathf.Sqrt(sqrDistanceToA) - sphereRadius);
            }
            return((sphereCenter - segmentB).Length() - sphereRadius);
        }
Beispiel #49
0
        /// <summary>
        /// https://bitbucket.org/sinbad/ogre/src/9db75e3ba05c/OgreMain/include/OgreVector3.h#cl-651
        /// </summary>
        public static Quaternion getRotationTo(Vector3 src, Vector3 dst, Vector3 fallbackAxis)
        {
            // Based on Stan Melax's article in Game Programming Gems
            Quaternion q = new Quaternion();
            // Copy, since cannot modify local
            Vector3 v0 = src.Normalized();
            Vector3 v1 = dst.Normalized();

            float d = Vector3.Dot (v0, v1);
            // If dot == 1, vectors are the same
            if (d >= 1.0f)
            {
                return Quaternion.Identity;
            }
            if (d < (1e-6f - 1.0f))
            {
                if (fallbackAxis != Vector3.Zero)
                {
                    // rotate 180 degrees about the fallback axis
                    q = Quaternion.FromAxisAngle (fallbackAxis, (float)Math.PI);
                }
                else
                {
                    // Generate an axis
                    Vector3 axis = Vector3.Cross(Vector3.UnitX, v0);
                    if (axis.Length <= 0.001f) // pick another if colinear
                        axis = Vector3.Cross(Vector3.UnitY, v0);
                    axis.Normalize();
                    q = Quaternion.FromAxisAngle (axis, (float)Math.PI);
                }
            }
            else
            {
                float s = (float)Math.Sqrt( (1f+d)*2f );
                float invs = 1f / s;

                Vector3 c = Vector3.Cross (v0, v1);

                q.X = c.X * invs;
                q.Y = c.Y * invs;
                q.Z = c.Z * invs;
                q.W = s * 0.5f;
                q.Normalize();
            }
            return q;
        }
 /// <summary>
 /// Is vector parallel to other vector?
 /// </summary>
 public static bool IsParallelTo(this Vector3 vector, Vector3 other, float tolerance = 1E-6f)
 {
     return(System.Math.Abs(1.0 - System.Math.Abs(vector.Normalized().Dot(other.Normalized()))) <= tolerance);
 }
 //start at the highest, rightmost point. work anticlockwise. highest has priority
 public void CalcNormals(Vector3 a, Vector3 b, Vector3 c)
 {
     normals[0] = a.Normalized();
     normals[1] = b.Normalized();
     normals[2] = c.Normalized();
 }
Beispiel #52
0
        public static Quaternion ConstraintLookAt(StaticModel actor, Vector3 targetAbsRef, Vector3 upRelRef, Vector3 constraintAxisSelect)
        {

            Vector3 targetRelRef;

            //Transforming target into relative coordinates if child
            if (actor.IsChild)
                targetRelRef = Geometric.Quaternion_Rotate(actor.ParentModel.Orientation.Inverted(), targetAbsRef);
            else
                targetRelRef = new Vector3(targetAbsRef.X, targetAbsRef.Y, targetAbsRef.Z);

            
            // HACK INVERSION
            //targetRelRef = -targetRelRef;
            //
            

            //Make a non projected safe copy of relative target
            Vector3 targetRelRef_notConstraint = new Vector3(targetRelRef.X, targetRelRef.Y, targetRelRef.Z);

            /*
            //Project relative target to plane defined by constraint
            if (constraintAxisSelect.X != 0)
                targetRelRef.X = 0;
            else if (constraintAxisSelect.Y != 0)
                targetRelRef.Y = 0;
            else if (constraintAxisSelect.Z != 0)
                targetRelRef.Z = 0;
             */

            //Normalizing constrainted relative target
            Vector3 eye = actor.PositionRelative;
            Vector3 up;
            Vector3 forward;
            if (actor.IsChild)
            {
                //Normalizing target and transforming it to local system
                forward = targetRelRef - actor.ParentModel.Position;
                up = Quaternion_Rotate(actor.OrientationRelative, upRelRef);
            }
            else
            {
                //Normalizing target.. local system is the same as world system
                forward = targetRelRef;
                up = upRelRef;
            }

            //Normalizing upVector (we are assuming it is expressed in local system)


            //Insert manual imprecision tilt to avoid singularity  (if any!)
            float ciao = Vector3.Dot(targetRelRef_notConstraint.Normalized(), up);
            if (Vector3.Dot(targetRelRef_notConstraint.Normalized(), up) == 1)
            {
                forward.X = 0.001f;
                forward.Y = 0.001f;
                forward.Z = 0.001f;
            }

            //Project relative target to plane defined by constraint
            if (constraintAxisSelect.X != 0)
                forward.X = 0;
            else if (constraintAxisSelect.Y != 0)
                forward.Y = 0;
            else if (constraintAxisSelect.Z != 0)
                forward.Z = 0;

            //forward = forward.Normalized();

//            Vector3 v1 = new Vector3(forward.X,forward.Y,forward.Z)
//            float ciao = Vector3.Dot(forward, up);


            //float angle = (float)Math.Acos( Vector3.Dot(current,targetAbsRef) );
            //Vector3 rotAxis = Vector3.CrossProduct(current, forward).Normalized();
            //Vector3 right = Vector3.CrossProduct(forward, up);

            Matrix4 lookAt_result = Matrix4.LookAt(forward.X, forward.Y, forward.Z, eye.X, eye.Y, eye.Z, up.X, up.Y, up.Z);
            Matrix3 targetRelOrientation_matrix = new Matrix3(lookAt_result);
            Quaternion targetRelOrientation_quaternion = Quaternion.FromMatrix(targetRelOrientation_matrix);

            /*
            Quaternion targetRelOrientation_quaternion = new Quaternion();
            targetRelOrientation_quaternion.W = (float)Math.Sqrt((double)(1.0f + right.X + up.Y + forward.Z)) * 0.5f;
            float w4_recip = 1.0f / (4.0f * targetRelOrientation_quaternion.W);
            targetRelOrientation_quaternion.X = (forward.Y - up.Z) * w4_recip;
            targetRelOrientation_quaternion.Y = (right.Z - forward.X) * w4_recip;
            targetRelOrientation_quaternion.Z = (up.X - right.Y) * w4_recip;
            */

            return targetRelOrientation_quaternion;

        }
Beispiel #53
0
        public virtual void updateExecution(float timeElapsed)
        {
            if (timeElapsed <= 0f)
            {
                return;
            }

            // basic proportional navigation. see wikipedia
            var mParams = missile.parameters;
            var target  = missile.target;

            Vector3 Vr    = target.velocity - missile.velocity;
            Vector3 R     = target.position - missile.position;
            Vector3 omega = Vector3.Cross(R, Vr) / R.LengthSquared;
            Vector3 cross = Vector3.Cross(Vr, omega);
            Vector3 latax;

            if (cross.LengthSquared == 0)
            {
                latax = R.Normalized() * mParams.pursuitMaxAcc;
            }
            else
            {
                latax = mParams.pursuitNavigationGain * cross;
            }

            if (mParams.pursuitAugmentedPN == true)
            {
                // this code is not tested as there are currently no targets with well defined accelerations
                Vector3 losDir       = R.Normalized();
                float   targetAccLos = Vector3.Dot(target.acceleration, losDir);
                Vector3 targetLatAx  = target.acceleration - targetAccLos * losDir;
                latax += mParams.pursuitNavigationGain * targetLatAx / 2f;
            }

            missile._lataxDebug = latax;

            // apply latax
            var oldVelMag = missile.velocity.LengthFast;

            missile.velocity += latax * timeElapsed;
            float tempVelMag = missile.velocity.LengthFast;

            if (oldVelMag != 0f)
            {
                float r = tempVelMag / oldVelMag;
                if (r > 1f)
                {
                    missile.velocity /= r;
                }
            }

            if (mParams.pursuitHitTimeCorrection &&
                !float.IsNaN(missile.timeToHit))
            {
                // apply pursuit hit time correction
                float dist = R.LengthFast;
                if (dist != 0f)
                {
                    Vector3 targetDir        = R / dist;
                    float   v0               = -Vector3.Dot(Vr, targetDir);
                    float   t                = missile.timeToHit;
                    float   correctionAccMag = 2f * (dist - v0 * t) / t / t;
                    Vector3 corrAcc          = correctionAccMag * targetDir;
                    missile.velocity            += corrAcc * timeElapsed;
                    missile._hitTimeCorrAccDebug = corrAcc;
                }
            }
            else
            {
                // hit time correction inactive. allow accelerating to achieve optimal velocity or forever
                oldVelMag = missile.velocity.LengthFast;
                float velDelta  = mParams.pursuitMaxAcc * timeElapsed;
                float newVelMag = Math.Min(oldVelMag + velDelta, mParams.pursuitMaxVelocity);
                if (oldVelMag != 0f)
                {
                    missile.velocity *= (newVelMag / oldVelMag);
                }
            }
        }
        public static void Run()
        {
            GraphicsContext context = new GraphicsContext()
            {
                Camera = new FirstPersonCamera(new Vector3(4, 3, 3), Vector3.UnitY)
            };
            Matrix4 World = Matrix4.Identity;

            VoxelTypeMap v = new VoxelTypeMap();
            v[0] = new VoxelTypeMap.VoxelTypeData()
            {
                Color = Vector4.One,
                Visible = false
            };

            v[1] = new VoxelTypeMap.VoxelTypeData()
            {
                Color = Vector4.UnitY * 0.7f + Vector4.UnitW,
                Visible = true
            };

            v[2] = new VoxelTypeMap.VoxelTypeData()
            {
                Color = Vector4.UnitX + Vector4.UnitW,
                Visible = true
            };

            BlockManager man = new BlockManager();
            man.Side = 32;
            man.VoxelTypes = v;

            //Rendering stuff
            ShaderProgram prog = null;

            GraphicsDevice.Load += () =>
            {
                //GraphicsDevice.Winding = FaceWinding.Clockwise;
                GraphicsDevice.CullMode = OpenTK.Graphics.OpenGL4.CullFaceMode.Back;
                GraphicsDevice.DepthTestEnabled = true;
                GraphicsDevice.Window.KeyUp += (k, e) =>
                {
                    if (e.Key == OpenTK.Input.Key.Z) GraphicsDevice.Wireframe = !GraphicsDevice.Wireframe;
                    else if (e.Key == OpenTK.Input.Key.C) GraphicsDevice.CullEnabled = !GraphicsDevice.CullEnabled;
                };

                Random rng = new Random(0);
                double n = 64;

                v.UpdateBuffers();
                GraphicsDevice.SetBufferTexture(0, v.ColorData);

                ShaderSource vShader = ShaderSource.Load(OpenTK.Graphics.OpenGL4.ShaderType.VertexShader, "Testing/VoxTest/vertex.glsl");
                ShaderSource fShader = ShaderSource.Load(OpenTK.Graphics.OpenGL4.ShaderType.FragmentShader, "Testing/VoxTest/fragment.glsl");

                prog = new ShaderProgram(vShader, fShader);
                prog.Set("materialColors", 0);

            };

            GraphicsDevice.Update += (e) =>
            {
                context.Update(e);

                //World *= Matrix4.CreateRotationY(0.01f);

                prog.Set("World", Matrix4.Identity);
                prog.Set("View", context.View);
                prog.Set("Proj", context.Projection);
                prog.Set("Fcoef", (float)(2.0f / Math.Log(1000001) / Math.Log(2)));
                prog.Set("lightDir", new Vector3(5, 10, 5).Normalized());

            };

            GraphicsDevice.Render += (e) =>
            {
                GraphicsDevice.Clear();

                for (int k = -2; k < 0; k++)
                {
                    Vector3 a = new Vector3();
                    a.Y = k * man.Side;
                    for (int i = -5; i <= 5; i++)
                    {
                        a.Z = i * man.Side;
                        for (int j = -5; j <= 5; j++)
                        {
                            a.X = j * man.Side;
                            Vector3 dir = (context.Camera as FirstPersonCamera).Direction;
                            if (Vector3.Dot(dir.Normalized(), a.Normalized()) >= -0.3)
                            {
                                //Chunk c = man.Draw(-Vector3.UnitY * 123, out World);
                                Chunk c = man.Draw(context.Camera.Position + a, out World);
                                if (c.ChunkReady)
                                {
                                    c.Bind();
                                    prog.Set("World", World);

                                    prog.Set("range1", c.NormalOffsets[1]);
                                    prog.Set("range2", c.NormalOffsets[2]);
                                    prog.Set("range3", c.NormalOffsets[3]);
                                    prog.Set("range4", c.NormalOffsets[4]);
                                    prog.Set("range5", c.NormalOffsets[5]);
                                    GraphicsDevice.SetShaderProgram(prog);

                                    GraphicsDevice.Draw(OpenTK.Graphics.OpenGL4.PrimitiveType.Triangles, 0, c.NormalGroupSizes[6]);
                                }
                            }
                        }
                    }
                }

                GraphicsDevice.SwapBuffers();
            };

            GraphicsDevice.Name = "Voxel Test";
            GraphicsDevice.Run(60, 0);
            if (GraphicsDevice.Cleanup != null) GraphicsDevice.Cleanup();
        }