Пример #1
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++)
        {

            #if  UNITY_4_0
            clips[ci].clip.legacy = true;
            #elif  UNITY_4_0_1
            clips[ci].clip.legacy = true;
            #elif UNITY_4_1
            clips[ci].clip.legacy = true;
            #elif UNITY_4_2
            clips[ci].clip.legacy = true;
            #elif UNITY_4_3
            clips[ci].clip.legacy = true;
            #elif  UNITY_4_5
            clips[ci].clip.legacy = true;
            #elif UNITY_4_6
            clips[ci].clip.legacy = true;
            #elif UNITY_5_0
            clips[ci].clip.legacy = true;
            #endif
            tr2movable.UnityAnimation.AddClip(clips[ci].clip, "" + ci);
            tr2movable.AnimClips.Add(clips[ci]);
        }
        return clips;
    }
Пример #2
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);
    }
Пример #3
0
    GameObject[] CreateMultiPartObject(Tr2Moveable tr2movable)
    {
        GameObject[] parts = new GameObject[tr2movable.NumMeshes];
        // run through all the meshes init transforms
        for (int i = 0; i < tr2movable.NumMeshes; i++)
        {
            int itemMeshIdx = (int)(tr2movable.StartingMesh + i); // mesh id in tr2  mesh table
            if (itemMeshIdx > m_leveldata.NumMeshes - 1)
            {
                itemMeshIdx = (int)(m_leveldata.NumMeshes - 1);
            }

            parts[i] = CreateObjectWithID(itemMeshIdx, Vector3.zero, Quaternion.identity, "objPart:" + itemMeshIdx);
            parts[i].transform.parent = null;
        }

        return(parts);
    }
Пример #4
0
    GameObject[] CreateMultiPartObject(Tr2Moveable tr2movable)
    {
        GameObject[] parts = new GameObject[tr2movable.NumMeshes];
        // run through all the meshes init transforms
        for (int i = 0; i < tr2movable.NumMeshes; i++)
        {
            int itemMeshIdx =	(int)(tr2movable.StartingMesh + i); // mesh id in tr2  mesh table
            if(itemMeshIdx > m_leveldata.NumMeshes-1)
            {
                itemMeshIdx = (int)(m_leveldata.NumMeshes-1);
            }

            parts[i] = CreateObjectWithID(itemMeshIdx, Vector3.zero, Quaternion.identity, "objPart:" + itemMeshIdx);
            parts[i].transform.parent = null;

        }

        return parts;
    }
Пример #5
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);
    }
