Пример #1
0
		public static Lib3dsTrack lib3ds_track_new(Lib3dsTrackType type, int nkeys)
		{
			Lib3dsTrack track=new Lib3dsTrack();
			track.type=type;
			lib3ds_track_resize(track, nkeys);
			return track;
		}
Пример #2
0
		public static void lib3ds_track_resize(Lib3dsTrack track, int nkeys)
		{
			Debug.Assert(track!=null);
			if(track.keys.Count==nkeys) return;
			while(track.keys.Count<nkeys) track.keys.Add(new Lib3dsKey());
			if(track.keys.Count>nkeys) track.keys.RemoveRange(nkeys, track.keys.Count-nkeys);
		}
Пример #3
0
        public static void lib3ds_track_eval_bool(Lib3dsTrack track, out bool b, float t)
        {
            b = false;
            if (track == null)
            {
                return;
            }

            Debug.Assert(track.type == Lib3dsTrackType.LIB3DS_TRACK_BOOL);

            if (track.keys.Count == 0)
            {
                return;
            }

            float u;
            int   index = find_index(track, t, out u);

            if (index < 0)
            {
                return;
            }
            if (index >= track.keys.Count)
            {
                b = (track.keys.Count & 1) == 0;
            }
            else
            {
                b = (index & 1) == 0;
            }
        }
Пример #4
0
        public static Lib3dsTrack lib3ds_track_new(Lib3dsTrackType type, int nkeys)
        {
            Lib3dsTrack track = new Lib3dsTrack();

            track.type = type;
            lib3ds_track_resize(track, nkeys);
            return(track);
        }
Пример #5
0
        public static void lib3ds_track_read(Lib3dsTrack track, Lib3dsIo io)
        {
            track.flags = (Lib3dsTrackFlags)lib3ds_io_read_word(io);
            lib3ds_io_read_dword(io);
            lib3ds_io_read_dword(io);
            int nkeys = lib3ds_io_read_intd(io);

            lib3ds_track_resize(track, nkeys);

            switch (track.type)
            {
            case Lib3dsTrackType.LIB3DS_TRACK_BOOL:
                for (int i = 0; i < nkeys; i++)
                {
                    track.keys[i].frame = lib3ds_io_read_intd(io);
                    tcb_read(track.keys[i], io);
                }
                break;

            case Lib3dsTrackType.LIB3DS_TRACK_FLOAT:
                for (int i = 0; i < nkeys; i++)
                {
                    track.keys[i].frame = lib3ds_io_read_intd(io);
                    tcb_read(track.keys[i], io);
                    track.keys[i].value[0] = lib3ds_io_read_float(io);
                }
                break;

            case Lib3dsTrackType.LIB3DS_TRACK_VECTOR:
                for (int i = 0; i < nkeys; i++)
                {
                    track.keys[i].frame = lib3ds_io_read_intd(io);
                    tcb_read(track.keys[i], io);
                    lib3ds_io_read_vector(io, track.keys[i].value);
                }
                break;

            case Lib3dsTrackType.LIB3DS_TRACK_QUAT:
                for (int i = 0; i < nkeys; i++)
                {
                    track.keys[i].frame = lib3ds_io_read_intd(io);
                    tcb_read(track.keys[i], io);
                    track.keys[i].value[3] = lib3ds_io_read_float(io);
                    lib3ds_io_read_vector(io, track.keys[i].value);
                }
                break;
                //case Lib3dsTrackType.LIB3DS_TRACK_MORPH:
                //    for(int i=0; i<nkeys; i++)
                //    {
                //        track.keys[i].frame = lib3ds_io_read_intd(io);
                //        tcb_read(track.keys[i].tcb, io);
                //        lib3ds_io_read_string(io, track.keys[i].data.m.name, 64);
                //    }
                //    break;
            }
        }
Пример #6
0
 static void quat_for_index(Lib3dsTrack track, int index, float[] q)
 {
     float[] p = new float[4];
     lib3ds_quat_identity(q);
     for (int i = 0; i <= index; i++)
     {
         lib3ds_quat_axis_angle(p, track.keys[i].value, track.keys[i].value[3]);
         lib3ds_quat_mul(q, p, q);
     }
 }
