예제 #1
0
        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);
        }
예제 #2
0
        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;
        }
예제 #3
0
        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);
        }