mirror of
https://github.com/aap/librw.git
synced 2024-11-25 05:05:42 +00:00
userdata changes; hanim fixes; support for reading old skins
This commit is contained in:
parent
26a5502ee1
commit
171e737842
@ -132,7 +132,7 @@ Animation::streamReadLegacy(Stream *stream)
|
||||
stream->read32(&frames[i].t, 3*4);
|
||||
frames[i].time = stream->readF32();
|
||||
int32 prev = stream->readI32();
|
||||
frames[i].prevFrame = &frames[prev];
|
||||
frames[i].prev = &frames[prev];
|
||||
}
|
||||
return anim;
|
||||
}
|
||||
@ -162,7 +162,7 @@ Animation::streamWriteLegacy(Stream *stream)
|
||||
stream->write32(&frames[i].q, 4*4);
|
||||
stream->write32(&frames[i].t, 3*4);
|
||||
stream->writeF32(frames[i].time);
|
||||
stream->writeI32(frames[i].prevFrame - frames);
|
||||
stream->writeI32(frames[i].prev - frames);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -488,8 +488,10 @@ Matrix::lookAt(const V3d &dir, const V3d &up)
|
||||
this->flags = TYPEORTHONORMAL;
|
||||
}
|
||||
|
||||
/* For a row-major representation, this calculates src1 * src.
|
||||
* For colum-major src2 * src1 */
|
||||
/* For a row-major representation, this calculates src1 * src2.
|
||||
* For column-major src2 * src1.
|
||||
* i.e. a vector is first xformed by src1, then by src2
|
||||
*/
|
||||
void
|
||||
Matrix::mult_(Matrix *dst, const Matrix *src1, const Matrix *src2)
|
||||
{
|
||||
|
@ -102,7 +102,8 @@ HAnimHierarchy::attachByIndex(int32 idx)
|
||||
int32 id = this->nodeInfo[idx].id;
|
||||
// Frame *f = findById(this->parentFrame, id);
|
||||
Frame *f = findUnattachedById(this, this->parentFrame, id);
|
||||
this->nodeInfo[idx].frame = f;
|
||||
if(f)
|
||||
this->nodeInfo[idx].frame = f;
|
||||
}
|
||||
|
||||
void
|
||||
@ -172,8 +173,13 @@ HAnimHierarchy::updateMatrices(void)
|
||||
HAnimNodeInfo *node = this->nodeInfo;
|
||||
for(i = 0; i < this->numNodes; i++){
|
||||
anim->applyCB(&animMat, anim->getInterpFrame(i));
|
||||
|
||||
// TODO: here we could update local matrices
|
||||
|
||||
Matrix::mult(curMat, &animMat, parentMat);
|
||||
|
||||
// TODO: here we could update LTM
|
||||
|
||||
if(node->flags & PUSH)
|
||||
*sp++ = parentMat;
|
||||
parentMat = curMat;
|
||||
@ -317,7 +323,7 @@ hAnimFrameRead(Stream *stream, Animation *anim)
|
||||
stream->read32(&frames[i].q, 4*4);
|
||||
stream->read32(&frames[i].t, 3*4);
|
||||
int32 prev = stream->readI32()/0x24;
|
||||
frames[i].prevFrame = &frames[prev];
|
||||
frames[i].prev = &frames[prev];
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,7 +335,7 @@ hAnimFrameWrite(Stream *stream, Animation *anim)
|
||||
stream->writeF32(frames[i].time);
|
||||
stream->write32(&frames[i].q, 4*4);
|
||||
stream->write32(&frames[i].t, 3*4);
|
||||
stream->writeI32((frames[i].prevFrame - frames)*0x24);
|
||||
stream->writeI32((frames[i].prev - frames)*0x24);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -63,6 +63,10 @@ struct Animation
|
||||
int32 flags, float duration);
|
||||
void destroy(void);
|
||||
int32 getNumNodes(void);
|
||||
KeyFrameHeader *getAnimFrame(int32 n){
|
||||
return (KeyFrameHeader*)((uint8*)this->keyframes +
|
||||
n*this->interpInfo->animKeyFrameSize);
|
||||
}
|
||||
static Animation *streamRead(Stream *stream);
|
||||
static Animation *streamReadLegacy(Stream *stream);
|
||||
bool streamWrite(Stream *stream);
|
||||
|
@ -6,7 +6,7 @@ namespace rw {
|
||||
|
||||
struct HAnimKeyFrame
|
||||
{
|
||||
HAnimKeyFrame *prevFrame;
|
||||
HAnimKeyFrame *prev;
|
||||
float32 time;
|
||||
Quat q;
|
||||
V3d t;
|
||||
|
@ -64,7 +64,18 @@ struct UserDataExtension
|
||||
int32 numArrays;
|
||||
UserDataArray *arrays;
|
||||
|
||||
// TODO: static accessors
|
||||
int32 add(const char *name, int32 datatype, int32 numElements);
|
||||
void remove(int32 n);
|
||||
int32 getCount(void) { return numArrays; }
|
||||
UserDataArray *get(int32 n) { return n >= numArrays ? nil : &arrays[n]; }
|
||||
int32 findIndex(const char *name);
|
||||
|
||||
static UserDataExtension *get(Geometry *geo);
|
||||
static UserDataExtension *get(Frame *frame);
|
||||
static UserDataExtension *get(Camera *cam);
|
||||
static UserDataExtension *get(Light *light);
|
||||
static UserDataExtension *get(Material *mat);
|
||||
static UserDataExtension *get(Texture *tex);
|
||||
};
|
||||
|
||||
struct UserDataGlobals
|
||||
|
50
src/skin.cpp
50
src/skin.cpp
@ -252,6 +252,55 @@ getSizeSkin(void *object, int32 offset, int32)
|
||||
return size;
|
||||
}
|
||||
|
||||
static Stream*
|
||||
readSkinLegacy(Stream *stream, int32 len, void *object, int32, int32)
|
||||
{
|
||||
Atomic *atomic = (Atomic*)object;
|
||||
Geometry *geometry = atomic->geometry;
|
||||
|
||||
int32 numBones = stream->readI32();
|
||||
int32 numVertices = stream->readI32();
|
||||
assert(numVertices == geometry->numVertices);
|
||||
|
||||
Skin *skin = rwNewT(Skin, 1, MEMDUR_EVENT | ID_SKIN);
|
||||
*PLUGINOFFSET(Skin*, geometry, skinGlobals.geoOffset) = skin;
|
||||
skin->init(numBones, numBones, numVertices);
|
||||
skin->numWeights = 4;
|
||||
|
||||
stream->read8(skin->indices, numVertices*4);
|
||||
stream->read32(skin->weights, numVertices*16);
|
||||
|
||||
HAnimHierarchy *hier = HAnimHierarchy::create(numBones, nil, nil, 0, 36);
|
||||
|
||||
for(int i = 0; i < numBones; i++){
|
||||
hier->nodeInfo[i].id = stream->readI32();
|
||||
hier->nodeInfo[i].index = stream->readI32();
|
||||
hier->nodeInfo[i].flags = stream->readI32() & 3;
|
||||
// printf("%d %d %d %d\n", i, hier->nodeInfo[i].id, hier->nodeInfo[i].index, hier->nodeInfo[i].flags);
|
||||
stream->read32(&skin->inverseMatrices[i*16], 64);
|
||||
|
||||
Matrix mat;
|
||||
Matrix::invert(&mat, (Matrix*)&skin->inverseMatrices[i*16]);
|
||||
// printf("[ [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
|
||||
// " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
|
||||
// " [ %8.4f, %8.4f, %8.4f, %8.4f ]\n"
|
||||
// " [ %8.4f, %8.4f, %8.4f, %8.4f ] ]\n"
|
||||
// " %08x == flags\n",
|
||||
// mat.right.x, mat.up.x, mat.at.x, mat.pos.x,
|
||||
// mat.right.y, mat.up.y, mat.at.y, mat.pos.y,
|
||||
// mat.right.z, mat.up.z, mat.at.z, mat.pos.z,
|
||||
// 0.0f, 0.0f, 0.0f, 1.0f,
|
||||
// mat.flags);
|
||||
}
|
||||
Frame *frame = atomic->getFrame()->child;
|
||||
assert(frame->next == nil); // in old files atomic is above hierarchy it seems
|
||||
assert(frame->count() == numBones); // assuming one frame per node this should also be true
|
||||
HAnimData::get(frame)->hierarchy = hier;
|
||||
hier->parentFrame = frame;
|
||||
|
||||
return stream;
|
||||
}
|
||||
|
||||
static void
|
||||
skinRights(void *object, int32, int32, uint32)
|
||||
{
|
||||
@ -317,6 +366,7 @@ registerSkinPlugin(void)
|
||||
o = Atomic::registerPlugin(sizeof(HAnimHierarchy*),ID_SKIN,
|
||||
createSkinAtm, destroySkinAtm, copySkinAtm);
|
||||
skinGlobals.atomicOffset = o;
|
||||
Atomic::registerPluginStream(ID_SKIN, readSkinLegacy, nil, nil);
|
||||
Atomic::setStreamRightsCallback(ID_SKIN, skinRights);
|
||||
}
|
||||
|
||||
|
@ -226,27 +226,27 @@ getSizeUserData(void *object, int32 offset, int32)
|
||||
return size;
|
||||
}
|
||||
|
||||
static int32
|
||||
add(UserDataExtension *ext, const char *name, int32 datatype, int32 numElements)
|
||||
int32
|
||||
UserDataExtension::add(const char *name, int32 datatype, int32 numElements)
|
||||
{
|
||||
int32 i;
|
||||
int32 len;
|
||||
int32 typesz;
|
||||
UserDataArray *a;
|
||||
// try to find empty slot
|
||||
for(i = 0; i < ext->numArrays; i++)
|
||||
if(ext->arrays[i].datatype == USERDATANA)
|
||||
for(i = 0; i < this->numArrays; i++)
|
||||
if(this->arrays[i].datatype == USERDATANA)
|
||||
goto alloc;
|
||||
// have to realloc
|
||||
a = (UserDataArray*)udMalloc((ext->numArrays+1)*sizeof(UserDataArray));
|
||||
a = (UserDataArray*)udMalloc((this->numArrays+1)*sizeof(UserDataArray));
|
||||
if(a == nil)
|
||||
return -1;
|
||||
memcpy(a, ext->arrays, ext->numArrays*sizeof(UserDataArray));
|
||||
rwFree(ext->arrays);
|
||||
ext->arrays = a;
|
||||
i = ext->numArrays++;
|
||||
memcpy(a, this->arrays, this->numArrays*sizeof(UserDataArray));
|
||||
rwFree(this->arrays);
|
||||
this->arrays = a;
|
||||
i = this->numArrays++;
|
||||
alloc:
|
||||
a = &ext->arrays[i];
|
||||
a = &this->arrays[i];
|
||||
len = (int32)strlen(name)+1;
|
||||
a->name = (char*)udMalloc(len+1);
|
||||
assert(a->name);
|
||||
@ -262,11 +262,11 @@ alloc:
|
||||
return i;
|
||||
}
|
||||
|
||||
static void
|
||||
remove(UserDataExtension *ext, int32 n)
|
||||
void
|
||||
UserDataExtension::remove(int32 n)
|
||||
{
|
||||
int32 i;
|
||||
UserDataArray *a = &ext->arrays[n];
|
||||
UserDataArray *a = &this->arrays[n];
|
||||
if(a->name){
|
||||
rwFree(a->name);
|
||||
a->name = nil;
|
||||
@ -282,39 +282,39 @@ remove(UserDataExtension *ext, int32 n)
|
||||
a->numElements = 0;
|
||||
}
|
||||
|
||||
int32
|
||||
UserDataExtension::findIndex(const char *name) {
|
||||
for(int32 i = 0; i < this->numArrays; i++)
|
||||
if(strcmp(this->arrays[i].name, name) == 0)
|
||||
return i;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define ACCESSOR(TYPE, NAME) \
|
||||
int32 \
|
||||
UserDataArray::NAME##Add(TYPE *t, const char *name, int32 datatype, int32 numElements) \
|
||||
{ \
|
||||
return add(PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset), \
|
||||
name, datatype, numElements); \
|
||||
return PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset)->add(name, datatype, numElements); \
|
||||
} \
|
||||
void \
|
||||
UserDataArray::NAME##Remove(TYPE *t, int32 n) \
|
||||
{ \
|
||||
remove(PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset), n); \
|
||||
PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset)->remove(n); \
|
||||
} \
|
||||
int32 \
|
||||
UserDataArray::NAME##GetCount(TYPE *t) \
|
||||
{ \
|
||||
return PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset)->numArrays; \
|
||||
return PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset)->getCount(); \
|
||||
} \
|
||||
UserDataArray* \
|
||||
UserDataArray::NAME##Get(TYPE *t, int32 n) \
|
||||
{ \
|
||||
if(n >= PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset)->numArrays) \
|
||||
return nil; \
|
||||
return &PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset)->arrays[n]; \
|
||||
return PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset)->get(n); \
|
||||
} \
|
||||
int32 \
|
||||
UserDataArray::NAME##FindIndex(TYPE *t, const char *name) \
|
||||
{ \
|
||||
int32 i; \
|
||||
UserDataExtension *ext = PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset); \
|
||||
for(i = 0; i < ext->numArrays; i++) \
|
||||
if(strcmp(ext->arrays[i].name, name) == 0) \
|
||||
return i; \
|
||||
return -1; \
|
||||
return PLUGINOFFSET(UserDataExtension, t, userDataGlobals.NAME##Offset)->findIndex(name); \
|
||||
}
|
||||
|
||||
ACCESSOR(Geometry, geometry)
|
||||
@ -324,6 +324,13 @@ ACCESSOR(Light, light)
|
||||
ACCESSOR(Material, material)
|
||||
ACCESSOR(Texture, texture)
|
||||
|
||||
UserDataExtension *UserDataExtension::get(Geometry *geo) { return PLUGINOFFSET(UserDataExtension, geo, userDataGlobals.geometryOffset); }
|
||||
UserDataExtension *UserDataExtension::get(Frame *frame) { return PLUGINOFFSET(UserDataExtension, frame, userDataGlobals.frameOffset); }
|
||||
UserDataExtension *UserDataExtension::get(Camera *cam) { return PLUGINOFFSET(UserDataExtension, cam, userDataGlobals.cameraOffset); }
|
||||
UserDataExtension *UserDataExtension::get(Light *light) { return PLUGINOFFSET(UserDataExtension, light, userDataGlobals.lightOffset); }
|
||||
UserDataExtension *UserDataExtension::get(Material *mat) { return PLUGINOFFSET(UserDataExtension, mat, userDataGlobals.materialOffset); }
|
||||
UserDataExtension *UserDataExtension::get(Texture *tex) { return PLUGINOFFSET(UserDataExtension, tex, userDataGlobals.textureOffset); }
|
||||
|
||||
void
|
||||
registerUserDataPlugin(void)
|
||||
{
|
||||
|
Loading…
Reference in New Issue
Block a user