Пример #6
0
    //Raw structure data casting is problematice in C#. So break down a structure to it's fields and read them individually. This looks
    //ugly but works : )
    static object Cast2Struct(byte[] buffer, System.Type type)
    {
        object retval = null;
        if(type ==  typeof(Tr2RoomInfo))
        {
            Tr2RoomInfo t = new Tr2RoomInfo();
            t.x = System.BitConverter.ToInt32(buffer,0);
            t.z = System.BitConverter.ToInt32(buffer,4);
            t.yBottom = System.BitConverter.ToInt32(buffer,8);
            t.yTop = System.BitConverter.ToInt32(buffer,8);
            retval = t;
        }
        else if(type==  typeof(Tr2VertexRoom))
        {
            Tr2VertexRoom t = new Tr2VertexRoom();
            t.Vertex.x = System.BitConverter.ToInt16(buffer,0);
            t.Vertex.y = System.BitConverter.ToInt16(buffer,2);
            t.Vertex.z = System.BitConverter.ToInt16(buffer,4);
            t.Lighting1 =  System.BitConverter.ToInt16(buffer,6);    // values range from 0 to 32767, 0=total darkness. (TR3)
            // I think the values ranged from 0 to 8192 in TR1/2, 0=total brightness
            t.Attributes =  System.BitConverter.ToUInt16(buffer,8);   // 0x8000 something to do with water surface
            // 0x4000 under water lighting modulation and movement if viewed from above water surface
            // 0x2000 water/quicksand surface movement
            // 0x1fef nothing?
            // 0x0010 everything?
            t.Lighting2 =  System.BitConverter.ToInt16(buffer,10);     // seems to be the same as lighting1
            retval = t;
        }
        else if(type ==  typeof(Tr2Vertex))
        {
            Tr2Vertex  t = new Tr2Vertex();
            t.x = System.BitConverter.ToInt16(buffer,0);
            t.y = System.BitConverter.ToInt16(buffer,2);
            t.z = System.BitConverter.ToInt16(buffer,4);
            retval = t;
        }
        else if(type ==  typeof(Tr2RoomSector))
        {
            Tr2RoomSector  t = new Tr2RoomSector();
            t.FDindex = System.BitConverter.ToUInt16(buffer,0);
            t.BoxIndex = System.BitConverter.ToUInt16(buffer,2);
            t.RoomBelow = buffer[4];       // 255 if none
            t.Floor =(sbyte) buffer[5];    //char ==2 byte in c# here; chaqnge it to byte
            t.RoomAbove = buffer[6];       // 255 if none
            t.Ceiling = (sbyte) buffer[7];
            retval = t;
        }
        else if(type ==  typeof(Tr2RoomLight))
        {
            Tr2RoomLight  t = new Tr2RoomLight();
            t.x =  System.BitConverter.ToInt32(buffer,0);
            t.y =  System.BitConverter.ToInt32(buffer,4);
            t.z =  System.BitConverter.ToInt32(buffer,8);
            t.Intensity1 =  System.BitConverter.ToUInt16(buffer,12);
            t.Intensity2 =  System.BitConverter.ToUInt16(buffer,14);
            t.Fade1 = System.BitConverter.ToUInt32(buffer,16);
            t.Fade2  = System.BitConverter.ToUInt32(buffer,20);
            retval = t;
        }
        else if(type ==  typeof(Tr2RoomStaticMesh))
        {
            Tr2RoomStaticMesh  t = new Tr2RoomStaticMesh();
            t.x =  System.BitConverter.ToInt32(buffer,0);              // absolute position in world coordinates
            t.y =  System.BitConverter.ToInt32(buffer,4);
            t.z =  System.BitConverter.ToInt32(buffer,8);
            t.Rotation =  System.BitConverter.ToUInt16(buffer,12);      // high two bits (0xc000) indicate steps of 90 degrees
            t.Intensity1 =  System.BitConverter.ToUInt16(buffer,14);
            t.Intensity2 =  System.BitConverter.ToUInt16(buffer,16);
            t.ObjectID  =  System.BitConverter.ToUInt16(buffer,18);     // which StaticMesh item to draw
            retval = t;
        }
        else if(type ==  typeof(Tr2RoomSprite))
        {
            Tr2RoomSprite  t = new Tr2RoomSprite();
            t.Vertex = System.BitConverter.ToInt16(buffer,0);     // offset into vertex list
            t.Texture = System.BitConverter.ToInt16(buffer,2);    // offset into texture list
            retval = t;
        }
        else if(type ==  typeof(Tr2Face4))
        {
            Tr2Face4  t = new Tr2Face4();
            t.Vertices0 =  System.BitConverter.ToUInt16(buffer,0);
            t.Vertices1 =  System.BitConverter.ToUInt16(buffer,2);
            t.Vertices2 =  System.BitConverter.ToUInt16(buffer,4);
            t.Vertices3 =  System.BitConverter.ToUInt16(buffer,6);
            t.Texture =  System.BitConverter.ToUInt16(buffer,8);
            retval = t;
        }
        else if(type==  typeof(Tr2Face3))
        {
            Tr2Face3  t = new Tr2Face3();
            t.Vertices0 =  System.BitConverter.ToUInt16(buffer,0);
            t.Vertices1 =  System.BitConverter.ToUInt16(buffer,2);
            t.Vertices2 =  System.BitConverter.ToUInt16(buffer,4);
            t.Texture =  System.BitConverter.ToUInt16(buffer,6);
            retval = t;
        }
        else if(type ==  typeof(Tr2Animation))
        {
            Tr2Animation  t = new Tr2Animation();
            t.FrameOffset =  System.BitConverter.ToUInt32(buffer,0);     // byte offset into Frames[] (divide by 2 for Frames[i])
            t.FrameRate =  buffer[4];                                    // "ticks" per frame
            t.FrameSize = buffer[5];                                      // number of words in Frames[] used by this animation
            t.StateID =  System.BitConverter.ToInt16(buffer,6);
            t.Unknown1 =  System.BitConverter.ToInt16(buffer,8);
            t.Unknown2 =  System.BitConverter.ToInt16(buffer,10);
            t.Unknown3 =  System.BitConverter.ToInt16(buffer,12);
            t.Unknown4 =  System.BitConverter.ToInt16(buffer,14);
            t.FrameStart =  System.BitConverter.ToUInt16(buffer,16);      // first frame in this animation
            t.FrameEnd =  System.BitConverter.ToUInt16(buffer,18);        // last frame in this animation (numframes = (End - Start) + 1)
            t.NextAnimation =  System.BitConverter.ToUInt16(buffer,20);
            t.NextFram =  System.BitConverter.ToUInt16(buffer,22);
            t.NumStateChanges =  System.BitConverter.ToUInt16(buffer,24);
            t.StateChangeOffset =  System.BitConverter.ToUInt16(buffer,26);  // offset into StateChanges[]
            t.NumAnimCommands =  System.BitConverter.ToUInt16(buffer,28);
            t.AnimCommand =  System.BitConverter.ToUInt16(buffer,30);        // offset into AnimCommands[]
            retval = t;
        }
        else if(type ==  typeof(Tr2StateChange))
        {
            Tr2StateChange  t = new Tr2StateChange();
            t.StateID  =  System.BitConverter.ToUInt16(buffer,0);  ;
            t.NumAnimDispatches  =  System.BitConverter.ToUInt16(buffer,2);  ;  // number of dispatches (seems to always be 1..5)
            t.AnimDispatch  =  System.BitConverter.ToUInt16(buffer,4);  ;       // Offset into AnimDispatches[]
            retval = t;
        }
        else if(type ==  typeof(Tr2AnimDispatch))
        {

            Tr2AnimDispatch  t = new Tr2AnimDispatch();
            t.Low =  System.BitConverter.ToInt16(buffer,0);
            t.High =  System.BitConverter.ToInt16(buffer,2);;
            t.NextAnimation =  System.BitConverter.ToInt16(buffer,4);;
            t.NextFrame =  System.BitConverter.ToInt16(buffer,6);;
            retval = t;
        }
        else if(type ==  typeof(Tr2AnimCommand))
        {
            Tr2AnimCommand  t = new Tr2AnimCommand();
            t.Value = System.BitConverter.ToInt16(buffer,0);;
            retval = t;
        }
        else if(type ==  typeof(Tr2Moveable))
        {
            Tr2Moveable  t = new Tr2Moveable();
            t.ObjectID =  System.BitConverter.ToUInt32(buffer,0);        // Item Identifier
            t.NumMeshes =  System.BitConverter.ToUInt16(buffer,4);       // number of meshes in this object
            t.StartingMesh =  System.BitConverter.ToUInt16(buffer,6);    // first mesh
            t.MeshTree =  System.BitConverter.ToUInt32(buffer,8);        // offset into MeshTree[]
            t.FrameOffset =  System.BitConverter.ToUInt32(buffer,12);    // byte offset into Frames[] (divide by 2 for Frames[i])
            t.Animation =  System.BitConverter.ToUInt16(buffer,16);      // offset into Animations[]
            retval = t;

        }
        else if(type ==  typeof(Tr2ObjectTextureVertex))
        {
            Tr2ObjectTextureVertex t = new Tr2ObjectTextureVertex();
            t.Xcoordinate = buffer[0];
            t.Xpixel = buffer[1];
            t.Ycoordinate = buffer[2];
            t.Ypixel = buffer[3];
            retval = t;
        }
        else if(type ==  typeof(Tr2SpriteTexture))
        {
            Tr2SpriteTexture t = new Tr2SpriteTexture();
            t.Tile =  System.BitConverter.ToUInt16(buffer,0);
            t.x = buffer[2];
            t.y = buffer[3];
            t.Width =  System.BitConverter.ToUInt16(buffer,4);     // actually, (width * 256) + 255
            t.Height =  System.BitConverter.ToUInt16(buffer,6);    // actually, (height * 256) + 255
            t.LeftSide =  System.BitConverter.ToInt16(buffer,8);
            t.TopSide =  System.BitConverter.ToInt16(buffer,10);
            t.RightSide =  System.BitConverter.ToInt16(buffer,12);
            t.Bottomside =  System.BitConverter.ToInt16(buffer,14);
            retval = t;
        }
        else if(type ==  typeof(Tr2SpriteSequence))
        {
            Tr2SpriteSequence t = new Tr2SpriteSequence();
            t.ObjectID =  System.BitConverter.ToInt32(buffer,0);         // Item identifier (same numbering as in tr2_moveable)
            t.NegativeLength =  System.BitConverter.ToInt16(buffer,4);   // negative of "how many sprites are in this sequence"
            t.Offset =  System.BitConverter.ToInt16(buffer,6);           // where (in sprite texture list) this sequence starts
            retval = t;
        }
        else if(type ==  typeof(Tr2Camera))
        {
            Tr2Camera t = new Tr2Camera();
            t.x  =  System.BitConverter.ToInt32(buffer,0);
            t.y  =  System.BitConverter.ToInt32(buffer,4);
            t.z  =  System.BitConverter.ToInt32(buffer,8);
            t.Room  =  System.BitConverter.ToInt16(buffer,12);
            t.Unknown1  =  System.BitConverter.ToUInt16(buffer,14);        // correlates to Boxes[]?
            retval = t;
        }
        else if(type ==  typeof(Tr2SoundSource))
        {
            Tr2SoundSource t =new Tr2SoundSource();
            t.x =  System.BitConverter.ToInt32(buffer,0);;                 // position of sound source
            t.y =  System.BitConverter.ToInt32(buffer,4);;
            t.z =  System.BitConverter.ToInt32(buffer,8);;
            t.SoundID =  System.BitConverter.ToUInt16(buffer,12);;         // internal sound index
            t.Flags =  System.BitConverter.ToUInt16(buffer,14);;  ;        // 0x40, 0x80, or 0xc0
            retval = t;
        }
        else if(type ==  typeof(Tr2BBox))
        {
            Tr2BBox t = new Tr2BBox();
            t.Zmin = buffer[0];             // sectors (* 1024 units)
            t.Zmax = buffer[1];
            t.Xmin = buffer[2];
            t.Xmax = buffer[3];
            t.TrueFloor =  System.BitConverter.ToInt16(buffer,4);        // Y value (no scaling)
            t.OverlapIndex =  System.BitConverter.ToInt16(buffer,6);     // index into Overlaps[]
            retval = t;
        }
        else if(type ==  typeof(Tr2Item))
        {
            Tr2Item t = new Tr2Item();
            t.ObjectID  =  System.BitConverter.ToInt16(buffer,0); ;
            t.Room  =  System.BitConverter.ToInt16(buffer,2); ;
            t.x  =  System.BitConverter.ToInt32(buffer,4); ;
            t.y  =  System.BitConverter.ToInt32(buffer,8); ;
            t.z  =  System.BitConverter.ToInt32(buffer,12); ;
            t.Angle  =  System.BitConverter.ToInt16(buffer,16); ;
            t.Intensity1  =  System.BitConverter.ToInt16(buffer,18); ;
            t.Intensity2  =  System.BitConverter.ToInt16(buffer,20); ;
            t.Flags  =  System.BitConverter.ToInt16(buffer,22); ;         // 0x0100 indicates "inactive" or "invisible"
            retval = t;
        }
        else if(type ==  typeof(Tr2CinematicFrame))
        {
            Tr2CinematicFrame t = new Tr2CinematicFrame();
            t.rotY = System.BitConverter.ToInt16(buffer,2);
            t.rotZ = System.BitConverter.ToInt16(buffer,2);
            t.rotZ2 = System.BitConverter.ToInt16(buffer,2);
            t.posZ = System.BitConverter.ToInt16(buffer,2);
            t.posY = System.BitConverter.ToInt16(buffer,2);
            t.posX = System.BitConverter.ToInt16(buffer,2);
            t.Unknown1 = System.BitConverter.ToInt16(buffer,2);
            t.rotX= System.BitConverter.ToInt16(buffer,2);
        }

        return retval;
    }
