diff --git a/src/anim.cpp b/src/anim.cpp index f6ab109..4141e88 100644 --- a/src/anim.cpp +++ b/src/anim.cpp @@ -123,7 +123,7 @@ Animation::streamReadLegacy(Stream *stream) stream->read(&frames[i].t, 3*4); frames[i].time = stream->readF32(); int32 prev = stream->readI32(); - frames[i].prev = &frames[prev]; + frames[i].prevFrame = &frames[prev]; } return anim; } @@ -153,7 +153,7 @@ Animation::streamWriteLegacy(Stream *stream) stream->write(&frames[i].q, 4*4); stream->write(&frames[i].t, 3*4); stream->writeF32(frames[i].time); - stream->writeI32(frames[i].prev - frames); + stream->writeI32(frames[i].prevFrame - frames); } return true; } diff --git a/src/base.cpp b/src/base.cpp index 5458ccc..6630b10 100644 --- a/src/base.cpp +++ b/src/base.cpp @@ -82,6 +82,25 @@ mult(const Quat &q, const Quat &p) q.w*p.z + q.z*p.w + q.x*p.y - q.y*p.x); } + +Quat* +Quat::rotate(const V3d *axis, float32 angle, CombineOp op) +{ + Quat rot = rotation(angle, *axis); + switch(op){ + case COMBINEREPLACE: + *this = rot; + break; + case COMBINEPRECONCAT: + *this = mult(*this, rot); + break; + case COMBINEPOSTCONCAT: + *this = mult(rot, *this); + break; + } + return this; +} + Quat lerp(const Quat &q, const Quat &p, float32 r) { diff --git a/src/charset.cpp b/src/charset.cpp index 0001804..1ca88fc 100644 --- a/src/charset.cpp +++ b/src/charset.cpp @@ -60,7 +60,7 @@ Charset::close(void) } Charset* -Charset::create(RGBA *foreground, RGBA *background) +Charset::create(const RGBA *foreground, const RGBA *background) { Charset *charset = (Charset*)rwMalloc(sizeof(Charset), MEMDUR_EVENT); if(charset == nil){ @@ -91,7 +91,7 @@ Charset::destroy(void) } Charset* -Charset::setColors(RGBA *foreground, RGBA *background) +Charset::setColors(const RGBA *foreground, const RGBA *background) { Image *img = Image::create(256, 256, 8); if(img == nil) diff --git a/src/hanim.cpp b/src/hanim.cpp index b9efafd..e3893c4 100644 --- a/src/hanim.cpp +++ b/src/hanim.cpp @@ -35,7 +35,7 @@ HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs, RWERROR((ERR_ALLOC, sizeof(*hier))); return nil; } - hier->currentAnim = AnimInterpolator::create(numNodes, maxKeySize); + hier->interpolator = AnimInterpolator::create(numNodes, maxKeySize); hier->numNodes = numNodes; hier->flags = flags; @@ -68,6 +68,7 @@ HAnimHierarchy::create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs, void HAnimHierarchy::destroy(void) { + this->interpolator->destroy(); rwFree(this->matricesUnaligned); rwFree(this->nodeInfo); rwFree(this); @@ -156,7 +157,7 @@ HAnimHierarchy::updateMatrices(void) Matrix **sp, *stack[64]; Frame *frm, *parfrm; int32 i; - AnimInterpolator *anim = this->currentAnim; + AnimInterpolator *anim = this->interpolator; sp = stack; curMat = this->matrices; @@ -228,7 +229,7 @@ copyHAnim(void *dst, void *src, int32 offset, int32) dsthanim->hierarchy = nil; srchier = srchanim->hierarchy; if(srchier && !(srchier->flags & HAnimHierarchy::SUBHIERARCHY)){ - dsthier = HAnimHierarchy::create(srchier->numNodes, nil, nil, srchier->flags, srchier->currentAnim->maxInterpKeyFrameSize); + dsthier = HAnimHierarchy::create(srchier->numNodes, nil, nil, srchier->flags, srchier->interpolator->maxInterpKeyFrameSize); for(i = 0; i < dsthier->numNodes; i++){ dsthier->nodeInfo[i].frame = nil; dsthier->nodeInfo[i].flags = srchier->nodeInfo[i].flags; @@ -286,7 +287,7 @@ writeHAnim(Stream *stream, int32, void *object, int32 offset, int32) HAnimHierarchy *hier = hanim->hierarchy; stream->writeI32(hier->numNodes); stream->writeI32(hier->flags); - stream->writeI32(hier->currentAnim->maxInterpKeyFrameSize); + stream->writeI32(hier->interpolator->maxInterpKeyFrameSize); for(int32 i = 0; i < hier->numNodes; i++){ stream->writeI32(hier->nodeInfo[i].id); stream->writeI32(hier->nodeInfo[i].index); @@ -316,7 +317,7 @@ hAnimFrameRead(Stream *stream, Animation *anim) stream->read(&frames[i].q, 4*4); stream->read(&frames[i].t, 3*4); int32 prev = stream->readI32()/0x24; - frames[i].prev = &frames[prev]; + frames[i].prevFrame = &frames[prev]; } } @@ -328,7 +329,7 @@ hAnimFrameWrite(Stream *stream, Animation *anim) stream->writeF32(frames[i].time); stream->write(&frames[i].q, 4*4); stream->write(&frames[i].t, 3*4); - stream->writeI32((frames[i].prev - frames)*0x24); + stream->writeI32((frames[i].prevFrame - frames)*0x24); } } diff --git a/src/rwbase.h b/src/rwbase.h index 1a06d0b..d486849 100644 --- a/src/rwbase.h +++ b/src/rwbase.h @@ -235,19 +235,33 @@ struct V4d }; inline bool32 equal(const V4d &v1, const V4d &v2) { return v1.x == v2.x && v1.y == v2.y && v1.z == v2.z && v1.w == v2.w; } +enum CombineOp +{ + COMBINEREPLACE, + COMBINEPRECONCAT, + COMBINEPOSTCONCAT +}; + + Quat makeQuat(float32 w, float32 x, float32 y, float32 z); Quat makeQuat(float32 w, const V3d &vec); struct Quat { // order is important for streaming - float32 x, y, z, w; + union { + struct { float32 x, y, z, w; }; + // needed for RW compatibility + struct { V3d imag; float32 real; }; + }; static Quat rotation(float32 angle, const V3d &axis){ - return makeQuat(cos(angle/2.0f), scale(axis, sin(angle/2.0f))); } + return makeQuat(cos(angle/2.0f), scale(normalize(axis), sin(angle/2.0f))); } void set(float32 w, float32 x, float32 y, float32 z){ this->w = w; this->x = x; this->y = y; this->z = z; } V3d vec(void){ return makeV3d(x, y, z); } + + Quat *rotate(const V3d *axis, float32 angle, CombineOp op); }; inline Quat makeQuat(float32 w, float32 x, float32 y, float32 z) { Quat q = { x, y, z, w }; return q; } @@ -265,13 +279,6 @@ inline V3d rotate(const V3d &v, const Quat &q) { return mult(mult(q, makeQuat(0. Quat lerp(const Quat &q, const Quat &p, float32 r); Quat slerp(const Quat &q, const Quat &p, float32 a); -enum CombineOp -{ - COMBINEREPLACE, - COMBINEPRECONCAT, - COMBINEPOSTCONCAT -}; - struct RawMatrix { V3d right; diff --git a/src/rwcharset.h b/src/rwcharset.h index 3616603..d4576ed 100644 --- a/src/rwcharset.h +++ b/src/rwcharset.h @@ -12,9 +12,9 @@ struct Charset static bool32 open(void); static void close(void); - static Charset *create(RGBA *foreground, RGBA *background); + static Charset *create(const RGBA *foreground, const RGBA *background); void destroy(void); - Charset *setColors(RGBA *foreground, RGBA *background); + Charset *setColors(const RGBA *foreground, const RGBA *background); void print(const char *str, int32 x, int32 y, bool32 hideSpaces); void printBuffered(const char *str, int32 x, int32 y, bool32 hideSpaces); static void flushBuffer(void); diff --git a/src/rwplugins.h b/src/rwplugins.h index b26046a..af23303 100644 --- a/src/rwplugins.h +++ b/src/rwplugins.h @@ -6,7 +6,7 @@ namespace rw { struct HAnimKeyFrame { - HAnimKeyFrame *prev; + HAnimKeyFrame *prevFrame; float32 time; Quat q; V3d t; @@ -37,7 +37,7 @@ struct HAnimHierarchy HAnimNodeInfo *nodeInfo; Frame *parentFrame; HAnimHierarchy *parentHierarchy; // mostly unused - AnimInterpolator *currentAnim; + AnimInterpolator *interpolator; static HAnimHierarchy *create(int32 numNodes, int32 *nodeFlags, int32 *nodeIDs, int32 flags, int32 maxKeySize);