Esempio n. 1
0
        public void AddNewPolygonList(List<TransparentPolygonReference> p, Transform transform, Frustum frustum, Camera cam)
        {
            foreach (var pp in p)
            {
                var transformed = new Polygon();
                transformed.Vertices.Resize(pp.Polygon.Vertices.Count, () => new Vertex());
                transformed.Transform(pp.Polygon, transform);
                transformed.DoubleSide = pp.Polygon.DoubleSide;

                if(frustum.IsPolyVisible(transformed, cam))
                {
                    addPolygon(ref _root, new BSPFaceRef(transform, pp), transformed);
                }
            }
        }
Esempio n. 2
0
 public static void Mat4_Translate(Transform mat, float x, float y, float z)
 {
     Mat4_Translate(mat, new Vector3(x, y, z));
 }
Esempio n. 3
0
        public void DrawListDebugLines()
        {
            if(World == null || !(drawBoxes || drawRoomBoxes || drawPortals || drawFrustums || drawAxis || drawNormals || drawColl))
            {
                return;
            }

            if(World.Character != null)
            {
                DebugDrawer.DrawEntityDebugLines(World.Character, this);
            }

            // Render world debug information
            if(drawNormals && World.SkyBox != null)
            {
                var tr = new Transform();
                tr.SetIdentity();
                tr.Origin = Camera.Position + World.SkyBox.Animations[0].Frames[0].BoneTags[0].Offset;
                tr.Rotation = World.SkyBox.Animations[0].Frames[0].BoneTags[0].QRotate;
                DebugDrawer.DrawMeshDebugLines(World.SkyBox.MeshTree[0].MeshBase, tr, new List<Vector3>(),
                    new List<Vector3>(), this);
            }

            foreach (var room in renderList)
            {
                DebugDrawer.DrawRoomDebugLines(room, this, Camera);
            }

            if(drawColl)
            {
                BtEngineDynamicsWorld.DebugDrawWorld();
            }

            if(!DebugDrawer.IsEmpty)
            {
                var shader = ShaderManager.GetDebugLineShader();
                GL.UseProgram(shader.Program);
                GL.Uniform1(shader.Sampler, 0);
                GL.UniformMatrix4(shader.ModelViewProjection, false, ref Camera.GLViewProjMat);
                GL.BindTexture(TextureTarget.Texture2D, EngineWorld.Textures.Last());
                GL.PointSize(6.0f);
                GL.LineWidth(3.0f);
                DebugDrawer.Render();
            }
        }
Esempio n. 4
0
        public void DrawMeshDebugLines(BaseMesh mesh, Transform transform, List<Vector3> overrideVertices,
            List<Vector3> overrideNormals, Render render)
        {
            if(render.drawNormals)
            {
                SetColor(0.8f, 0.0f, 0.9f);
                if(overrideVertices.Any())
                {
                    for (var i = 0; i < mesh.Vertices.Count; i++)
                    {
                        var ov = overrideVertices[i];
                        var on = overrideNormals[i];

                        var v = transform * ov;
                        buffer.Add(v.ToArray());
                        buffer.Add(color);
                        v += transform.Basis.MultiplyByVector(on) * 128;
                        buffer.Add(v.ToArray());
                        buffer.Add(color);
                    }
                }
                else
                {
                    foreach (var mv in mesh.Vertices)
                    {
                        var v = transform * mv.Position;
                        buffer.Add(v.ToArray());
                        buffer.Add(color);
                        v += transform.Basis.MultiplyByVector(mv.Normal) * 128;
                        buffer.Add(v.ToArray());
                        buffer.Add(color);
                    }
                }
            }
        }
Esempio n. 5
0
        public void DrawAxis(float r, Transform transform)
        {
            var origin = transform.Origin.ToArray();

            var v = transform.Basis.Column0 * r;
            v += transform.Origin;
            buffer.Add(origin);
            buffer.Add(new[] {1.0f, 0.0f, 0.0f});
            buffer.Add(v.ToArray());
            buffer.Add(new[] {1.0f, 0.0f, 0.0f});

            v = transform.Basis.Column1 * r;
            v += transform.Origin;
            buffer.Add(origin);
            buffer.Add(new[] { 0.0f, 1.0f, 0.0f });
            buffer.Add(v.ToArray());
            buffer.Add(new[] { 0.0f, 1.0f, 0.0f });

            v = transform.Basis.Column2 * r;
            v += transform.Origin;
            buffer.Add(origin);
            buffer.Add(new[] { 0.0f, 0.0f, 1.0f });
            buffer.Add(v.ToArray());
            buffer.Add(new[] { 0.0f, 0.0f, 1.0f });
        }
Esempio n. 6
0
        public void RenderHair(Character entity, Matrix4 modelViewMatrix, Matrix4 projection)
        {
            if (entity == null || entity.Hairs.Count == 0) return;

            // Calculate lighting
            var shader = setupEntityLight(entity, modelViewMatrix, true);

            for (var h = 0; h < entity.Hairs.Count; h++)
            {
                // First: Head attachment
                var globalHead = (Matrix4)(entity.Transform * entity.Bf.BoneTags[(int)entity.Hairs[h].OwnerBody].FullTransform);
                var globalAttachment = globalHead.MultiplyByTransform(entity.Hairs[h].OwnerBodyHairRoot);

                var matrixCount = 10;

                var hairModelToGlobalMatrices = Helper.RepeatValue(16, () => new float[matrixCount]);
                unsafe
                {
                    var tmp = modelViewMatrix * globalAttachment;
                    fixed (float* ptr = &hairModelToGlobalMatrices[0][0])
                        Helper.PointerCopy(&tmp.Row0.X, ptr, 16);
                }

                // Then: Individual hair pieces
                for (var i = 0; i < entity.Hairs[h].Elements.Count; i++)
                {
                    StaticFuncs.Assert(i + 1 < matrixCount);
                    /*
                     * Definitions: x_o - as in original file. x_h - as in hair model
                     * (translated)
                     * M_ho - translation matrix. x_g = global position (before modelview)
                     * M_go - global position
                     *
                     * We know:
                     * x_h = M_ho * x_o
                     * x_g = M_go * x_o
                     * We want:
                     * M_hg so that x_g = M_gh * x_m
                     * We have: M_oh, M_g
                     *
                     * x_h = M_ho * x_o => x_o = M_oh^-1 * x_h
                     * x_g = M_go * M_ho^-1 * x_h
                     * (M_ho^-1 = M_oh so x_g = M_go * M_oh * x_h)
                     */

                    var invOriginToHairModel = new Transform();
                    invOriginToHairModel.SetIdentity();
                    // Simplification: Always translation matrix, no invert needed
                    invOriginToHairModel.Origin -= entity.Hairs[h].Elements[i].Position;

                    var globalFromHair =
                        entity.Hairs[h].Elements[i].Body.GetWorldTransform().MultiplyByTransform(invOriginToHairModel);

                    unsafe
                    {
                        var tmp = modelViewMatrix * globalFromHair;
                        fixed (float* ptr = &hairModelToGlobalMatrices[i + 1][0])
                            Helper.PointerCopy(&tmp.Row0.X, ptr, 16);
                    }
                }

                unsafe
                {
                    fixed (float* ptr = &hairModelToGlobalMatrices[0][0])
                        GL.UniformMatrix4(shader.ModelView, entity.Hairs[h].Elements.Count + 1, false, ptr);
                }
                
                GL.UniformMatrix4(shader.Projection, false, ref projection);

                RenderMesh(entity.Hairs[h].Mesh);
            }
        }
