예제 #1
0
        public void GetFrameData_()
        {
            //bool is_ = this.Name.Contains("Tram");
            Model mdl = (this.Links[0] as Model);

            if (this.Master != null)
            {
                this.PlayingFrame = this.Master.PlayingFrame;
                this.PlayingIndex = this.Master.PlayingIndex;

                if ((this.PlayingIndex < 0))
                {
                    this.Links[0].Render = false;
                }
                if (this.PlayingIndex < 0)
                {
                    this.PlayingFrame = 0;
                    return;
                }
            }
            if (this.PlayingIndex < 0 || this.PlayingIndex > this.br.Count - 1)
            {
                return;
            }
            if (changingAnimation)
            {
                this.MaxTick    = BitConverter.ToInt32(this.br[this.PlayingIndex], 0);
                this.MinTick    = BitConverter.ToInt32(this.br[this.PlayingIndex], 4);
                this.TransposeX = this.br[this.PlayingIndex][8] != 0;
                this.TransposeY = this.br[this.PlayingIndex][9] != 0;
                this.TransposeZ = this.br[this.PlayingIndex][10] != 0;
                byte b = this.br[this.PlayingIndex][11];
                if (b == 255)
                {
                    this.InterpolateAnimation = false;
                }
                else
                {
                    this.InterpolateAnimation = true;
                    if (b > 0)
                    {
                        this.InterpolateFrameRate = b;
                    }
                }

                this.Skeleton.RememberSRT();

                changingAnimation = false;
            }

            UpdateEC(this.PlayingIndex);
            if (this.HasMaster)
            {
            }
            else
            {
                this.PlayingFrame += this.FrameStep;

                #if (!playAnims)
                if (this.NextPlayingIndex > -1)
                {
                    if ((int)this.PlayingFrame > (int)this.MaxTick - 1)
                    {
                        if (this.NextPlayingIndex != this.PlayingIndex && mdl.cState != Model.ControlState.Jump)
                        {
                            this.PlayingIndex = this.NextPlayingIndex;
                        }
                        else
                        {
                            this.PlayingFrame = this.MinTick;
                        }
                        return;
                    }
                }
                #endif
            }

            if (this.PlayingFrame < 0)
            {
                this.PlayingFrame = 0;
            }

            if ((this.MaxTick - this.MinTick) < 1.001)
            {
                if (this.PlayingFrame > this.MaxTick - 1)
                {
                    //if (this.MinTick == this.MaxTick - 1)
                    this.PlayingFrame = this.MinTick;
                }
            }
            else
            if ((int)this.PlayingFrame > (int)(this.MaxTick - 1))
            {
                //if (this.MinTick == this.MaxTick - 1)
                this.PlayingFrame = this.MinTick;
            }

            int pos = 0x10 + (int)this.PlayingFrame * this.Skeleton.Bones.Count * 0x40;

            /*Matrix m0 = this.Skeleton.Bones[this.Skeleton.RootBone].localMatrix * 1f;
             * Vector3 s0 = Vector3.Zero;
             * Quaternion q0 = Quaternion.Identity;
             * Vector3 t0 = Vector3.Zero;
             * m0.Decompose(out s0, out q0, out t0);*/

            List <Vector3> atts         = new List <Vector3>(0);
            List <Vector3> attsComputed = new List <Vector3>(0);

            for (int t = 0; t < mdl.AttachmentsModels.Count; t++)
            {
                Model sujet = mdl.AttachmentsModels[t];
                atts.Add(Vector3.Transform(sujet.Location, Matrix.Invert(mdl.Skeleton.Bones[mdl.Skeleton.RootBone].localMatrix)));
                attsComputed.Add((sujet.Location - mdl.Skeleton.Bones[mdl.Skeleton.RootBone].localMatrix.Translation) / Vector3.Distance(sujet.Location, mdl.Skeleton.Bones[mdl.Skeleton.RootBone].localMatrix.Translation));
            }
            Vector3 old = this.Skeleton.Bones[0].localMatrix.Translation;



            for (int t = 0; t < this.Skeleton.Bones.Count; t++)
            {
                m.M11 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M12 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M13 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M14 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;

                m.M21 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M22 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M23 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M24 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;

                m.M31 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M32 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M33 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M34 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;

                m.M41 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M42 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M43 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                m.M44 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;

                /*if (t==0)
                 * {
                 *      if (mdl.Opacity<0.0001)
                 *      {
                 *              m *= Matrix.CreateScale(0);
                 *      }
                 * }*/
                if (this.Skeleton.NeckBoneSet && t == this.Skeleton.NeckBone)
                {
                    ScaRoTra scaRoTra = new ScaRoTra(m);
                    scaRoTra.RotateZ += mdl.Skeleton.NeckBoneDest;
                    m = scaRoTra.Matrix;
                }

                if ((this.TransposeX || this.TransposeY || this.TransposeZ) && this.Master == null && t == this.Skeleton.RootBone)
                {
                    if (!Single.IsNaN(this.TransportingZero.X))
                    {
                        this.TransportedZero = m.Translation - this.TransportingZero;
                    }
                    this.TransportingZero = m.Translation;
                    //if (!this.InterpolateAnimation)
                    Vector3 offset = Vector3.Transform(this.TransportedZero, mdl.Rotate_matrix);
                    Vector3 newLoc = mdl.Location;

                    Vector3 zerop = m.Translation;
                    if (this.TransposeX)
                    {
                        if (Program.game.CombatCountDown > 0)
                        {
                            zerop.X = this.Skeleton.ZeroPositionFight.X;
                        }
                        else
                        {
                            zerop.X = this.Skeleton.ZeroPosition.X;
                        }
                        newLoc.X += offset.X;
                    }
                    if (this.TransposeY)
                    {
                        if (Program.game.CombatCountDown > 0)
                        {
                            zerop.Y = this.Skeleton.ZeroPositionFight.Y;
                        }
                        else
                        {
                            zerop.Y = this.Skeleton.ZeroPosition.Y;
                        }
                        newLoc.Y += offset.Y;
                    }
                    if (this.TransposeZ)
                    {
                        if (Program.game.CombatCountDown > 0)
                        {
                            zerop.Z = this.Skeleton.ZeroPositionFight.Z;
                        }
                        else
                        {
                            zerop.Z = this.Skeleton.ZeroPosition.Z;
                        }
                        newLoc.Z += offset.Z;
                    }
                    if (!mdl.Cutscene)
                    {
                        KHDebug.Collision.MonitorCollision(mdl, ref newLoc);
                    }
                    mdl.Location  = newLoc;
                    m.Translation = zerop;
                    //Program.game.cursors[0].Position = mdl.Location;
                }

                if (this.InterpolateAnimation && this.ComputingFrame <= this.InterpolateFrameRate)
                {
                    float remember = (float)(this.InterpolateFrameRate - this.ComputingFrame) / (float)this.InterpolateFrameRate;
                    float current  = (float)this.ComputingFrame / (float)this.InterpolateFrameRate;

                    Matrix m1 = this.Skeleton.Bones[t].RememberMatrix;
                    Matrix m2 = m;

                    Quaternion q  = Quaternion.Slerp(m1.Rotation, m2.Rotation, current);
                    Vector3    tr = m1.Translation * remember + m2.Translation * current;
                    Matrix     m_ = Matrix.CreateFromQuaternion(q) * Matrix.CreateTranslation(tr);
                    this.Skeleton.Bones[t].localMatrix = m_;


                    //this.Skeleton.Bones[t].localMatrix = Matrix.CreateFromQuaternion((m1 + m2).Rotation) * Matrix.CreateTranslation((m1 + m2).Translation);


                    //this.Skeleton.Bones[t].GlobalMatrix = m_;
                    //this.Skeleton.Bones[t].GetSRT(m_);
                }
                else
                {
                    this.Skeleton.Bones[t].localMatrix = m;
                    //this.Skeleton.Bones[t].GlobalMatrix = m;
                    //this.Skeleton.Bones[t].GetSRT(m);
                }

                this.Skeleton.Bones[t].DirtyMatrix = true;
            }


            /*if (this.ResourceIndex ==  "TT08-SKY0")
             * {
             *
             *  Console.WriteLine(this.FrameStep);
             *  Console.WriteLine(this.MinTick+"/"+this.MaxTick);
             *  Console.WriteLine(this.PlayingFrame);
             *  Console.WriteLine("");
             * }*/
            if (Math.Floor(this.PlayingFrame) < this.PlayingFrame)
            {
                float percentageDiff = this.PlayingFrame - (float)Math.Floor(this.PlayingFrame);
                float currPercentage = 1 - percentageDiff;
                float nextPercentage = percentageDiff;

                int nextFrame = (int)this.PlayingFrame + 1;

                if (nextFrame > this.MaxTick - 1)
                {
                    nextFrame = this.MinTick;
                }


                pos = 0x10 + nextFrame * this.Skeleton.Bones.Count * 0x40;

                for (int t = 0; t < this.Skeleton.Bones.Count; t++)
                {
                    m.M11 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M12 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M13 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M14 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;

                    m.M21 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M22 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M23 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M24 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;

                    m.M31 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M32 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M33 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M34 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;

                    m.M41 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M42 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M43 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;
                    m.M44 = BitConverter.ToSingle(this.br[this.PlayingIndex], pos); pos += 4;

                    Matrix m1 = this.Skeleton.Bones[t].LocalMatrix;
                    Matrix m2 = m;

                    Quaternion q  = Quaternion.Slerp(m1.Rotation, m2.Rotation, nextPercentage);
                    Vector3    tr = m1.Translation * currPercentage + m2.Translation * nextPercentage;
                    Vector3    sc = new Vector3(1f, 1f, 1f);// m1.Scale * currPercentage + m2.Scale * nextPercentage;

                    Matrix m_ = Matrix.CreateScale(sc) * Matrix.CreateFromQuaternion(q) * Matrix.CreateTranslation(tr);

                    //this.Skeleton.Bones[t].GetSRT(m_);

                    this.Skeleton.Bones[t].localMatrix = m_;

                    this.Skeleton.Bones[t].DirtyMatrix = true;
                }
            }

            if (mdl.AttachmentsModels.Count > 0)
            {
                for (int i = 0; i < mdl.AttachmentsModels.Count; i++)
                {
                    Model sujet = mdl.AttachmentsModels[i];
                    sujet.Location = Vector3.Transform(atts[i], this.Skeleton.Bones[this.Skeleton.RootBone].localMatrix);


                    Vector3 diff = (sujet.Location - mdl.Skeleton.Bones[mdl.Skeleton.RootBone].localMatrix.Translation) / Vector3.Distance(sujet.Location, mdl.Skeleton.Bones[mdl.Skeleton.RootBone].localMatrix.Translation);


                    float an1      = (float)Math.Atan2(attsComputed[i].X, attsComputed[i].Z);
                    float an2      = (float)Math.Atan2(diff.X, diff.Z);
                    float diffloat = an1 - an2;
                    SrkBinary.MakePrincipal(ref diffloat);

                    sujet.DestRotate -= diffloat;

                    Model target = Program.game.mainCamera.Target;
                    if (target != null && sujet.ResourceIndex == target.ResourceIndex)
                    {
                        Program.game.mainCamera.DestYaw -= diffloat;
                    }
                }
                mdl.Attachments.Clear();
                mdl.AttachmentsModels.Clear();
            }

            /*if (mdl.ResourceIndex == 13)
             * {
             *  Console.WriteLine(Vector3.Distance(this.Skeleton.Bones[0].localMatrix.Translation, old));
             *  Console.WriteLine("");
             * }*/
            Skeleton.Wrap(this.Skeleton);


            if (mdl.LowestFloor < Single.MinValue / 2f)
            {
                Vector3 v = (mdl.Location + Vector3.Transform(mdl.Skeleton.Bones[mdl.Skeleton.RootBone].localMatrix.Translation, mdl.Rotate_matrix));
                KHDebug.Collision.MonitorCollision(mdl, ref v);
            }
        }