Пример #7
0
        public static void lib3ds_track_write(Lib3dsTrack track, Lib3dsIo io)
        {
            lib3ds_io_write_word(io, (ushort)track.flags);
            lib3ds_io_write_dword(io, 0);
            lib3ds_io_write_dword(io, 0);
            lib3ds_io_write_intd(io, track.keys.Count);

            switch (track.type)
            {
            case Lib3dsTrackType.LIB3DS_TRACK_BOOL:
                for (int i = 0; i < track.keys.Count; i++)
                {
                    lib3ds_io_write_intd(io, track.keys[i].frame);
                    tcb_write(track.keys[i], io);
                }
                break;

            case Lib3dsTrackType.LIB3DS_TRACK_FLOAT:
                for (int i = 0; i < track.keys.Count; i++)
                {
                    lib3ds_io_write_intd(io, track.keys[i].frame);
                    tcb_write(track.keys[i], io);
                    lib3ds_io_write_float(io, track.keys[i].value[0]);
                }
                break;

            case Lib3dsTrackType.LIB3DS_TRACK_VECTOR:
                for (int i = 0; i < track.keys.Count; i++)
                {
                    lib3ds_io_write_intd(io, track.keys[i].frame);
                    tcb_write(track.keys[i], io);
                    lib3ds_io_write_vector(io, track.keys[i].value);
                }
                break;

            case Lib3dsTrackType.LIB3DS_TRACK_QUAT:
                for (int i = 0; i < track.keys.Count; i++)
                {
                    lib3ds_io_write_intd(io, track.keys[i].frame);
                    tcb_write(track.keys[i], io);
                    lib3ds_io_write_float(io, track.keys[i].value[3]);
                    lib3ds_io_write_vector(io, track.keys[i].value);
                }
                break;
                //case Lib3dsTrackType.LIB3DS_TRACK_MORPH:
                //    for(int i=0; i<track.keys.Count; i++)
                //    {
                //        lib3ds_io_write_intd(io, track.keys[i].frame);
                //        tcb_write(track.keys[i].tcb, io);
                //        lib3ds_io_write_string(io, track.keys[i].data.m.name);
                //    }
                //    break;
            }
        }
Пример #8
0
        public static void lib3ds_track_eval_vector(Lib3dsTrack track, float[] v, float t)
        {
            lib3ds_vector_zero(v);
            if (track == null)
            {
                return;
            }

            Debug.Assert(track.type == Lib3dsTrackType.LIB3DS_TRACK_VECTOR);

            track_eval_linear(track, v, t);
        }
Пример #9
0
        public static void lib3ds_track_eval_float(Lib3dsTrack track, out float f, float t)
        {
            f = 0;
            if (track == null)
            {
                return;
            }

            Debug.Assert(track.type == Lib3dsTrackType.LIB3DS_TRACK_FLOAT);
            float[] tmp = new float[1];

            track_eval_linear(track, tmp, t);
            f = tmp[0];
        }
Пример #10
0
        static int find_index(Lib3dsTrack track, float t, out float u)
        {
            Debug.Assert(track != null);
            Debug.Assert(track.keys.Count > 0);

            u = 0;
            if (track.keys.Count <= 1)
            {
                return(-1);
            }

            int   t0 = track.keys[0].frame;
            int   t1 = track.keys[track.keys.Count - 1].frame;
            float nt;

            if ((track.flags & Lib3dsTrackFlags.LIB3DS_TRACK_REPEAT) != 0)
            {
                nt = (float)Math.IEEERemainder(t - t0, t1 - t0) + t0;
            }
            else
            {
                nt = t;
            }

            if (nt <= t0)
            {
                return(-1);
            }
            if (nt >= t1)
            {
                return(track.keys.Count);
            }

            int i = 1;

            for (; i < track.keys.Count; i++)
            {
                if (nt < track.keys[i].frame)
                {
                    break;
                }
            }

            u  = nt - (float)track.keys[i - 1].frame;
            u /= (float)(track.keys[i].frame - track.keys[i - 1].frame);

            Debug.Assert((u >= 0.0f) && (u <= 1.0f));
            return(i);
        }
Пример #11
0
 public static void lib3ds_track_resize(Lib3dsTrack track, int nkeys)
 {
     Debug.Assert(track != null);
     if (track.keys.Count == nkeys)
     {
         return;
     }
     while (track.keys.Count < nkeys)
     {
         track.keys.Add(new Lib3dsKey());
     }
     if (track.keys.Count > nkeys)
     {
         track.keys.RemoveRange(nkeys, track.keys.Count - nkeys);
     }
 }
