public void BuildMeshes() { GameObject parent = new GameObject("_Models"); parent.transform.parent = MapRenderer.mapParent.transform; Dictionary <int, AnimProperties> anims = new Dictionary <int, AnimProperties>(); int nodeId = 0; foreach (RSM.CompiledModel model in models) { GameObject modelObj = new GameObject(model.rsm.name); modelObj.transform.parent = parent.transform; foreach (var nodeData in model.nodesData) { foreach (var meshesByTexture in nodeData) { long textureId = meshesByTexture.Key; RSM.NodeMeshData meshData = meshesByTexture.Value; RSM.Node node = meshData.node; if (meshesByTexture.Value.vertices.Count == 0) { continue; } for (int i = 0; i < meshData.vertices.Count; i += 3) { meshData.triangles.AddRange(new int[] { i + 0, i + 1, i + 2 }); } //create node unity mesh Mesh mesh = new Mesh(); mesh.vertices = meshData.vertices.ToArray(); mesh.triangles = meshData.triangles.ToArray(); //mesh.normals = meshData.normals.ToArray(); mesh.uv = meshData.uv.ToArray(); GameObject nodeObj = new GameObject(node.name); nodeObj.transform.parent = modelObj.transform; string textureFile = model.rsm.textures[textureId]; var mf = nodeObj.AddComponent <MeshFilter>(); mf.mesh = mesh; var mr = nodeObj.AddComponent <MeshRenderer>(); if (meshData.twoSided) { mr.material = material2s; if (textureFile.EndsWith("tga")) { mr.material.shader = Resources.Load("2SidedAlpha") as Shader; mr.material.renderQueue += 1; } } else { mr.material = material; if (textureFile.EndsWith("tga")) { mr.material.shader = Resources.Load("ModelShaderAlpha") as Shader; mr.material.renderQueue += 1; } } mr.material.mainTexture = FileManager.Load("data/texture/" + textureFile) as Texture2D; if (model.rsm.shadeType == RSM.SHADING.SMOOTH) { NormalSolver.RecalculateNormals(mf.mesh, 60); } else { mf.mesh.RecalculateNormals(); } var matrix = node.GetPositionMatrix(); nodeObj.transform.position = matrix.ExtractPosition(); var rotation = matrix.ExtractRotation(); nodeObj.transform.rotation = rotation; nodeObj.transform.localScale = matrix.ExtractScale(); var properties = nodeObj.AddComponent <NodeProperties>(); properties.nodeId = nodeId; properties.mainName = model.rsm.mainNode.name; properties.parentName = node.parentName; if (node.posKeyframes.Count > 0 || node.rotKeyframes.Count > 0) { nodeObj.AddComponent <NodeAnimation>().nodeId = nodeId; anims.Add(nodeId, new AnimProperties() { posKeyframes = node.posKeyframes, rotKeyframes = node.rotKeyframes, animLen = model.rsm.animLen, baseRotation = rotation, isChild = properties.isChild }); } nodeId++; } } modelObj.SetActive(false); //instantiate model for (int i = 0; i < model.rsm.instances.Count; i++) { GameObject instanceObj; if (i == model.rsm.instances.Count - 1) { //last instance instanceObj = modelObj; } else { instanceObj = UnityEngine.Object.Instantiate(modelObj); } instanceObj.transform.parent = parent.transform; instanceObj.name += "[" + i + "]"; RSW.ModelDescriptor descriptor = model.rsm.instances[i]; instanceObj.transform.Rotate(Vector3.forward, -descriptor.rotation[2]); instanceObj.transform.Rotate(Vector3.right, -descriptor.rotation[0]); instanceObj.transform.Rotate(Vector3.up, descriptor.rotation[1]); Vector3 scale = new Vector3(descriptor.scale[0], -descriptor.scale[1], descriptor.scale[2]); instanceObj.transform.localScale = scale; //avoid z fighting between models float xRandom = UnityEngine.Random.Range(-0.002f, 0.002f); float yRandom = UnityEngine.Random.Range(-0.002f, 0.002f); float zRandom = UnityEngine.Random.Range(-0.002f, 0.002f); Vector3 position = new Vector3(descriptor.position[0] + xRandom, descriptor.position[1] + yRandom, descriptor.position[2] + zRandom); position.x += MapRenderer.width; position.y *= -1; position.z += MapRenderer.height; instanceObj.transform.position = position; //setup hierarchy var propertiesComponents = instanceObj.GetComponentsInChildren <NodeProperties>(); foreach (var properties in propertiesComponents) { if (properties.isChild) { var nodeParent = instanceObj.transform.FindRecursive(properties.parentName); properties.transform.parent = nodeParent; } } //setup animations var animComponents = instanceObj.GetComponentsInChildren <NodeAnimation>(); foreach (var animComponent in animComponents) { var properties = anims[animComponent.nodeId]; animComponent.Initialize(properties); } instanceObj.SetActive(true); } } anims.Clear(); }
public static RSW Load(BinaryReader data) { //read header string header = data.ReadBinaryString(4); string version = Convert.ToString(data.ReadByte()); string subversion = Convert.ToString(data.ReadByte()); version += "." + subversion; double dversion = double.Parse(version, CultureInfo.InvariantCulture); //check for valid .rsw file if (!string.Equals(header, RSW.Header)) { throw new Exception("WorldLoader.Load: Header (" + header + ") is not \"GRSW\""); } RSW rsw = new RSW(version); //read sub files files.ini = data.ReadBinaryString(40); files.gnd = data.ReadBinaryString(40); files.gat = data.ReadBinaryString(40); if (dversion >= 1.4) { files.src = data.ReadBinaryString(40); } //read water info if (dversion >= 1.3) { rsw.water.level = data.ReadFloat() / 5; if (dversion >= 1.8) { rsw.water.type = data.ReadLong(); rsw.water.waveHeight = data.ReadFloat() / 5; rsw.water.waveSpeed = data.ReadFloat(); rsw.water.wavePitch = data.ReadFloat(); if (dversion >= 1.9) { rsw.water.animSpeed = data.ReadLong(); } } } //read lightmap if (dversion >= 1.5) { rsw.light.longitude = data.ReadLong(); rsw.light.latitude = data.ReadLong(); for (int i = 0; i < 3; i++) { rsw.light.diffuse[i] = data.ReadFloat(); } for (int i = 0; i < 3; i++) { rsw.light.ambient[i] = data.ReadFloat(); } if (dversion >= 1.7) { rsw.light.intensity = data.ReadFloat(); } } // Read ground if (dversion >= 1.6) { rsw.ground.top = data.ReadLong(); rsw.ground.bottom = data.ReadLong(); rsw.ground.left = data.ReadLong(); rsw.ground.right = data.ReadLong(); } // Read Object int count = data.ReadLong(); var models = rsw.modelDescriptors = new List <RSW.ModelDescriptor>(count); var lights = rsw.lights = new List <RSW.Light>(count); var sounds = rsw.sounds = new List <RSW.Sound>(count); var effects = rsw.effects = new List <RSW.Effect>(count); for (int i = 0; i < count; i++) { switch (data.ReadLong()) { case 1: //load model var model = new RSW.ModelDescriptor(); model.name = dversion >= 1.3 ? data.ReadBinaryString(40) : null; model.animType = dversion >= 1.3 ? data.ReadLong() : 0; model.animSpeed = dversion >= 1.3 ? data.ReadFloat() : 0f; model.blockType = dversion >= 1.3 ? data.ReadLong() : 0; model.filename = data.ReadBinaryString(80); model.nodename = data.ReadBinaryString(80); model.position = new float[3]; for (int j = 0; j < model.position.Length; j++) { model.position[j] = data.ReadFloat() / 5; } model.rotation = new float[3]; for (int j = 0; j < model.rotation.Length; j++) { model.rotation[j] = data.ReadFloat(); } model.scale = new float[3]; for (int j = 0; j < model.scale.Length; j++) { model.scale[j] = data.ReadFloat() / 5; } models.Add(model); continue; case 2: //load light var light = new RSW.Light(); light.name = data.ReadBinaryString(80); light.pos = new float[3]; for (int j = 0; j < light.pos.Length; j++) { light.pos[j] = data.ReadFloat() / 5; } light.color = new float[3]; for (int j = 0; j < light.color.Length; j++) { light.color[j] = data.ReadFloat(); } light.range = data.ReadFloat(); lights.Add(light); continue; case 3: //load sound var sound = new RSW.Sound(); sound.name = data.ReadBinaryString(80); sound.file = "data/wav/" + data.ReadBinaryString(80); sound.pos = new float[3]; for (int j = 0; j < sound.pos.Length; j++) { sound.pos[j] = data.ReadFloat() / 5; } sound.vol = data.ReadFloat(); sound.width = data.ReadLong(); sound.height = data.ReadLong(); sound.range = data.ReadFloat(); sound.cycle = dversion >= 2.0 ? data.ReadFloat() : 0f; sounds.Add(sound); continue; case 4: //load effect var effect = new RSW.Effect(); effect.name = data.ReadBinaryString(80); effect.pos = new float[3]; for (int j = 0; j < effect.pos.Length; j++) { effect.pos[j] = data.ReadFloat() / 5; } effect.id = data.ReadLong(); effect.delay = data.ReadFloat() * 10; effect.param = new float[4]; for (int j = 0; j < effect.param.Length; j++) { effect.param[j] = data.ReadFloat(); } effects.Add(effect); continue; } } models.TrimExcess(); sounds.TrimExcess(); lights.TrimExcess(); effects.TrimExcess(); return(rsw); }
public void CreateInstance(RSW.ModelDescriptor model) { instances.Add(model); }