Exemple #1
0
        protected static DataStructures.Models.Mesh AddMesh(DataStructures.Models.Model sledgeModel, Assimp.Mesh assimpMesh, Matrix4x4 selfMatrix)
        {
            var sledgeMesh             = new DataStructures.Models.Mesh(0);
            List <MeshVertex> vertices = new List <MeshVertex>();

            for (int i = 0; i < assimpMesh.VertexCount; i++)
            {
                var assimpVertex = assimpMesh.Vertices[i];
                assimpVertex = selfMatrix * assimpVertex;
                var assimpNormal = assimpMesh.Normals[i];
                assimpNormal = selfMatrix * assimpNormal;
                var assimpUv = assimpMesh.TextureCoordinateChannels[0][i];

                vertices.Add(new MeshVertex(new CoordinateF(assimpVertex.X, -assimpVertex.Z, assimpVertex.Y),
                                            new CoordinateF(assimpNormal.X, -assimpNormal.Z, assimpNormal.Y),
                                            sledgeModel.Bones[0], assimpUv.X, -assimpUv.Y));
            }

            foreach (var face in assimpMesh.Faces)
            {
                var triInds = face.Indices;
                for (var i = 1; i < triInds.Count - 1; i++)
                {
                    sledgeMesh.Vertices.Add(new MeshVertex(vertices[triInds[0]].Location, vertices[triInds[0]].Normal, vertices[triInds[0]].BoneWeightings, vertices[triInds[0]].TextureU, vertices[triInds[0]].TextureV));
                    sledgeMesh.Vertices.Add(new MeshVertex(vertices[triInds[i + 1]].Location, vertices[triInds[i + 1]].Normal, vertices[triInds[i + 1]].BoneWeightings, vertices[triInds[i + 1]].TextureU, vertices[triInds[i + 1]].TextureV));
                    sledgeMesh.Vertices.Add(new MeshVertex(vertices[triInds[i]].Location, vertices[triInds[i]].Normal, vertices[triInds[i]].BoneWeightings, vertices[triInds[i]].TextureU, vertices[triInds[i]].TextureV));
                }
            }

            return(sledgeMesh);
        }
Exemple #2
0
 private static void UnloadModel(DataStructures.Models.Model model)
 {
     model.Dispose();
     foreach (var kv in Models.Where(x => x.Value == model))
     {
         Models.Remove(kv.Key);
     }
 }
Exemple #3
0
        protected static void AddNode(Scene scene, Node node, DataStructures.Models.Model model, DataStructures.Models.Texture tex, Matrix4x4 parentMatrix)
        {
            Matrix4x4 selfMatrix = node.Transform * parentMatrix;

            foreach (var meshIndex in node.MeshIndices)
            {
                DataStructures.Models.Mesh sledgeMesh = AddMesh(model, scene.Meshes[meshIndex], selfMatrix);
                foreach (var v in sledgeMesh.Vertices)
                {
                    v.TextureU *= tex.Width;
                    v.TextureV *= tex.Height;
                }
                model.AddMesh("mesh", 0, sledgeMesh);
            }

            foreach (var subNode in node.Children)
            {
                AddNode(scene, subNode, model, tex, selfMatrix);
            }
        }
Exemple #4
0
 public ModelReference(string path, DataStructures.Models.Model model)
 {
     Path  = path;
     Model = model;
 }
Exemple #5
0
        protected override DataStructures.Models.Model LoadFromFile(IFile file)
        {
            if (importer == null)
            {
                importer = new AssimpContext();
                //importer.SetConfig(new NormalSmoothingAngleConfig(66.0f));
            }

            DataStructures.Models.Model model = new DataStructures.Models.Model();
            DataStructures.Models.Bone  bone  = new DataStructures.Models.Bone(0, -1, null, "rootBone", CoordinateF.Zero, CoordinateF.Zero, CoordinateF.One, CoordinateF.One);
            model.Bones.Add(bone);

            Scene scene = importer.ImportFile(file.FullPathName);

            DataStructures.Models.Texture tex = null;

            if (scene.MaterialCount > 0)
            {
                //TODO: handle several textures
                for (int i = 0; i < scene.MaterialCount; i++)
                {
                    if (string.IsNullOrEmpty(scene.Materials[i].TextureDiffuse.FilePath))
                    {
                        continue;
                    }
                    string path = Path.Combine(Path.GetDirectoryName(file.FullPathName), scene.Materials[i].TextureDiffuse.FilePath);
                    if (!File.Exists(path))
                    {
                        path = scene.Materials[i].TextureDiffuse.FilePath;
                    }
                    if (File.Exists(path))
                    {
                        Bitmap bmp = new Bitmap(path);
                        tex = new DataStructures.Models.Texture {
                            Name   = path,
                            Index  = 0,
                            Width  = bmp.Width,
                            Height = bmp.Height,
                            Flags  = 0,
                            Image  = bmp
                        };
                    }
                    break;
                }
            }

            if (tex == null)
            {
                Bitmap bmp = new Bitmap(64, 64);
                for (int i = 0; i < 64; i++)
                {
                    for (int j = 0; j < 64; j++)
                    {
                        bmp.SetPixel(i, j, Color.DarkGray);
                    }
                }
                tex = new DataStructures.Models.Texture {
                    Name   = "blank",
                    Index  = 0,
                    Width  = 64,
                    Height = 64,
                    Flags  = 0,
                    Image  = bmp
                };
            }

            model.Textures.Add(tex);

            AddNode(scene, scene.RootNode, model, tex, Matrix4x4.Identity);

            return(model);
        }
