void LoadLevelFromUrl(byte[] data) { if (data == null) { return; } Parser.Tr2Level leveldata = Parser.Parse(data); if (leveldata != null) { //leveldata.Camera = m_Camera; //leveldata.Text3DPrefav = m_Text3D; if (m_SharedMaterial != null) { m_SharedMaterial.mainTexture = TextureUV.GenerateTextureTile(leveldata); m_Level = BuildLevel(leveldata, m_SharedMaterial, m_LevelName); } else { #if UNITY_EDITOR EditorUtility.DisplayDialog("Error", "m_SharedMaterial is not set in GameObject: " + this.name, "OK"); #else Debug.LogError("m_SharedMaterial is not set in GameObject" + this.name); #endif } } }
//TODO: This should go to State Player class public static void BuildMap(List <TRAnimationClip> clips, Animation animation, Parser.Tr2Level leveldata) { for (int clipid = 0; clipid < clips.Count; clipid++) { //collect statechange info into TRAnimStateChange class int offsetstatechange = (int)leveldata.Animations[clipid].StateChangeOffset; int nstatechange = leveldata.Animations[clipid].NumStateChanges; for (int statechangeid = 0; statechangeid < nstatechange; statechangeid++) { //read statechange info from global Parser.Tr2StateChange leveldata.StateChanges Parser.Tr2StateChange statechange = leveldata.StateChanges[offsetstatechange + statechangeid]; int ndispatch = statechange.NumAnimDispatches; int offsetdispatch = statechange.AnimDispatch; //create wrapper statechange object TRAnimStateChange unitystatechange = new TRAnimStateChange(); unitystatechange.stateid = (int)statechange.StateID; for (int dispatchid = 0; dispatchid < ndispatch; dispatchid++) { Parser.Tr2AnimDispatch animdispatch = leveldata.AnimDispatches[offsetdispatch + dispatchid]; //TRAnimDispatcher unityanimdispacher = new TRAnimDispatcher(); //unityanimdispacher.NextAnimation = animdispatch.NextAnimation; //unitystatechange.dispatchers.Add(unityanimdispacher); unitystatechange.tr2dispatchers.Add(animdispatch); } clips[clipid].statechanges.Add(unitystatechange); } clips[clipid].state = animation["" + clipid]; } }
static Parser.Tr2Level LoadLevelFromFile(string path) { Parser.Tr2Level leveldata = null; if (path != null) { #if UNITY_WEBPLAYER if (Settings.LoadDemoLevel) { m_DemoData = (TextAsset)Resources.Load("Demo Level", typeof(TextAsset)); m_RawFileData = m_DemoData.bytes; leveldata = Parser.Parse(m_RawFileData); Level.m_LevelName = Path.GetFileNameWithoutExtension(path); } #else if (Settings.LoadDemoLevel) { m_DemoData = (TextAsset)Resources.Load("Demo Level", typeof(TextAsset)); m_RawFileData = m_DemoData.bytes; } else { FileStream fstream = File.Open(path, FileMode.Open, FileAccess.ReadWrite); BinaryReader br = new BinaryReader(fstream); m_RawFileData = br.ReadBytes((int)fstream.Length); //File.ReadAllBytes(path); //fixed file read access violation br.Close(); } leveldata = Parser.Parse(m_RawFileData); m_LevelName = Path.GetFileNameWithoutExtension(path); Debug.Log("LoadLevelFromFile: " + m_LevelName); #endif } return(leveldata); }
void LoadLevel() { Parser.Tr2Level leveldata = LoadLevelFromFile(Settings.LevelFileLocalPath); if (leveldata != null) { //leveldata.Camera = m_Camera; //leveldata.Text3DPrefav = m_Text3D; if (m_SharedMaterial != null) { m_SharedMaterial.mainTexture = TextureUV.GenerateTextureTile(leveldata); m_Level = BuildLevel(leveldata, m_SharedMaterial, m_LevelName); } else { #if UNITY_EDITOR EditorUtility.DisplayDialog("Error", "m_SharedMaterial is not set in GameObject:" + this.name, "OK"); #else Debug.LogError("m_SharedMaterial is not set in GameObject" + this.name); #endif } } else { //Selected file is not tr2 type! Application.LoadLevel("Browser"); } }
static KeyFrameData CalculateAnimationKeyFrameData(int animid, Parser.Tr2Level leveldata) { //Note: animid is a index to tranim list. KeyFrameData tr2framedata = new KeyFrameData(); if (animid == leveldata.NumAnimations) { //endofanimation tr2framedata.endofanimation = true; return(tr2framedata); } if (animid == 0) { tr2framedata.bplayer = true; } Parser.Tr2Animation tr2animation = leveldata.Animations[animid]; //create s16 offset list of frames for this animation; //determine short stating offset to frames chunk of this animclip //calculate index into tr2frames[] and how large the frame is //tr2animation.FrameOffset is byte offset into Frame, make it short offset //tr2animation.FrameSize = (byte)((tr2frames[fo + 9] * 2) + 10); tr2framedata.data = leveldata.Frames; tr2framedata.startoffset = (int)tr2animation.FrameOffset / 2; tr2framedata.framesize = (int)tr2animation.FrameSize; // num shorts of this frame step tr2framedata.time_per_frame = (float)tr2animation.FrameRate / 30f; if (animid < (int)leveldata.NumAnimations - 1) { Parser.Tr2Animation nexttr2animation = leveldata.Animations[animid + 1]; int nextoffset = (int)(nexttr2animation.FrameOffset / 2); tr2framedata.numshorts = nextoffset - tr2framedata.startoffset; } else { tr2framedata.numshorts = (int)(leveldata.NumFrames - (uint)tr2framedata.startoffset); } if (tr2framedata.framesize != 0) { tr2framedata.numkeyframe = tr2framedata.numshorts / tr2framedata.framesize; } else { tr2framedata.numkeyframe = 0; } tr2framedata.start_animation_frame_index = tr2animation.FrameStart;// tr2animation (int)tr2framedata.startoffset / tr2framedata.framesize; // tr2framedata.numkeyframe = (tr2animation.FrameEnd - tr2animation.FrameStart) + 1; //if(tr2framedata.numkeyframe > 15) //Debug.Log("numkeyframe: " + tr2framedata.numkeyframe + " NextAnimation:" + tr2animation.NextAnimation); return(tr2framedata); }
static bool IsFaceInWater(Parser.Tr2Level level, ushort SearchIndex) { if (GetAnimatedTextureIndex(level.AnimatedTextures, level.NumAnimatedTextures, SearchIndex) != SearchIndex) { return(true); } return(false); }
public void InitRoom(Parser.Tr2Room room, List<GameObject> objects) { m_leveldata = Level.m_leveldata; m_Mesh = GetComponent<MeshFilter>().mesh; m_Transform = transform; m_StaticObjects = objects; m_Tr2Room = room; //These are not serialised by Editor. Move them to Start() //m_RoomVertices = m_Mesh.vertices; //m_SharedTriangles = MeshModifier.GetSharedTriangles(m_Mesh); //m_RoomAnalyzer = new SurfaceAnalyzer(m_Mesh); //m_RoomEdges = m_RoomAnalyzer.Analyze(m_RoomVertices, m_SharedTriangles,null); }
public static List <TRAnimationClip> AttachAnimation(Tr2Moveable tr2movable, Parser.Tr2Level leveldata) { List <TRAnimationClip> clips = CreateAnimationWithID(tr2movable, tr2movable.TransformsTree, leveldata); //tr2movable.UnityObject.AddComponent<AnimationPlayer>(); //m_DynamicPrefabs[i].AnimClips = new List<TRAnimationClip>(); //add these clips to Tr2Moveable tr2movable.UnityAnimation for (int ci = 0; ci < clips.Count; ci++) { tr2movable.UnityAnimation.AddClip(clips[ci].clip, "" + ci); } tr2movable.AnimClips = clips; return(clips); }
public static Level BuildLevel(Parser.Tr2Level leveldata, Material sharedmaterial, string levelname) { GameObject m_LevelRoot = new GameObject("Level " + levelname); SoundMananger sound_manager = null; if (Camera.main != null) { sound_manager = Camera.main.gameObject.AddComponent <SoundMananger>(); } else { sound_manager = m_LevelRoot.AddComponent <SoundMananger>(); Debug.LogError("No Camera Found!"); } //creat level Level level = new Level(leveldata, sharedmaterial, m_LevelRoot.transform); if (leveldata == null) { Debug.LogError(" leveldata not initialized!"); return(null); } //creat level manager LevelManager manager = m_LevelRoot.AddComponent <LevelManager>(); manager.SharedMaterial = level.GetSharedMaterial(); manager.InstancedMaterialWaterHolders = level.GetInstancedWaterHolderMaterials(); manager.SharedMaterialWater = level.GetSharedWaterMaterial(); manager.SetPlayer(Level.m_Player.GetComponent <Player>()); manager.SetFollowCamera(Camera.main.transform); manager.SetSoundManager(sound_manager); return(level); }
public static Mesh CreateObjectMesh(Parser.Tr2Mesh tr2mesh, Parser.Tr2Level leveldata) { Vector3[] sharedVertices = null; if (tr2mesh.NumVertices > 0) { sharedVertices = new Vector3[tr2mesh.NumVertices]; for (int vertAttribCount = 0; vertAttribCount < tr2mesh.NumVertices; vertAttribCount++) { float x = tr2mesh.Vertices[vertAttribCount].x; float y = tr2mesh.Vertices[vertAttribCount].y; float z = tr2mesh.Vertices[vertAttribCount].z; ////print("chk vtx x y z:" +x+ " " +y + " " +z); sharedVertices[vertAttribCount].x = x; sharedVertices[vertAttribCount].y = -y; sharedVertices[vertAttribCount].z = z; } //uv = new Vector2[leveldata.Rooms[chkRoom].RoomData.NumVertices]; } //warning: a variable lengh array in a structure can cause access violence //selected_texObjectIdx = leveldata.Rooms[chkRoom].RoomData.Rectangles[0].Texture; //selected_texObj = leveldata.ObjectTextures[selected_texObjectIdx]; //selected_texTileIdx = selected_texObj.Tile; int NumTexturedTriangles = tr2mesh.NumTexturedTriangles; int NumTexturedRectangles = tr2mesh.NumTexturedRectangles; int numNonsharedVertices = (NumTexturedRectangles * 4) + (NumTexturedTriangles * 3); int numNonsharedTris = (NumTexturedRectangles * 3 * 2) + (NumTexturedTriangles * 3); Vector3[] nonSharedVertices = new Vector3[numNonsharedVertices]; Vector2[] nonSharedUVs = new Vector2[numNonsharedVertices]; int[] nonSharedTris = new int[numNonsharedTris]; //triangles = new int[leveldata.Rooms[chkRoom].RoomData.NumRectangles * 3 * 2]; Parser.Tr2Face4[] TexturedRectangles = tr2mesh.TexturedRectangles; for (int rectCount = 0; rectCount < NumTexturedRectangles; rectCount++) { int Idx0 = TexturedRectangles[rectCount].Vertices0; int Idx1 = TexturedRectangles[rectCount].Vertices1; int Idx2 = TexturedRectangles[rectCount].Vertices2; int Idx3 = TexturedRectangles[rectCount].Vertices3; int vertOrUVIdx0 = rectCount * 4 + 0; int vertOrUVIdx1 = rectCount * 4 + 1; int vertOrUVIdx2 = rectCount * 4 + 2; int vertOrUVIdx3 = rectCount * 4 + 3; nonSharedVertices[vertOrUVIdx0] = sharedVertices[Idx0]; nonSharedVertices[vertOrUVIdx1] = sharedVertices[Idx1]; nonSharedVertices[vertOrUVIdx2] = sharedVertices[Idx2]; nonSharedVertices[vertOrUVIdx3] = sharedVertices[Idx3]; ushort texObjectIdx = TexturedRectangles[rectCount].Texture; if (texObjectIdx >= leveldata.ObjectTextures.Length) { continue; //fixed: outof bound exception for Parser.Tr2Level.ObjectTextures } Parser.Tr2ObjectTexture texObj = leveldata.ObjectTextures[texObjectIdx]; ushort texTileIdx = texObj.Tile; //bind this textile in material? //if(texTileIdx != prevTexture) //{ //newMatCount +=1; //prevTexture = texTileIdx; ////print("newMatCount:"+ newMatCount); //} SetFaceUVs(nonSharedUVs, vertOrUVIdx0, vertOrUVIdx1, vertOrUVIdx2, vertOrUVIdx3, texObj); ////print("uv[Idx0]"+ uv[Idx0].x + " " + uv[Idx0].y); ////print("uv[Idx1]"+ uv[Idx1].x + " " + uv[Idx1].y); //ushort opacity = texObj.TransparencyFlags; //isItOpacq nonSharedTris[rectCount * 6 + 0] = vertOrUVIdx0; nonSharedTris[rectCount * 6 + 1] = vertOrUVIdx1; nonSharedTris[rectCount * 6 + 2] = vertOrUVIdx2; nonSharedTris[rectCount * 6 + 3] = vertOrUVIdx2; nonSharedTris[rectCount * 6 + 4] = vertOrUVIdx3; nonSharedTris[rectCount * 6 + 5] = vertOrUVIdx0; } Parser.Tr2Face3[] TexturedTriangles = tr2mesh.TexturedTriangles; for (int triCount = 0; triCount < NumTexturedTriangles; triCount++) { int Idx0 = TexturedTriangles[triCount].Vertices0; int Idx1 = TexturedTriangles[triCount].Vertices1; int Idx2 = TexturedTriangles[triCount].Vertices2; int vertOrUVIdx0 = triCount * 3 + 0; int vertOrUVIdx1 = triCount * 3 + 1; int vertOrUVIdx2 = triCount * 3 + 2; int strideVertIdx = (NumTexturedRectangles * 4); int strideTriIdx = (NumTexturedRectangles * 3 * 2); nonSharedVertices[strideVertIdx + vertOrUVIdx0] = sharedVertices[Idx0]; nonSharedVertices[strideVertIdx + vertOrUVIdx1] = sharedVertices[Idx1]; nonSharedVertices[strideVertIdx + vertOrUVIdx2] = sharedVertices[Idx2]; ushort texObjectIdx = tr2mesh.TexturedTriangles[triCount].Texture; if (texObjectIdx >= leveldata.ObjectTextures.Length) { continue; //fixed: outof bound exception for Parser.Tr2Level.ObjectTextures } Parser.Tr2ObjectTexture texObj = leveldata.ObjectTextures[texObjectIdx]; //if(texTileIdx != prevTexture) //{ //newMatCount +=1; //prevTexture = texTileIdx; ////print("newMatCount:"+ newMatCount); //} SetFaceUVs(nonSharedUVs, strideVertIdx + vertOrUVIdx0, strideVertIdx + vertOrUVIdx1, strideVertIdx + vertOrUVIdx2, texObj); ////print("uv[Idx0]"+ uv[Idx0].x + " " + uv[Idx0].y); ////print("uv[Idx1]"+ uv[Idx1].x + " " + uv[Idx1].y); //ushort opacity = texObj.TransparencyFlags; //isItOpacq nonSharedTris[strideTriIdx + vertOrUVIdx0] = strideVertIdx + vertOrUVIdx0; nonSharedTris[strideTriIdx + vertOrUVIdx1] = strideVertIdx + vertOrUVIdx1; nonSharedTris[strideTriIdx + vertOrUVIdx2] = strideVertIdx + vertOrUVIdx2; } for (int i = 0; i < nonSharedVertices.Length; i++) { nonSharedVertices[i] = nonSharedVertices[i] * Settings.SceneScaling; } Mesh mesh = new Mesh(); mesh.Clear(); mesh.vertices = nonSharedVertices; mesh.uv = nonSharedUVs; mesh.triangles = nonSharedTris; MeshModifier.VertexWeild(mesh); #if UNITY_EDITOR Vector4[] tangents = new Vector4[mesh.vertices.Length]; computeTangentsAndBinormals(mesh.vertices, mesh.normals, mesh.uv, mesh.triangles, tangents); mesh.tangents = tangents; tangents = null; #endif //free some memory nonSharedVertices = null; nonSharedUVs = null; nonSharedTris = null; return(mesh); }
public static Mesh CreateRoomMesh(Parser.Tr2Room tr2room, Parser.Tr2Level leveldata, ref bool has_water) { Vector3[] sharedVertices = null; has_water = false; byte[] is_water_vertex = null; bool has_water_face = false; if (tr2room.RoomData.NumVertices > 0) { int LightMode = tr2room.LightMode; int NumVertices = tr2room.RoomData.NumVertices; // optimized for field access Parser.Tr2VertexRoom[] Vertices = tr2room.RoomData.Vertices; sharedVertices = new Vector3[NumVertices]; is_water_vertex = new byte[sharedVertices.Length]; for (int vertAttribCount = 0; vertAttribCount < NumVertices; vertAttribCount++) { float x = Vertices[vertAttribCount].Vertex.x; float y = Vertices[vertAttribCount].Vertex.y; float z = Vertices[vertAttribCount].Vertex.z; ////print("chk vtx x y z:" +x+ " " +y + " " +z); sharedVertices[vertAttribCount].x = x; sharedVertices[vertAttribCount].y = -y; sharedVertices[vertAttribCount].z = z; is_water_vertex[vertAttribCount] = 10; if ((Vertices[vertAttribCount].Attributes & 0x8000L) == 0x8000L) { is_water_vertex[vertAttribCount] = 1; has_water = true; } } //warning: avariable lengh array in a structure can cause access violence //if(tr2room.RoomData.NumRectangles > 0) //{ //selected_texObjectIdx = tr2room.RoomData.Rectangles[0].Texture; //selected_texObj = leveldata.ObjectTextures[selected_texObjectIdx]; //selected_texTileIdx = selected_texObj.Tile; int NumRectangles = tr2room.RoomData.NumRectangles; // optimized for field access int strideVertIdx = (NumRectangles * 4); int strideTriIdx = (NumRectangles * 3 * 2); int numNonsharedVertices = strideVertIdx + (tr2room.RoomData.NumTriangles * 3); int numNonsharedTris = strideTriIdx + (tr2room.RoomData.NumTriangles * 3); Vector3[] nonSharedVertices = new Vector3[numNonsharedVertices]; Vector2[] nonSharedUVs = new Vector2[numNonsharedVertices]; Vector2[] nonSharedUV2s = new Vector2[numNonsharedVertices]; Color[] nonSharedColor = new Color[numNonsharedVertices]; int[] nonSharedTris = new int[numNonsharedTris]; //triangles = new int[num_rectangles * 3 * 2]; Parser.Tr2Face4[] Rectangles = tr2room.RoomData.Rectangles; // optimized for field access for (int rectCount = 0; rectCount < NumRectangles; rectCount++) { int Idx0 = Rectangles[rectCount].Vertices0; int Idx1 = Rectangles[rectCount].Vertices1; int Idx2 = Rectangles[rectCount].Vertices2; int Idx3 = Rectangles[rectCount].Vertices3; ////print ("idx0 - Idx1 - Idx2 - Idx3:" + Idx0 + " " + Idx1 + " " + Idx2 +" " + Idx3); int vertOrUVIdx0 = rectCount * 4 + 0; int vertOrUVIdx1 = rectCount * 4 + 1; int vertOrUVIdx2 = rectCount * 4 + 2; int vertOrUVIdx3 = rectCount * 4 + 3; if (has_water) { if (IsFaceInWater(is_water_vertex, Idx0, Idx1, Idx2, Idx3)) //if all vertices are in water { continue; } } else { if (IsFaceInWater(leveldata, Rectangles[rectCount].Texture)) { has_water_face = true; continue; } } nonSharedVertices[vertOrUVIdx0] = sharedVertices[Idx0]; nonSharedVertices[vertOrUVIdx1] = sharedVertices[Idx1]; nonSharedVertices[vertOrUVIdx2] = sharedVertices[Idx2]; nonSharedVertices[vertOrUVIdx3] = sharedVertices[Idx3]; if (has_water) { //Added vertex color for lighting effect //Debug.Log("Light Atrrib0" + (Vertices[Idx0].Attributes & 0x1f)); //Debug.Log("Light Atrrib1" + (Vertices[Idx1].Attributes & 0x1f)); //Debug.Log("Light Atrrib2" + (Vertices[Idx2].Attributes & 0x1f)); } //Added vertex color for lighting effect nonSharedColor[vertOrUVIdx0] = Color.white * (1 - Vertices[Idx0].Lighting2 * 1.220852154804053e-4f); // ((0.5f - ((float)(Vertices[Idx0].Attributes & 0x1f) / 32f)) + 0.5f); nonSharedColor[vertOrUVIdx1] = Color.white * (1 - Vertices[Idx1].Lighting2 * 1.220852154804053e-4f); // ((0.5f - ((float)(Vertices[Idx1].Attributes & 0x1f) / 32f)) + 0.5f); nonSharedColor[vertOrUVIdx2] = Color.white * (1 - Vertices[Idx2].Lighting2 * 1.220852154804053e-4f); // ((0.5f - ((float)(Vertices[Idx2].Attributes & 0x1f) / 32f)) + 0.5f); nonSharedColor[vertOrUVIdx3] = Color.white * (1 - Vertices[Idx3].Lighting2 * 1.220852154804053e-4f); // ((0.5f - ((float)(Vertices[Idx3].Attributes & 0x1f) / 32f)) + 0.5f); ushort texObjectIdx = Rectangles[rectCount].Texture; if (texObjectIdx >= leveldata.ObjectTextures.Length) { continue; //fixed: outof bound exception for Parser.Tr2Level.ObjectTextures } Parser.Tr2ObjectTexture texObj = leveldata.ObjectTextures[texObjectIdx]; ushort texTileIdx = texObj.Tile; //bind this textile in material? //if(texTileIdx != prevTexture) //{ //newMatCount +=1; //prevTexture = texTileIdx; ////print("newMatCount:"+ newMatCount); //} SetFaceUVs(nonSharedUVs, vertOrUVIdx0, vertOrUVIdx1, vertOrUVIdx2, vertOrUVIdx3, texObj); ////print("uv[Idx0]"+ uv[Idx0].x + " " + uv[Idx0].y); ////print("uv[Idx1]"+ uv[Idx1].x + " " + uv[Idx1].y); //ushort opacity = texObj.TransparencyFlags; //isItOpacq nonSharedTris[rectCount * 6 + 0] = vertOrUVIdx0; nonSharedTris[rectCount * 6 + 1] = vertOrUVIdx1; nonSharedTris[rectCount * 6 + 2] = vertOrUVIdx2; nonSharedTris[rectCount * 6 + 3] = vertOrUVIdx2; nonSharedTris[rectCount * 6 + 4] = vertOrUVIdx3; nonSharedTris[rectCount * 6 + 5] = vertOrUVIdx0; } Parser.Tr2Face3[] Triangles = tr2room.RoomData.Triangles; // optimized for field access int NumTriangles = tr2room.RoomData.NumTriangles; for (int triCount = 0; triCount < NumTriangles; triCount++) { ////print("tr2room.RoomData.NumTriangles"+ tr2room.RoomData.NumTriangles); int Idx0 = Triangles[triCount].Vertices0; int Idx1 = Triangles[triCount].Vertices1; int Idx2 = Triangles[triCount].Vertices2; ////print ("idx0 - Idx1 - Idx2:" + Idx0 + " " + Idx1 + " " + Idx2); //[][][][]+[][][] int vertOrUVIdx0 = triCount * 3 + 0; int vertOrUVIdx1 = triCount * 3 + 1; int vertOrUVIdx2 = triCount * 3 + 2; if (has_water) { if (IsFaceInWater(is_water_vertex, Idx0, Idx1, Idx2)) //if all vertices are in water { continue; } } else { if (IsFaceInWater(leveldata, Triangles[triCount].Texture)) { has_water_face = true; continue; } } nonSharedVertices[strideVertIdx + vertOrUVIdx0] = sharedVertices[Idx0]; nonSharedVertices[strideVertIdx + vertOrUVIdx1] = sharedVertices[Idx1]; nonSharedVertices[strideVertIdx + vertOrUVIdx2] = sharedVertices[Idx2]; if (has_water) { //Added vertex color for lighting effect //Debug.Log("Light Atrrib0" + (Vertices[Idx0].Attributes & 0x1f)); //Debug.Log("Light Atrrib1" + (Vertices[Idx1].Attributes & 0x1f)); //Debug.Log("Light Atrrib2" + (Vertices[Idx2].Attributes & 0x1f)); } nonSharedColor[strideVertIdx + vertOrUVIdx0] = Color.white * (1 - Vertices[Idx0].Lighting2 * 1.220852154804053e-4f); ////Color.white * ((0.5f - ((float)(Vertices[Idx0].Attributes & 0x1f) / 32f)) + 0.5f); nonSharedColor[strideVertIdx + vertOrUVIdx1] = Color.white * (1 - Vertices[Idx1].Lighting2 * 1.220852154804053e-4f); ////Color.white * ((0.5f - ((float)(Vertices[Idx1].Attributes & 0x1f) / 32f)) + 0.5f); nonSharedColor[strideVertIdx + vertOrUVIdx2] = Color.white * (1 - Vertices[Idx2].Lighting2 * 1.220852154804053e-4f); ////Color.white * ((0.5f - ((float)(Vertices[Idx2].Attributes & 0x1f) / 32f)) + 0.5f); ushort texObjectIdx = Triangles[triCount].Texture; if (texObjectIdx >= leveldata.ObjectTextures.Length) { continue; //fixed: outof bound exception for Parser.Tr2Level.ObjectTextures } Parser.Tr2ObjectTexture texObj = leveldata.ObjectTextures[texObjectIdx]; //if(texTileIdx != prevTexture) //{ //newMatCount +=1; //prevTexture = texTileIdx; ////print("newMatCount:"+ newMatCount); //} SetFaceUVs(nonSharedUVs, strideVertIdx + vertOrUVIdx0, strideVertIdx + vertOrUVIdx1, strideVertIdx + vertOrUVIdx2, texObj); ////print("uv[Idx0]"+ uv[Idx0].x + " " + uv[Idx0].y); ////print("uv[Idx1]"+ uv[Idx1].x + " " + uv[Idx1].y); //ushort opacity = texObj.TransparencyFlags; //isItOpacq nonSharedTris[strideTriIdx + vertOrUVIdx0] = strideVertIdx + vertOrUVIdx0; nonSharedTris[strideTriIdx + vertOrUVIdx1] = strideVertIdx + vertOrUVIdx1; nonSharedTris[strideTriIdx + vertOrUVIdx2] = strideVertIdx + vertOrUVIdx2; ////print ("idx0 - Idx1 - Idx2:" + nonSharedTris[strideTriIdx + vertOrUVIdx0] + " " + nonSharedTris[strideTriIdx + vertOrUVIdx1] + " " + nonSharedTris[strideTriIdx + vertOrUVIdx2] ); } if (has_water_face) { has_water = true; } ////print("leveldata.Rooms[5].RoomData.NumRectangles:"+ tr2room.RoomData.NumRectangles); //SetTriangles (triangles : int[], submesh : int) : void //generate secondary uv set for (int i = 0; i < nonSharedVertices.Length; i++) { nonSharedVertices[i] = nonSharedVertices[i] * Settings.SceneScaling; } Mesh mesh = new Mesh(); mesh.Clear(); mesh.vertices = nonSharedVertices; mesh.uv = nonSharedUVs; mesh.uv2 = nonSharedUVs; mesh.colors = nonSharedColor; mesh.triangles = nonSharedTris; //mesh.Optimize(); mesh.RecalculateNormals(); #if UNITY_EDITOR Vector4[] tangents = new Vector4[mesh.vertices.Length]; computeTangentsAndBinormals(nonSharedVertices, mesh.normals, nonSharedUVs, nonSharedTris, tangents); mesh.tangents = tangents; tangents = null; #endif //free some memory nonSharedVertices = null; nonSharedUVs = null; nonSharedUV2s = null; nonSharedTris = null; nonSharedColor = null; //} return(mesh); } return(new Mesh()); //empty mesh }
public static Texture2D GenerateTextureTile(Parser.Tr2Level leveldata) { int c16_index = 0; int c16_pixel_count = 256 * 256; // pixel count optimization Color[][] ColorTable = new Color[leveldata.m_MaxTiles][]; for (int tileCount = 0; tileCount < leveldata.m_MaxTiles; tileCount++) { ColorTable[tileCount] = new Color[c16_pixel_count]; for (int c = 0; c < c16_pixel_count; c++) { ColorTable[tileCount][c] = Color.white; } //if(tileCount == 2) break; ushort[] tmparr = leveldata.Textile16[tileCount].Tile; Color[] cols = ColorTable[tileCount]; for (c16_index = 0; c16_index < c16_pixel_count; c16_index++) { //argb ushort ucolor = tmparr[c16_index]; if ((ucolor & 0x8000) == 0x8000) ////optimized bit shift and & operation ((ucolor >> 15) & 0x1) == 1 with direct & (ucolor & 0x8000) == 1 operation { cols[c16_index].a = 1.0f; } else { cols[c16_index].a = 0.0f; } //fix color conversion with range 0 - 31 cols[c16_index].b = (ucolor & 0x1f) * cmult; cols[c16_index].g = ((ucolor >> 5) & 0x1f) * cmult; cols[c16_index].r = ((ucolor >> 10) & 0x1f) * cmult; //Vector3 alpha_vec = new Vector3(cols[c16_index].r, cols[c16_index].g, cols[c16_index].b); //if(alpha_vec.magnitude <= 0.097) //{ //cols[c16_index].a = 0.0f; //} } //render transparancy information into tile int ntexObj = leveldata.ObjectTextures.Length; for (int i = 0; i < ntexObj; i++) { Parser.Tr2ObjectTexture texobj = leveldata.ObjectTextures[i]; // texobj.TransparencyFlags means geometry level transparancy, not pixel level transparency // this is used for geometry material batching if (texobj.Tile == tileCount && texobj.TransparencyFlags == 0) { //interpolate pixels //generate pixel bound Parser.Tr2ObjectTextureVertex[] vertices = texobj.Vertices; int minxi = vertices[0].Xpixel; int maxxi = vertices[0].Xpixel; int minyi = vertices[0].Ypixel; int maxyi = vertices[0].Ypixel; for (int v = 0; v < vertices.Length - 1; v++) { if (vertices[v].Xcoordinate < minxi) { minxi = vertices[v].Xpixel; } if (vertices[v].Xcoordinate > maxxi) { maxxi = vertices[v].Xpixel; } if (vertices[v].Ycoordinate < minyi) { minyi = vertices[v].Ypixel; } if (vertices[v].Ycoordinate > maxyi) { maxyi = vertices[v].Ypixel; } } //render transparancy in generated bound if (vertices.Length < 4) { Vector3 p0 = new Vector3(vertices[0].Xpixel, 0, vertices[0].Ypixel); Vector3 p1 = new Vector3(vertices[1].Xpixel, 0, vertices[1].Ypixel); Vector3 p2 = new Vector3(vertices[2].Xpixel, 0, vertices[2].Ypixel); for (int y = minyi; y < maxyi; y++) { for (int x = minxi; x < maxxi; x++) { if (IsUVInSide(p2, p1, p0, new Vector3(x, 0, y))) { int idx = y * 256 + x; cols[idx].a = 1; } } } } else { for (int y = minyi; y < maxyi; y++) { for (int x = minxi; x < maxxi; x++) { //if(IsUVInSide( p2, p1,p0, new Vector3(x,0, y) )) //{ int idx = y * 256 + x; cols[idx].a = 1; //} } } } } //end transparancy flag check } } //pack tiles float uvlength = 1.0f / (float)(leveldata.m_MaxTiles); //bug fixed: used leveldata.m_MaxTiles instead of hardcoded value 16 uvRects = new Rect[leveldata.m_MaxTiles]; Texture2D tex = new Texture2D(256, 256 * leveldata.m_MaxTiles, TextureFormat.ARGB32, false, true); tex.filterMode = FilterMode.Bilinear; tex.wrapMode = TextureWrapMode.Clamp; tex.anisoLevel = 9; for (int t = 0; t < leveldata.m_MaxTiles; t++) { Color[] cols = ColorTable[t]; uvRects[t] = new Rect(0, uvlength * t, 1, uvlength); //distorted uv error : reason careless uv stting tex.SetPixels(0, 256 * t, 256, 256, cols, 0); } tex.Apply(true); tex.name = "texAtlas"; tex.hideFlags = 0; return(tex); }
public static void Create() { //procedure to store last browsed path string path = PlayerPrefs.GetString("last_browsed_path", ""); if (path == "") { path = EditorUtility.OpenFilePanel("Open Tomb Raider II Level File (*.TR2)", Application.dataPath, "*.tr2; *.TR2"); } else { path = EditorUtility.OpenFilePanel("Open Tomb Raider II Level File (*.TR2)", path, "*.tr2; *.TR2"); } PlayerPrefs.SetString("last_browsed_path", Path.GetDirectoryName(path)); if (path != null) { Settings.LevelFileLocalPath = path; Parser.Tr2Level leveldata = LoadLevelFromFile(Settings.LevelFileLocalPath); if (leveldata != null) { leveldata.Camera = null; leveldata.Text3DPrefav = null; // generate shared texture Texture2D shared_texture = TextureUV.GenerateTextureTile(leveldata); if (!Directory.Exists(Application.dataPath + m_SharedTexturePath)) { Directory.CreateDirectory(Application.dataPath + m_SharedTexturePath); } //if(!File.Exists(Application.dataPath + "/Level Texture/" + Level.m_LevelName + ".png")) //File.WriteAllBytes(Application.dataPath + m_SharedTexturePath + Level.m_LevelName + ".png",shared_texture.EncodeToPNG()); FileStream fstream = File.Open(Application.dataPath + m_SharedTexturePath + m_LevelName + ".png", FileMode.OpenOrCreate, FileAccess.ReadWrite); BinaryWriter bw = new BinaryWriter(fstream); bw.Write(shared_texture.EncodeToPNG()); bw.Close(); //load shared texture //Refresh assete database for newly created texture AssetDatabase.Refresh(); TextureImporter teximp = TextureImporter.GetAtPath("Assets" + m_SharedTexturePath + m_LevelName + ".png") as TextureImporter; if (teximp == null) { EditorUtility.DisplayDialog("Error", "Assets" + m_SharedTexturePath + m_LevelName + ".png" + " is not found in Assets ", "OK"); return; } else { #if (UNITY_5_3_OR_NEWER || UNITY_5_3) teximp.alphaSource = TextureImporterAlphaSource.FromInput; teximp.filterMode = FilterMode.Bilinear; teximp.wrapMode = TextureWrapMode.Clamp; //teximp.sRGBTexture = true; teximp.textureType = TextureImporterType.Default; teximp.maxTextureSize = 4096; teximp.mipmapEnabled = false; teximp.textureCompression = TextureImporterCompression.Uncompressed; #else teximp.filterMode = FilterMode.Bilinear; teximp.grayscaleToAlpha = false; teximp.textureFormat = TextureImporterFormat.ARGB32; teximp.wrapMode = TextureWrapMode.Clamp; teximp.maxTextureSize = 4096; teximp.mipmapEnabled = false; #endif } //refresh assets to apply changes AssetDatabase.Refresh(); //reimport is need after import setting modification AssetDatabase.ImportAsset("Assets" + m_SharedTexturePath + m_LevelName + ".png"); //load shared material Material shared_material = (Material )AssetDatabase.LoadAssetAtPath("Assets" + m_SharedMaterialPath, typeof(Material)); if (shared_material == null) { EditorUtility.DisplayDialog("Error", "Assets" + m_SharedMaterialPath + " is not found in Assets ", "OK"); return; } shared_material.mainTexture = (Texture)AssetDatabase.LoadAssetAtPath("Assets" + m_SharedTexturePath + m_LevelName + ".png", typeof(Texture)); m_Level = BuildLevel(leveldata, shared_material, m_LevelName); } } }
public Level(Parser.Tr2Level leveldata, Material sharedmaterial, Transform roottransform) { m_LevelRoot = roottransform; m_leveldata = leveldata; //if (m_leveldata != null && m_leveldata.NumRooms > 0) { //TextureUV.GenerateTextureTile ismoved to Loader.cs for better responsibility managment //Trying to set assigned render material property, marks shared material as instance. //So change property of shared material before assign it to renderer. m_SharedMaterialWater = Resources.Load("water", typeof(Material)) as Material; m_SharedMaterialWaterHolder = Resources.Load("water_holder", typeof(Material)) as Material; Shader waterEffectShader = Resources.Load("WaterEffect", typeof(Shader)) as Shader; //init materials m_SharedMaterial = sharedmaterial; m_SharedMaterial.color = new Color(1f, 1f, 1f, 1.0f); m_SharedMaterial.SetFloat("_InSideWater", 0); m_SharedMaterial.SetFloat("_WaterPlaneY", 0); m_SharedMaterialWater.mainTexture = m_SharedMaterial.mainTexture; //m_SharedMaterialWater.color = new Color(0.045f, 0.075f,0.090f, 1) ; //should be set by user m_SharedMaterialWaterHolder.mainTexture = m_SharedMaterial.mainTexture; //m_SharedMaterialWaterHolder.color = new Color(0.45f * 0.5f, 0.75f * 0.5f, 0.90f * 0.5f, 1); m_SharedMaterialWaterHolder.SetFloat("_InSideWater", 0); m_RoomExs = new RoomEx[m_leveldata.NumRooms]; Transform PrefavContainer = new GameObject("PrefavContainer").transform; PrefavContainer.parent = m_LevelRoot; m_DynamicPrefabs = BuildDynamicPrefabObjects(PrefavContainer); m_StaticPrefabs = BuildStaticPrefabObjects(PrefavContainer); //determine animation clip size for each movable object for (int i = 0; i < m_DynamicPrefabs.Count - 1; i++) { int startoffset0 = m_DynamicPrefabs[i].Animation; int startoffset1 = m_DynamicPrefabs[i + 1].Animation; m_DynamicPrefabs[i].NumClips = startoffset1 - startoffset0; } if (m_DynamicPrefabs.Count > 0) { int startoffset0 = m_DynamicPrefabs[m_DynamicPrefabs.Count - 1].Animation; m_DynamicPrefabs[m_DynamicPrefabs.Count - 1].NumClips = (int)m_leveldata.NumAnimations - 1 - startoffset0; } //attach animation and their state change for (int i = 0; i < m_DynamicPrefabs.Count; i++) { List <TRAnimationClip> clips = Animator.AttachAnimation(m_DynamicPrefabs[i], m_leveldata); AnimationStateMapper.BuildMap(clips, m_DynamicPrefabs[i].UnityAnimation, m_leveldata); } //attach 3DText Box to movable objects to mark their ID if (Settings.ShowObjectID) { for (int i = 0; i < m_DynamicPrefabs.Count; i++) { if (m_leveldata.Text3DPrefav != null) { TextMesh text3d = (TextMesh)GameObject.Instantiate(m_leveldata.Text3DPrefav); text3d.transform.position = m_DynamicPrefabs[i].UnityObject.transform.position + Vector3.up * 1000 * Settings.SceneScaling; text3d.transform.parent = m_DynamicPrefabs[i].UnityObject.transform; text3d.characterSize = 100 * Settings.SceneScaling; text3d.text = "" + m_DynamicPrefabs[i].ObjectID; } } } //build rooms //container for water go Transform WaterContainer = new GameObject("WaterContainer").transform; WaterContainer.parent = m_LevelRoot; Transform RoomContainer = new GameObject("RoomContainer").transform; RoomContainer.parent = m_LevelRoot; for (int i = 0; i < m_leveldata.NumRooms; i++) { Parser.Tr2Room tr2room = leveldata.Rooms[i]; bool has_water = false; Mesh roommesh = MeshBuilder.CreateRoomMesh(tr2room, m_leveldata, ref has_water); Vector3 position = new Vector3(m_leveldata.Rooms[i].info.x, 0, m_leveldata.Rooms[i].info.z); GameObject go = CreateRoom(roommesh, position * Settings.SceneScaling, i, m_SharedMaterial, FloorAttribute.Solid); go.transform.parent = RoomContainer; m_RoomExs[i] = go.AddComponent <RoomEx>(); //build room object List <GameObject> objects = InstantiateStaticObjects(tr2room, i, go.transform); m_RoomExs[i].InitRoom(tr2room, objects); if ((tr2room.Flags & 1) == 1) //Is room water holder { //override water holder material //MeshFilter mf = go.GetComponent<MeshFilter>(); //mf.mesh = MeshModifier.VertexWeild(mf.mesh); MeshRenderer mr = go.GetComponent <MeshRenderer>(); mr.sharedMaterial = new Material(waterEffectShader); // Generate material instances for water holder using m_SharedMaterialWaterHolder mr.receiveShadows = false; Vector3 center = m_RoomExs[i].GetCenterPoint(); mr.sharedMaterial.SetFloat("_CenterX", center.x); mr.sharedMaterial.SetFloat("_CenterY", center.y); mr.sharedMaterial.SetFloat("_CenterZ", center.z); mr.sharedMaterial.SetFloat("_WaterPlaneY", Mathf.Infinity); mr.sharedMaterial.SetTexture("_MainTex", m_SharedMaterialWaterHolder.mainTexture); mr.sharedMaterial.SetColor("_Color", m_SharedMaterialWaterHolder.color); mr.sharedMaterial.SetFloat("_InSideWater", 0); m_InstancedMaterialWaterHolders.Add(mr.sharedMaterial); } else //regular room { } //create room water surface if (has_water) //surface? { //create water surface roommesh = MeshBuilder.CreateRoomWaterMesh(tr2room, m_leveldata); go = CreateRoom(roommesh, position * Settings.SceneScaling, i, m_SharedMaterialWater, FloorAttribute.Water); go.name = "water_" + i; go.transform.parent = WaterContainer; } } Transform ObjectContainer = new GameObject("ObjectContainer").transform; ObjectContainer.parent = m_LevelRoot; m_MovableInstances = InstantiateDynamicObjects(ObjectContainer); try // { SetupTrigers(); } catch (System.Exception e) { Debug.LogError(e.Message); } //attach components to m_MovableInstances for (int i = 0; i < m_MovableInstances.Count; i++) { InitialiseInstance(m_MovableInstances[i]); } } }
//param transformtree: number of transform used in animation clip //param startclipid : first animation clip index into Parser.Tr2Animation array //keyframeinfo: holds tr2 keyframes related info for an animation public static List <TRAnimationClip> CreateAnimationWithID(Tr2Moveable tr2movable, Transform[] transformtree, Parser.Tr2Level leveldata) { List <TRAnimationClip> tranimclips = new List <TRAnimationClip>(); int ntransform = transformtree.Length; int trclipoffset = tr2movable.AnimationStartOffset; Parser.TR2VersionType enginetype = leveldata.EngineVersion; //each tr anim actually information that reffer a chunk of animation frames contained in frames[] //each frame chunk contain sequential data [key] for all of the transform of this object //Now question is how many animation clips there are ? //KeyFrameData keyframeinfo = CalculateAnimationKeyFrameData(trclipoffset, leveldata); /*bool shortanimation = false; * if (keyframeinfo.numkeyframe < 15) * { * shortanimation = true; * } * * int nclip = 1; * if (tr2movable.ObjectID == 0) * { * nclip = 261; * * Debug.Log(" lara trclipoffset: " + trclipoffset); * } * * //Debug.Log("ID: " + tr2movable.ObjectID + " trclipoffset: " + trclipoffset); */ for (int clipid = 0; clipid < tr2movable.NumClips; clipid++) { //if(shortanimation && clipid > 5) break; KeyFrameData keyframeinfo = CalculateAnimationKeyFrameData(trclipoffset, leveldata); Parser.Tr2Animation tr2animation = leveldata.Animations[trclipoffset]; AnimationCurve curvRelX = null; AnimationCurve curvRelY = null; AnimationCurve curvRelZ = null; AnimationCurve[] curvRelRotX = new AnimationCurve[ntransform]; AnimationCurve[] curvRelRotY = new AnimationCurve[ntransform]; AnimationCurve[] curvRelRotZ = new AnimationCurve[ntransform]; AnimationCurve[] curvRelRotW = new AnimationCurve[ntransform]; //prepare curves for animation for (int transformId = 0; transformId < ntransform; transformId++) { //create curves curvRelRotX[transformId] = new AnimationCurve(null); curvRelRotY[transformId] = new AnimationCurve(null); curvRelRotZ[transformId] = new AnimationCurve(null); curvRelRotW[transformId] = new AnimationCurve(null); if (transformId == 0) { curvRelX = new AnimationCurve(null); curvRelY = new AnimationCurve(null); curvRelZ = new AnimationCurve(null); } } int numkeyframe = keyframeinfo.numkeyframe; for (int keyFrameCount = 0; keyFrameCount < numkeyframe; ++keyFrameCount) { int frameoffset = keyframeinfo.startoffset + (keyframeinfo.framesize * keyFrameCount); //extract key frme rotation int l = 9; //first angle offset in this Frame for (int transformId = 0; transformId < ntransform; transformId++) { ushort itmp = keyframeinfo.data[frameoffset + l]; ushort itmp2; double angle; float rotx = 0; float roty = 0; float rotz = 0; l = l + 1; if (enginetype == Parser.TR2VersionType.TombRaider_1) { // all angles are three-axis angle = (itmp >> 4) & 0x03ff; angle *= 360.0 / 1024.0; rotx = (float)angle; //keyframe rotx value itmp2 = (ushort)((itmp << 6) & 0x03c0); itmp = keyframeinfo.data[frameoffset + l]; // get Z rotation l = l + 1; itmp2 |= (ushort)((itmp >> 10) & 0x003f); angle = itmp2; angle *= 360.0 / 1024.0; roty = (float)angle; //keyframe roty value angle = itmp & 0x3ff; angle *= 360.0 / 1024.0; rotz = (float)angle; //keyframe rotz value } else if ((itmp & 0xc000) > 0) // TR2, TR3, TR4 - single axis of rotation { if (enginetype == Parser.TR2VersionType.TombRaider_4) { angle = itmp & 0x0fff; angle /= 4096.0; angle *= 360.0; } else { angle = itmp & 0x3ff; angle /= 1024.0; angle *= 360.0; } switch (itmp & 0xc000) { case 0x4000: rotx = (float)angle; break; case 0x8000: roty = (float)angle; break; case 0xc000: rotz = (float)angle; break; } } else // TR2, TR3, TR4 - three axes { angle = (itmp >> 4) & 0x03ff; angle *= 360.0 / 1024.0; rotx = (float)angle; itmp2 = (ushort)((itmp << 6) & 0x03c0); itmp = keyframeinfo.data[frameoffset + l]; // get Z rotation l = l + 1; itmp2 |= (ushort)((itmp >> 10) & 0x003f); angle = itmp2; angle *= 360.0 / 1024.0; roty = (float)angle; angle = itmp & 0x3ff; angle *= 360.0 / 1024.0; rotz = (float)angle; } //if(rotx > 180) //{ rotx = Mathf.Abs(360 - rotx); //} //if(rotz > 180) //{ rotz = Mathf.Abs(360 - rotz);; //} //if(roty > 180) //{ //roty= Mathf.Abs(360 - roty) ;; //} if (transformId == 0) { float ItemAnimX = (short)keyframeinfo.data[frameoffset + 6] * Settings.SceneScaling; float ItemAnimY = (short)keyframeinfo.data[frameoffset + 7] * Settings.SceneScaling; float ItemAnimZ = (short)keyframeinfo.data[frameoffset + 8] * Settings.SceneScaling; if (numkeyframe == 1) //addition key after last key { curvRelX.AddKey(0, ItemAnimX); curvRelY.AddKey(0, -ItemAnimY); curvRelZ.AddKey(0, ItemAnimZ); curvRelX.AddKey(1 * keyframeinfo.time_per_frame, ItemAnimX); curvRelY.AddKey(1 * keyframeinfo.time_per_frame, -ItemAnimY); curvRelZ.AddKey(1 * keyframeinfo.time_per_frame, ItemAnimZ); } else { int keylength = curvRelX.length; if (keylength > 0) { Keyframe kx = new Keyframe(keylength * keyframeinfo.time_per_frame, ItemAnimX, Mathf.Infinity, Mathf.Infinity); Keyframe ky = new Keyframe(keylength * keyframeinfo.time_per_frame, -ItemAnimY, Mathf.Infinity, Mathf.Infinity); Keyframe kz = new Keyframe(keylength * keyframeinfo.time_per_frame, ItemAnimZ, Mathf.Infinity, Mathf.Infinity); curvRelX.AddKey(kx); curvRelY.AddKey(ky); curvRelZ.AddKey(kz); } else { curvRelX.AddKey(0, ItemAnimX); curvRelY.AddKey(0, -ItemAnimY); curvRelZ.AddKey(0, ItemAnimZ); } } } //TODO: //multiply transform with reltive rotation and translation data //relative translation of animation. allready provided? //problem: animation transform works in local space.Thats mean it does not work on root?Am I working in root? Quaternion finalrot = Quaternion.AngleAxis(roty, Vector3.up) * Quaternion.AngleAxis(rotx, Vector3.right) * Quaternion.AngleAxis(rotz, Vector3.forward); if (numkeyframe == 1) //addition key after last key { curvRelRotX[transformId].AddKey(0, finalrot.x); curvRelRotY[transformId].AddKey(0, finalrot.y); curvRelRotZ[transformId].AddKey(0, finalrot.z); curvRelRotW[transformId].AddKey(0, finalrot.w); curvRelRotX[transformId].AddKey(keyframeinfo.time_per_frame, finalrot.x); curvRelRotY[transformId].AddKey(keyframeinfo.time_per_frame, finalrot.y); curvRelRotZ[transformId].AddKey(keyframeinfo.time_per_frame, finalrot.z); curvRelRotW[transformId].AddKey(keyframeinfo.time_per_frame, finalrot.w); } else { int keylength = curvRelRotX[transformId].length; if (keylength > 0) { //FIX: set outTangent and inTangent to Mathf.Infinity Keyframe kfrotx = new Keyframe(keylength * keyframeinfo.time_per_frame, finalrot.x, Mathf.Infinity, Mathf.Infinity); Keyframe kfroty = new Keyframe(keylength * keyframeinfo.time_per_frame, finalrot.y, Mathf.Infinity, Mathf.Infinity); Keyframe kfrotz = new Keyframe(keylength * keyframeinfo.time_per_frame, finalrot.z, Mathf.Infinity, Mathf.Infinity); Keyframe kfrotw = new Keyframe(keylength * keyframeinfo.time_per_frame, finalrot.w, Mathf.Infinity, Mathf.Infinity); curvRelRotX[transformId].AddKey(kfrotx); curvRelRotY[transformId].AddKey(kfroty); curvRelRotZ[transformId].AddKey(kfrotz); curvRelRotW[transformId].AddKey(kfrotw); } else { curvRelRotX[transformId].AddKey(0, finalrot.x); curvRelRotY[transformId].AddKey(0, finalrot.y); curvRelRotZ[transformId].AddKey(0, finalrot.z); curvRelRotW[transformId].AddKey(0, finalrot.w); } } } } AnimationClip animClip = new AnimationClip(); //if animClip is not set to legacy set curve will not workt on vesion 4 or higher #if UNITY_4_0 animClip.legacy = true; #elif UNITY_4_0_1 animClip.legacy = true; #elif UNITY_4_1 animClip.legacy = true; #elif UNITY_4_2 animClip.legacy = true; #elif UNITY_4_3 animClip.legacy = true; #elif UNITY_4_5 animClip.legacy = true; #elif UNITY_4_6 animClip.legacy = true; #elif UNITY_5_0 animClip.legacy = true; #endif #if (UNITY_5_3_OR_NEWER || UNITY_5_3) animClip.legacy = true; #endif for (int transformId = 0; transformId < ntransform; transformId++) { System.String relCurvePath = CalculateCurveRelativePath(transformtree[transformId]); //print("relCurvePath:"+relCurvePath); if (transformId != 0) { animClip.SetCurve(relCurvePath, typeof(Transform), "localRotation.x", curvRelRotX[transformId]); animClip.SetCurve(relCurvePath, typeof(Transform), "localRotation.y", curvRelRotY[transformId]); animClip.SetCurve(relCurvePath, typeof(Transform), "localRotation.z", curvRelRotZ[transformId]); animClip.SetCurve(relCurvePath, typeof(Transform), "localRotation.w", curvRelRotW[transformId]); } else { animClip.SetCurve(relCurvePath, typeof(Transform), "localRotation.x", curvRelRotX[transformId]); animClip.SetCurve(relCurvePath, typeof(Transform), "localRotation.y", curvRelRotY[transformId]); animClip.SetCurve(relCurvePath, typeof(Transform), "localRotation.z", curvRelRotZ[transformId]); animClip.SetCurve(relCurvePath, typeof(Transform), "localRotation.w", curvRelRotW[transformId]); animClip.SetCurve(relCurvePath, typeof(Transform), "localPosition.x", curvRelX); animClip.SetCurve(relCurvePath, typeof(Transform), "localPosition.y", curvRelY); animClip.SetCurve(relCurvePath, typeof(Transform), "localPosition.z", curvRelZ); } } TRAnimationClip tranimclip = new TRAnimationClip(animClip, leveldata.Animations[clipid].StateID); tranimclip.time_per_frame = keyframeinfo.time_per_frame; tranimclip.starttime = 0.0f; tranimclip.endtime = keyframeinfo.numkeyframe * tranimclip.time_per_frame; tranimclip.framerate = 7 - tr2animation.FrameRate;// 1f / tranimclip.time_per_frame ; tranimclip.index = clipid; tranimclip.start_animation_frame_index = keyframeinfo.start_animation_frame_index; tranimclips.Add(tranimclip); //goto next clip trclipoffset++; } return(tranimclips); }
public Level(Parser.Tr2Level leveldata) { m_leveldata = leveldata; m_LevelRoot = new GameObject ("Level " + m_LevelName); //m_LevelRoot.AddComponent(typeof (MeshFilter)); //m_LevelRoot.AddComponent(typeof (MeshRenderer)); if(m_leveldata!=null && m_leveldata.NumRooms > 0) { m_LevelTextureTile = TextureUV.GenerateTextureTile (m_leveldata); m_RoomExs = new RoomEx[m_leveldata.NumRooms]; m_DynamicPrefabs = BuildDynamicPrefabObjects(); m_StaticPrefabs = BuildStaticPrefabObjects(); //determine animation clip size for each movable object for(int i = 0; i < m_DynamicPrefabs.Count - 1; i++) { int startoffset0 = m_DynamicPrefabs[i].Animation; int startoffset1 = m_DynamicPrefabs[i + 1].Animation; m_DynamicPrefabs[i].NumClips = startoffset1 - startoffset0; } if(m_DynamicPrefabs.Count > 0) { int startoffset0 = m_DynamicPrefabs[m_DynamicPrefabs.Count - 1].Animation; m_DynamicPrefabs[m_DynamicPrefabs.Count - 1].NumClips = (int) m_leveldata.NumAnimations - 1 - startoffset0; } //attach animation and their state change for(int i = 0; i < m_DynamicPrefabs.Count; i++) { List<TRAnimationClip> clips = Animator.AttachAnimation(m_DynamicPrefabs[i], m_leveldata); AnimationStateMapper.BuildMap(clips, m_DynamicPrefabs[i].UnityAnimation, m_leveldata); } //attach 3DText Box to movable objects to mark their ID if(Settings.ShowObjectID) { for(int i = 0; i < m_DynamicPrefabs.Count; i++) { if(m_leveldata.Text3DPrefav!=null) { TextMesh text3d = (TextMesh)GameObject.Instantiate(m_leveldata.Text3DPrefav); text3d.transform.position = m_DynamicPrefabs[i].UnityObject.transform.position + Vector3.up * 1000; text3d.transform.parent = m_DynamicPrefabs[i].UnityObject.transform; text3d.characterSize = 100; text3d.text = "" + m_DynamicPrefabs[i].ObjectID; } } } //build rooms for(int i = 0 ; i < m_leveldata.NumRooms; i++) { Parser.Tr2Room tr2room = leveldata.Rooms[i]; Mesh roommesh = MeshBuilder.CreateRoomMesh(tr2room, m_leveldata); Vector3 position = new Vector3(m_leveldata.Rooms[i].info.x,0,m_leveldata.Rooms[i].info.z); GameObject go = CreateRoom(roommesh, position, i); go.transform.parent = m_LevelRoot.transform; m_RoomExs[i] = go.AddComponent<RoomEx>(); //build room object List <GameObject> objects = InstantiateStaticObjects(tr2room, i); m_RoomExs[i].InitRoom(tr2room, objects); } m_MovableInstances = InstantiateDynamicObjects(); SetupTrigers(); //attach components to m_MovableInstances for(int i = 0; i < m_MovableInstances.Count; i++) { InitialiseInstance(m_MovableInstances[i]); } } }
public static Mesh CreateRoomWaterMesh(Parser.Tr2Room tr2room, Parser.Tr2Level leveldata) { Vector3[] sharedVertices = null; byte[] is_water_vertex = null; bool has_water = false; if (tr2room.RoomData.NumVertices > 0) { int NumVertices = tr2room.RoomData.NumVertices; sharedVertices = new Vector3[NumVertices]; is_water_vertex = new byte[sharedVertices.Length]; Parser.Tr2VertexRoom[] Vertices = tr2room.RoomData.Vertices; for (int vertAttribCount = 0; vertAttribCount < NumVertices; vertAttribCount++) { float x = Vertices[vertAttribCount].Vertex.x; float y = Vertices[vertAttribCount].Vertex.y; float z = Vertices[vertAttribCount].Vertex.z; ////print("chk vtx x y z:" +x+ " " +y + " " +z); sharedVertices[vertAttribCount].x = x; sharedVertices[vertAttribCount].y = -y; sharedVertices[vertAttribCount].z = z; is_water_vertex[vertAttribCount] = 10; if ((Vertices[vertAttribCount].Attributes & 0x8000L) == 0x8000L) { is_water_vertex[vertAttribCount] = 1; has_water = true; } } } //warning: avariable lengh array in a structure can cause access violence //if(tr2room.RoomData.NumRectangles > 0) //{ //selected_texObjectIdx = tr2room.RoomData.Rectangles[0].Texture; //selected_texObj = leveldata.ObjectTextures[selected_texObjectIdx]; //selected_texTileIdx = selected_texObj.Tile; int NumRectangles = tr2room.RoomData.NumRectangles; int strideVertIdx = (NumRectangles * 4); int strideTriIdx = (NumRectangles * 3 * 2); int numNonsharedVertices = strideVertIdx + (tr2room.RoomData.NumTriangles * 3); int numNonsharedTris = strideTriIdx + (tr2room.RoomData.NumTriangles * 3); Vector3[] nonSharedVertices = new Vector3[numNonsharedVertices]; Vector2[] nonSharedUVs = new Vector2[numNonsharedVertices]; Vector2[] nonSharedUV2s = new Vector2[numNonsharedVertices]; int[] nonSharedTris = new int[numNonsharedTris]; Parser.Tr2Face4[] Rectangles = tr2room.RoomData.Rectangles; for (int rectCount = 0; rectCount < NumRectangles; rectCount++) { int Idx0 = Rectangles[rectCount].Vertices0; int Idx1 = Rectangles[rectCount].Vertices1; int Idx2 = Rectangles[rectCount].Vertices2; int Idx3 = Rectangles[rectCount].Vertices3; ////print ("idx0 - Idx1 - Idx2 - Idx3:" + Idx0 + " " + Idx1 + " " + Idx2 +" " + Idx3); int vertOrUVIdx0 = rectCount * 4 + 0; int vertOrUVIdx1 = rectCount * 4 + 1; int vertOrUVIdx2 = rectCount * 4 + 2; int vertOrUVIdx3 = rectCount * 4 + 3; if (has_water) { if (!IsFaceInWater(is_water_vertex, Idx0, Idx1, Idx2, Idx3)) //if not all vertices are in water { continue; } } else { if (!IsFaceInWater(leveldata, Rectangles[rectCount].Texture)) { continue; } } nonSharedVertices[vertOrUVIdx0] = sharedVertices[Idx0]; nonSharedVertices[vertOrUVIdx1] = sharedVertices[Idx1]; nonSharedVertices[vertOrUVIdx2] = sharedVertices[Idx2]; nonSharedVertices[vertOrUVIdx3] = sharedVertices[Idx3]; ushort texObjectIdx = Rectangles[rectCount].Texture; if (texObjectIdx >= leveldata.ObjectTextures.Length) { continue; //fixed: outof bound exception for Parser.Tr2Level.ObjectTextures } Parser.Tr2ObjectTexture texObj = leveldata.ObjectTextures[texObjectIdx]; ushort texTileIdx = texObj.Tile; //bind this textile in material? //if(texTileIdx != prevTexture) //{ //newMatCount +=1; //prevTexture = texTileIdx; ////print("newMatCount:"+ newMatCount); //} SetFaceUVs(nonSharedUVs, vertOrUVIdx0, vertOrUVIdx1, vertOrUVIdx2, vertOrUVIdx3, texObj); ////print("uv[Idx0]"+ uv[Idx0].x + " " + uv[Idx0].y); ////print("uv[Idx1]"+ uv[Idx1].x + " " + uv[Idx1].y); //ushort opacity = texObj.TransparencyFlags; //isItOpacq //generate secondary uv for animation by going through all animated texture group and checking existance of //texObjectIdx in that group //leveldata.AnimatedTextures[] // this is varable length record of animated texture group int texture_idx = GetAnimatedTextureIndex(leveldata.AnimatedTextures, leveldata.NumAnimatedTextures, texObjectIdx); if (texture_idx > -1) { texObj = leveldata.ObjectTextures[texture_idx]; SetFaceUVs(nonSharedUV2s, vertOrUVIdx0, vertOrUVIdx1, vertOrUVIdx2, vertOrUVIdx3, texObj); } nonSharedTris[rectCount * 6 + 0] = vertOrUVIdx0; nonSharedTris[rectCount * 6 + 1] = vertOrUVIdx1; nonSharedTris[rectCount * 6 + 2] = vertOrUVIdx2; nonSharedTris[rectCount * 6 + 3] = vertOrUVIdx2; nonSharedTris[rectCount * 6 + 4] = vertOrUVIdx3; nonSharedTris[rectCount * 6 + 5] = vertOrUVIdx0; } int NumTriangles = tr2room.RoomData.NumTriangles; Parser.Tr2Face3[] Triangles = tr2room.RoomData.Triangles; for (int triCount = 0; triCount < tr2room.RoomData.NumTriangles; triCount++) { ////print("tr2room.RoomData.NumTriangles"+ tr2room.RoomData.NumTriangles); int Idx0 = Triangles[triCount].Vertices0; int Idx1 = Triangles[triCount].Vertices1; int Idx2 = Triangles[triCount].Vertices2; ////print ("idx0 - Idx1 - Idx2:" + Idx0 + " " + Idx1 + " " + Idx2); //[][][][]+[][][] int vertOrUVIdx0 = triCount * 3 + 0; int vertOrUVIdx1 = triCount * 3 + 1; int vertOrUVIdx2 = triCount * 3 + 2; if (has_water) { if (!IsFaceInWater(is_water_vertex, Idx0, Idx1, Idx2)) //if not all vertices are in water { continue; } } else { if (!IsFaceInWater(leveldata, Triangles[triCount].Texture)) { continue; } } nonSharedVertices[strideVertIdx + vertOrUVIdx0] = sharedVertices[Idx0]; nonSharedVertices[strideVertIdx + vertOrUVIdx1] = sharedVertices[Idx1]; nonSharedVertices[strideVertIdx + vertOrUVIdx2] = sharedVertices[Idx2]; ushort texObjectIdx = Triangles[triCount].Texture; if (texObjectIdx >= leveldata.ObjectTextures.Length) { continue; //fixed: outof bound exception for Parser.Tr2Level.ObjectTextures } Parser.Tr2ObjectTexture texObj = leveldata.ObjectTextures[texObjectIdx]; //if(texTileIdx != prevTexture) //{ //newMatCount +=1; //prevTexture = texTileIdx; ////print("newMatCount:"+ newMatCount); //} SetFaceUVs(nonSharedUVs, strideVertIdx + vertOrUVIdx0, strideVertIdx + vertOrUVIdx1, strideVertIdx + vertOrUVIdx2, texObj); int texture_idx = GetAnimatedTextureIndex(leveldata.AnimatedTextures, leveldata.NumAnimatedTextures, texObjectIdx); if (texture_idx > -1) { texObj = leveldata.ObjectTextures[texture_idx]; SetFaceUVs(nonSharedUV2s, strideVertIdx + vertOrUVIdx0, strideVertIdx + vertOrUVIdx1, strideVertIdx + vertOrUVIdx2, texObj); } ////print("uv[Idx0]"+ uv[Idx0].x + " " + uv[Idx0].y); ////print("uv[Idx1]"+ uv[Idx1].x + " " + uv[Idx1].y); //ushort opacity = texObj.TransparencyFlags; //isItOpacq nonSharedTris[strideTriIdx + vertOrUVIdx0] = strideVertIdx + vertOrUVIdx0; nonSharedTris[strideTriIdx + vertOrUVIdx1] = strideVertIdx + vertOrUVIdx1; nonSharedTris[strideTriIdx + vertOrUVIdx2] = strideVertIdx + vertOrUVIdx2; ////print ("idx0 - Idx1 - Idx2:" + nonSharedTris[strideTriIdx + vertOrUVIdx0] + " " + nonSharedTris[strideTriIdx + vertOrUVIdx1] + " " + nonSharedTris[strideTriIdx + vertOrUVIdx2] ); } ////print("leveldata.Rooms[5].RoomData.NumRectangles:"+ tr2room.RoomData.NumRectangles); //SetTriangles (triangles : int[], submesh : int) : void //generate secondary uv set for (int i = 0; i < nonSharedVertices.Length; i++) { nonSharedVertices[i] = nonSharedVertices[i] * Settings.SceneScaling; } Mesh mesh = new Mesh(); mesh.Clear(); mesh.vertices = nonSharedVertices; mesh.uv = nonSharedUVs; mesh.uv2 = nonSharedUV2s; mesh.triangles = nonSharedTris; //mesh.Optimize(); mesh.RecalculateNormals(); #if UNITY_EDITOR Vector4[] tangents = new Vector4[mesh.vertices.Length]; computeTangentsAndBinormals(nonSharedVertices, mesh.normals, nonSharedUVs, nonSharedTris, tangents); mesh.tangents = tangents; tangents = null; #endif //free some memory nonSharedVertices = null; nonSharedUVs = null; nonSharedUV2s = null; nonSharedTris = null; //} return(mesh); }