Пример #7
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);

        //[0][0][0][0][0][0][0][0][0][0]
        for(int clipid = 0; clipid < tr2movable.NumClips; clipid++)
        {
            //if(shortanimation && clipid > 5) break;

            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];
                        float ItemAnimY = (short)keyframeinfo.data[frameoffset + 7];
                        float ItemAnimZ = (short)keyframeinfo.data[frameoffset + 8];

                        if(numkeyframe == 1) //addition key after last key
                        {
                            curvRelX.AddKey(0, ItemAnimX);
                            curvRelY.AddKey(0, -ItemAnimY);
                            curvRelZ.AddKey(0, ItemAnimZ);

                            curvRelX.AddKey(1 * keyframeinfo.framerate, ItemAnimX);
                            curvRelY.AddKey(1 * keyframeinfo.framerate, -ItemAnimY);
                            curvRelZ.AddKey(1 * keyframeinfo.framerate, ItemAnimZ);
                        }
                        else
                        {
                            int keylength = curvRelX.length;
                            if(keylength > 0)
                            {

                                Keyframe kx = new Keyframe(keylength * keyframeinfo.framerate, ItemAnimX,Mathf.Infinity,Mathf.Infinity);
                                Keyframe ky = new Keyframe(keylength * keyframeinfo.framerate, -ItemAnimY,Mathf.Infinity,Mathf.Infinity);
                                Keyframe kz = new Keyframe(keylength * keyframeinfo.framerate, 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.framerate, finalrot.x);
                        curvRelRotY[transformId].AddKey(keyframeinfo.framerate, finalrot.y);
                        curvRelRotZ[transformId].AddKey(keyframeinfo.framerate, finalrot.z);
                        curvRelRotW[transformId].AddKey(keyframeinfo.framerate, 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.framerate, finalrot.x,Mathf.Infinity,Mathf.Infinity);
                            Keyframe kfroty = new Keyframe(keylength * keyframeinfo.framerate, finalrot.y,Mathf.Infinity,Mathf.Infinity);
                            Keyframe kfrotz = new Keyframe(keylength * keyframeinfo.framerate, finalrot.z,Mathf.Infinity,Mathf.Infinity);
                            Keyframe kfrotw = new Keyframe(keylength * keyframeinfo.framerate, 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();
            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.starttime = 0.0f;
            tranimclip.endtime = keyframeinfo.numkeyframe * keyframeinfo.framerate;
            tranimclip.framerate = (7.0f - tr2animation.FrameRate);
            tranimclips.Add(tranimclip);

            //goto next clip
            trclipoffset++;
        }

        return tranimclips;
    }
Пример #8
0
    List <Tr2Moveable> BuildDynamicPrefabObjects(Transform container)
    {
        List <Tr2Moveable> objects = new List <Tr2Moveable>();

        for (int MovableObjectIdx = 0; MovableObjectIdx < m_leveldata.Moveables.Length; MovableObjectIdx++)
        {
            Tr2Moveable tr2movable  = m_leveldata.Moveables[MovableObjectIdx];
            int         startclipid = tr2movable.Animation;
            if (startclipid > m_leveldata.Animations.Length)
            {
                continue;
            }

            GameObject[] parts         = CreateMultiPartObject(tr2movable);
            Transform[]  transformtree = new Transform[parts.Length];
            for (int i = 0; i < parts.Length; i++)
            {
                transformtree[i] = parts[i].transform;
                if (tr2movable.ObjectID != 0)
                {
                    MeshCollider mf = parts[i].AddComponent <MeshCollider>();
                }
            }

            //creat a place holder gameObject and make it root transform ;
            tr2movable.UnityObject = new GameObject("prefab type:" + MovableObjectIdx);
            GameObject objRoot = tr2movable.UnityObject;
            objRoot.transform.parent = container;
            objRoot.transform.Translate(Vector3.zero);
            objRoot.transform.Rotate(Vector3.zero);

            //add unity animation components
            tr2movable.UnityAnimation          = objRoot.AddComponent <Animation>();
            tr2movable.UnityAnimation.wrapMode = WrapMode.Loop;
            tr2movable.TransformsTree          = transformtree;
            tr2movable.AnimationStartOffset    = startclipid;
            tr2movable.AnimClips = new List <TRAnimationClip>();
            objects.Add(tr2movable);

            //build mesh tree with stack
            ComputionModel.StackInit();

            //setup parent transform
            Transform Parent = transformtree[0];
            Parent.Translate(Vector3.zero);
            Parent.Rotate(Vector3.zero);
            Parent.parent = objRoot.transform;

            int animRootId = 0;
            for (int i = 0; i < tr2movable.NumMeshes; i++)
            {
                if (i != 0)   // first mesh - position to world coordinates, set rotation
                {
                    Vector3 meshPos = Vector3.zero;

                    // tr2movable.MeshTree is a byte offset into MeshTrees[],
                    // so we have to do a little converting here...

                    int offsetMeshTree = (int)tr2movable.MeshTree;
                    int Idx            = (i - 1) * 4 + offsetMeshTree;
                    meshPos.x = (float)m_leveldata.MeshTrees[Idx + 1];
                    meshPos.y = -(float)m_leveldata.MeshTrees[Idx + 2];
                    meshPos.z = (float)m_leveldata.MeshTrees[Idx + 3];

                    int flagVal1 = (int)((m_leveldata.MeshTrees[Idx + 0]) & 0x01);
                    int flagVal2 = (int)((m_leveldata.MeshTrees[Idx + 0]) & 0x02);

                    if (flagVal1 > 0 && flagVal2 > 0)
                    {
                        //print("poping - pushing ");
                        animRootId = ComputionModel.Pop();
                        Parent     = transformtree[animRootId];
                        animRootId = ComputionModel.Push(animRootId);
                    }
                    else
                    {
                        if (flagVal1 > 0)  // pop last saved anchor
                        {
                            //print("poping "+i);
                            animRootId = ComputionModel.Pop();
                            Parent     = transformtree[animRootId];
                        }
                        else
                        {
                            Parent = transformtree[i - 1];
                        }

                        if (flagVal2 > 0)  // push new anchor save
                        {
                            //print("pushing "+i);
                            animRootId = ComputionModel.Push(i - 1);
                            //prevParent = transformtree[animRootId];
                        }
                    }

                    transformtree[i].parent        = Parent;
                    transformtree[i].localPosition = meshPos * Settings.SceneScaling;
                    //transformtree[i].localRotation = relRot;
                }
            }
            AICondition.SetActive(objRoot, false);
        }

        return(objects);
    }