Lephisto/src/sbre/collfunc.cpp
2017-11-19 12:28:18 +00:00

228 lines
6.6 KiB
C++

#include <malloc.h>
#include "sbre_int.h"
#include "sbre.h" /* For subobject. */
static void ExpandVertices(CollMesh* pCMesh, int n) {
if(n < 100) n = 100;
pCMesh->maxv += n; n = pCMesh->maxv;
pCMesh->pVertex = (float*)realloc(pCMesh->pVertex, n*3*sizeof(float));
}
static void ExpandIndices(CollMesh* pCMesh, int n) {
if(n < 100) n = 100;
pCMesh->maxi += n; n = pCMesh->maxi;
pCMesh->pIndex = (int*)realloc(pCMesh->pIndex, n*sizeof(int));
pCMesh->pFlag = (int*)realloc(pCMesh->pFlag, sizeof(int) * n/3);
}
void ResolveVtx(Vector* pIn, Vector* pOut, RState* pState) {
Vector tv;
MatVecMult(&pState->objorient, pIn, &tv);
VecMul(&tv, pState->scale, &tv);
VecAdd(&tv, &pState->objpos, pOut);
}
static int CollFuncMatAnim(uint16* pData, Model* pMod, RState* pState) {
return 22;
}
static int CollFuncMatFixed(uint16* pData, Model* pMod, RState* pState) {
return 11;
}
static int CollFuncMatVar(uint16* pData, Model* pMod, RState* pState) {
return 2;
}
static int CollFuncZBias(uint16* pData, Model* pMod, RState* pState) {
return 4;
}
static int CollFuncTriFlat(uint16* pData, Model* pMod, RState* pState) {
Vector* pVtx = pState->pVtx;
CollMesh* pCMesh = pState->pCMesh;
if(pCMesh->maxv - pCMesh->nv < 6) ExpandVertices(pCMesh, 6);
if(pCMesh->maxi - pCMesh->ni < 6) ExpandIndices(pCMesh, 6);
int ni = pCMesh->ni; int nv = pCMesh->nv;
Vector* pOut = (Vector*)pCMesh->pVertex;
int* pIdx = pCMesh->pIndex;
pCMesh->pFlag[ni/3] = pCMesh->cflag;
for(int i = 0; i < 3; i++) {
ResolveVtx(pVtx+pData[i+1], pOut+nv, pState);
pIdx[ni++] = nv++;
}
if(pData[0] & RFLAG_XREF) {
pCMesh->pFlag[ni/3] = pCMesh->cflag;
for(int i = 0; i < 3; i++) {
Vector* pVec = pVtx + pData[3-i];
VecSet(-pVec->x, pVec->y, pVec->z, pOut+nv);
ResolveVtx(pOut+nv, pOut+nv, pState);
pIdx[ni++] = nv++;
}
}
pCMesh->ni = ni; pCMesh->nv = nv;
return 4;
}
static int CollFuncQuadFlat(uint16* pData, Model* pMod, RState* pState) {
Vector* pVtx = pState->pVtx;
CollMesh* pCMesh = pState->pCMesh;
if(pCMesh->maxv - pCMesh->nv < 8) ExpandVertices(pCMesh, 8);
if(pCMesh->maxi - pCMesh->ni < 12) ExpandIndices(pCMesh, 12);
int ni = pCMesh->ni; int nv = pCMesh->nv;
Vector* pOut = (Vector*)pCMesh->pVertex;
int* pIdx = pCMesh->pIndex;
pCMesh->pFlag[ni/3] = pCMesh->pFlag[1+ni/3] = pCMesh->cflag;
for(int i = 0; i < 4; i++) ResolveVtx(pVtx+pData[i+1], pOut+nv+i, pState);
pIdx[ni+0] = nv; pIdx[ni+1] = nv+1; pIdx[ni+2] = nv+2;
pIdx[ni+3] = nv; pIdx[ni+4] = nv+2; pIdx[ni+5] = nv+3;
ni += 6; nv += 4;
if(pData[0] & RFLAG_XREF) {
pCMesh->pFlag[ni/3] = pCMesh->pFlag[1+ni/3] = pCMesh->cflag;
for(int i = 0; i < 4; i++) {
Vector* pVec = pVtx + pData[i+1];
VecSet(-pVec->x, pVec->y, pVec->z, pOut+nv+i);
ResolveVtx(pOut+nv+i, pOut+nv+i, pState);
}
pIdx[ni+0] = nv; pIdx[ni+1] = nv+2; pIdx[ni+2] = nv + 1;
pIdx[ni+3] = nv; pIdx[ni+4] = nv+3; pIdx[ni+5] = nv + 2;
ni += 6; nv += 4;
}
pCMesh->ni = ni; pCMesh->nv = nv;
return 5;
}
static void ArrayCallback(int nv2, int ni2, Vector* pVertex, uint16* pIndex,
uint16 flags, RState* pState) {
CollMesh* pCMesh = pState->pCMesh;
if(pCMesh->maxv - pCMesh->nv < nv2*2) ExpandVertices(pCMesh, nv2*2);
if(pCMesh->maxi - pCMesh->ni < ni2*2) ExpandIndices(pCMesh, ni2*2);
int ni = pCMesh->ni; int nv = pCMesh->nv;
Vector* pOut = (Vector*)pCMesh->pVertex;
int* pIdx = pCMesh->pIndex;
int* pFlag = pCMesh->pFlag;
for(int i = 0; i < nv2; i++) ResolveVtx(pVertex+i*2, pOut+nv+i, pState);
for(int i = 0; i < ni2; i++) pIdx[ni+i] = nv+pIndex[i];
for(int i = 0; i < ni2/3; i++) pFlag[ni/3+i] = pCMesh->cflag;
ni += ni2; nv += nv2;
if(flags & RFLAG_XREF) {
for(int i = 0; i < nv2; i++) {
Vector* pVec = pVertex + i*2;
VecSet(-pVec->x, pVec->y, pVec->z, pOut+nv+i);
ResolveVtx(pOut+nv+i, pOut+nv+i, pState);
}
for(int i = 0; i < ni2; i += 3) {
pIdx[ni+i+0] = nv+pIndex[i];
pIdx[ni+i+1] = nv+pIndex[i+2];
pIdx[ni+i+2] = nv+pIndex[i+1];
}
for(int i = 0; i < ni2/3; i++) pFlag[ni/3+1] = pCMesh->cflag;
ni += ni2; nv+= nv2;
}
pCMesh->ni = ni; pCMesh->nv = nv;
}
static int CollFuncCompoundSmooth(uint16* pData, Model* pMod, RState* pState) {
pState->pCallback = ArrayCallback;
return pPrimFuncTable[*pData & 0xff](pData, pMod, pState);
}
static int CollFuncCylinder(uint16* pData, Model* pMod, RState* pState) {
pState->pCallback = ArrayCallback;
return pPrimFuncTable[*pData & 0xff](pData, pMod, pState);
}
static int CollFuncCircle(uint16* pData, Model* pMod, RState* pState) {
pState->pCallback = ArrayCallback;
return pPrimFuncTable[*pData & 0xff](pData, pMod, pState);
}
static int CollFuncTube(uint16* pData, Model* pMod, RState* pState) {
pState->pCallback = ArrayCallback;
return pPrimFuncTable[*pData & 0xff](pData, pMod, pState);
}
static int CollFuncExtrusion(uint16* pData, Model* pMod, RState* pState) {
pState->pCallback = ArrayCallback;
return pPrimFuncTable[*pData & 0xff](pData, pMod, pState);
}
/*
uint16 PFUNC_SUBOBJECT
uint16 anim
uint16 modelnum
uint16 offset
uint16 norm
uint16 zaxis
uint16 scale
*/
static int CollFuncSubObject(uint16* pData, Model* pMod, RState* pState) {
/* Return immediately if object is not present. */
if(pData[1] != 0x8000 && !pState->pObjParam->pFlag[pData[1]]) return 7;
/* Build transform matrix, offset. */
Vector v1, v2, v3, pos; Matrix m, orient;
VecNorm(pState->pVtx+pData[4], &v2);
VecNorm(pState->pVtx+pData[5], &v3);
VecCross(&v2, &v3, &v1);
m.x1 = v1.x; m.x2 = v2.x; m.x3 = v3.x;
m.y1 = v1.y; m.y2 = v2.y; m.y3 = v3.y;
m.z1 = v1.z; m.z2 = v2.z; m.z3 = v3.z;
MatMatMult(&pState->objorient, &m, &orient);
MatVecMult(&pState->objorient, pState->pVtx+pData[3], &pos);
VecMul(&pos, pState->scale, &pos);
VecAdd(&pos, &pState->objpos, &pos);
float scale = pState->scale*pData[6]*0.01f;
GenCollMeshInternal(&pos, &orient, pData[2], pState->pObjParam, scale, pState->pCMesh);
return 7;
}
static int CollFuncText(uint16* pData, Model* pMod, RState* pState) {
return 9;
}
/*
uint16 PFUNC_SETCFLAG
uint16 flag
*/
static int CollFuncSetCFlag(uint16* pData, Model* pMod, RState* pState) {
pState->pCMesh->cflag = pData[1];
return 2;
}
int (*pCollFuncTable[])(uint16*, Model*, RState*) = {
0, /* End. */
CollFuncMatAnim,
CollFuncMatFixed,
CollFuncMatVar,
CollFuncZBias,
CollFuncTriFlat,
CollFuncQuadFlat,
CollFuncCompoundSmooth, /* Just uses steps = 0. */
CollFuncCompoundSmooth,
CollFuncCircle,
CollFuncCylinder,
CollFuncTube,
CollFuncSubObject,
CollFuncText,
CollFuncExtrusion,
CollFuncSetCFlag,
};