private ModelBone ProcessBone(PooledTexture2D texture, EntityModel source, EntityModelBone bone, List <VertexPositionColorTexture> vertices, Vector2 textureSize, Dictionary <string, ModelBone> modelBones) { ModelBone modelBone; List <short> indices = new List <short>(); //bone.Pivot *= new Vector3(-1f, 1f, 1f); if (bone.Cubes != null) { foreach (var cube in bone.Cubes) { if (cube == null) { Log.Warn("Cube was null!"); continue; } //if (cube.Uv.IsOutOfBound(textureSize)) { // continue; } var inflation = (float)(cube.Inflate ?? bone.Inflate); var mirror = cube.Mirror ?? bone.Mirror; Cube built = new Cube(source, cube, textureSize, mirror, inflation); vertices = ModifyCubeIndexes(vertices, cube, ref built.Front, bone, inflation); vertices = ModifyCubeIndexes(vertices, cube, ref built.Back, bone, inflation); vertices = ModifyCubeIndexes(vertices, cube, ref built.Top, bone, inflation); vertices = ModifyCubeIndexes(vertices, cube, ref built.Bottom, bone, inflation); vertices = ModifyCubeIndexes(vertices, cube, ref built.Left, bone, inflation); vertices = ModifyCubeIndexes(vertices, cube, ref built.Right, bone, inflation); indices.AddRange( built.Front.indexes.Concat(built.Back.indexes).Concat(built.Top.indexes) .Concat(built.Bottom.indexes).Concat(built.Left.indexes).Concat(built.Right.indexes) .ToArray()); } } var pivot = bone.Pivot ?? Vector3.Zero; var boneMatrix = Matrix.Identity; if (bone.BindPoseRotation.HasValue) { var rotation = bone.BindPoseRotation.Value; boneMatrix = Matrix.CreateTranslation(-pivot) * Matrix.CreateRotationX(MathUtils.ToRadians(-rotation.X)) * Matrix.CreateRotationY(MathUtils.ToRadians(rotation.Y)) * Matrix.CreateRotationZ(MathUtils.ToRadians(rotation.Z)) * Matrix.CreateTranslation(pivot); } modelBone = new ModelBone(texture, indices.ToArray(), bone, boneMatrix); if (bone.Rotation.HasValue) { var r = bone.Rotation.Value; modelBone.Rotation = new Vector3(r.X, r.Y, r.Z); } modelBone.Setup(Alex.Instance.GraphicsDevice); foreach (var childBone in source.Bones.Where( x => x.Parent != null && string.Equals(x.Parent, bone.Name, StringComparison.OrdinalIgnoreCase))) { if (childBone.Parent != null && childBone.Parent.Equals(childBone.Name)) { continue; } if (string.IsNullOrWhiteSpace(childBone.Name)) { childBone.Name = Guid.NewGuid().ToString(); } var child = ProcessBone(texture, source, childBone, vertices, textureSize, modelBones); child.Parent = modelBone; modelBone.AddChild(child); if (!modelBones.TryAdd(childBone.Name, child)) { Log.Warn($"Failed to add bone! {childBone.Name}"); break; } } return(modelBone); }
private void Cache(EntityModel model, Dictionary <string, ModelBone> modelBones) { List <EntityModelBone> headBones = new List <EntityModelBone>(); var headBone = model.Bones.FirstOrDefault(x => x.Name.Contains("head", StringComparison.InvariantCultureIgnoreCase)); if (headBone != null) { headBones.Add(headBone); foreach (var bone in model.Bones) { if (bone == headBone) { continue; } if (bone.Parent != null && bone.Parent.Equals(headBone.Name)) { headBones.Add(bone); } } foreach (var bone in model.Bones.Where(x => !headBones.Any(hb => hb.Name.Equals(x.Name, StringComparison.InvariantCultureIgnoreCase)))) { if (headBones.Any(x => x.Name.Equals(bone.Name, StringComparison.InvariantCultureIgnoreCase))) { headBones.Add(bone); } } } List <VertexPositionNormalTexture> vertices = new List <VertexPositionNormalTexture>(); var textureSize = new Vector2(model.Texturewidth, model.Textureheight); var newSize = new Vector2(Texture.Width, Texture.Height); if (textureSize.X == 0 && textureSize.Y == 0) { textureSize = newSize; } var uvScale = newSize / textureSize; foreach (var bone in model.Bones) { if (bone == null || bone.NeverRender) { continue; } // if (bone.NeverRender) continue; bool partOfHead = headBones.Contains(bone); //bone.Pivot = new Vector3(-bone.Pivot.X, bone.Pivot.Y, bone.Pivot.Z); List <ModelBoneCube> c = new List <ModelBoneCube>(); ModelBone modelBone; if (bone.Cubes != null) { foreach (var cube in bone.Cubes) { if (cube == null) { Log.Warn("Cube was null!"); continue; } var size = cube.Size; var origin = cube.Origin; var pivot = bone.Pivot; var rotation = bone.Rotation; //VertexPositionNormalTexture[] vertices; Cube built = new Cube(size * (float)cube.Inflate, textureSize); built.Mirrored = bone.Mirror; built.BuildCube(cube.Uv * uvScale); vertices = ModifyCubeIndexes(vertices, ref built.Front, origin); vertices = ModifyCubeIndexes(vertices, ref built.Back, origin); vertices = ModifyCubeIndexes(vertices, ref built.Top, origin); vertices = ModifyCubeIndexes(vertices, ref built.Bottom, origin); vertices = ModifyCubeIndexes(vertices, ref built.Left, origin); vertices = ModifyCubeIndexes(vertices, ref built.Right, origin); var part = new ModelBoneCube(built.Front.indexes .Concat(built.Back.indexes) .Concat(built.Top.indexes) .Concat(built.Bottom.indexes) .Concat(built.Left.indexes) .Concat(built.Right.indexes) .ToArray(), Texture, rotation, pivot, origin); part.Mirror = bone.Mirror; if (partOfHead) { part.ApplyHeadYaw = true; part.ApplyYaw = true; } else { part.ApplyPitch = false; part.ApplyYaw = true; part.ApplyHeadYaw = false; } c.Add(part); } } modelBone = new ModelBone(c.ToArray(), bone.Parent); modelBone.UpdateRotationMatrix = !bone.NeverRender; if (!modelBones.TryAdd(bone.Name, modelBone)) { Log.Debug($"Failed to add bone! {model.Name}:{bone.Name}"); } } VertexBuffer = GpuResourceManager.GetBuffer(this, Alex.Instance.GraphicsDevice, VertexPositionNormalTexture.VertexDeclaration, vertices.Count, BufferUsage.None); VertexBuffer.SetData(vertices.ToArray()); Valid = true; }
private ModelBone ProcessBone( EntityModel source, EntityModelBone bone, ref List <VertexPositionColorTexture> vertices, Vector2 textureSize, Dictionary <string, ModelBone> modelBones) { ModelBone modelBone; int startIndex = vertices.Count; int elementCount = 0; if (bone.Cubes != null) { foreach (var cube in bone.Cubes) { if (cube == null) { Log.Warn("Cube was null!"); continue; } var inflation = (float)(cube.Inflate ?? bone.Inflate); var mirror = cube.Mirror ?? bone.Mirror; var origin = cube.InflatedOrigin(inflation); MCMatrix matrix = MCMatrix.CreateTranslation(origin); if (cube.Rotation.HasValue) { var rotation = cube.Rotation.Value; Vector3 pivot = origin + (cube.InflatedSize(inflation) / 2f); if (cube.Pivot.HasValue) { pivot = cube.InflatedPivot(inflation); // cube.Pivot.Value; } matrix = MCMatrix.CreateTranslation(origin) * MCMatrix.CreateTranslation((-pivot)) * MCMatrix.CreateRotationDegrees(rotation) * MCMatrix.CreateTranslation(pivot); } Cube built = new Cube(cube, textureSize, mirror, inflation); ModifyCubeIndexes(ref vertices, built.Front, origin, matrix); ModifyCubeIndexes(ref vertices, built.Back, origin, matrix); ModifyCubeIndexes(ref vertices, built.Top, origin, matrix); ModifyCubeIndexes(ref vertices, built.Bottom, origin, matrix); ModifyCubeIndexes(ref vertices, built.Left, origin, matrix); ModifyCubeIndexes(ref vertices, built.Right, origin, matrix); } } elementCount = vertices.Count - startIndex; modelBone = new ModelBone(bone, startIndex, elementCount); if (bone.Rotation.HasValue) { var r = bone.Rotation.Value; modelBone.BindingRotation = new Vector3(r.X, r.Y, r.Z); } if (bone.BindPoseRotation.HasValue) { var r = bone.BindPoseRotation.Value; modelBone.BindingRotation += new Vector3(r.X, r.Y, r.Z); } foreach (var childBone in source.Bones.Where( x => x.Parent != null && string.Equals(x.Parent, bone.Name, StringComparison.OrdinalIgnoreCase))) { if (childBone.Parent != null && childBone.Parent.Equals(childBone.Name)) { continue; } if (string.IsNullOrWhiteSpace(childBone.Name)) { childBone.Name = Guid.NewGuid().ToString(); } var child = ProcessBone(source, childBone, ref vertices, textureSize, modelBones); //child.Parent = modelBone; modelBone.AddChild(child); if (!modelBones.TryAdd(childBone.Name, child)) { Log.Warn($"Failed to add bone! {childBone.Name}"); break; } } return(modelBone); }