Esempio n. 7
0
        public void Draw()
        {
            if (!active) return;

            var item = EngineWorld.GetBaseItemByID((uint)this.item);
            if (item == null) return;

            var anim = item.BoneFrame.Animations.CurrentAnimation;
            var frame = item.BoneFrame.Animations.CurrentFrame;
            var time = item.BoneFrame.Animations.FrameTime;

            item.BoneFrame.Animations.CurrentAnimation = 0;
            item.BoneFrame.Animations.CurrentFrame = 0;
            item.BoneFrame.Animations.FrameTime = 0.0f;

            Gui.Item_Frame(item.BoneFrame, 0.0f);
            var matrix = new Transform();
            matrix.SetIdentity();
            VMath.Mat4_Translate(matrix, currPosX, posY, -2048.0f);
            VMath.Mat4_RotateY(matrix, currRotX + rotX);
            VMath.Mat4_RotateX(matrix, currRotY + rotY);
            Gui.RenderItem(item.BoneFrame, size, matrix);

            item.BoneFrame.Animations.CurrentAnimation = anim;
            item.BoneFrame.Animations.CurrentFrame = frame;
            item.BoneFrame.Animations.FrameTime = time;
        }
Esempio n. 8
0
        /// <summary>
        /// Creates hair into allocated hair structure, using previously defined setup and entity index.
        /// </summary>
        public bool Create(HairSetup setup, Entity parentEntity)
        {
            // No setup or parent to link to - bypass function.
            if (parentEntity == null || setup == null || setup.LinkBody >= parentEntity.Bf.BoneTags.Count ||
                parentEntity.Bt.BtBody[(int)setup.LinkBody] == null)
                return false;

            var model = EngineWorld.GetModelByID(setup.Model);

            // No model to link to - bypass function.
            if (model == null || model.MeshCount == 0) return false;

            // Setup engine container. FIXME: DOESN'T WORK PROPERLY ATM.
            Container = new EngineContainer();
            Container.Room = parentEntity.Self.Room;
            Container.ObjectType = OBJECT_TYPE.Hair;
            Container.Object = this;

            // Setup initial hair parameters.
            OwnerChar = parentEntity; // Entity to refer to.
            OwnerBody = setup.LinkBody; // Entity body to refer to.

            // Setup initial position / angles.
            var ownerBodyTransform = parentEntity.Transform * parentEntity.Bf.BoneTags[(int) OwnerBody].FullTransform;

            // Number of elements (bodies) is equal to number of hair meshes.
            Elements = new List<HairElement>();
            Elements.Resize(model.MeshCount, () => new HairElement());

            // Root index should be always zero, as it is how engine determines that it is
            // connected to head and renders it properly. Tail index should be always the
            // last element of the hair, as it indicates absence of "child" constraint.
            RootIndex = 0;
            TailIndex = (byte)(Elements.Count - 1);

            // Weight step is needed to determine the weight of each hair body.
            // It is derived from root body weight and tail body weight.
            var weightStep = (setup.RootWeight - setup.TailWeight) / Elements.Count;
            var currentWeight = setup.RootWeight;

            for (var i = 0; i < Elements.Count; i++)
            {
                // Point to corresponding mesh.
                Elements[i].Mesh = model.MeshTree[i].MeshBase;

                // Begin creating ACTUAL physical hair mesh.
                var localInertia = BulletSharp.Math.Vector3.Zero;

                // Make collision shape out of mesh.
                Elements[i].Shape = BT_CSfromMesh(Elements[i].Mesh, true, true, false);
                Elements[i].Shape.CalculateLocalInertia(currentWeight * setup.HairInertia, out localInertia);

                // Decrease next body weight to weight_step parameter.
                currentWeight -= weightStep;

                // Initialize motion state for body.
                var startTransform = ownerBodyTransform;
                var motionState = new DefaultMotionState(((Matrix4)startTransform).ToBullet());

                // Make rigid body.
                Elements[i].Body = new RigidBody(new RigidBodyConstructionInfo(currentWeight, motionState, Elements[i].Shape, localInertia));

                // Damping makes body stop in space by itself, to prevent it from continous movement.
                Elements[i].Body.SetDamping(setup.HairDamping[0], setup.HairDamping[1]);

                // Restitution and friction parameters define "bounciness" and "dullness" of hair.
                Elements[i].Body.Restitution = setup.HairRestitution;
                Elements[i].Body.Friction = setup.HairFriction;

                // Since hair is always moving with Lara, even if she's in still state (like, hanging
                // on a ledge), hair bodies shouldn't deactivate over time.
                Elements[i].Body.ForceActivationState(ActivationState.DisableDeactivation);

                // Hair bodies must not collide with each other, and also collide ONLY with kinematic
                // bodies (e. g. animated meshes), or else Lara's ghost object or anything else will be able to
                // collide with hair!
                Elements[i].Body.UserObject = Container;
                BtEngineDynamicsWorld.AddRigidBody(Elements[i].Body, CollisionFilterGroups.CharacterFilter, CollisionFilterGroups.KinematicFilter);

                Elements[i].Body.Activate();
            }

            // GENERATE CONSTRAINTS.
            // All constraints are generic 6-DOF type, as they seem perfect fit for hair.

            // Joint count is calculated from overall body amount multiplied by per-body constraint
            // count.
            Joints = new List<Generic6DofConstraint>();
            Joints.Resize(Elements.Count);

            // If multiple joints per body is specified, joints are placed in circular manner,
            // with obvious step of (SIMD_2_PI) / joint count. It means that all joints will form
            // circle-like figure.
            var currJoint = 0;

            for (var i = 0; i < Elements.Count; i++)
            {
                float bodyLength;
                var localA = new Transform();
                localA.SetIdentity();
                var localB = new Transform();
                localB.SetIdentity();

                var jointX = 0.0f;
                var jointY = 0.0f;

                RigidBody prevBody;
                if(i == 0) // First joint group
                {
                    // Adjust pivot point A to parent body.
                    localA.Origin = setup.HeadOffset + new Vector3(jointX, 0.0f, jointY);
                    Helper.SetEulerZYX(ref localA.Basis, setup.RootAngle.X, setup.RootAngle.Y, setup.RootAngle.Z);
                    // Stealing this calculation because I need it for drawing
                    OwnerBodyHairRoot = localA;

                    localB.Origin = new Vector3(jointX, 0.0f, jointY);
                    Helper.SetEulerZYX(ref localB.Basis, 0, -HalfPI, 0);

                    prevBody = parentEntity.Bt.BtBody[(int) OwnerBody]; // Previous body is parent body.
                }
                else
                {
                    // Adjust pivot point A to previous mesh's length, considering mesh overlap multiplier.
                    bodyLength = Math.Abs(Elements[i - 1].Mesh.BBMax.Y - Elements[i - 1].Mesh.BBMin.Y) *
                                 setup.JointOverlap;

                    localA.Origin = new Vector3(jointX, bodyLength, jointY);
                    Helper.SetEulerZYX(ref localA.Basis, 0, -HalfPI, 0);

                    // Pivot point B is automatically adjusted by Bullet.
                    localB.Origin = new Vector3(jointX, 0.0f, jointY);
                    Helper.SetEulerZYX(ref localB.Basis, 0, -HalfPI, 0);

                    prevBody = Elements[i - 1].Body; // Previous body is preceding hair mesh.
                }

                // Create 6DOF constraint.
                Joints[currJoint] = new Generic6DofConstraint(prevBody, Elements[i].Body, ((Matrix4) localA).ToBullet(),
                    ((Matrix4) localB).ToBullet(), true);

                // CFM and ERP parameters are critical for making joint "hard" and link
                // to Lara's head. With wrong values, constraints may become "elastic".
                for (var axis = 0; axis < 6; axis++)
                {
                    Joints[currJoint].SetParam(ConstraintParam.StopCfm, setup.JointCfm, axis);
                    Joints[currJoint].SetParam(ConstraintParam.StopErp, setup.JointErp, axis);
                }

                Joints[currJoint].LinearLowerLimit = BulletSharp.Math.Vector3.Zero;
                Joints[currJoint].LinearUpperLimit = BulletSharp.Math.Vector3.Zero;

                if(i == 0)
                {
                    // First joint group should be more limited in motion, as it is connected
                    // right to the head. NB: Should we make it scriptable as well?
                    Joints[currJoint].AngularLowerLimit = new BulletSharp.Math.Vector3(-HalfPI, 0.0f, -HalfPI * 0.4f);
                    Joints[currJoint].AngularLowerLimit = new BulletSharp.Math.Vector3(-HalfPI * 0.3f, 0.0f, HalfPI * 0.4f);

                    // Increased solver iterations make constraint even more stable.
                    Joints[currJoint].OverrideNumSolverIterations = 100;
                }
                else
                {
                    // Normal joint with more movement freedom.
                    Joints[currJoint].AngularLowerLimit = new BulletSharp.Math.Vector3(-HalfPI * 0.5f, 0.0f, -HalfPI * 0.5f);
                    Joints[currJoint].AngularLowerLimit = new BulletSharp.Math.Vector3(HalfPI * 0.5f, 0.0f, HalfPI * 0.5f);
                }

                Joints[currJoint].DebugDrawSize = 5.0f; // Draw constraint axes.

                // Add constraint to the world.
                BtEngineDynamicsWorld.AddConstraint(Joints[currJoint], true);

                currJoint++; // Point to the next joint.
            }

            createHairMesh(model);

            return true;
        }