Пример #12
0
        static void track_eval_linear(Lib3dsTrack track, float[] value, float t)
        {
            Debug.Assert(track != null);

            if (track.keys.Count == 0)
            {
                for (int i = 0; i < (int)track.type; i++)
                {
                    value[i] = 0.0f;
                }
                return;
            }

            float u;
            int   index = find_index(track, t, out u);

            if (index < 0)
            {
                for (int i = 0; i < (int)track.type; i++)
                {
                    value[i] = track.keys[0].value[i];
                }
                return;
            }
            if (index >= track.keys.Count)
            {
                for (int i = 0; i < (int)track.type; i++)
                {
                    value[i] = track.keys[track.keys.Count - 1].value[i];
                }
                return;
            }

            Lib3dsKey pp = new Lib3dsKey(), p0 = new Lib3dsKey(), p1 = new Lib3dsKey(), pn = new Lib3dsKey();

            float[] dsp = new float[3], ddp = new float[3], dsn = new float[3], ddn = new float[3];

            setup_segment(track, index, ref pp, ref p0, ref p1, ref pn);

            pos_key_setup((int)track.type, pp.frame >= 0?pp:null, p0, p1, ddp, dsp);
            pos_key_setup((int)track.type, p0, p1, pn.frame >= 0?pn:null, ddn, dsn);

            lib3ds_math_cubic_interp(value, p0.value, ddp, dsn, p1.value, (int)track.type, u);
        }
Пример #13
0
        public static void lib3ds_track_eval_quat(Lib3dsTrack track, float[] q, float t)
        {
            lib3ds_quat_identity(q);
            if (track == null)
            {
                return;
            }

            Debug.Assert(track.type == Lib3dsTrackType.LIB3DS_TRACK_QUAT);
            if (track.keys.Count == 0)
            {
                return;
            }

            float u;
            int   index = find_index(track, t, out u);

            if (index < 0)
            {
                lib3ds_quat_axis_angle(q, track.keys[0].value, track.keys[0].value[3]);
                return;
            }
            if (index >= track.keys.Count)
            {
                quat_for_index(track, track.keys.Count - 1, q);
                return;
            }

            Lib3dsKey pp = new Lib3dsKey(), p0 = new Lib3dsKey(), p1 = new Lib3dsKey(), pn = new Lib3dsKey();

            setup_segment(track, index, ref pp, ref p0, ref p1, ref pn);

            float[] ap = new float[4], bp = new float[4], an = new float[4], bn = new float[4];
            rot_key_setup(pp.frame >= 0?pp:null, p0, p1, ap, bp);
            rot_key_setup(p0, p1, pn.frame >= 0?pn:null, an, bn);

            lib3ds_quat_squad(q, p0.value, ap, bn, p1.value, u);
        }
Пример #14
0
		public static void lib3ds_track_eval_float(Lib3dsTrack track, out float f, float t)
		{
			f=0;
			if(track==null) return;

			Debug.Assert(track.type==Lib3dsTrackType.LIB3DS_TRACK_FLOAT);
			float[] tmp=new float[1];

			track_eval_linear(track, tmp, t);
			f=tmp[0];
		}
Пример #15
0
		static void track_eval_linear(Lib3dsTrack track, float[] value, float t)
		{
			Debug.Assert(track!=null);

			if(track.keys.Count==0)
			{
				for(int i=0; i<(int)track.type; i++) value[i]=0.0f;
				return;
			}

			float u;
			int index=find_index(track, t, out u);

			if(index<0)
			{
				for(int i=0; i<(int)track.type; i++) value[i]=track.keys[0].value[i];
				return;
			}
			if(index>=track.keys.Count)
			{
				for(int i=0; i<(int)track.type; i++) value[i]=track.keys[track.keys.Count-1].value[i];
				return;
			}

			Lib3dsKey pp=new Lib3dsKey(), p0=new Lib3dsKey(), p1=new Lib3dsKey(), pn=new Lib3dsKey();
			float[] dsp=new float[3], ddp=new float[3], dsn=new float[3], ddn=new float[3];

			setup_segment(track, index, ref pp, ref p0, ref p1, ref pn);

			pos_key_setup((int)track.type, pp.frame>=0?pp:null, p0, p1, ddp, dsp);
			pos_key_setup((int)track.type, p0, p1, pn.frame>=0?pn:null, ddn, dsn);

			lib3ds_math_cubic_interp(value, p0.value, ddp, dsn, p1.value, (int)track.type, u);
		}
