Ejemplo n.º 1
0
        public Capsule(Vector3 p0, Vector3 p1, Single radius)
        {
            ModelMeshPart mesh = new ModelMeshPart();

            int segments = 10; // Higher numbers improve quality
            radius = 3;    // The radius (width) of the cylinder
            int height = 10;   // The height of the cylinder

            var vertices = new List<Vector3>();
            for (double y = 0; y < 2; y++)
            {
                for (double x = 0; x < segments; x++)
                {
                    double theta = (x / (segments - 1)) * 2 * Math.PI;

                    vertices.Add(new Vector3()
                    {
                        X = (float)(radius * Math.Cos(theta)),
                        Y = (float)(height * y),
                        Z = (float)(radius * Math.Sin(theta)),
                    });
                }
            }

            var indices = new List<int>();
            for (int x = 0; x < segments - 1; x++)
            {
                indices.Add(x);
                indices.Add(x + segments);
                indices.Add(x + segments + 1);

                indices.Add(x + segments + 1);
                indices.Add(x + 1);
                indices.Add(x);
            }
        }
Ejemplo n.º 2
0
        public Sphere(Single radius, int stacks = 15, int slices = 15)
        {
            ModelMeshPart meshpart = new ModelMeshPart();

            // TODO: Correctly assign normals and UVs

            for (int t = 0; t < stacks; t++)
            {
                Single theta1 = ((Single)(t) / stacks) * (Single)Math.PI;
                Single theta2 = ((Single)(t + 1) / stacks) * (Single)Math.PI;

                for (int p = 0; p < slices; p++)
                {
                    Single phi1 = ((Single)(p) / slices) * 2 * (Single)Math.PI;
                    Single phi2 = ((Single)(p + 1) / slices) * 2 * (Single)Math.PI;

                    var n1 = new Vector3(
                                    (Single)(Math.Sin(theta1) * Math.Cos(phi1)),
                                    (Single)(Math.Cos(theta1)),
                                    (Single)(Math.Sin(theta1) * Math.Sin(phi1))
                             );

                    var n2 = new Vector3(
                                    (Single)(Math.Sin(theta1) * Math.Cos(phi2)),
                                    (Single)(Math.Cos(theta1)),
                                    (Single)(Math.Sin(theta1) * Math.Sin(phi2))
                             );

                    var n3 = new Vector3(
                                    (Single)(Math.Sin(theta2) * Math.Cos(phi2)),
                                    (Single)(Math.Cos(theta2)),
                                    (Single)(Math.Sin(theta2) * Math.Sin(phi2))
                             );

                    var n4 = new Vector3(
                                    (Single)(Math.Sin(theta2) * Math.Cos(phi1)),
                                    (Single)(Math.Cos(theta2)),
                                    (Single)(Math.Sin(theta2) * Math.Sin(phi1))
                             );

                    var p1 = n1 * radius;
                    var p2 = n2 * radius;
                    var p3 = n3 * radius;
                    var p4 = n4 * radius;

                    var uv1 = new Vector2(
                                    0.5f + (Single)Math.Atan2(-p1.Z, p1.X) / MathHelper.TwoPi,
                                    0.5f - (Single)Math.Asin(p1.Y) / MathHelper.Pi
                              );

                    var uv2 = new Vector2(
                                    0.5f + (Single)Math.Atan2(-p2.Z, p2.X) / MathHelper.TwoPi,
                                    0.5f - (Single)Math.Asin(p2.Y) / MathHelper.Pi
                              );

                    var uv3 = new Vector2(
                                    0.5f + (Single)Math.Atan2(-p3.Z, p3.X) / MathHelper.TwoPi,
                                    0.5f - (Single)Math.Asin(p3.Y) / MathHelper.Pi
                              );

                    var uv4 = new Vector2(
                                    0.5f + (Single)Math.Atan2(-p4.Z, p4.X) / MathHelper.TwoPi,
                                    0.5f - (Single)Math.Asin(p4.Y) / MathHelper.Pi
                              );

                    if (t == 0)
                    {
                        meshpart.AddFace(
                            new Vector3[] { p1, p3, p4 },
                            new Vector3[] { n1, n3, n4 },
                            new Vector2[] { uv1, uv3, uv4 }
                        );
                    }
                    else if (t + 1 == stacks)
                    {
                        meshpart.AddFace(
                            new Vector3[] { p3, p1, p2 },
                            new Vector3[] { n3, n1, n2 },
                            new Vector2[] { uv3, uv1, uv2 }
                        );
                    }
                    else
                    {
                        meshpart.AddFace(
                            new Vector3[] { p1, p2, p4 },
                            new Vector3[] { n1, n2, n4 },
                            new Vector2[] { uv1, uv2, uv4 }
                        );

                        meshpart.AddFace(
                            new Vector3[] { p2, p3, p4 },
                            new Vector3[] { n2, n3, n4 },
                            new Vector2[] { uv2, uv3, uv4 }
                        );
                    }
                }
            }

            //Material material = new Material { Name = "sky", Texture = new Texture() };
            //SceneManager.Current.Add(material);
            //meshpart.Material = material;

            this.AddModelMeshPart(meshpart);
        }