Esempio n. 9
0
        public void UpdateRigidBody(bool force)
        {
            if(TypeFlags.HasFlag(ENTITY_TYPE.Dynamic))
            {
                Transform = (Transform)Bt.BtBody[0].WorldTransform.ToOpenTK();
                UpdateRoomPos();
                for(var i = 0; i < Bf.BoneTags.Count; i++)
                {
                    Bf.BoneTags[i].FullTransform = Transform.Inverse * Bt.BtBody[i].WorldTransform.ToOpenTK();
                }

                // that cycle is necessary only for skinning models
                foreach (var t in Bf.BoneTags)
                {
                    t.Transform = t.Parent != null ? t.Parent.FullTransform.Inverse * t.FullTransform : t.FullTransform;
                }

                UpdateGhostRigidBody();

                Bf.BBMin = Bf.BoneTags[0].MeshBase.BBMin;
                Bf.BBMax = Bf.BoneTags[0].MeshBase.BBMax;
                if(Bf.BoneTags.Count > 1)
                {
                    foreach (var b in Bf.BoneTags)
                    {
                        var pos = b.FullTransform.Origin;
                        var bbmin = b.MeshBase.BBMin;
                        var bbmax = b.MeshBase.BBMax;
                        var r = bbmax.X - bbmin.X;
                        var t = bbmax.Y - bbmin.Y;
                        r = Math.Max(t, r);
                        t = bbmax.Z - bbmin.Z;
                        r = Math.Max(t, r);
                        r *= 0.5f;

                        Bf.BBMin = Helper.Vec3Min(Bf.BBMin, pos.AddF(-r));

                        Bf.BBMax = Helper.Vec3Max(Bf.BBMax, pos.AddF(r));
                    }
                }
            }
            else
            {
                if (Bf.Animations.Model == null || Bt.BtBody.Count == 0 ||
                    !force && Bf.Animations.Model.Animations.Count == 1 &&
                    Bf.Animations.Model.Animations[0].Frames.Count == 1)
                {
                    return;
                }

                UpdateRoomPos();
                if(Self.CollisionType != COLLISION_TYPE.Static)
                {
                    for(var i = 0; i < Bf.BoneTags.Count; i++)
                    {
                        if(Bt.BtBody[i] != null)
                        {
                            Bt.BtBody[i].WorldTransform = ((Matrix4)(Transform * Bf.BoneTags[i].FullTransform)).ToBullet();
                        }
                    }
                }
            }
            RebuildBV();
        }
Esempio n. 10
0
        public Entity(uint id)
        {
            ID = id;
            MoveType = MoveType.OnFloor;
            Self = new EngineContainer();

            Transform = new Transform();
            Transform.SetIdentity();
            Self.Object = this;
            Self.ObjectType = OBJECT_TYPE.Entity;
            Self.Room = null;
            Self.CollisionType = COLLISION_TYPE.None;
            OBB = new OBB();
            OBB.Transform = Transform;
            Bt = new BtEntityData();
            Bt.BtBody = new List<RigidBody>();
            Bt.BtJoints = new List<TypedConstraint>();
            Bt.NoFixAll = false;
            Bt.NoFixBodyParts = 0x0000000;
            Bt.ManifoldArray = null;
            Bt.Shapes = new List<CollisionShape>();
            Bt.GhostObjects = new List<PairCachingGhostObject>();
            Bt.LastCollisions = new List<EntityCollisionNode>();

            Bf = new SSBoneFrame();
            Bf.Animations = new SSAnimation();
            Bf.Animations.Model = null;
            Bf.Animations.ClearOnFrame();
            Bf.Animations.FrameTime = 0.0f;
            Bf.Animations.LastState = TR_STATE.LaraWalkForward;
            Bf.Animations.NextState = TR_STATE.LaraWalkForward;
            Bf.Animations.Lerp = 0.0f;
            Bf.Animations.CurrentAnimation = TR_ANIMATION.LaraRun;
            Bf.Animations.CurrentFrame = 0;
            Bf.Animations.NextAnimation = TR_ANIMATION.LaraRun;
            Bf.Animations.NextFrame = 0;
            Bf.Animations.Next = null;
            Bf.BoneTags = new List<SSBoneTag>();
            Bf.BBMax = Vector3.Zero;
            Bf.BBMin = Vector3.Zero;
            Bf.Centre = Vector3.Zero;
            Bf.Position = Vector3.Zero;
            Speed = Vector3.Zero;
        }