Пример #16
0
		public static void lib3ds_track_eval_bool(Lib3dsTrack track, out bool b, float t)
		{
			b=false;
			if(track==null) return;

			Debug.Assert(track.type==Lib3dsTrackType.LIB3DS_TRACK_BOOL);

			if(track.keys.Count==0) return;

			float u;
			int index=find_index(track, t, out u);
			if(index<0) return;
			if(index>=track.keys.Count) b=(track.keys.Count&1)==0;
			else b=(index&1)==0;
		}
Пример #17
0
		public static void lib3ds_track_free(Lib3dsTrack track)
		{
			Debug.Assert(track!=null);
			lib3ds_track_resize(track, 0);
		}
Пример #18
0
		static void setup_segment(Lib3dsTrack track, int index, ref Lib3dsKey pp, ref Lib3dsKey p0, ref Lib3dsKey p1, ref Lib3dsKey pn)
		{
			int ip=0, @in=0;

			pp.frame=pn.frame=-1;
			if(index>=2)
			{
				ip=index-2;
				pp=track.keys[index-2];
			}
			else
			{
				if((track.flags&Lib3dsTrackFlags.LIB3DS_TRACK_SMOOTH)!=0)
				{
					ip=track.keys.Count-2;
					pp=track.keys[track.keys.Count-2];
					pp.frame=track.keys[track.keys.Count-2].frame-(track.keys[track.keys.Count-1].frame-track.keys[0].frame);
				}
			}

			p0=track.keys[index-1];
			p1=track.keys[index];

			if(index<(int)track.keys.Count-1)
			{
				@in=index+1;
				pn=track.keys[index+1];
			}
			else
			{
				if((track.flags&Lib3dsTrackFlags.LIB3DS_TRACK_SMOOTH)!=0)
				{
					@in=1;
					pn=track.keys[1];
					pn.frame=track.keys[1].frame+(track.keys[track.keys.Count-1].frame-track.keys[0].frame);
				}
			}

			if(track.type==Lib3dsTrackType.LIB3DS_TRACK_QUAT)
			{
				float[] q=new float[4];
				if(pp.frame>=0) quat_for_index(track, ip, pp.value);
				else lib3ds_quat_identity(pp.value);

				quat_for_index(track, index-1, p0.value);
				lib3ds_quat_axis_angle(q, track.keys[index].value, track.keys[index].value[3]);
				lib3ds_quat_mul(p1.value, q, p0.value);

				if(pn.frame>=0)
				{
					lib3ds_quat_axis_angle(q, track.keys[@in].value, track.keys[@in].value[3]);
					lib3ds_quat_mul(pn.value, q, p1.value);
				}
				else lib3ds_quat_identity(pn.value);
			}
		}
Пример #19
0
		static void quat_for_index(Lib3dsTrack track, int index, float[] q)
		{
			float[] p=new float[4];
			lib3ds_quat_identity(q);
			for(int i=0; i<=index; i++)
			{
				lib3ds_quat_axis_angle(p, track.keys[i].value, track.keys[i].value[3]);
				lib3ds_quat_mul(q, p, q);
			}
		}
Пример #20
0
 public static void lib3ds_track_free(Lib3dsTrack track)
 {
     Debug.Assert(track != null);
     lib3ds_track_resize(track, 0);
 }