Ejemplo n.º 3
0
 public void AddModelMeshPart(ModelMeshPart meshpart, bool bFinalise = true)
 {
     if (bFinalise) { meshpart.Finalise(); }
     meshParts.Add(meshpart);
 }
Ejemplo n.º 4
0
        public static void PreProcess(Model model, PreProcessOptions options)
        {
            if (options.HasFlag(PreProcessOptions.SplitMeshPart))
            {
                // Specific to C:R, I'll abstract this out as and when necessary
                foreach (ModelMesh mesh in model.Meshes)
                {
                    int partCount = mesh.MeshParts.Count;

                    for (int i = partCount - 1; i >= 0; i--)
                    {
                        ModelMeshPart part = mesh.MeshParts[i];

                        if (part.VertexBuffer.Data.Count > 16383)
                        {
                            while (part.IndexBuffer.Data.Count > 0)
                            {
                                var buffer = part.IndexBuffer.Data;
                                HashSet<int> usedVerts = new HashSet<int>();
                                int total = buffer.Count;

                                for (int j = 0; j < buffer.Count; j += 3)
                                {
                                    usedVerts.Add(buffer[j + 0]);
                                    usedVerts.Add(buffer[j + 1]);
                                    usedVerts.Add(buffer[j + 2]);

                                    int chunkSize = Math.Min(buffer.Count, 16383);

                                    if (j + 3 == buffer.Count || usedVerts.Count >= chunkSize)
                                    {
                                        if (usedVerts.Count == chunkSize) { j += 3; }

                                        Dictionary<int, int> indexLUT = new Dictionary<int, int>();

                                        var newPart = new ModelMeshPart();
                                        newPart.Material = part.Material;

                                        for (int k = 0; k < j; k++)
                                        {
                                            if (!indexLUT.ContainsKey(buffer[k]))
                                            {
                                                indexLUT.Add(buffer[k], newPart.VertexBuffer.AddVertex(part.VertexBuffer.Data[buffer[k]]));
                                            }

                                            newPart.IndexBuffer.AddIndex(indexLUT[buffer[k]]);
                                        }

                                        buffer.RemoveRange(0, j);

                                        mesh.AddModelMeshPart(newPart);

                                        SceneManager.Current.UpdateProgress(string.Format("Allocated {0:n0} of {1:n0}", j * chunkSize, total));
                                        break;
                                    }
                                }
                            }

                            mesh.MeshParts.RemoveAt(i);
                        }
                    }
                }
            }

            if (options.HasFlag(PreProcessOptions.Dedupe))
            {
                foreach (ModelMesh mesh in model.Meshes)
                {
                    foreach (ModelMeshPart part in mesh.MeshParts)
                    {
                        part.Optimise();
                    }
                }
            }

            if (options.HasFlag(PreProcessOptions.ResolveNonManifold))
            {
                foreach (ModelMesh mesh in model.Meshes)
                {
                    foreach (ModelMeshPart part in mesh.MeshParts)
                    {
                        Dictionary<int, int> edgeCounts = new Dictionary<int, int>();
                        List<int> buffer = part.IndexBuffer.Data;
                        bool bFixedNonManifoldMesh = false;

                        for (int i = 0; i < buffer.Count; i += 3)
                        {
                            int[] edges = new int[3];

                            for (int j = 0; j < 3; j++)
                            {
                                int oppositeIndex = (j + 1 < 3 ? j + 1 : 0);

                                edges[j] = Math.Max(buffer[i + j], buffer[i + oppositeIndex]) << 24 + Math.Min(buffer[i + j], buffer[i + oppositeIndex]);

                                if (edgeCounts.ContainsKey(edges[j]))
                                {
                                    if (edgeCounts[edges[j]] == 2)
                                    {
                                        buffer[i + j] = part.VertexBuffer.AddVertex(part.VertexBuffer.Data[buffer[i + j]].Clone());
                                        buffer[i + oppositeIndex] = part.VertexBuffer.AddVertex(part.VertexBuffer.Data[buffer[i + oppositeIndex]].Clone());

                                        j--;

                                        bFixedNonManifoldMesh = true;
                                    }
                                    else
                                    {
                                        edgeCounts[edges[j]]++;
                                    }
                                }
                                else
                                {
                                    edgeCounts.Add(edges[j], 1);
                                }
                            }
                        }

                        if (bFixedNonManifoldMesh)
                        {
                            part.IndexBuffer.Initialise();
                            part.VertexBuffer.Initialise();
                        }
                    }
                }
            }
        }