Esempio n. 11
0
        public bool CreateRagdoll(RDSetup setup)
        {
            // No entity, setup or body count overflow - bypass function.

            if (setup == null || setup.BodySetup.Count > Bf.BoneTags.Count)
            {
                return false;
            }

            var result = true;

            // If ragdoll already exists, overwrite it with new one.

            if (Bt.BtJoints.Count > 0)
            {
                result = DeleteRagdoll();
            }

            // Setup bodies.
            Bt.BtJoints.Clear();
            // update current character animation and full fix body to avoid starting ragdoll partially inside the wall or floor...
            UpdateCurrentBoneFrame(Bf, Transform);
            Bt.NoFixAll = false;
            Bt.NoFixBodyParts = 0x00000000;
#if NOPE
            int map_size = m_bf.animations.model->collision_map.size();             // does not works, strange...
            m_bf.animations.model->collision_map.size() = m_bf.animations.model->mesh_count;
            fixPenetrations(nullptr);
            m_bf.animations.model->collision_map.size() = map_size;
#else
            FixPenetrations(Vector3.Zero);
#endif

            for(var i = 0; i < setup.BodySetup.Count; i++)
            {
                // TODO: First check useless?
                if(i >= Bf.BoneTags.Count || Bt.BtBody[i] == null)
                {
                    result = false;
                    continue; // If body is absent, return false and bypass this body setup.
                }

                var inertia = BulletSharp.Math.Vector3.Zero;
                var mass = setup.BodySetup[i].Mass;

                BtEngineDynamicsWorld.RemoveRigidBody(Bt.BtBody[i]);

                Bt.BtBody[i].CollisionShape.CalculateLocalInertia(mass, out inertia);
                Bt.BtBody[i].SetMassProps(mass, inertia);

                Bt.BtBody[i].UpdateInertiaTensor();
                Bt.BtBody[i].ClearForces();

                Bt.BtBody[i].LinearFactor = BulletSharp.Math.Vector3.One;
                Bt.BtBody[i].AngularFactor = BulletSharp.Math.Vector3.One;

                Bt.BtBody[i].SetDamping(setup.BodySetup[i].Damping[0], setup.BodySetup[i].Damping[1]);
                Bt.BtBody[i].Restitution = setup.BodySetup[i].Restitution;
                Bt.BtBody[i].Friction = setup.BodySetup[i].Friction;

                Bt.BtBody[i].SetSleepingThresholds(RD_DEFAULT_SLEEPING_THRESHOLD, RD_DEFAULT_SLEEPING_THRESHOLD);

                if(Bf.BoneTags[i].Parent == null)
                {
                    var r = GetInnerBBRadius(Bf.BoneTags[i].MeshBase.BBMin, Bf.BoneTags[i].MeshBase.BBMax);
                    Bt.BtBody[i].CcdMotionThreshold = 0.8f * r;
                    Bt.BtBody[i].CcdSweptSphereRadius = r;
                }
            }

            UpdateRigidBody(true);
            for(var i = 0; i < Bf.BoneTags.Count; i++)
            {
                BtEngineDynamicsWorld.AddRigidBody(Bt.BtBody[i]);
                Bt.BtBody[i].Activate();
                Bt.BtBody[i].LinearVelocity = Speed.ToBullet();
                if (i < Bt.GhostObjects.Count && Bt.GhostObjects[i] != null)
                {
                    BtEngineDynamicsWorld.RemoveCollisionObject(Bt.GhostObjects[i]);
                    BtEngineDynamicsWorld.AddCollisionObject(Bt.GhostObjects[i], CollisionFilterGroups.None, CollisionFilterGroups.None);
                }
            }

            // Setup constraints.
            Bt.BtJoints.Resize(setup.JointSetup.Count);

            for(var i = 0; i < setup.JointSetup.Count; i++)
            {
                if(setup.JointSetup[i].BodyIndex >= Bf.BoneTags.Count || Bt.BtBody[setup.JointSetup[i].BodyIndex] == null)
                {
                    result = false;
                    break; // If body 1 or body 2 are absent, return false and bypass this joint.
                }

                var localA = new Transform();
                var localB = new Transform();
                var btB = Bf.BoneTags[setup.JointSetup[i].BodyIndex];
                var btA = btB.Parent;
                if(btA == null)
                {
                    result = false;
                    break;
                }
#if NOPE
                localA.setFromOpenGLMatrix(btB->transform);
                localB.setIdentity();
#else
                Helper.SetEulerZYX(ref localA.Basis, setup.JointSetup[i].Body1Angle);
                //localA.Origin = setup.JointSetup[i].Body1Offset;
                localA.Origin = btB.Transform.Origin;

                Helper.SetEulerZYX(ref localB.Basis, setup.JointSetup[i].Body2Angle);
                //localB.Origin = setup.JointSetup[i].Body2Offset;
                localB.Origin = Vector3.Zero;
#endif

                switch(setup.JointSetup[i].JointType)
                {
                    case RDJointSetup.Type.Point:
                        Bt.BtJoints[i] = new Point2PointConstraint(Bt.BtBody[btA.Index], Bt.BtBody[btB.Index],
                            localA.Origin.ToBullet(), localB.Origin.ToBullet());
                        break;

                        case RDJointSetup.Type.Hinge:
                        var hingeC = new HingeConstraint(Bt.BtBody[btA.Index], Bt.BtBody[btB.Index], ((Matrix4) localA).ToBullet(),
                            ((Matrix4) localB).ToBullet());
                        hingeC.SetLimit(setup.JointSetup[i].JointLimit[0], setup.JointSetup[i].JointLimit[1], 0.9f, 0.3f, 0.3f);
                        Bt.BtJoints[i] = hingeC;
                        break;

                    case RDJointSetup.Type.Cone:
                        var coneC = new ConeTwistConstraint(Bt.BtBody[btA.Index], Bt.BtBody[btB.Index], ((Matrix4)localA).ToBullet(),
                            ((Matrix4)localB).ToBullet());
                        coneC.SetLimit(setup.JointSetup[i].JointLimit[0], setup.JointSetup[i].JointLimit[1], setup.JointSetup[i].JointLimit[2], 0.9f, 0.3f, 0.7f);
                        Bt.BtJoints[i] = coneC;
                        break;
                }

                Bt.BtJoints[i].SetParam(ConstraintParam.StopCfm, setup.JointCfm, -1);
                Bt.BtJoints[i].SetParam(ConstraintParam.StopErp, setup.JointErp, -1);

                Bt.BtJoints[i].DebugDrawSize = 64.0f;
                BtEngineDynamicsWorld.AddConstraint(Bt.BtJoints[i], true);
            }

            if(!result)
            {
                DeleteRagdoll(); // PARANOID: Clean up the mess, if something went wrong.
            }
            else
            {
                TypeFlags |= ENTITY_TYPE.Dynamic;
            }
            return result;
        }
Esempio n. 12
0
        public static void UpdateCurrentBoneFrame(SSBoneFrame bf, Transform etr)
        {
            var btag = bf.BoneTags[0];
            var model = bf.Animations.Model;

            var nextBf = model.Animations[(int) bf.Animations.NextAnimation].Frames[bf.Animations.NextFrame];
            var currBf = model.Animations[(int) bf.Animations.CurrentAnimation].Frames[bf.Animations.CurrentFrame];

            var tr = Vector3.Zero;
            var cmd_tr = Vector3.Zero;
            if (etr != null && currBf.Command.HasFlagUns(ANIM_CMD.Move))
            {
                tr = etr.Basis.MultiplyByVector(currBf.Move);
                cmd_tr = tr * bf.Animations.Lerp;
            }

            bf.BBMax = currBf.BBMax.Lerp(nextBf.BBMax, bf.Animations.Lerp) + cmd_tr;
            bf.BBMin = currBf.BBMin.Lerp(nextBf.BBMin, bf.Animations.Lerp) + cmd_tr;
            bf.Centre = currBf.Centre.Lerp(nextBf.Centre, bf.Animations.Lerp) + cmd_tr;
            bf.Position = currBf.Position.Lerp(nextBf.Position, bf.Animations.Lerp) + cmd_tr;

            var next_btag = nextBf.BoneTags[0];
            var src_btag = currBf.BoneTags[0];
            for (var k = 0;
                k < currBf.BoneTags.Count;)
            {
                btag.Offset = src_btag.Offset.Lerp(next_btag.Offset, bf.Animations.Lerp);
                btag.Transform.Origin = btag.Offset;
                btag.Transform.Origin.Z = 1.0f;
                if(k == 0)
                {
                    btag.Transform.Origin += bf.Position;
                    btag.QRotate = Quaternion.Slerp(src_btag.QRotate, next_btag.QRotate, bf.Animations.Lerp);
                }
                else
                {
                    var ov_src_btag = src_btag;
                    var ov_next_btag = next_btag;
                    var ov_lerp = bf.Animations.Lerp;
                    for (var ov_anim = bf.Animations.Next; ov_anim != null; ov_anim = ov_anim.Next)
                    {
                        if (ov_anim.Model != null && ov_anim.Model.MeshTree[k].ReplaceAnim != 0)
                        {
                            var ov_curr_bf =
                                ov_anim.Model.Animations[(int) ov_anim.CurrentAnimation].Frames[ov_anim.CurrentFrame];
                            var ov_next_bf =
                                ov_anim.Model.Animations[(int) ov_anim.NextAnimation].Frames[ov_anim.NextFrame];
                            ov_src_btag = ov_curr_bf.BoneTags[k];
                            ov_next_btag = ov_next_bf.BoneTags[k];
                            ov_lerp = ov_anim.Lerp;
                            break;
                        }
                    }
                    btag.QRotate = Quaternion.Slerp(ov_src_btag.QRotate, ov_next_btag.QRotate, ov_lerp);
                }
                btag.Transform.Rotation = btag.QRotate;
                k++;
                if (k < bf.BoneTags.Count)
                {
                    btag = bf.BoneTags[k];
                    src_btag = currBf.BoneTags[k];
                    next_btag = nextBf.BoneTags[k];
                }
            }

            // build absolute coordinate matrix system
            var btagI = 0;
            btag = bf.BoneTags[btagI];
            btag.FullTransform = btag.Transform;
            var incBtag = new Action(() =>
            {
                btagI++;
                btag = btagI < bf.BoneTags.Count ? bf.BoneTags[btagI] : null;
            });
            for(var k = 1; k < currBf.BoneTags.Count; k++, incBtag())
            {
                btag.FullTransform = (btag.Parent?.FullTransform ?? new Transform()) * btag.Transform;
            }
        }
