From 2186d5f3f95cd74a070a490d899291648d58667a Mon Sep 17 00:00:00 2001 From: Steven Fuller Date: Sun, 1 Jul 2001 00:55:22 +0000 Subject: Initial revision --- src/morph.c | 322 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 322 insertions(+) create mode 100644 src/morph.c (limited to 'src/morph.c') diff --git a/src/morph.c b/src/morph.c new file mode 100644 index 0000000..d868a50 --- /dev/null +++ b/src/morph.c @@ -0,0 +1,322 @@ +#include "3dc.h" + +#include "inline.h" + + +/* + externs for commonly used global variables and arrays +*/ + + extern MORPHDISPLAY MorphDisplay; + extern int NormalFrameTime; + + +/* + + Global Variables + +*/ + + + + + +/* + + Update Morphing Animation Control Block + +*/ + +void UpdateMorphing(MORPHCTRL *mcptr) + +{ + + MORPHHEADER *mhdr = mcptr->ObMorphHeader; + int UpdateRate; + + + /*textprint("UpdateMorphing\n");*/ + + + if(mcptr->ObMorphFlags & mph_flag_play) { + + /* How fast? */ + + if(mcptr->ObMorphSpeed == ONE_FIXED) { + + UpdateRate = NormalFrameTime; + + } + + else { + + UpdateRate = MUL_FIXED(NormalFrameTime, mcptr->ObMorphSpeed); + + } + + + /* Update the current frame */ + + if(mcptr->ObMorphFlags & mph_flag_reverse) { + + mcptr->ObMorphCurrFrame -= UpdateRate; + + if(mcptr->ObMorphCurrFrame < 0) { + + if(mcptr->ObMorphFlags & mph_flag_noloop) { + + mcptr->ObMorphCurrFrame = 0; + + /* The sequence has finished and we are at the start */ + + mcptr->ObMorphFlags |= (mph_flag_finished | mph_flag_start); + + } + + else { + + mcptr->ObMorphCurrFrame += mhdr->mph_maxframes; + + /* The sequence has looped and we are back at the end */ + + mcptr->ObMorphFlags |= (mph_flag_looped | mph_flag_end); + + } + + } + + } + + else { + + mcptr->ObMorphCurrFrame += UpdateRate; + + if(mcptr->ObMorphCurrFrame >= mhdr->mph_maxframes) { + + if(mcptr->ObMorphFlags & mph_flag_noloop) { + + /* The sequence has finished and we are at the end */ + + mcptr->ObMorphFlags |= (mph_flag_finished | mph_flag_end); + + mcptr->ObMorphCurrFrame = mhdr->mph_maxframes - 1; + + } + + else { + + mcptr->ObMorphCurrFrame -= mhdr->mph_maxframes; + + /* The sequence has looped and we are back at the start */ + + mcptr->ObMorphFlags |= (mph_flag_looped | mph_flag_start); + + } + + } + + } + + } + +} + + + +/* + + Update the Morphing Animation for this object + +*/ + +void UpdateMorphingDptr(DISPLAYBLOCK *dptr) + +{ + + SHAPEHEADER *sptr1; + SHAPEHEADER *sptr2; + + + /* Update object radius and extents */ + + GetMorphDisplay(&MorphDisplay, dptr); + + sptr1 = MorphDisplay.md_sptr1; + sptr2 = MorphDisplay.md_sptr2; + + #if 0 + textprint("sptr1->shaperadius = %d\n", sptr1->shaperadius); + textprint("sptr2->shaperadius = %d\n", sptr2->shaperadius); + #endif + + + /* Radius */ + + if(sptr1->shaperadius == sptr2->shaperadius) { + + dptr->ObRadius = sptr1->shaperadius; + + } + + else { + + dptr->ObRadius = WideMul2NarrowDiv(sptr1->shaperadius, + MorphDisplay.md_one_minus_lerp, + sptr2->shaperadius, + MorphDisplay.md_lerp, ONE_FIXED); + + } + + + /* X Extent */ + + if(sptr1->shapemaxx == sptr2->shapemaxx) { + + dptr->ObMaxX = sptr1->shapemaxx; + + } + + else { + + dptr->ObMaxX = WideMul2NarrowDiv(sptr1->shapemaxx, + MorphDisplay.md_one_minus_lerp, + sptr2->shapemaxx, + MorphDisplay.md_lerp, ONE_FIXED); + + } + + if(sptr1->shapeminx == sptr2->shapeminx) { + + dptr->ObMinX = sptr1->shapeminx; + + } + + else { + + dptr->ObMinX = WideMul2NarrowDiv(sptr1->shapeminx, + MorphDisplay.md_one_minus_lerp, + sptr2->shapeminx, + MorphDisplay.md_lerp, ONE_FIXED); + + } + + + /* Y Extent */ + + if(sptr1->shapemaxy == sptr2->shapemaxy) { + + dptr->ObMaxY = sptr1->shapemaxy; + + } + + else { + + dptr->ObMaxY = WideMul2NarrowDiv(sptr1->shapemaxy, + MorphDisplay.md_one_minus_lerp, + sptr2->shapemaxy, + MorphDisplay.md_lerp, ONE_FIXED); + + } + + if(sptr1->shapeminy == sptr2->shapeminy) { + + dptr->ObMinY = sptr1->shapeminy; + + } + + else { + + dptr->ObMinY = WideMul2NarrowDiv(sptr1->shapeminy, + MorphDisplay.md_one_minus_lerp, + sptr2->shapeminy, + MorphDisplay.md_lerp, ONE_FIXED); + + } + + + /* Z Extent */ + + if(sptr1->shapemaxz == sptr2->shapemaxz) { + + dptr->ObMaxZ = sptr1->shapemaxz; + + } + + else { + + dptr->ObMaxZ = WideMul2NarrowDiv(sptr1->shapemaxz, + MorphDisplay.md_one_minus_lerp, + sptr2->shapemaxz, + MorphDisplay.md_lerp, ONE_FIXED); + + } + + if(sptr1->shapeminz == sptr2->shapeminz) { + + dptr->ObMinZ = sptr1->shapeminz; + + } + + else { + + dptr->ObMinZ = WideMul2NarrowDiv(sptr1->shapeminz, + MorphDisplay.md_one_minus_lerp, + sptr2->shapeminz, + MorphDisplay.md_lerp, ONE_FIXED); + + } + + #if 0 + textprint("dptr->ObRadius = %d\n", dptr->ObRadius); + #endif + +} + + + +/* + + Using the current frame, calculate the lerp values and find out which two + shapes to interpolate between. + + Write this information back to a MORPHDISPLAY structure. + +*/ + +void GetMorphDisplay(MORPHDISPLAY *md, DISPLAYBLOCK *dptr) + +{ + + MORPHFRAME *mdata; + MORPHCTRL *mc = dptr->ObMorphCtrl; + MORPHHEADER *mhdr = mc->ObMorphHeader; + + + md->md_lerp = mc->ObMorphCurrFrame & 0xffff; + md->md_one_minus_lerp = ONE_FIXED - md->md_lerp; + + mdata = mhdr->mph_frames; + mdata = &mdata[mc->ObMorphCurrFrame >> 16]; + + md->md_shape1 = mdata->mf_shape1; + md->md_shape2 = mdata->mf_shape2; + + md->md_sptr1 = GetShapeData(md->md_shape1); + md->md_sptr2 = GetShapeData(md->md_shape2); + +} + + +void CopyMorphCtrl(MORPHCTRL *src, MORPHCTRL *dst) + +{ + + dst->ObMorphCurrFrame = src->ObMorphCurrFrame; + dst->ObMorphFlags = src->ObMorphFlags; + dst->ObMorphSpeed = src->ObMorphSpeed; + dst->ObMorphHeader = src->ObMorphHeader; + +} + + + \ No newline at end of file -- cgit v1.3