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); } } }
public void RenderSkeletalModel(LitShaderDescription shader, SSBoneFrame bframe, Matrix4 mvMatrix, Matrix4 mvpMatrix) { foreach (var btag in bframe.BoneTags) { var mvTransform = mvMatrix.MultiplyByTransform(btag.FullTransform); GL.UniformMatrix4(shader.ModelView, false, ref mvTransform); var mvpTransform = mvpMatrix.MultiplyByTransform(btag.FullTransform); GL.UniformMatrix4(shader.ModelViewProjection, false, ref mvpTransform); RenderMesh(btag.MeshBase); if (btag.MeshSlot != null) { RenderMesh(btag.MeshSlot); } } }
public bool CreateItem(uint itemID, uint modelID, uint worldModelID, MenuItemType type, ushort count, string name) { var model = GetModelByID(modelID); if (model == null) { return false; } var bf = new SSBoneFrame(); bf.FromModel(model); var item = new BaseItem { ID = itemID, WorldModelId = worldModelID, Type = type, Count = count, Name = (char) 0 + name, // TODO: Is it useful? BoneFrame = bf }; ItemsTree[item.ID] = item; return true; }
/// <summary> /// Next frame and next anim calculation function. /// </summary> public static void GetNextFrame(SSBoneFrame bf, float time, StateChange stc, out short frame, out TR_ANIMATION anim, AnimControlFlags animFlags) { var currAnim = bf.Animations.Model.Animations[(int) bf.Animations.CurrentAnimation]; frame = (short)((bf.Animations.FrameTime + time) / bf.Animations.Period); frame = Math.Max(frame, (short)0); // paranoid checking anim = bf.Animations.CurrentAnimation; // Flag has a highest priority if(animFlags == AnimControlFlags.LoopLastFrame) { if(frame >= currAnim.Frames.Count - 1) { frame = (short) (currAnim.Frames.Count - 1); anim = bf.Animations.CurrentAnimation; // paranoid duplicate } return; } else if(animFlags == AnimControlFlags.Lock) { frame = 0; anim = bf.Animations.CurrentAnimation; return; } // Check next anim if frame >= frames.Count if(frame >= currAnim.Frames.Count) { if(currAnim.NextAnim != null) { frame = (short)currAnim.NextFrame; anim = currAnim.NextAnim.ID; return; } frame = (short)(frame % currAnim.Frames.Count); anim = bf.Animations.CurrentAnimation; // paranoid duplicate return; } // State change check if(stc != null) { foreach (var disp in stc.AnimDispatch) { if(disp.FrameHigh >= disp.FrameLow && frame.IsBetween(disp.FrameLow, disp.FrameHigh)) { anim = disp.NextAnim; frame = (short) disp.NextFrame; return; } } } }
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; }
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; } }