Esempio n. 13
0
 public static void Mat4_Translate(Transform mat, Vector3 v)
 {
     mat.Origin += mat.Basis.MultiplyByVector(v);
 }
Esempio n. 14
0
        public static void Mat4_RotateZ(Transform mat, float ang)
        {
            var tmp = ang * RadPerDeg;
            var sina = (float)Math.Sin(tmp);
            var cosa = (float)Math.Cos(tmp);

            var m = Matrix3.Transpose(mat.Basis);
            m.Row0 = mat.Basis.Column0 * cosa + mat.Basis.Column1 * sina;
            m.Row1 = -mat.Basis.Column0 * sina + mat.Basis.Column1 * cosa;

            mat.Basis = Matrix3.Transpose(m);
        }
Esempio n. 15
0
 public static void Mat4_Scale(Transform mat, float x, float y, float z)
 {
     mat.Basis = mat.Basis.Scaled(new Vector3(x, y, z));
 }
Esempio n. 16
0
        public ClimbInfo CheckClimbability(Vector3 offset, HeightInfo nfc, float testHeight)
        {
            Vector3 from, to;
            float d;
            var pos = Transform.Origin;
            var t1 = new Transform();
            var t2 = new Transform();
            byte upFounded;
            var castRay = new float[6];

            // init callbacks functions
            nfc.Cb = RayCb;
            nfc.Ccb = ConvexCb;
            var tmp = pos + offset;

            var ret = new ClimbInfo();
            ret.HeightInfo = CheckNextStep(offset + new Vector3(0, 0, 128), nfc);
            ret.CanHang = false;
            ret.EdgeHit = false;
            ret.EdgeObject = null;
            ret.FloorLimit = HeightInfo.FloorHit ? HeightInfo.FloorPoint.Z : -9e10f;
            ret.CeilingLimit = HeightInfo.CeilingHit ? HeightInfo.CeilingPoint.Z : 9e10f;
            if (nfc.CeilingHit && nfc.CeilingPoint.Z < ret.CeilingLimit)
            {
                ret.CeilingLimit = nfc.CeilingPoint.Z;
            }
            ret.Point = Climb.Point;

            // check max height
            if (HeightInfo.CeilingHit && tmp.Z > HeightInfo.CeilingPoint.Z - ClimbR - 1.0f)
            {
                tmp.Z = HeightInfo.CeilingPoint.Z - ClimbR - 1.0f;
            }

            // let's calculate edge
            from.X = pos.X - Transform.Basis.Column1.X * ClimbR * 2.0f;
            from.Y = pos.Y - Transform.Basis.Column1.Y * ClimbR * 2.0f;
            from.Z = pos.Z;
            to = tmp;

            t1.SetIdentity();
            t2.SetIdentity();
            upFounded = 0;
            testHeight = Math.Max(testHeight, MaxStepUpHeight);
            d = pos.Z + Bf.BBMax.Z - testHeight;
            to.CopyToArray(castRay, 0);
            to.CopyToArray(castRay, 3);
            castRay[5] -= d;
            var n0 = Vector3.Zero;
            var n1 = Vector3.Zero;
            var n0d = 0.0f;
            var n1d = 0.0f;
            do
            {
                t1.Origin = from;
                t2.Origin = to;
                nfc.Ccb.ClosestHitFraction = 1.0f;
                nfc.Ccb.HitCollisionObject = null;
                BtEngineDynamicsWorld.ConvexSweepTest(ClimbSensor, ((Matrix4) t1).ToBullet(), ((Matrix4) t2).ToBullet(), nfc.Ccb);
                if (nfc.Ccb.HasHit)
                {
                    if (nfc.Ccb.HitNormalWorld.Z >= 0.1f)
                    {
                        upFounded = 1;
                        n0 = nfc.Ccb.HitNormalWorld.ToOpenTK();
                        n0d = -n0.Dot(nfc.Ccb.HitPointWorld.ToOpenTK());
                    }
                    if (upFounded != 0 && nfc.Ccb.HitNormalWorld.Z < 0.001f)
                    {
                        n1 = nfc.Ccb.HitNormalWorld.ToOpenTK();
                        n1d = -n1.Dot(nfc.Ccb.HitPointWorld.ToOpenTK());
                        Climb.EdgeObject = nfc.Ccb.HitCollisionObject;
                        upFounded = 2;
                        break;
                    }
                }
                else
                {
                    tmp.X = to.X;
                    tmp.Y = to.Y;
                    tmp.Z = d;
                    t1.Origin = to;
                    t2.Origin = tmp;
                    t1.Origin = from;
                    t2.Origin = to;
                    nfc.Ccb.ClosestHitFraction = 1.0f;
                    nfc.Ccb.HitCollisionObject = null;
                    BtEngineDynamicsWorld.ConvexSweepTest(ClimbSensor, ((Matrix4) t1).ToBullet(), ((Matrix4) t2).ToBullet(), nfc.Ccb);
                    if (nfc.Ccb.HasHit)
                    {
                        upFounded = 1;
                        n0 = nfc.Ccb.HitNormalWorld.ToOpenTK();
                        n0d = -n0.Dot(nfc.Ccb.HitPointWorld.ToOpenTK());
                    }
                    else
                    {
                        return ret;
                    }
                }

                // mult 0.66 is magic, but it must be less than 1.0 and greater than 0.0;
                // close to 1.0 - bad precision, good speed;
                // close to 0.0 - bad speed, bad precision;
                // close to 0.5 - middle speed, good precision
                from.Z -= 0.66f * ClimbR;
                to.Z -= 0.66f * ClimbR;
            } while (to.Z >= d); // we can't climb under floor!

            if (upFounded != 2)
            {
                return ret;
            }

            // get the character plane equation
            var n2 = Transform.Basis.Column0;
            var n2d = -n2.Dot(pos);

            Assert(!n0.FuzzyZero());
            Assert(!n1.FuzzyZero());
            Assert(!n2.FuzzyZero());

            /*
             * Solve system of the linear equations by Kramer method!
             * I know - It may be slow, but it has a good precision!
             * The root is point of 3 planes intersection.
             */
            d = -n0[0] * (n1[1] * n2[2] - n1[2] * n2[1]) +
                n1[0] * (n0[1] * n2[2] - n0[2] * n2[1]) -
                n2[0] * (n0[1] * n1[2] - n0[2] * n1[1]);

            if (Math.Abs(d) < 0.005f)
            {
                return ret;
            }

            ret.EdgePoint[0] = n0d * (n1[1] * n2[2] - n1[2] * n2[1]) -
                               n1d * (n0[1] * n2[2] - n0[2] * n2[1]) +
                               n2d * (n0[1] * n1[2] - n0[2] * n1[1]);
            ret.EdgePoint[0] /= d;

            ret.EdgePoint[1] = n0[0] * (n1d * n2[2] - n1[2] * n2d) -
                               n1[0] * (n0d * n2[2] - n0[2] * n2d) +
                               n2[0] * (n0d * n1[2] - n0[2] * n1d);
            ret.EdgePoint[1] /= d;

            ret.EdgePoint[2] = n0[0] * (n1[1] * n2d - n1d * n2[1]) -
                               n1[0] * (n0[1] * n2d - n0d * n2[1]) +
                               n2[0] * (n0[1] * n1d - n0d * n1[1]);
            ret.EdgePoint[2] /= d;
            ret.Point = ret.EdgePoint;
            ret.Point.CopyToArray(castRay, 3);
            /*
             * unclimbable edge slant %)
             */
            n2 = n0.Cross(n1);
            d = CriticalSlantZComponent;
            d *= d * (n2[0] * n2[0] + n2[1] * n2[1] + n2[2] * n2[2]);
            if (n2[2] * n2[2] > d)
            {
                return ret;
            }

            /*
             * Now, let us calculate z_angle
             */
            ret.EdgeHit = true;

            n2.Z = n2.X;
            n2.X = n2.Y;
            n2.Y = -n2.Z;
            n2.Z = 0.0f;
            if (n2.X * Transform.Basis.Column1.X + n2.Y * Transform.Basis.Column1.Y > 0) // direction fixing
            {
                n2.X = -n2.X;
                n2.Y = -n2.Y;
            }

            ret.N = n2;
            ret.Up.X = 0.0f;
            ret.Up.Y = 0.0f;
            ret.Up.Z = 1.0f;
            ret.EdgeZAngle = Helper.Atan2(n2.X, -n2.Y) * DegPerRad;
            ret.EdgeTanXY.X = -n2.Y;
            ret.EdgeTanXY.Y = n2.X;
            ret.EdgeTanXY.Z = 0.0f;
            ret.EdgeTanXY /= (float) Math.Sqrt(n2.X * n2.X + n2.Y * n2.Y);
            ret.Right = ret.EdgeTanXY;

            if (!HeightInfo.FloorHit || ret.EdgePoint.Z - HeightInfo.FloorPoint.Z >= Height)
            {
                ret.CanHang = true;
            }

            ret.NextZSpace = 2.0f * Height;
            if (nfc.FloorHit && nfc.CeilingHit)
            {
                ret.NextZSpace = nfc.CeilingPoint.Z - nfc.FloorPoint.Z;
            }

            return ret;
        }