Exemple #6
0
        private static DataStructures.Models.Model ReadModel(BinaryReader br, IFile file, ModelLoadItems loadItems)
        {
            // int id - Not really an int. This is a magic string, either "IDST" or "IDSQ".
            var magicString = br.ReadFixedLengthString(Encoding.UTF8, 4);
            if (magicString != MagicStringIDST && magicString != MagicStringIDSQ)
            {
                throw new ProviderException("Bad magic number for model. Expected [IDST,IDSQ], got: " + magicString);
            }

            // int version - Half-life 1 models are version 10.
            var version = br.ReadInt32();
            if (version != MDLVersionGoldsource
                && version != MDLVersionSource2006
                && version != MDLVersionSourceEpisode2
                && version != MDLVersionSourcePortal
                && version != MDLVersionSource2007
                && version != MDLVersionSource2012)
            {
                throw new ProviderException("Bad version number for model. Expected [10,44,45,46,48,49], got: " + version);
            }

            var modelData = new ModelData {Version = version};

            if (version >= MDLVersionSource2006)
            {
                if (loadItems.HasFlag(ModelLoadItems.Meshes))
                {
                    // Source vertex and mesh info is stored in flat file structures, preload these separately.
                    LoadSourceMeshData(modelData, file);
                }
            }

            long checksum = 0;
            if (version >= MDLVersionSource2006)
            {
                checksum = br.ReadInt32(); // This is a long in the headers but is only written to the file in 4 bytes. Why? I don't know.
            }

            // char name[64] - The name of the model (file path)
            var path = br.ReadFixedLengthString(Encoding.UTF8, 64);

            // int length - The size of the model file in bytes
            var fileSize = br.ReadInt32();

            var eyePosition = br.ReadCoordinateF();

            var illumPosition = CoordinateF.Zero;
            if (version >= MDLVersionSource2006)
            {
                illumPosition = br.ReadCoordinateF();
            }

            var hullMin = br.ReadCoordinateF();
            var hullMax = br.ReadCoordinateF();

            var bbMin = br.ReadCoordinateF();
            var bbMax = br.ReadCoordinateF();

            // int flags - Unknown.
            var flags = br.ReadInt32();

            var numBones = br.ReadInt32();
            var boneIndex = br.ReadInt32();

            var numBoneControllers = br.ReadInt32();
            var boneControllerIndex = br.ReadInt32();

            var numHitBoxes = br.ReadInt32();
            var hitboxIndex = br.ReadInt32();

            if (version >= MDLVersionSource2006)
            {
                var numAnim = br.ReadInt32();
                var animIndex = br.ReadInt32();
                if (loadItems.HasFlag(ModelLoadItems.Animations))
                {
                    // Source animation data is stored on their own instead of inside the sequence
                    LoadSourceAnimationData(br, modelData, numAnim, animIndex);
                }
            }

            var numSeq = br.ReadInt32();
            var seqIndex = br.ReadInt32();

            int numSeqGroups = 0, seqGroupIndex = 0, activitylistversion = 0, eventsindexed = 0;
            if (version >= MDLVersionSource2006)
            {
                activitylistversion = br.ReadInt32();
                eventsindexed = br.ReadInt32();
            }
            else if (version == MDLVersionGoldsource)
            {
                numSeqGroups = br.ReadInt32();
                seqGroupIndex = br.ReadInt32();
            }

            var numTextures = br.ReadInt32();
            var textureIndex = br.ReadInt32();
            var textureDataIndex = 0;

            if (version == MDLVersionGoldsource)
            {
                textureDataIndex = br.ReadInt32();
            }

            if (version >= MDLVersionSource2006)
            {
                var numcdtextures = br.ReadInt32();
                var cdtextureindex = br.ReadInt32();
            }

            var numSkinRef = br.ReadInt32();
            var numSkinFamilies = br.ReadInt32();
            var skinIndex = br.ReadInt32();

            var numBodyParts = br.ReadInt32();
            var bodyPartIndex = br.ReadInt32();

            var numAttachments = br.ReadInt32();
            var attachmentIndex = br.ReadInt32();

            if (version >= MDLVersionSource2006)
            {
                var numlocalnodes = br.ReadInt32();
                var localnodeindex = br.ReadInt32();
                var localnodenameindex = br.ReadInt32();

                var numflexdesc = br.ReadInt32();
                var flexdescindex = br.ReadInt32();

                var numflexcontrollers = br.ReadInt32();
                var flexcontrollerindex = br.ReadInt32();

                var numflexrules = br.ReadInt32();
                var flexruleindex = br.ReadInt32();

                var numikchains = br.ReadInt32();
                var ikchainindex = br.ReadInt32();

                var nummouths = br.ReadInt32();
                var mouthindex = br.ReadInt32();

                var numlocalposeparameters = br.ReadInt32();
                var localposeparamindex = br.ReadInt32();

                var surfacepropindex = br.ReadInt32();

                var keyvalueindex = br.ReadInt32();
                var keyvaluesize = br.ReadInt32();

                var numlocalikautoplaylocks = br.ReadInt32();
                var localikautoplaylockindex = br.ReadInt32();

                var mass = br.ReadSingle();
                var contents = br.ReadInt32();

                var numincludemodels = br.ReadInt32();
                var includemodelindex = br.ReadInt32();

                var virtualModelPointer = br.ReadInt32();

                var szanimblocknameindex = br.ReadInt32();
                var numanimblocks = br.ReadInt32();
                var animblockindex = br.ReadInt32();
                var animblockModelPointer = br.ReadInt32();

                var bonetablebynameindex = br.ReadInt32();

                var pVertexBasePointer = br.ReadInt32();
                var pIndexBasePointer = br.ReadInt32();

                var constdirectionallightdot = br.ReadByte();
                var rootLod = br.ReadByte();
                var numAllowedRootLods = br.ReadByte(); // Unused in Source2006
                br.ReadByte(); // Unused

                var zeroframecacheindex = br.ReadInt32(); // Unused in Source2007

                if (version == MDLVersionSource2006)
                {
                    br.ReadBytes(6); // Unused
                }
                else if (version == MDLVersionSource2007)
                {
                    var numflexcontrollerui = br.ReadInt32();
                    var flexcontrolleruiindex = br.ReadInt32();

                    br.ReadIntArray(2); // Unused

                    var studiohdr2Index = br.ReadInt32();
                    br.ReadInt32(); // Unused
                }
            }
            else if (version == MDLVersionGoldsource)
            {
                var soundTable = br.ReadInt32();
                var soundIndex = br.ReadInt32();
                var soundGroups = br.ReadInt32();
                var soundGroupIndex = br.ReadInt32();

                var numTransitions = br.ReadInt32();
                var transitionIndex = br.ReadInt32();
            }

            var model = new DataStructures.Models.Model();
            model.Name = file.NameWithoutExtension;
            model.BonesTransformMesh = modelData.Version == MDLVersionGoldsource;

            if (loadItems.HasFlag(ModelLoadItems.Bones))
            {
                // Bones
                br.BaseStream.Position = boneIndex;
                for (var i = 0; i < numBones; i++) ReadBone(br, i, modelData, model);
            }

            // Controllers
            // TODO

            // Attachments
            // TODO

            // Hitboxes
            // TODO

            if (loadItems.HasFlag(ModelLoadItems.Animations))
            {
                if (version >= MDLVersionSource2006)
                {
                    throw new ProviderException("Source animations are currently not supported.");
                }

                // Sequence Groups
                var groups = new List<SequenceGroup>();
                br.BaseStream.Position = seqGroupIndex;
                for (var i = 0; i < numSeqGroups; i++) groups.Add(ReadSequenceGroup(br, modelData));

                // Sequences
                br.BaseStream.Position = seqIndex;
                for (var i = 0; i < numSeq; i++) ReadSequence(br, i, modelData, model, groups);
            }

            // Transitions
            // TODO

            if (loadItems.HasFlag(ModelLoadItems.Meshes))
            {
                // Body parts
                br.BaseStream.Position = bodyPartIndex;
                for (var i = 0; i < numBodyParts; i++) ReadBodyPart(br, i, modelData, model);
            }

            // Texture Info
            if (loadItems.HasFlag(ModelLoadItems.TextureInfo) || loadItems.HasFlag(ModelLoadItems.TextureData))
            {
                ReadTextureInfo(file, br, modelData, model, numTextures, textureIndex);
            }

            // Textures

            return model;
        }