Example #1
0
    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];
        }
    }
Example #3
0
    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);
    }
Example #4
0
    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");
        }
    }
Example #5
0
    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);
    }
Example #6
0
    static bool IsFaceInWater(Parser.Tr2Level level, ushort SearchIndex)
    {
        if (GetAnimatedTextureIndex(level.AnimatedTextures, level.NumAnimatedTextures, SearchIndex) != SearchIndex)
        {
            return(true);
        }

        return(false);
    }
Example #7
0
    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);
    }
Example #8
0
    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);
    }
Example #9
0
    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);
    }
Example #10
0
    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);
    }
Example #11
0
    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
    }
Example #12
0
    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);
    }
Example #13
0
    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);
            }
        }
    }
Example #14
0
    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]);
            }
        }
    }
Example #15
0
    //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);
    }
Example #16
0
    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]);
            }

        }
    }
Example #17
0
    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);
    }