Esempio n. 17
0
        public ClimbInfo CheckWallsClimbability()
        {
            var ret = new ClimbInfo();
            ret.CanHang = false;
            ret.WallHit = ClimbType.None;
            ret.EdgeHit = false;
            ret.EdgeObject = null;
            ret.FloorLimit = HeightInfo.FloorHit ? HeightInfo.FloorPoint.Z : -9e10f;
            ret.CeilingLimit = HeightInfo.CeilingHit ? HeightInfo.CeilingPoint.Z : 9e10f;
            ret.Point = Climb.Point;

            if (!HeightInfo.WallsClimb)
            {
                return ret;
            }

            ret.Up = Vector3.UnitZ;

            var pos = Transform.Origin;
            var from = pos + Transform.Basis.Column2 * Bf.BBMax.Z - Transform.Basis.Column1 * ClimbR;
            var to = from;
            var t = ForwardSize + Bf.BBMax.Y;
            to += Transform.Basis.Column1 * t;

            var ccb = ConvexCb;
            ccb.ClosestHitFraction = 1.0f;
            ccb.HitCollisionObject = null;

            var tr1 = new Transform();
            tr1.SetIdentity();
            tr1.Origin = from;

            var tr2 = new Transform();
            tr2.SetIdentity();
            tr2.Origin = to;

            BtEngineDynamicsWorld.ConvexSweepTest(ClimbSensor, ((Matrix4) tr1).ToBullet(), ((Matrix4) tr2).ToBullet(), ccb);
            if (!ccb.HasHit)
            {
                return ret;
            }

            ret.Point = ccb.HitPointWorld.ToOpenTK();
            ret.N = ccb.HitNormalWorld.ToOpenTK();
            var wn2 = new[] {ret.N.X, ret.N.Y};
            t = (float) Math.Sqrt(wn2[0] * wn2[0] + wn2[1] * wn2[1]);
            wn2[0] /= t;
            wn2[1] /= t;

            ret.Right.X = -wn2[1];
            ret.Right.Y = wn2[0];
            ret.Right.Z = 0.0f;

            // now we have wall normale in XOY plane. Let us check all flags
            if (HeightInfo.WallsClimbDir.HasFlagSig(SectorFlag.ClimbNorth) && wn2[1] < -0.7f
                || HeightInfo.WallsClimbDir.HasFlagSig(SectorFlag.ClimbEast) && wn2[0] < -0.7f
                || HeightInfo.WallsClimbDir.HasFlagSig(SectorFlag.ClimbSouth) && wn2[1] > 0.7f
                || HeightInfo.WallsClimbDir.HasFlagSig(SectorFlag.ClimbWest) && wn2[0] > 0.7f)
            {
                ret.WallHit = ClimbType.HandsOnly;
            }

            if (ret.WallHit != ClimbType.None)
            {
                t = 0.67f * Height;
                from -= Transform.Basis.Column2 * t;
                to = from;
                t = ForwardSize + Bf.BBMax.Y;
                to += Transform.Basis.Column1 * t;

                ccb.ClosestHitFraction = 1.0f;
                ccb.HitCollisionObject = null;
                tr1.SetIdentity();
                tr1.Origin = from;
                tr2.SetIdentity();
                tr2.Origin = to;
                BtEngineDynamicsWorld.ConvexSweepTest(ClimbSensor, ((Matrix4) tr1).ToBullet(), ((Matrix4) tr2).ToBullet(), ccb);
                if (ccb.HasHit)
                {
                    ret.WallHit = ClimbType.FullBody;
                }
            }

            return ret;
        }
Esempio n. 18
0
 public BSPFaceRef(Transform matrix, TransparentPolygonReference polygon)
 {
     Transform = matrix;
     Polygon = polygon;
 }
Esempio n. 19
0
        public void Render()
        {
            if(CurrentState != InventoryState.Disabled && inventory != null && inventory.Count > 0 && Global.FontManager != null)
            {
                var num = 0;
                foreach (var i in inventory)
                {
                    var bi = EngineWorld.GetBaseItemByID(i.ID);
                    if(bi == null || bi.Type != currentItemsType)
                    {
                        continue;
                    }

                    var matrix = new Transform();
                    matrix.SetIdentity();
                    VMath.Mat4_Translate(matrix, 0.0f, 0.0f, -baseRingRadius * 2.0f);
                    //VMath.Mat4_RotateX(matrix, 25.0f);
                    VMath.Mat4_RotateX(matrix, 25.0f + ringVerticalAngle);
                    var ang = ringAngleStep * (-itemsOffset + num) + ringAngle;
                    VMath.Mat4_RotateY(matrix, ang);
                    VMath.Mat4_Translate(matrix, 0.0f, verticalOffset, ringRadius);
                    VMath.Mat4_RotateX(matrix, -90.0f);
                    VMath.Mat4_RotateZ(matrix, 90.0f);
                    if(num == itemsOffset)
                    {
                        if(bi.Name[0] != 0)
                        {
                            LabelItemName.Text = bi.Name;

                            if(i.Count > 1)
                            {
                                var counter = EngineLua.GetString(STR_GEN_MASK_INVHEADER);
                                LabelItemName.Text = Helper.Format(counter, bi.Name, i.Count);
                            }
                        }
                        VMath.Mat4_RotateZ(matrix, 90.0f + itemAngle - ang);
                        Gui.Item_Frame(bi.BoneFrame, 0.0f); // here will be time != 0 for using items animation
                    }
                    else
                    {
                        VMath.Mat4_RotateZ(matrix, 90.0f - ang);
                        Gui.Item_Frame(bi.BoneFrame, 0.0f);
                    }
                    VMath.Mat4_Translate(matrix, -0.5f * bi.BoneFrame.Centre);
                    VMath.Mat4_Scale(matrix, 0.7f, 0.7f, 0.7f);
                    Gui.RenderItem(bi.BoneFrame, 0.0f, matrix);

                    num++;
                }
            }
        }
