public override GameObject LoadObject(string path, Mission mission) { GameObject rootObject = LoadCachedObject(path); if (rootObject == null) { rootObject = new GameObject(path); } else { return(rootObject); } Stream fs; try { fs = GameAPI.instance.fileSystem.GetStreamFromPath(path); } catch { return(null); } using (var reader = new BinaryReader(fs)) { var sceneLoader = new MafiaFormats.Scene2BINLoader(); lastLoader = sceneLoader; sceneLoader.Load(reader); fs.Close(); // TODO: Check if refs are null, clear then ModelGenerator.cachedTextures.Clear(); var objects = new List <KeyValuePair <GameObject, MafiaFormats.Scene2BINLoader.Object> >(); var backdrop = new GameObject("Backdrop sector"); backdrop.transform.parent = rootObject.transform; StoreReference(mission, backdrop.name, backdrop); foreach (var obj in sceneLoader.objects) { GameObject newObject; if (obj.Value.modelName == null || (obj.Value.type != MafiaFormats.Scene2BINLoader.ObjectType.Model && obj.Value.specialType == 0)) { newObject = new GameObject(); } else { newObject = GameAPI.instance.modelGenerator.LoadObject(Path.Combine("models", obj.Value.modelName), null); } if (newObject == null) { continue; } newObject.name = obj.Value.name; StoreReference(mission, newObject.name, newObject); newObject.transform.localPosition = obj.Value.pos; newObject.transform.localRotation = obj.Value.rot; newObject.transform.localScale = obj.Value.scale; objects.Add(new KeyValuePair <GameObject, MafiaFormats.Scene2BINLoader.Object>(newObject, obj.Value)); } var primary = FetchReference(mission, "Primary sector"); var objDef = primary.AddComponent <ObjectDefinition>(); var dummySectorData = new MafiaFormats.Scene2BINLoader.Object(); dummySectorData.type = MafiaFormats.Scene2BINLoader.ObjectType.Sector; objDef.data = dummySectorData; primary.transform.parent = rootObject.transform; foreach (var obj in objects) { var newObject = obj.Key; if (obj.Value.isPatch) { var searchName = obj.Value.name.Replace(".", "/"); var redefObject = GameObject.Find(searchName); if (redefObject != null) { if (obj.Value.isParentPatched && obj.Value.parentName != null) { var parent = FindParent(mission, obj.Value.parentName); if (parent != null) { redefObject.transform.parent = parent.transform; } } if (obj.Value.isPositionPatched) { redefObject.transform.localPosition = obj.Value.pos; } /* if (obj.Value.isPosition2Patched) * redefObject.transform.position = obj.Value.pos2; */ if (obj.Value.isRotationPatched) { redefObject.transform.localRotation = obj.Value.rot; } if (obj.Value.isScalePatched) { redefObject.transform.localScale = obj.Value.scale; } redefObject.SetActive(!obj.Value.isHidden); GameObject.DestroyImmediate(newObject, true); continue; } } newObject.transform.parent = FindParent(mission, obj.Value.parentName, rootObject).transform; newObject.transform.localPosition = obj.Value.pos; newObject.transform.localRotation = obj.Value.rot; newObject.transform.localScale = obj.Value.scale; var specObject = newObject.AddComponent <ObjectDefinition>(); specObject.data = obj.Value; specObject.Init(); } } // NOTE(zaklaus): Hardcode 'Primary sector' scale to (1,1,1) var primarySector = GameObject.Find("Primary sector"); if (primarySector != null) { primarySector.transform.localScale = new Vector3(1, 1, 1); } StoreChachedObject(path, rootObject); return(rootObject); }
public GameObject LoadCollisions(Mission mission, string path) { GameObject rootObject = LoadCachedObject(path); if (rootObject == null) { rootObject = new GameObject(path); } else { return(rootObject); } Stream fs; try { fs = GameAPI.instance.fileSystem.GetStreamFromPath(path); } catch { return(null); } using (var reader = new BinaryReader(fs)) { var newKlzLoader = new MafiaFormats.KLZLoader(); newKlzLoader.load(reader); fs.Close(); //NOTE(DavoSK): All face colls are inside of mesh nodes not in tree.klz //tree.klz node game object contains only primitive colliders. //Check for face colisioned meshed and add mesh collider string lastFaceColledMesh = ""; foreach (var faceCol in newKlzLoader.faceCols) { var link = faceCol.indices[0].link; if (lastFaceColledMesh != newKlzLoader.linkTables[link].name) { lastFaceColledMesh = newKlzLoader.linkTables[link].name; ApplyMeshColliderToMeshNode(mission, lastFaceColledMesh); } } //Cylinder are mesh colided in unity for us :) foreach (var cylCol in newKlzLoader.cylinderCols) { var linkName = newKlzLoader.linkTables[(int)cylCol.link].name; ApplyMeshColliderToMeshNode(mission, linkName); } //Load spehere collisions foreach (var sphereCol in newKlzLoader.sphereCols) { var linkName = newKlzLoader.linkTables[(int)sphereCol.link].name; var objectToBeColisioned = new GameObject(linkName); if (objectToBeColisioned) { objectToBeColisioned.transform.parent = rootObject.transform; objectToBeColisioned.transform.position = sphereCol.position; var sphereCollider = objectToBeColisioned.AddComponent <SphereCollider>(); sphereCollider.radius = sphereCol.radius; } } //Load ABB Colls Needs more math foreach (var ABBCol in newKlzLoader.AABBCols) { var linkName = newKlzLoader.linkTables[(int)ABBCol.link].name; var objectToBeColisioned = new GameObject(linkName); if (objectToBeColisioned) { objectToBeColisioned.transform.parent = rootObject.transform; Vector3 p1 = ABBCol.min; Vector3 p2 = ABBCol.max; Vector3 center = (p1 + p2) / 2.0f; Vector3 bboxCorner = p2 - center; objectToBeColisioned.transform.position = center; var boxCollider = objectToBeColisioned.AddComponent <BoxCollider>(); boxCollider.size = bboxCorner * 2; } } //Load XTOBB Cols foreach (var XTOBBCol in newKlzLoader.XTOBBCols) { var linkName = newKlzLoader.linkTables[(int)XTOBBCol.link].name; var objectToBeColisioned = new GameObject(linkName); if (objectToBeColisioned) { objectToBeColisioned.transform.parent = rootObject.transform; objectToBeColisioned.transform.localScale = MatrixExtension.ExtractScale(XTOBBCol.transform); objectToBeColisioned.transform.localRotation = MatrixExtension.ExtractRotation(XTOBBCol.transform); objectToBeColisioned.transform.position = MatrixExtension.ExtractPosition(XTOBBCol.transform); var boxCollider = objectToBeColisioned.AddComponent <BoxCollider>(); Vector3 p1 = XTOBBCol.extends[0]; Vector3 p2 = XTOBBCol.extends[1]; Vector3 center = (p1 + p2) / 2.0f; Vector3 bboxCorner = p2 + center; boxCollider.size = bboxCorner * 2; boxCollider.center = center; } } //Load OBB Cols foreach (var OBBCol in newKlzLoader.OBBCols) { var linkName = newKlzLoader.linkTables[(int)OBBCol.link].name; var objectToBeColisioned = new GameObject(linkName); if (objectToBeColisioned) { objectToBeColisioned.transform.parent = rootObject.transform; objectToBeColisioned.transform.localScale = MatrixExtension.ExtractScale(OBBCol.transform); objectToBeColisioned.transform.localRotation = MatrixExtension.ExtractRotation(OBBCol.transform); objectToBeColisioned.transform.position = MatrixExtension.ExtractPosition(OBBCol.transform); var boxCollider = objectToBeColisioned.AddComponent <BoxCollider>(); Vector3 p1 = OBBCol.extends[0]; Vector3 p2 = OBBCol.extends[1]; Vector3 center = (p1 + p2) / 2.0f; Vector3 bboxCorner = p2 + center; boxCollider.size = bboxCorner * 2; boxCollider.center = center; } } StoreChachedObject(path, rootObject); return(rootObject); } }
public override GameObject LoadObject(string path, Mission mission) { GameObject rootObject = LoadCachedObject(path); if (rootObject == null) { rootObject = new GameObject(path); } else { return(rootObject); } Stream fs; try { fs = GameAPI.instance.fileSystem.GetStreamFromPath(path); } catch (Exception ex) { GameObject.DestroyImmediate(rootObject); Debug.LogWarning(ex.ToString()); return(null); } using (BinaryReader reader = new BinaryReader(fs)) { var modelLoader = new MafiaFormats.Reader4DS(); var model = modelLoader.loadModel(reader); fs.Close(); if (model == null) { return(null); } var meshId = 0; var children = new List <KeyValuePair <int, Transform> >(); foreach (var mafiaMesh in model.meshes) { var child = new GameObject(mafiaMesh.meshName, typeof(MeshFilter)); var meshFilter = child.GetComponent <MeshFilter>(); StoreReference(mission, child.name, child); children.Add(new KeyValuePair <int, Transform>(mafiaMesh.parentID, child.transform)); if (mafiaMesh.meshType == MafiaFormats.MeshType.Joint) { var bone = child.AddComponent <Bone>(); bone.data = mafiaMesh.joint; continue; } else if (mafiaMesh.meshType == MafiaFormats.MeshType.Collision) { Material[] temp; child.AddComponent <MeshCollider>().sharedMesh = GenerateMesh(mafiaMesh, child, mafiaMesh.standard.lods[0], model, out temp); continue; } else if (mafiaMesh.meshType == MafiaFormats.MeshType.Sector) { // NOTE: Set up dummy data for this sector. MafiaFormats.Scene2BINLoader.Object dummySectorData = new MafiaFormats.Scene2BINLoader.Object(); dummySectorData.type = MafiaFormats.Scene2BINLoader.ObjectType.Sector; var objDef = child.AddComponent <ObjectDefinition>(); objDef.data = dummySectorData; objDef.sectorBounds.SetMinMax(mafiaMesh.sector.minBox, mafiaMesh.sector.maxBox); objDef.Init(); continue; } else if (mafiaMesh.meshType != MafiaFormats.MeshType.Standard) { continue; } if (mafiaMesh.standard.instanced != 0) { continue; } var def = child.AddComponent <ModelDefinition>(); def.model = model; def.mesh = mafiaMesh; Material[] materials; switch (mafiaMesh.visualMeshType) { case MafiaFormats.VisualMeshType.Standard: { // TODO build up more lods if (mafiaMesh.standard.lods.Count > 0) { var meshRenderer = child.AddComponent <MeshRenderer>(); meshFilter.mesh = GenerateMesh(mafiaMesh, child, mafiaMesh.standard.lods[0], model, out materials); meshRenderer.materials = materials; meshRenderer.shadowCastingMode = ShadowCastingMode.TwoSided; // Handle special textures foreach (var m in meshRenderer.sharedMaterials) { var name = m.GetTexture("_MainTex")?.name; if (IsTextureGlow(name)) { var glowTexture = (Texture2D)Resources.Load("Flares/" + Path.GetFileNameWithoutExtension(name)); m.shader = Shader.Find("Unlit/Transparent"); m.SetTexture("_MainTex", glowTexture); break; } } } else { continue; } } break; case MafiaFormats.VisualMeshType.Single_Mesh: { var meshRenderer = child.AddComponent <SkinnedMeshRenderer>(); meshFilter.mesh = GenerateMesh(mafiaMesh, child, mafiaMesh.singleMesh.standard.lods[0], model, out materials); meshRenderer.materials = materials; meshRenderer.sharedMesh = meshFilter.sharedMesh; meshRenderer.shadowCastingMode = ShadowCastingMode.TwoSided; } break; case MafiaFormats.VisualMeshType.Single_Morph: { var meshRenderer = child.AddComponent <SkinnedMeshRenderer>(); meshFilter.mesh = GenerateMesh(mafiaMesh, child, mafiaMesh.singleMorph.singleMesh.standard.lods[0], model, out materials); meshRenderer.materials = materials; meshRenderer.sharedMesh = meshFilter.sharedMesh; meshRenderer.shadowCastingMode = ShadowCastingMode.TwoSided; } break; case MafiaFormats.VisualMeshType.Billboard: { // TODO build up more lods var standard = mafiaMesh.billboard.standard; if (standard.lods.Count > 0) { //NOTE: (DavoSK) Add our custom billboard here child.AddComponent <CustomBillboard>(); var meshRenderer = child.AddComponent <MeshRenderer>(); meshFilter.mesh = GenerateMesh(mafiaMesh, child, standard.lods[0], model, out materials); meshRenderer.materials = materials; meshRenderer.shadowCastingMode = ShadowCastingMode.TwoSided; // Handle special textures foreach (var m in meshRenderer.sharedMaterials) { var name = m.GetTexture("_MainTex")?.name; if (IsTextureGlow(name)) { var glowTexture = (Texture2D)Resources.Load("Flares/" + Path.GetFileNameWithoutExtension(name)); m.shader = Shader.Find("Unlit/Transparent"); m.SetTexture("_MainTex", glowTexture); break; } } } else { continue; } } break; case MafiaFormats.VisualMeshType.Glow: { List <string> usedMaps = new List <string>(); foreach (var g in mafiaMesh.glow.glowData) { if (g.materialID - 1 >= model.materials.Count) { continue; } var matID = g.materialID - 1; var mat = model.materials[matID]; var mapName = mat.diffuseMapName; if (usedMaps.Contains(mapName)) { continue; } foreach (var m in model.meshes) { if (m.standard.lods == null) { continue; } if (m.standard.lods.Count < 1) { continue; } bool used = false; foreach (var gr in m.standard.lods[0].faceGroups) { if (gr.materialID == matID) { GenerateGlow(mapName, rootObject, m.pos); used = true; break; } } if (used == true) { break; } } usedMaps.Add(mapName); } } break; // TODO add more visual types default: continue; } def.modelName = Path.GetFileName(path); meshId++; } for (int i = 0; i < children.Count; i++) { var parentId = children[i].Key; var mafiaMesh = model.meshes[i]; if (parentId > 0) { children[i].Value.parent = children[parentId - 1].Value; } else { children[i].Value.parent = rootObject.transform; } children[i].Value.localPosition = mafiaMesh.pos; children[i].Value.localRotation = mafiaMesh.rot; children[i].Value.localScale = mafiaMesh.scale; } // NOTE(zaklaus): Do some extra work if this is a skinned mesh var baseObject = rootObject.transform.Find("base"); if (baseObject != null) { var skinnedMesh = baseObject.GetComponent <SkinnedMeshRenderer>(); if (skinnedMesh != null) { var def = baseObject.GetComponent <ModelDefinition>(); MafiaFormats.SingleMesh data; if (def.mesh.visualMeshType == MafiaFormats.VisualMeshType.Single_Mesh) { data = def.mesh.singleMesh; } else { data = def.mesh.singleMorph.singleMesh; } var boneData = data.LODs[0]; var bones = new List <Bone>(skinnedMesh.GetComponentsInChildren <Bone>()); var boneArray = new Transform[bones.Count]; foreach (var b in bones) { boneArray[b.data.boneID] = b.transform; } /* TODO: var boneTransforms = new List<Transform>(boneArray); */ var bindPoses = new Matrix4x4[bones.Count]; var boneWeights = new BoneWeight[skinnedMesh.sharedMesh.vertexCount]; skinnedMesh.bones = boneArray; int skipVertices = 0;//(int)boneData.nonWeightedVertCount; for (int i = 0; i < boneData.bones.Count; i++) { bindPoses[i] = boneData.bones[i].transform; for (int j = 0; j < boneData.bones[i].oneWeightedVertCount; j++) { boneWeights[skipVertices + j].boneIndex0 = i; boneWeights[skipVertices + j].weight0 = 1f; } skipVertices += (int)boneData.bones[i].oneWeightedVertCount; for (int j = 0; j < boneData.bones[i].weights.Count; j++) { boneWeights[skipVertices + j].boneIndex0 = i; boneWeights[skipVertices + j].weight0 = boneData.bones[i].weights[j]; boneWeights[skipVertices + j].boneIndex1 = (int)boneData.bones[i].boneID; boneWeights[skipVertices + j].weight1 = 1f - boneData.bones[i].weights[j]; } skipVertices += boneData.bones[i].weights.Count; } skinnedMesh.sharedMesh.bindposes = bindPoses; skinnedMesh.sharedMesh.boneWeights = boneWeights; } } children.Clear(); } StoreCachedObject(path, rootObject); return(rootObject); }
public virtual GameObject LoadObject(string path, Mission mission) { // NOTE(zaklaus): Implemented elsewhere... return(null); }