Пример #21
0
        static void setup_segment(Lib3dsTrack track, int index, ref Lib3dsKey pp, ref Lib3dsKey p0, ref Lib3dsKey p1, ref Lib3dsKey pn)
        {
            int ip = 0, @in = 0;

            pp.frame = pn.frame = -1;
            if (index >= 2)
            {
                ip = index - 2;
                pp = track.keys[index - 2];
            }
            else
            {
                if ((track.flags & Lib3dsTrackFlags.LIB3DS_TRACK_SMOOTH) != 0)
                {
                    ip       = track.keys.Count - 2;
                    pp       = track.keys[track.keys.Count - 2];
                    pp.frame = track.keys[track.keys.Count - 2].frame - (track.keys[track.keys.Count - 1].frame - track.keys[0].frame);
                }
            }

            p0 = track.keys[index - 1];
            p1 = track.keys[index];

            if (index < (int)track.keys.Count - 1)
            {
                @in = index + 1;
                pn  = track.keys[index + 1];
            }
            else
            {
                if ((track.flags & Lib3dsTrackFlags.LIB3DS_TRACK_SMOOTH) != 0)
                {
                    @in      = 1;
                    pn       = track.keys[1];
                    pn.frame = track.keys[1].frame + (track.keys[track.keys.Count - 1].frame - track.keys[0].frame);
                }
            }

            if (track.type == Lib3dsTrackType.LIB3DS_TRACK_QUAT)
            {
                float[] q = new float[4];
                if (pp.frame >= 0)
                {
                    quat_for_index(track, ip, pp.value);
                }
                else
                {
                    lib3ds_quat_identity(pp.value);
                }

                quat_for_index(track, index - 1, p0.value);
                lib3ds_quat_axis_angle(q, track.keys[index].value, track.keys[index].value[3]);
                lib3ds_quat_mul(p1.value, q, p0.value);

                if (pn.frame >= 0)
                {
                    lib3ds_quat_axis_angle(q, track.keys[@in].value, track.keys[@in].value[3]);
                    lib3ds_quat_mul(pn.value, q, p1.value);
                }
                else
                {
                    lib3ds_quat_identity(pn.value);
                }
            }
        }
Пример #22
0
		public static void lib3ds_track_read(Lib3dsTrack track, Lib3dsIo io)
		{
			track.flags=(Lib3dsTrackFlags)lib3ds_io_read_word(io);
			lib3ds_io_read_dword(io);
			lib3ds_io_read_dword(io);
			int nkeys=lib3ds_io_read_intd(io);
			lib3ds_track_resize(track, nkeys);

			switch(track.type)
			{
				case Lib3dsTrackType.LIB3DS_TRACK_BOOL:
					for(int i=0; i<nkeys; i++)
					{
						track.keys[i].frame=lib3ds_io_read_intd(io);
						tcb_read(track.keys[i], io);
					}
					break;
				case Lib3dsTrackType.LIB3DS_TRACK_FLOAT:
					for(int i=0; i<nkeys; i++)
					{
						track.keys[i].frame=lib3ds_io_read_intd(io);
						tcb_read(track.keys[i], io);
						track.keys[i].value[0]=lib3ds_io_read_float(io);
					}
					break;
				case Lib3dsTrackType.LIB3DS_TRACK_VECTOR:
					for(int i=0; i<nkeys; i++)
					{
						track.keys[i].frame=lib3ds_io_read_intd(io);
						tcb_read(track.keys[i], io);
						lib3ds_io_read_vector(io, track.keys[i].value);
					}
					break;
				case Lib3dsTrackType.LIB3DS_TRACK_QUAT:
					for(int i=0; i<nkeys; i++)
					{
						track.keys[i].frame=lib3ds_io_read_intd(io);
						tcb_read(track.keys[i], io);
						track.keys[i].value[3]=lib3ds_io_read_float(io);
						lib3ds_io_read_vector(io, track.keys[i].value);
					}
					break;
				//case Lib3dsTrackType.LIB3DS_TRACK_MORPH:
				//    for(int i=0; i<nkeys; i++)
				//    {
				//        track.keys[i].frame = lib3ds_io_read_intd(io);
				//        tcb_read(track.keys[i].tcb, io);
				//        lib3ds_io_read_string(io, track.keys[i].data.m.name, 64);
				//    }
				//    break;
			}
		}
Пример #23
0
		public static void lib3ds_track_eval_vector(Lib3dsTrack track, float[] v, float t)
		{
			lib3ds_vector_zero(v);
			if(track==null) return;

			Debug.Assert(track.type==Lib3dsTrackType.LIB3DS_TRACK_VECTOR);

			track_eval_linear(track, v, t);
		}