Esempio n. 20
0
 public void VTransform(Polygon src, Transform tr)
 {
     Plane.Normal = tr.Basis.MultiplyByVector(src.Plane.Normal);
     for (var i = 0; i < src.Vertices.Count; i++)
     {
         Vertices[i].Position = tr * src.Vertices[i].Position;
     }
     Plane.MoveTo(Vertices[0].Position);
 }
Esempio n. 21
0
        public void RenderSkeletalModelSkin(LitShaderDescription shader, Entity ent, Matrix4 mvMatrix, Matrix4 pMatrix)
        {
            GL.UniformMatrix4(shader.Projection, false, ref pMatrix);

            foreach (var btag in ent.Bf.BoneTags)
            {
                var transforms = new float[32];
                var mvTransforms = mvMatrix.MultiplyByTransform(btag.FullTransform);
                unsafe
                {
                    Array.Copy(Helper.GetArrayFromPointer(&mvTransforms.Row0.X, 16), transforms, 16);
                }

                // Calculate parent transform
                var parentTransform = btag.Parent == null ? ent.Transform : btag.Parent.FullTransform;

                var translate = new Transform();
                translate.SetIdentity();
                translate.Origin += btag.Offset;

                var secondTransform = parentTransform * translate;

                var mvTransforms2 = mvMatrix.MultiplyByTransform(secondTransform);
                unsafe
                {
                    Array.Copy(Helper.GetArrayFromPointer(&mvTransforms2.Row0.X, 16), 0, transforms, 16, 16);
                }
                GL.UniformMatrix4(shader.ModelView, 2, false, transforms);

                if(btag.MeshSkin != null)
                {
                    RenderMesh(btag.MeshSkin);
                }
            }
        }
Esempio n. 22
0
        public void Transform(Polygon src, Transform tr)
        {
            Vertices.Resize(src.Vertices.Count, () => new Vertex());

            Plane.Normal = tr.Basis.MultiplyByVector(src.Plane.Normal);
            for (var i = 0; i < src.Vertices.Count; i++)
            {
                Vertices[i].Position = tr * src.Vertices[i].Position;
                Vertices[i].Normal = tr.Basis.MultiplyByVector(src.Vertices[i].Normal);
            }
            Plane.MoveTo(Vertices[0].Position);
        }
Esempio n. 23
0
        public void RenderSkyBox(Matrix4 modelViewProjectionMatrix)
        {
            if (drawSkybox && World?.SkyBox != null)
            {
                GL.DepthMask(false);
                var tr = new Transform();
                tr.Origin = Camera.Position + World.SkyBox.Animations[0].Frames[0].BoneTags[0].Offset;
                tr.Rotation = World.SkyBox.Animations[0].Frames[0].BoneTags[0].QRotate;
                var fullView = modelViewProjectionMatrix.MultiplyByTransform(tr);

                var shader = ShaderManager.GetStaticMeshShader();
                GL.UseProgram(shader.Program);
                GL.UniformMatrix4(shader.ModelViewProjection, false, ref fullView);
                GL.Uniform1(shader.Sampler, 0);
                var tint = new float[] {1, 1, 1, 1};
                GL.Uniform4(shader.TintMult, 1, tint);

                RenderMesh(World.SkyBox.MeshTree[0].MeshBase);
                GL.DepthMask(true);
            }
        }
Esempio n. 24
0
 public void TransformSelf(Transform tr)
 {
     Plane.Normal = tr.Basis.MultiplyByVector(Plane.Normal);
     foreach (var t in Vertices)
     {
         t.Position *= tr;
         t.Normal = tr.Basis.MultiplyByVector(t.Normal);
     }
     Plane.MoveTo(Vertices[0].Position);
 }
Esempio n. 25
0
 public void DrawBBox(Vector3 bbMin, Vector3 bbMax, Transform transform)
 {
     obb.Rebuild(bbMin, bbMax);
     obb.Transform = transform;
     obb.DoTransform();
     DrawOBB(obb);
 }
Esempio n. 26
0
 public static bool Cam_HasHit(BtEngineClosestConvexResultCallback cb, Transform cameraFrom, Transform cameraTo)
 {
     var cameraSphere = new SphereShape(COLLISION_CAMERA_SPHERE_RADIUS)
     {
         Margin = COLLISION_MARGIN_DEFAULT
     };
     cb.ClosestHitFraction = 1.0f;
     cb.HitCollisionObject = null;
     BtEngineDynamicsWorld.ConvexSweepTest(cameraSphere, ((Matrix4)cameraFrom).ToBullet(), ((Matrix4)cameraTo).ToBullet(), cb);
     return cb.HasHit;
 }
Esempio n. 27
0
 public void DrawSkeletalModelDebugLines(SSBoneFrame bframe, Transform transform, Render render)
 {
     if(render.drawNormals)
     {
         foreach (var btag in bframe.BoneTags)
         {
             var tr = transform * btag.FullTransform;
             DrawMeshDebugLines(btag.MeshBase, tr, new List<Vector3>(), new List<Vector3>(), render);
         }
     }
 }
