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); }
private static void UnloadModel(DataStructures.Models.Model model) { model.Dispose(); foreach (var kv in Models.Where(x => x.Value == model)) { Models.Remove(kv.Key); } }
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); } }
public ModelReference(string path, DataStructures.Models.Model model) { Path = path; Model = model; }
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); }
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; }