Пример #24
0
		public static void lib3ds_track_eval_quat(Lib3dsTrack track, float[] q, float t)
		{
			lib3ds_quat_identity(q);
			if(track==null) return;

			Debug.Assert(track.type==Lib3dsTrackType.LIB3DS_TRACK_QUAT);
			if(track.keys.Count==0) return;

			float u;
			int index=find_index(track, t, out u);
			if(index<0)
			{
				lib3ds_quat_axis_angle(q, track.keys[0].value, track.keys[0].value[3]);
				return;
			}
			if(index>=track.keys.Count)
			{
				quat_for_index(track, track.keys.Count-1, q);
				return;
			}

			Lib3dsKey pp=new Lib3dsKey(), p0=new Lib3dsKey(), p1=new Lib3dsKey(), pn=new Lib3dsKey();
			setup_segment(track, index, ref pp, ref p0, ref p1, ref pn);

			float[] ap=new float[4], bp=new float[4], an=new float[4], bn=new float[4];
			rot_key_setup(pp.frame>=0?pp:null, p0, p1, ap, bp);
			rot_key_setup(p0, p1, pn.frame>=0?pn:null, an, bn);

			lib3ds_quat_squad(q, p0.value, ap, bn, p1.value, u);
		}
Пример #25
0
		static int find_index(Lib3dsTrack track, float t, out float u)
		{
			Debug.Assert(track!=null);
			Debug.Assert(track.keys.Count>0);

			u=0;
			if(track.keys.Count<=1) return -1;

			int t0=track.keys[0].frame;
			int t1=track.keys[track.keys.Count-1].frame;
			float nt;
			if((track.flags&Lib3dsTrackFlags.LIB3DS_TRACK_REPEAT)!=0) nt=(float)Math.IEEERemainder(t-t0, t1-t0)+t0;
			else nt=t;

			if(nt<=t0) return -1;
			if(nt>=t1) return track.keys.Count;

			int i=1;
			for(; i<track.keys.Count; i++)
			{
				if(nt<track.keys[i].frame) break;
			}

			u=nt-(float)track.keys[i-1].frame;
			u/=(float)(track.keys[i].frame-track.keys[i-1].frame);

			Debug.Assert((u>=0.0f)&&(u<=1.0f));
			return i;
		}
Пример #26
0
		public static void lib3ds_track_write(Lib3dsTrack track, Lib3dsIo io)
		{
			lib3ds_io_write_word(io, (ushort)track.flags);
			lib3ds_io_write_dword(io, 0);
			lib3ds_io_write_dword(io, 0);
			lib3ds_io_write_intd(io, track.keys.Count);

			switch(track.type)
			{
				case Lib3dsTrackType.LIB3DS_TRACK_BOOL:
					for(int i=0; i<track.keys.Count; i++)
					{
						lib3ds_io_write_intd(io, track.keys[i].frame);
						tcb_write(track.keys[i], io);
					}
					break;
				case Lib3dsTrackType.LIB3DS_TRACK_FLOAT:
					for(int i=0; i<track.keys.Count; i++)
					{
						lib3ds_io_write_intd(io, track.keys[i].frame);
						tcb_write(track.keys[i], io);
						lib3ds_io_write_float(io, track.keys[i].value[0]);
					}
					break;
				case Lib3dsTrackType.LIB3DS_TRACK_VECTOR:
					for(int i=0; i<track.keys.Count; i++)
					{
						lib3ds_io_write_intd(io, track.keys[i].frame);
						tcb_write(track.keys[i], io);
						lib3ds_io_write_vector(io, track.keys[i].value);
					}
					break;
				case Lib3dsTrackType.LIB3DS_TRACK_QUAT:
					for(int i=0; i<track.keys.Count; i++)
					{
						lib3ds_io_write_intd(io, track.keys[i].frame);
						tcb_write(track.keys[i], io);
						lib3ds_io_write_float(io, track.keys[i].value[3]);
						lib3ds_io_write_vector(io, track.keys[i].value);
					}
					break;
				//case Lib3dsTrackType.LIB3DS_TRACK_MORPH:
				//    for(int i=0; i<track.keys.Count; i++)
				//    {
				//        lib3ds_io_write_intd(io, track.keys[i].frame);
				//        tcb_write(track.keys[i].tcb, io);
				//        lib3ds_io_write_string(io, track.keys[i].data.m.name);
				//    }
				//    break;
			}
		}