Esempio n. 28
0
        public static void Cam_FollowEntity(Camera cam, Entity ent, float dx, float dz)
        {
            var cameraFrom = new Transform();
            var cameraTo = new Transform();

            // Reset to initial
            cameraFrom.SetIdentity();
            cameraTo.SetIdentity();

            var cb = ent.CallbackForCamera();

            var camPos = cam.Position;

            // Basic camera override, completely placeholder until a system classic-like is created
            if (!ControlStates.MouseLook) // If mouse look is off
            {
                var currentAngle = CamAngles.X * RadPerDeg; // Current is the current cam angle
                var targetAngle = ent.Angles.X * RadPerDeg;
                    // Target is the target angle which is the entity's angle itself
                var rotSpeed = 2.0f; // Speed of rotation

                //@FIXME
                // If Lara is in a specific state we want to rotate -75 deg or +75 deg depending on camera collision
                if(ent.Bf.Animations.LastState == TR_STATE.LaraReach)
                {
                    if(cam.TargetDir == TR_CAM_TARG.Back)
                    {
                        var camPos2 = camPos;
                        cameraFrom.Origin = camPos2;
                        camPos2.X += (float) (Math.Sin((ent.Angles.X - 90.0f) * RadPerDeg) *
                                              ControlStates.CamDistance);
                        camPos2.Y -= (float) (Math.Cos((ent.Angles.X - 90.0f) * RadPerDeg) *
                                              ControlStates.CamDistance);
                        cameraTo.Origin = camPos2;

                        // If collided we want to go right otherwise stay left
                        if(Cam_HasHit(cb, cameraFrom, cameraTo))
                        {
                            camPos2 = camPos;
                            cameraFrom.Origin = camPos2;
                            camPos2.X += (float)(Math.Sin((ent.Angles.X + 90.0f) * RadPerDeg) *
                                             ControlStates.CamDistance);
                            camPos2.Y -= (float)(Math.Cos((ent.Angles.X + 90.0f) * RadPerDeg) *
                                                  ControlStates.CamDistance);
                            cameraTo.Origin = camPos2;

                            // If collided we want to go to back else right
                            cam.TargetDir = Cam_HasHit(cb, cameraFrom, cameraTo) ? TR_CAM_TARG.Back : TR_CAM_TARG.Right;
                        }
                        else
                        {
                            cam.TargetDir = TR_CAM_TARG.Left;
                        }
                    }
                }
                else if(ent.Bf.Animations.LastState == TR_STATE.LaraJumpBack)
                {
                    cam.TargetDir = TR_CAM_TARG.Front;
                }
                // ReSharper disable once RedundantCheckBeforeAssignment
                else if(cam.TargetDir != TR_CAM_TARG.Back)
                {
                    cam.TargetDir = TR_CAM_TARG.Back; // Reset to back
                }

                // If target mis-matches current we need to update the camera's angle to reach target!
                if (currentAngle != targetAngle)
                {
                    switch (cam.TargetDir)
                    {
                        case TR_CAM_TARG.Back:
                            targetAngle = ent.Angles.X * RadPerDeg;
                            break;
                        case TR_CAM_TARG.Front:
                            targetAngle = (ent.Angles.X - 180.0f) * RadPerDeg;
                            break;
                        case TR_CAM_TARG.Left:
                            targetAngle = (ent.Angles.X - 75.0f) * RadPerDeg;
                            break;
                        case TR_CAM_TARG.Right:
                            targetAngle = (ent.Angles.X + 75.0f) * RadPerDeg;
                            break;
                        default:
                            targetAngle = ent.Angles.X * RadPerDeg; // Same as TR_CAM_TARG_BACK (default pos)
                            break;
                    }

                    var dAngle = CamAngles.X - targetAngle;
                    if (dAngle > Rad90)
                    {
                        dAngle -= 1 * RadPerDeg;
                    }
                    else
                    {
                        dAngle += 1 * RadPerDeg;
                    }
                    CamAngles.X =
                        (CamAngles.X +
                         Helper.Atan2((float) Math.Sin(currentAngle - dAngle), (float) Math.Cos(currentAngle + dAngle)) *
                         EngineFrameTime * rotSpeed) % Rad360; // Update camera's angle
                }
            }

            camPos = ent.CamPosForFollowing(dz);

            // Code to manage screen shaking effects
            if(Renderer.Camera.ShakeTime > 0.0f && Renderer.Camera.ShakeValue > 0.0f)
            {
                camPos = camPos.AddF((Helper.CPPRand() % Math.Abs(Renderer.Camera.ShakeValue) -
                                     Renderer.Camera.ShakeValue / 2.0f) * Renderer.Camera.ShakeTime);
                Renderer.Camera.ShakeTime = Renderer.Camera.ShakeTime < 0.0f
                    ? 0.0f
                    : Renderer.Camera.ShakeTime - EngineFrameTime;
            }

            cameraFrom.Origin = camPos;
            camPos.Z += dz;
            cameraTo.Origin = camPos;
            if(Cam_HasHit(cb, cameraFrom, cameraTo))
            {
                Helper.SetInterpolate3(out camPos, cameraFrom.Origin, cameraTo.Origin, cb.ClosestHitFraction);
                camPos += (cb.HitNormalWorld * 2.0f).ToOpenTK();
            }

            if(dx != 0.0f)
            {
                cameraFrom.Origin = camPos;
                camPos += dx * cam.RightDirection;
                cameraTo.Origin = camPos;
                if (Cam_HasHit(cb, cameraFrom, cameraTo))
                {
                    Helper.SetInterpolate3(out camPos, cameraFrom.Origin, cameraTo.Origin, cb.ClosestHitFraction);
                    camPos += (cb.HitNormalWorld * 2.0f).ToOpenTK();
                }

                cameraFrom.Origin = camPos;

                var cosAy = Math.Cos(CamAngles.Y);
                var camDx = Math.Sin(CamAngles.X) * cosAy;
                var camDy = -Math.Cos(CamAngles.X) * cosAy;
                var camDz = -Math.Sin(CamAngles.Y);
                camPos.X += (float) (camDx * ControlStates.CamDistance);
                camPos.Y += (float) (camDy * ControlStates.CamDistance);
                camPos.Z += (float) (camDz * ControlStates.CamDistance);

                cameraTo.Origin = camPos;
                if (Cam_HasHit(cb, cameraFrom, cameraTo))
                {
                    Helper.SetInterpolate3(out camPos, cameraFrom.Origin, cameraTo.Origin, cb.ClosestHitFraction);
                    camPos += (cb.HitNormalWorld * 2.0f).ToOpenTK();
                }
            }

            // Update cam pos
            cam.Position = camPos;

            // Modify cam pos for quicksand rooms
            cam.CurrentRoom = Room.FindPosCogerrence(cam.Position - new Vector3(0, 0, 128), cam.CurrentRoom);
            if(cam.CurrentRoom != null && cam.CurrentRoom.Flags.HasFlagUns(RoomFlag.Quicksand))
            {
                var pos = cam.Position;
                pos.Z = cam.CurrentRoom.BBMax.Z + 2.0f * 64.0f;
                cam.Position = pos;
            }

            cam.SetRotation(CamAngles);
            cam.CurrentRoom = Room.FindPosCogerrence(cam.Position, cam.CurrentRoom);
        }
Esempio n. 29
0
        public void RenderDynamicEntitySkin(LitShaderDescription shader, Entity ent, Matrix4 mvMatrix, Matrix4 pMatrix)
        {
            GL.UniformMatrix4(shader.Projection, false, ref pMatrix);

            for (var i = 0; i < ent.Bf.BoneTags.Count; i++)
            {
                var mat0 = mvMatrix * ent.Bt.BtBody[i].GetWorldTransform();
                var tr1 = new Matrix4();
                // Calculate parent transform
                var btag = ent.Bf.BoneTags[i];
                var foundParentTransform = false;
                for (var j = 0; j < ent.Bf.BoneTags.Count; j++)
                {
                    if(ent.Bf.BoneTags[i] == btag.Parent)
                    {
                        tr1 = ent.Bt.BtBody[j].GetWorldTransform();
                        foundParentTransform = true;
                        break;
                    }
                }
                if (!foundParentTransform)
                    tr1 = (Matrix4) ent.Transform;

                var translate = new Transform();
                translate.SetIdentity();
                translate.Origin += btag.Offset;

                var secondTransform = tr1.MultiplyByTransform(translate);
                var mat1 = mvMatrix * secondTransform;

                var transforms = new float[32];
                unsafe
                {
                    Array.Copy(Helper.GetArrayFromPointer(&mat0.Row0.X, 16), transforms, 16);
                    Array.Copy(Helper.GetArrayFromPointer(&mat1.Row0.X, 16), 0, transforms, 16, 16);
                }
                GL.UniformMatrix4(shader.ModelView, 2, false, transforms);

                if (btag.MeshSkin != null)
                {
                    RenderMesh(btag.MeshSkin);
                }
            }
        }
Esempio n. 30
0
        public static void PrimaryMouseDown()
        {
            var cont = new EngineContainer();
            var dbgR = 128.0f;
            var v = EngineCamera.Position;
            var dir = EngineCamera.ViewDirection;
            var localInertia = BulletSharp.Math.Vector3.Zero;

            var cshape = new SphereShape(dbgR);
            cshape.Margin = COLLISION_MARGIN_DEFAULT;

            var startTransform = new Transform();
            startTransform.SetIdentity();
            var newPos = v;
            startTransform.Origin = newPos;
            cshape.CalculateLocalInertia(12.0f, out localInertia);
            var motionState = new DefaultMotionState(((Matrix4)startTransform).ToBullet());
            var body = new RigidBody(new RigidBodyConstructionInfo(12.0f, motionState, cshape, localInertia));
            BtEngineDynamicsWorld.AddRigidBody(body);
            body.LinearVelocity = (dir * 6000).ToBullet();
            cont.Room = Room.FindPosCogerrence(newPos, EngineCamera.CurrentRoom);
            cont.ObjectType = OBJECT_TYPE.BulletMisc; // bullet have to destroy this user pointer
            body.UserObject = cont;
            body.CcdMotionThreshold = dbgR; // disable tunneling effect
            body.CcdSweptSphereRadius = dbgR;
        }