Ejemplo n.º 5
0
        public static void Normalise(ModelMeshPart model)
        {
            List<Vector3> faceNormals = new List<Vector3>();

            for (int i = 0; i < model.IndexBuffer.Length; i += 3)
            {
                Vector3 v0 = model.VertexBuffer.Data[model.IndexBuffer.Data[i + 0]].Position;
                Vector3 v1 = model.VertexBuffer.Data[model.IndexBuffer.Data[i + 1]].Position;
                Vector3 v2 = model.VertexBuffer.Data[model.IndexBuffer.Data[i + 2]].Position;

                Vector3 u = v0 - v1;
                Vector3 v = v0 - v2;

                faceNormals.Add(Vector3.Cross(u, v).Normalized());
            }

            for (int i = 0; i < model.VertexBuffer.Data.Count; i++)
            {
                for (int j = 0; j < model.IndexBuffer.Length; j += 3)
                {
                    if (model.IndexBuffer.Data[j + 0] == i) { model.VertexBuffer.ModifyVertexNormal(i, model.VertexBuffer.Data[i].Normal + faceNormals[j / 3]); }
                    if (model.IndexBuffer.Data[j + 1] == i) { model.VertexBuffer.ModifyVertexNormal(i, model.VertexBuffer.Data[i].Normal + faceNormals[j / 3]); }
                    if (model.IndexBuffer.Data[j + 2] == i) { model.VertexBuffer.ModifyVertexNormal(i, model.VertexBuffer.Data[i].Normal + faceNormals[j / 3]); }
                }
            }

            for (int i = 0; i < model.VertexBuffer.Data.Count; i++)
            {
                model.VertexBuffer.ModifyVertexNormal(i, model.VertexBuffer.Data[i].Normal.Normalized());
            }
        }
Ejemplo n.º 6
0
        public void Draw()
        {
            if (Linked)
            {
                var parentTransform = ((ModelBone)link).CombinedTransform;

                if (linkType == LinkType.All)
                {
                    transform = parentTransform;
                }
                else
                {
                    transform = Matrix4.Identity;

                    var v = parentTransform.ExtractTranslation();
                    parentTransform.Normalize();
                    parentTransform.M41 = v.X;
                    parentTransform.M42 = v.Y;
                    parentTransform.M43 = v.Z;

                    if ((linkType & LinkType.Rotation) == LinkType.Rotation) { transform *= Matrix4.CreateFromQuaternion(parentTransform.ExtractRotation()); }
                    if ((linkType & LinkType.Scale)    == LinkType.Scale)    { transform *= Matrix4.CreateScale(parentTransform.ExtractScale()); }
                    if ((linkType & LinkType.Position) == LinkType.Position) { transform *= Matrix4.CreateTranslation(parentTransform.ExtractTranslation()); }
                }
            }

            var mS = SceneManager.Current.Transform;
            var mT = transform;

            switch (assetType)
            {
                case AssetType.Model:
                    var model = asset as Model;
                    if (model != null)
                    {
                        GL.PushMatrix();

                        GL.MultMatrix(ref mS);
                        GL.MultMatrix(ref mT);

                        model.Draw();

                        GL.PopMatrix();
                    }
                    break;

                case AssetType.Sprite:
                    if (asset == null)
                    {
                        var sprite = new ModelMeshPart();
                        sprite.AddVertex(new Vector3(-0.25f, -0.25f, 0.0f), Vector3.UnitY, new Vector2(0, 1));
                        sprite.AddVertex(new Vector3(-0.25f,  0.25f, 0.0f), Vector3.UnitY, new Vector2(0, 0));
                        sprite.AddVertex(new Vector3( 0.25f,  0.25f, 0.0f), Vector3.UnitY, new Vector2(1, 0));
                        sprite.AddVertex(new Vector3( 0.25f, -0.25f, 0.0f), Vector3.UnitY, new Vector2(1, 1));

                        sprite.AddVertex(new Vector3( 0.25f, -0.25f, 0.0f), Vector3.UnitY, new Vector2(0, 1));
                        sprite.AddVertex(new Vector3( 0.25f,  0.25f, 0.0f), Vector3.UnitY, new Vector2(0, 0));
                        sprite.AddVertex(new Vector3(-0.25f,  0.25f, 0.0f), Vector3.UnitY, new Vector2(1, 0));
                        sprite.AddVertex(new Vector3(-0.25f, -0.25f, 0.0f), Vector3.UnitY, new Vector2(1, 1));
                        sprite.IndexBuffer.Initialise();
                        sprite.VertexBuffer.Initialise();
                        sprite.Material = new Material { Name = "Entity.Asset", Texture = SceneManager.Current.Content.Load<Texture, PNGImporter>("entity_" + entityType.ToString().ToLower(), Path.GetDirectoryName(Application.ExecutablePath) + @"\data\icons\") };
                        sprite.PrimitiveType = PrimitiveType.Quads;
                        var spritemesh = new ModelMesh();
                        spritemesh.AddModelMeshPart(sprite);
                        var spritemodel = new Model();
                        spritemodel.AddMesh(spritemesh);
                        asset = spritemodel;
                    }

                    GL.PushMatrix();

                    var position = Matrix4.CreateTranslation(mT.ExtractTranslation());

                    GL.MultMatrix(ref mS);
                    GL.MultMatrix(ref position);

                    GL.Enable(EnableCap.Blend);
                    GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
                    ((Model)asset).Draw();
                    GL.Disable(EnableCap.Blend);

                    GL.PopMatrix();
                    break;
            }
        }