Пример #27
0
        public static void lib3ds_node_read(Lib3dsNode node, Lib3dsIo io)
        {
            Lib3dsChunk  c = new Lib3dsChunk();
            Lib3dsChunks chunk;

            Debug.Assert(node != null);
            lib3ds_chunk_read_start(c, 0, io);

            switch (c.chunk)
            {
            case Lib3dsChunks.CHK_AMBIENT_NODE_TAG:
            case Lib3dsChunks.CHK_OBJECT_NODE_TAG:
            case Lib3dsChunks.CHK_CAMERA_NODE_TAG:
            case Lib3dsChunks.CHK_TARGET_NODE_TAG:
            case Lib3dsChunks.CHK_LIGHT_NODE_TAG:
            case Lib3dsChunks.CHK_SPOTLIGHT_NODE_TAG:
            case Lib3dsChunks.CHK_L_TARGET_NODE_TAG: break;

            default: return;
            }

            while ((chunk = lib3ds_chunk_read_next(c, io)) != 0)
            {
                switch (chunk)
                {
                case Lib3dsChunks.CHK_NODE_ID:
                    node.node_id   = lib3ds_io_read_word(io);
                    node.hasNodeID = true;
                    lib3ds_io_log_indent(io, 1);
                    lib3ds_io_log(io, Lib3dsLogLevel.LIB3DS_LOG_INFO, "ID={0}", node.node_id);
                    lib3ds_io_log_indent(io, -1);
                    break;

                case Lib3dsChunks.CHK_NODE_HDR:
                    node.name      = lib3ds_io_read_string(io, 64);
                    node.flags     = lib3ds_io_read_dword(io);
                    node.parent_id = lib3ds_io_read_word(io);

                    lib3ds_io_log_indent(io, 1);
                    lib3ds_io_log(io, Lib3dsLogLevel.LIB3DS_LOG_INFO, "NAME={0}", node.name);
                    lib3ds_io_log(io, Lib3dsLogLevel.LIB3DS_LOG_INFO, "PARENT={0}", (short)node.parent_id);
                    lib3ds_io_log_indent(io, -1);
                    break;

                case Lib3dsChunks.CHK_PIVOT:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE)
                    {
                        Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node;
                        lib3ds_io_read_vector(io, n.pivot);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                case Lib3dsChunks.CHK_INSTANCE_NAME:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE)
                    {
                        Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node;
                        n.instance_name = lib3ds_io_read_string(io, 64);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                case Lib3dsChunks.CHK_BOUNDBOX:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE)
                    {
                        Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node;
                        lib3ds_io_read_vector(io, n.bbox_min);
                        lib3ds_io_read_vector(io, n.bbox_max);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                case Lib3dsChunks.CHK_COL_TRACK_TAG:
                {
                    Lib3dsTrack track = null;
                    switch (node.type)
                    {
                    case Lib3dsNodeType.LIB3DS_NODE_AMBIENT_COLOR:
                    {
                        Lib3dsAmbientColorNode n = (Lib3dsAmbientColorNode)node;
                        track = n.color_track;
                    }
                    break;

                    case Lib3dsNodeType.LIB3DS_NODE_OMNILIGHT:
                    {
                        Lib3dsOmnilightNode n = (Lib3dsOmnilightNode)node;
                        track = n.color_track;
                    }
                    break;

                    case Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT:
                    {
                        Lib3dsSpotlightNode n = (Lib3dsSpotlightNode)node;
                        track = n.color_track;
                    }
                    break;

                    default: lib3ds_chunk_unknown(chunk, io); break;
                    }
                    if (track != null)
                    {
                        lib3ds_track_read(track, io);
                    }
                }
                break;

                case Lib3dsChunks.CHK_POS_TRACK_TAG:
                {
                    Lib3dsTrack track = null;
                    switch (node.type)
                    {
                    case Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE:
                    {
                        Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node;
                        track = n.pos_track;
                    }
                    break;

                    case Lib3dsNodeType.LIB3DS_NODE_CAMERA:
                    {
                        Lib3dsCameraNode n = (Lib3dsCameraNode)node;
                        track = n.pos_track;
                    }
                    break;

                    case Lib3dsNodeType.LIB3DS_NODE_CAMERA_TARGET:
                    {
                        Lib3dsTargetNode n = (Lib3dsTargetNode)node;
                        track = n.pos_track;
                    }
                    break;

                    case Lib3dsNodeType.LIB3DS_NODE_OMNILIGHT:
                    {
                        Lib3dsOmnilightNode n = (Lib3dsOmnilightNode)node;
                        track = n.pos_track;
                    }
                    break;

                    case Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT:
                    {
                        Lib3dsSpotlightNode n = (Lib3dsSpotlightNode)node;
                        track = n.pos_track;
                    }
                    break;

                    case Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT_TARGET:
                    {
                        Lib3dsTargetNode n = (Lib3dsTargetNode)node;
                        track = n.pos_track;
                    }
                    break;

                    default: lib3ds_chunk_unknown(chunk, io); break;
                    }
                    if (track != null)
                    {
                        lib3ds_track_read(track, io);
                    }
                }
                break;

                case Lib3dsChunks.CHK_ROT_TRACK_TAG:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE)
                    {
                        Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node;
                        n.rot_track.type = Lib3dsTrackType.LIB3DS_TRACK_QUAT;
                        lib3ds_track_read(n.rot_track, io);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                case Lib3dsChunks.CHK_SCL_TRACK_TAG:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE)
                    {
                        Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node;
                        n.scl_track.type = Lib3dsTrackType.LIB3DS_TRACK_VECTOR;
                        lib3ds_track_read(n.scl_track, io);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                case Lib3dsChunks.CHK_FOV_TRACK_TAG:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_CAMERA)
                    {
                        Lib3dsCameraNode n = (Lib3dsCameraNode)node;
                        n.fov_track.type = Lib3dsTrackType.LIB3DS_TRACK_FLOAT;
                        lib3ds_track_read(n.fov_track, io);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                case Lib3dsChunks.CHK_HOT_TRACK_TAG:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT)
                    {
                        Lib3dsSpotlightNode n = (Lib3dsSpotlightNode)node;
                        n.hotspot_track.type = Lib3dsTrackType.LIB3DS_TRACK_FLOAT;
                        lib3ds_track_read(n.hotspot_track, io);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                case Lib3dsChunks.CHK_FALL_TRACK_TAG:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT)
                    {
                        Lib3dsSpotlightNode n = (Lib3dsSpotlightNode)node;
                        n.falloff_track.type = Lib3dsTrackType.LIB3DS_TRACK_FLOAT;
                        lib3ds_track_read(n.falloff_track, io);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                case Lib3dsChunks.CHK_ROLL_TRACK_TAG:
                    switch (node.type)
                    {
                    case Lib3dsNodeType.LIB3DS_NODE_CAMERA:
                    {
                        Lib3dsCameraNode n = (Lib3dsCameraNode)node;
                        n.roll_track.type = Lib3dsTrackType.LIB3DS_TRACK_FLOAT;
                        lib3ds_track_read(n.roll_track, io);
                    }
                    break;

                    case Lib3dsNodeType.LIB3DS_NODE_SPOTLIGHT:
                    {
                        Lib3dsSpotlightNode n = (Lib3dsSpotlightNode)node;
                        n.roll_track.type = Lib3dsTrackType.LIB3DS_TRACK_FLOAT;
                        lib3ds_track_read(n.roll_track, io);
                    }
                    break;

                    default: lib3ds_chunk_unknown(chunk, io); break;
                    }
                    break;

                case Lib3dsChunks.CHK_HIDE_TRACK_TAG:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE)
                    {
                        Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node;
                        n.hide_track.type = Lib3dsTrackType.LIB3DS_TRACK_BOOL;
                        lib3ds_track_read(n.hide_track, io);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                case Lib3dsChunks.CHK_MORPH_SMOOTH:
                    if (node.type == Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE)
                    {
                        Lib3dsMeshInstanceNode n = (Lib3dsMeshInstanceNode)node;
                        n.morph_smooth = lib3ds_io_read_float(io);
                    }
                    else
                    {
                        lib3ds_chunk_unknown(chunk, io);
                    }
                    break;

                //case Lib3dsChunks.LIB3DS_MORPH_TRACK_TAG:
                //    if(node.type==Lib3dsNodeType.LIB3DS_NODE_MESH_INSTANCE)
                //    {
                //        Lib3dsMeshInstanceNode n=(Lib3dsMeshInstanceNode)node;
                //        n.morph_track=lib3ds_track_new(node, LIB3DS_TRACK_MORPH, 0);
                //        lib3ds_track_read(n.morph_track, io);
                //    }
                //    else lib3ds_chunk_unknown(chunk, io);
                //    break;
                default: lib3ds_chunk_unknown(chunk, io); break;
                }
            }

            lib3ds_chunk_read_end(c, io);
        }