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); } }
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; } }