예제 #2
0
        public static void MonitorCollision(Model sujet, ref Vector3 pos)
        {
			var collision = Program.game.MapSet ? Program.game.Map.Links[0] as Collision : null;

			if (sujet.Epaisseur < 0.1)
				return;

            bool jumping = sujet.Location.Y> sujet.LowestFloor+sujet.StairHeight && pos.Y > sujet.Location.Y;

            Vector3 refPosBottom = pos + new Vector3(0, sujet.StairHeight, 0);
            Vector3 refPosTop = pos + new Vector3(0, sujet.MaxVertex.Y, 0);

            Vector3 inter;
            Vector3 shadowAngle = Vector3.Zero;
            Vector3 globalBone0 = sujet.GetGlobalBone(0, Vector3.Zero);
            globalBone0.Y = sujet.MinVertex.Y;

            float tallest = Single.MinValue;
            float smallest = Single.MaxValue;
            shadowAngle = Vector3.Zero;
			
            Vector3 forwardCliffStart = new Vector3(0, 10f, sujet.Epaisseur * 1.1f);
            Vector3 forwardCliffEnd = new Vector3(0, -10f, sujet.Epaisseur * 1.1f);


            forwardCliffStart = Vector3.Transform(forwardCliffStart, sujet.Rotate_matrix);
            forwardCliffEnd = Vector3.Transform(forwardCliffEnd, sujet.Rotate_matrix);
            cliffBackwards = Vector3.Transform(cliffBackwards, sujet.Rotate_matrix);






			bool pushed = false;


            sujet.Attached = false;
			int moreRes = 0;
			if (Program.game.MapSet)
				moreRes = Program.game.Map.Supp.Count;

			if ((ScenePlayer.ScenePlaying  && ScenePlayer.AllowContactCollision) ||
                !ScenePlayer.ScenePlaying)
            if (!sujet.NPC && sujet.cState != Model.ControlState.Cliff)
            for (int i = 0; i < MainGame.ResourceFiles.Count + moreRes; i++)
            {
                Model mdl = null;
                if (i >= MainGame.ResourceFiles.Count)
                    mdl = Program.game.Map.Supp[i- MainGame.ResourceFiles.Count] as Model;
                else
                    mdl = MainGame.ResourceFiles[i] as Model;

				if (mdl == null) continue;
                if (sujet.ResourceIndex == mdl.ResourceIndex) continue;
				if (mdl.Collision == null)
				{
					if (mdl.Epaisseur < 1) continue;
							if (mdl.NPC || sujet.Masse <= mdl.Masse)
							{
								Vector2 sujetPos = new Vector2(pos.X, pos.Z);
								Vector2 mdlPos = new Vector2(mdl.Location.X, mdl.Location.Z);

								if (sujet.Location.Y > mdl.Location.Y-mdl.StairHeight*2f && sujet.Location.Y<mdl.Location.Y+mdl.MaxVertex.Y)
								{
									float hypo = Vector2.Distance(sujetPos, mdlPos);
									sujetPos -= mdlPos;
									sujetPos /= hypo;
									if (hypo < (mdl.Epaisseur + sujet.Epaisseur))
									{
										sujetPos = mdlPos + sujetPos * (mdl.Epaisseur + sujet.Epaisseur) * 1.1f;
										pos.X = sujetPos.X;
										pos.Z = sujetPos.Y;
									}
									/*else
									if (sujet.ResourceIndex == Program.game.mainCamera.Target.ResourceIndex &&  hypo < (mdl.Epaisseur + sujet.Epaisseur)*2f)
									{
										float val1 = (float)Math.Atan2(sujetPos.X, sujetPos.Y);
										float val2 = sujet.DestRotate + MainGame.PI;
										SrkBinary.MakePrincipal(ref val1);
										SrkBinary.MakePrincipal(ref val2);


										if (Math.Abs(val1-val2) < 1)
										{
											if (Program.game.mainCamera.LXY_read==0)
											{
												Program.game.mainCamera.LXY_read = 10;
												float cam_mdl_diff = (float)(Math.Atan2(Program.game.mainCamera.joyLY_, Program.game.mainCamera.joyLX_) + MathHelper.ToRadians(33));

												Program.game.mainCamera.joyLY_ = (float)Math.Sin(cam_mdl_diff);
												Program.game.mainCamera.joyLX_ = (float)Math.Cos(cam_mdl_diff);
											}
										}
									}*/
								}
							}
				}
				else


				for (int p=0;p< mdl.Collision.PolyCount; p++)
				{
					int start_ = mdl.Collision.StartEnds[p][0];
					int end_ = mdl.Collision.StartEnds[p][1];
					for (int j = start_; j < end_; j++)
					{
						Matrix mt = mdl.Skeleton.Bones[p].LocalMatrix;

						if (Vector3.Distance(mdl.Location,Vector3.Zero) > 0)
							mt = Matrix.Identity;
						Vector3 v1 = Vector3.Transform(
							Vector3.Transform(mdl.Collision.cols[mdl.Collision.indices[j][0][0]], mt), mdl.Rotate_matrix) + mdl.Location;
						Vector3 v2 = Vector3.Transform(
							Vector3.Transform(mdl.Collision.cols[mdl.Collision.indices[j][1][0]], mt), mdl.Rotate_matrix) + mdl.Location;
						Vector3 v3 = Vector3.Transform(
							Vector3.Transform(mdl.Collision.cols[mdl.Collision.indices[j][2][0]], mt), mdl.Rotate_matrix) + mdl.Location;

									var mt_mat = Matrix.CreateFromQuaternion(mt.Rotation);
						Vector3 n1 = Vector3.Transform(mdl.Collision.norms[mdl.Collision.indices[j][0][1]], mt_mat);
						Vector3 n2 = Vector3.Transform(mdl.Collision.norms[mdl.Collision.indices[j][1][1]], mt_mat);
						Vector3 n3 = Vector3.Transform(mdl.Collision.norms[mdl.Collision.indices[j][2][1]], mt_mat);
						Vector3 normal = (n1 + n2 + n3) / 3f;
                        
						if (mdl.NPC || sujet.Masse <= mdl.Masse)
						{
							bool newAttach = false;
							if (!ScenePlayer.ScenePlaying && normal.Y < -0.5)
								if (Inside(refPosTop, v1 - 10f * n1, v2 - 10f * n2, v3 - 10f * n3, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3))
								{
									if (normal.Y < -0.5)
										sujet.JumpCollisionCancel = true;
									Vector3 direction = refPosTop + normal * sujet.Epaisseur;
									if (intersect3D_RayTriangle(refPosTop, direction, v1, v2, v3, out inter) == 1)
									{
										//pos += ((inter + new Vector3(0, -height, 0))- pos)/10f;
										pos = (inter + new Vector3(0, -(sujet.MaxVertex.Y), 0));
										if (pos.Y < sujet.LowestFloor)
											pos.Y = sujet.LowestFloor;

										refPosTop = pos + new Vector3(0, sujet.MaxVertex.Y, 0);
									}
								}
							if (!ScenePlayer.ScenePlaying && Math.Abs(normal.Y) < 0.5f)
							{
								if (Inside(refPosBottom, v1 - 10f * n1, v2 - 10f * n2, v3 - 10f * n3, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3))
								{
									Vector3 direction = refPosBottom + normal * sujet.Epaisseur * 10f;
									if (jumping && normal.Y < -0.5)
										sujet.JumpCollisionCancel = true;
									if (intersect3D_RayTriangle(refPosBottom, direction, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3, out inter) == 1)
									{
										pos.X = inter.X;
										pos.Z = inter.Z;
										refPosBottom = pos + new Vector3(0, sujet.StairHeight, 0);
									}
								}

								if (Inside(refPosTop, v1 - 20f * n1, v2 - 20f * n2, v3 - 20f * n3, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3))
								{
									Vector3 direction = refPosTop + normal * sujet.Epaisseur * 10f;
									if (intersect3D_RayTriangle(refPosTop, direction, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3, out inter) == 1)
									{
										pos.X = inter.X;
										pos.Z = inter.Z;
										refPosTop = pos + new Vector3(0, sujet.MaxVertex.Y, 0);
									}
								}
							}
							else if (normal.Y > 0.5)
							{
								if (intersect3D_RayTriangle(pos + globalBone0 + new Vector3(0, 50000, 0), pos + globalBone0 + new Vector3(0, -50000, 0), v1, v2, v3, out inter) == 1)
								{
									if (Math.Abs(inter.Y-pos.Y)<sujet.StairHeight)
									{
										if (inter.Y < smallest)
										{
											smallest = inter.Y;
										}
										if (inter.Y <= sujet.Location.Y + sujet.StairHeight * 1.5f && inter.Y > tallest)
										{
											shadowAngle = new Vector3(
											0,
											(float)Math.Atan2(normal.Z, normal.Y),
											(float)Math.Atan2(-normal.X, normal.Y));
											tallest = inter.Y;
										}
									}
								}
							}
							if (tallest > Single.MinValue / 2f)
							{
								if (tallest < sujet.Location.Y + sujet.StairHeight * 1.5f)
								{
									sujet.LowestFloor = tallest;
									newAttach = true;
								}
							}
							else if (smallest < Single.MaxValue / 2f)
							{
								if (smallest < sujet.Location.Y + sujet.StairHeight * 1.5f)
								{
									sujet.LowestFloor = smallest;
									newAttach = true;
								}
							}
							if (newAttach && Math.Abs(pos.Y-sujet.LowestFloor)<1)
							{
											if (collision!=null)
												collision.AttachTo(mdl, sujet);
							}
                        
							/*if (!ScenePlayer.ScenePlaying && Math.Abs(normal.Y) < 0.5f)
							{
								if (Inside(refPosBottom, v1 - 20f * n1, v2 - 20f * n2, v3 - 20f * n3, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3))
								{
									Vector3 direction = refPosBottom + normal * sujet.Epaisseur * 10f;

									if (intersect3D_RayTriangle(refPosBottom, direction, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3, out inter) == 1)
									{
										pushed = true;
										pos.X = inter.X;
										pos.Z = inter.Z;
										refPosBottom = pos + new Vector3(0, sujet.StairHeight, 0);
									}
								}

								if (Inside(refPosTop, v1 - 20f * n1, v2 - 20f * n2, v3 - 20f * n3, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3))
								{
									Vector3 direction = refPosTop + normal * sujet.Epaisseur * 10f;
									if (intersect3D_RayTriangle(refPosTop, direction, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3, out inter) == 1)
									{
										pushed = true;
										pos.X = inter.X;
										pos.Z = inter.Z;
										refPosTop = pos + new Vector3(0, sujet.MaxVertex.Y, 0);
									}
								}
							}*/
						}
                    

					}

				}
            }
            sujet.ShadowMatrixSurface = Matrix.CreateFromYawPitchRoll(shadowAngle.X, shadowAngle.Y, shadowAngle.Z);
			bool cliff = sujet.cState == Model.ControlState.Cliff || sujet.cState == Model.ControlState.UnCliff;

			if (collision == null)
				return;
			collision.UpdateIndex(sujet.Location);

			int start = collision.StartEnds[collision.CurrIndex][0];
			int end = collision.StartEnds[collision.CurrIndex][1];
			for (int i = start; i < end; i++)
            {
                Vector3 v1 = collision.cols[collision.indices[i][0][0]];
                Vector3 v2 = collision.cols[collision.indices[i][1][0]];
                Vector3 v3 = collision.cols[collision.indices[i][2][0]];

                Vector3 n1 = collision.norms[collision.indices[i][0][1]];
                Vector3 n2 = collision.norms[collision.indices[i][1][1]];
                Vector3 n3 = collision.norms[collision.indices[i][2][1]];
                Vector3 normal = (n1 + n2 + n3) / 3f;


                if (!cliff && !ScenePlayer.ScenePlaying && normal.Y < -0.5)
                if (Inside(refPosTop, v1 - 20f * n1, v2 - 20f * n2, v3 - 20f * n3, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3))
                {
                    Vector3 direction = refPosTop + normal * sujet.Epaisseur;
                    if (intersect3D_RayTriangle(refPosTop, direction, v1, v2, v3, out inter) == 1)
                    {
                        //pos += ((inter + new Vector3(0, -height, 0))- pos)/10f;
                        pos = (inter + new Vector3(0, -(sujet.MaxVertex.Y), 0));
                        if (pos.Y < sujet.LowestFloor)
                            pos.Y = sujet.LowestFloor;

                        refPosTop = pos + new Vector3(0, sujet.MaxVertex.Y, 0);
                    }
                }
                if (!cliff && !ScenePlayer.ScenePlaying && Math.Abs(normal.Y) < 0.5f)
                {
                    if (Inside(refPosBottom, v1-20f*n1, v2 - 20f * n2, v3 - 20f * n3, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3))
                    {
                        Vector3 direction = refPosBottom + normal * sujet.Epaisseur * 10f;
                        if (jumping && normal.Y < -0.5)
                            sujet.JumpCollisionCancel = true;
                        if (intersect3D_RayTriangle(refPosBottom, direction, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3, out inter) == 1)
                        {
                            pos = (inter + new Vector3(0, -sujet.StairHeight, 0));
                            refPosBottom = pos + new Vector3(0, sujet.StairHeight, 0);
                        }
                    }

                    if (Inside(refPosTop, v1 - 20f * n1, v2 - 20f * n2, v3 - 20f * n3, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3))
                    {
                        Vector3 direction = refPosTop + normal * sujet.Epaisseur * 10f;
                        if (intersect3D_RayTriangle(refPosTop, direction, v1 + sujet.Epaisseur * n1, v2 + sujet.Epaisseur * n2, v3 + sujet.Epaisseur * n3, out inter) == 1)
                        {
                            pos = (inter + new Vector3(0, -(sujet.MaxVertex.Y), 0));
                            if (pos.Y < sujet.LowestFloor)
                                pos.Y = sujet.LowestFloor;

                            refPosTop = pos + new Vector3(0, sujet.MaxVertex.Y, 0);
                        }
                    }
                }
                else if (normal.Y>0.5)
				{
					if (!cliff && !ScenePlayer.ScenePlaying && sujet.cState == Model.ControlState.Fall && !sujet.CliffCancel && (sujet.Links.Count == 0 || sujet.Links[0].ResourceIndex != 39))
                    {
                        if (intersect3D_RayTriangle(refPosTop + forwardCliffStart, refPosTop + forwardCliffEnd, v1, v2, v3, out inter) == 1 && inter.Y > refPosTop.Y + forwardCliffEnd.Y)
                        {
                            Vector3 coin = inter;


							int ordre = 0;  /* V1V2  V2V3  V3V1*/
							float nearest = Single.MaxValue;

							Vector3 va_vb = v1 * 1f;
							Vector3 step_va_vb = (v2 - v1) / Vector3.Distance(v2, v1);
							
							while (Vector3.Distance(va_vb, v2) > sujet.Epaisseur * 2f)
							{
								va_vb += step_va_vb;
								float dist2d = MainGame.Vector3Distance2D(va_vb, refPosTop);
								if (dist2d < nearest)
								{
									coin = va_vb * 1f;
									nearest = dist2d;
									ordre = 0;
								}
							}

							va_vb = v2 * 1f;
							step_va_vb = (v3 - v2) / Vector3.Distance(v3, v2);

							while (Vector3.Distance(va_vb, v3) > sujet.Epaisseur * 2f)
							{
								va_vb += step_va_vb;
								float dist2d = MainGame.Vector3Distance2D(va_vb, refPosTop);
								if (dist2d < nearest)
								{
									coin = va_vb * 1f;
									nearest = dist2d;
									ordre = 1;
								}
							}

							va_vb = v3 * 1f;
							step_va_vb = (v1 - v3) / Vector3.Distance(v1, v3);

							while (Vector3.Distance(va_vb, v1) > sujet.Epaisseur * 2f)
							{
								va_vb += step_va_vb;
								float dist2d = MainGame.Vector3Distance2D(va_vb, refPosTop);
								if (dist2d < nearest)
								{
									coin = va_vb *1f;
									nearest = dist2d;
									ordre = 2;
								}
							}


							float angle = 0;

                            if (ordre == 0)
                            {
                                Vector3 v1v2Base = v2 - v1;
                                v1v2Base /= Vector3.Distance(Vector3.Zero, v1v2Base);
                                angle = (float)Math.Atan2(v1v2Base.X, v1v2Base.Z);
                            }
                            if (ordre == 1)
                            {
                                Vector3 v2v3Base = v3 - v2;
                                v2v3Base /= Vector3.Distance(Vector3.Zero, v2v3Base);
                                angle = (float)Math.Atan2(v2v3Base.X, v2v3Base.Z);
                            }
                            if (ordre == 2)
                            {
                                Vector3 v3v1Base = v1 - v3;
                                v3v1Base /= Vector3.Distance(Vector3.Zero, v3v1Base);
                                angle = (float)Math.Atan2(v3v1Base.X, v3v1Base.Z);
							}


							if (coin.Y > sujet.LowestFloor + sujet.MaxVertex.Y)
                            {
								float newDest = angle + MainGame.PI / 2f;
								SrkBinary.MakePrincipal(ref newDest);

								sujet.DestRotate = newDest;
                                sujet.Rotate = sujet.DestRotate;
                                sujet.cState = Model.ControlState.Cliff;

								//Program.game.cursors[0].Position = coin;
								/*try
                                {
                                    string[] input = File.ReadAllLines("data.txt");
                                    cliffBackwards.X = MainGame.SingleParse(input[0]);
                                    cliffBackwards.Y = MainGame.SingleParse(input[1]);
                                    cliffBackwards.Z = MainGame.SingleParse(input[2]);
                                    cliffBackwards = Vector3.Transform(cliffBackwards, rotYMat);

                                }
                                catch
                                {

                                }*/
								

								/*string[] text = File.ReadAllLines(@"D:\Desktop\KHDebug\KHDebug\bin\DesktopGL\AnyCPU\Debug\Content\Models\P_EX100\Joints.txt");
								text = text[9].Split(':')[1].Split(',');
								sujet.CliffPosition.X = MainGame.SingleParse(text[0]);
								sujet.CliffPosition.Y = MainGame.SingleParse(text[1]);
								sujet.CliffPosition.Z = MainGame.SingleParse(text[2]);*/

								cliffBackwards = Vector3.Transform(sujet.CliffPosition, sujet.Rotate_matrix);
                                pos = coin - cliffBackwards;

								sujet.locBlock = 10;
								sujet.loc = pos;
								sujet.locAction = sujet.loc;

								return;
                            }

                            
                        }

                    }

                    if (intersect3D_RayTriangle(pos + globalBone0+new Vector3(0, 50000, 0), pos + globalBone0 + new Vector3(0, -50000, 0), v1, v2, v3, out inter) ==1)
                    {
						if (Single.IsNaN(sujet.LastLand.X))
						{
							if (inter.Y < smallest)
							{
								smallest = inter.Y;
							}
							if (inter.Y <= sujet.Location.Y + sujet.StairHeight * 1.5f && inter.Y > tallest)
							{
								shadowAngle = new Vector3(
								0,
								(float)Math.Atan2(normal.Z, normal.Y),
								(float)Math.Atan2(-normal.X, normal.Y));
								tallest = inter.Y;
							}
						}
                    }
                }
                if (tallest > Single.MinValue / 2f)
                {
                    if (tallest <sujet.Location.Y + sujet.StairHeight * 1.5f)
                    sujet.LowestFloor = tallest;
                }
                else if (smallest < Single.MaxValue / 2f)
                {
                    if (smallest < sujet.Location.Y + sujet.StairHeight * 1.5f)
                        sujet.LowestFloor = smallest;
                }
            }
            sujet.ShadowMatrixSurface = Matrix.CreateFromYawPitchRoll(shadowAngle.X, shadowAngle.Y, shadowAngle.Z);
            if (pushed && pos.Y<sujet.LowestFloor)
            {
                pos.Y = sujet.LowestFloor;
            }
        }