FITD/FitdLib/renderer.cpp

1111 lines
27 KiB
C++

#include "common.h"
/* Projection:
Z += cameraPerspective;
float transformedX = ((X * cameraFovX) / Z) + cameraCenterX;
float transformedY = ((Y * cameraFovY) / Z) + cameraCenterY;
{X, Y, Z, 1}
{
((X * cameraFovX) / Z) + cameraCenterX
((Y * cameraFovY) / Z) + cameraCenterY
Z + cameraPerspective
?
}
((X * CameraFovX) + (Z+CameraPersp) * cameraCenterX) / (Z+cameraPersp)
*/
struct rendererPointStruct
{
float X;
float Y;
float Z;
};
#define NUM_MAX_VERTEX_IN_PRIM 64
struct primEntryStruct
{
u8 material;
u8 color;
u16 size;
u16 numOfVertices;
primTypeEnum type;
rendererPointStruct vertices[NUM_MAX_VERTEX_IN_PRIM];
};
#define NUM_MAX_PRIM_ENTRY 500
primEntryStruct primTable[NUM_MAX_PRIM_ENTRY];
u32 positionInPrimEntry = 0;
int BBox3D1=0;
int BBox3D2=0;
int BBox3D3=0;
int BBox3D4=0;
int renderVar1=0;
int numOfPrimitiveToRender=0;
char renderBuffer[3261];
char* renderVar2=NULL;
int modelFlags = 0;
int modelCosAlpha;
int modelSinAlpha;
int modelCosBeta;
int modelSinBeta;
int modelCosGamma;
int modelSinGamma;
bool noModelRotation;
int renderX;
int renderY;
int renderZ;
int numOfPoints;
int numOfBones;
std::array<point3dStruct, NUM_MAX_POINT_IN_POINT_BUFFER> pointBuffer;
s16 cameraSpaceBuffer[NUM_MAX_POINT_IN_POINT_BUFFER*3];
s16 bonesBuffer[NUM_MAX_BONES];
bool boneRotateX;
bool boneRotateY;
bool boneRotateZ;
int boneRotateXCos;
int boneRotateXSin;
int boneRotateYCos;
int boneRotateYSin;
int boneRotateZCos;
int boneRotateZSin;
char primBuffer[30000];
int renderVar3;
#ifndef AITD_UE4
void fillpoly(s16 * datas, int n, char c);
#endif
/*
*/
void transformPoint(float* ax, float* bx, float* cx)
{
int X = (int)*ax;
int Y = (int)*bx;
int Z = (int)*cx;
{
int* ax = &X;
int* bx = &Y;
int* cx = &Z;
{
int x;
int y;
int z;
if(transformUseY)
{
x = (((((*ax) * transformYSin) - ((*cx) * transformYCos))) / 0x10000)<<1;
z = (((((*ax) * transformYCos) + ((*cx) * transformYSin))) / 0x10000)<<1;
}
else
{
x = (*ax);
z = (*cx);
}
//si = x
//ax = z
if(transformUseX)
{
int tempY = (*bx);
int tempZ = z;
y = ((((tempY * transformXSin ) - (tempZ * transformXCos))) / 0x10000)<<1;
z = ((((tempY * transformXCos ) + (tempZ * transformXSin))) / 0x10000)<<1;
}
else
{
y = (*bx);
}
// cx = y
// bx = z
if(transformUseZ)
{
int tempX = x;
int tempY = y;
x = ((((tempX * transformZSin) - ( tempY * transformZCos))) / 0x10000)<<1;
y = ((((tempX * transformZCos) + ( tempY * transformZSin))) / 0x10000)<<1;
}
*ax = x;
*bx = y;
*cx = z;
}
}
*ax = (float)X;
*bx = (float)Y;
*cx = (float)Z;
}
void InitGroupeRot(int transX,int transY,int transZ)
{
if(transX)
{
boneRotateXCos = cosTable[transX&0x3FF];
boneRotateXSin = cosTable[(transX+0x100)&0x3FF];
boneRotateX = true;
}
else
{
boneRotateX = false;
}
if(transY)
{
boneRotateYCos = cosTable[transY&0x3FF];
boneRotateYSin = cosTable[(transY+0x100)&0x3FF];
boneRotateY = true;
}
else
{
boneRotateY = false;
}
if(transZ)
{
boneRotateZCos = cosTable[transZ&0x3FF];
boneRotateZSin = cosTable[(transZ+0x100)&0x3FF];
boneRotateZ = true;
}
else
{
boneRotateZ = false;
}
}
void RotateList(point3dStruct* pointPtr, int numOfPoint)
{
for(int i=0;i<numOfPoint;i++)
{
point3dStruct& point = pointPtr[i];
int x = point.x;
int y = point.y;
int z = point.z;
if(boneRotateY)
{
int tempX = x;
int tempZ = z;
x = ((((tempX * boneRotateYSin) - (tempZ * boneRotateYCos)))>>16)<<1;
z = ((((tempX * boneRotateYCos) + (tempZ * boneRotateYSin)))>>16)<<1;
}
if(boneRotateX)
{
int tempY = y;
int tempZ = z;
y = ((((tempY * boneRotateXSin ) - (tempZ * boneRotateXCos)))>>16)<<1;
z = ((((tempY * boneRotateXCos ) + (tempZ * boneRotateXSin)))>>16)<<1;
}
if(boneRotateZ)
{
int tempX = x;
int tempY = y;
x = ((((tempX * boneRotateZSin) - ( tempY * boneRotateZCos)))>>16)<<1;
y = ((((tempX * boneRotateZCos) + ( tempY * boneRotateZSin)))>>16)<<1;
}
point.x = x;
point.y = y;
point.z = z;
}
}
void RotateGroupeOptimise(sGroup* ptr)
{
if (ptr->m_numGroup) // if group number is 0
{
int baseBone = ptr->m_start;
int numPoints = ptr->m_numVertices;
RotateList(pointBuffer.data() + baseBone, numPoints);
}
}
void RotateGroupe(sGroup* ptr)
{
int baseBone = ptr->m_start;
int numPoints = ptr->m_numVertices;
int temp;
int temp2;
RotateList(pointBuffer.data() + baseBone, numPoints);
temp = ptr->m_numGroup; // group number
temp2 = numOfBones - temp;
do
{
if (ptr->m_orgGroup == temp) // is it on of this group child
{
RotateGroupe(ptr); // yes, so apply the transformation to him
}
ptr++;
} while (--temp2);
}
void TranslateGroupe(int transX, int transY, int transZ, sGroup* ptr)
{
for (int i = 0; i < ptr->m_numVertices; i++)
{
point3dStruct& point = pointBuffer[ptr->m_start + i];
point.x += transX;
point.y += transY;
point.z += transZ;
}
}
void ZoomGroupe(int zoomX, int zoomY, int zoomZ, sGroup* ptr)
{
for (int i = 0; i < ptr->m_numVertices; i++)
{
point3dStruct& point = pointBuffer[ptr->m_start + i];
point.x = (point.x * (zoomX + 256)) / 256;
point.y = (point.y * (zoomY + 256)) / 256;
point.z = (point.z * (zoomZ + 256)) / 256;
}
}
int AnimNuage(int x,int y,int z,int alpha,int beta,int gamma, sBody* pBody)
{
renderX = x - translateX;
renderY = y;
renderZ = z - translateZ;
ASSERT(pBody->m_vertices.size()<NUM_MAX_POINT_IN_POINT_BUFFER);
for (int i = 0; i < pBody->m_vertices.size(); i++)
{
pointBuffer[i] = pBody->m_vertices[i];
}
numOfPoints = pBody->m_vertices.size();
numOfBones = pBody->m_groupOrder.size();
ASSERT(numOfBones<NUM_MAX_BONES);
if(pBody->m_flags & INFO_OPTIMISE)
{
for(int i=0;i<pBody->m_groupOrder.size();i++)
{
int boneDataOffset = pBody->m_groupOrder[i];
sGroup* pGroup = &pBody->m_groups[pBody->m_groupOrder[i]];
switch(pGroup->m_state.m_type)
{
case 1:
if(pGroup->m_state.m_delta.x || pGroup->m_state.m_delta.y || pGroup->m_state.m_delta.z)
{
TranslateGroupe(pGroup->m_state.m_delta.x, pGroup->m_state.m_delta.y, pGroup->m_state.m_delta.z, pGroup);
}
break;
case 2:
if (pGroup->m_state.m_delta.x || pGroup->m_state.m_delta.y || pGroup->m_state.m_delta.z)
{
ZoomGroupe(pGroup->m_state.m_delta.x, pGroup->m_state.m_delta.y, pGroup->m_state.m_delta.z, pGroup);
}
break;
}
InitGroupeRot(pGroup->m_state.m_rotateDelta.value().x, pGroup->m_state.m_rotateDelta.value().y, pGroup->m_state.m_rotateDelta.value().z);
RotateGroupeOptimise(pGroup);
}
}
else
{
pBody->m_groups[0].m_state.m_delta.x = alpha;
pBody->m_groups[0].m_state.m_delta.y = beta;
pBody->m_groups[0].m_state.m_delta.z = gamma;
for(int i=0;i<pBody->m_groups.size();i++)
{
int boneDataOffset = pBody->m_groupOrder[i];
sGroup* pGroup = &pBody->m_groups[pBody->m_groupOrder[i]];
int transX = pGroup->m_state.m_delta.x;
int transY = pGroup->m_state.m_delta.y;
int transZ = pGroup->m_state.m_delta.z;
if(transX || transY || transZ)
{
switch(pGroup->m_state.m_type)
{
case 0:
{
InitGroupeRot(transX,transY,transZ);
RotateGroupe(pGroup);
break;
}
case 1:
{
TranslateGroupe(transX,transY,transZ, pGroup);
break;
}
case 2:
{
ZoomGroupe(transX,transY,transZ, pGroup);
break;
}
}
}
}
}
for(int i=0;i<pBody->m_groups.size();i++)
{
sGroup* pGroup = &pBody->m_groups[i];
for(int j=0;j< pGroup->m_numVertices;j++)
{
pointBuffer[pGroup->m_start + j].x += pointBuffer[pGroup->m_baseVertices].x;
pointBuffer[pGroup->m_start + j].y += pointBuffer[pGroup->m_baseVertices].y;
pointBuffer[pGroup->m_start + j].z += pointBuffer[pGroup->m_baseVertices].z;
}
}
if(modelFlags & INFO_OPTIMISE)
{
InitGroupeRot(alpha,beta,gamma);
RotateList(pointBuffer.data(),numOfPoints);
}
{
s16* outPtr = cameraSpaceBuffer;
for(int i=0;i<numOfPoints;i++)
{
float X = pointBuffer[i].x;
float Y = pointBuffer[i].y;
float Z = pointBuffer[i].z;
X += renderX;
Y += renderY;
Z += renderZ;
#if defined(AITD_UE4)
*(outPtr++) = (s16)X;
*(outPtr++) = (s16)Y;
*(outPtr++) = (s16)Z;
#else
if(Y>10000) // height clamp
{
*(outPtr++) = -10000;
*(outPtr++) = -10000;
*(outPtr++) = -10000;
}
else
{
Y -= translateY;
transformPoint(&X,&Y,&Z);
*(outPtr++) = (s16)X;
*(outPtr++) = (s16)Y;
*(outPtr++) = (s16)Z;
}
#endif
}
s16* ptr = cameraSpaceBuffer;
float* outPtr2 = renderPointList;
int k = numOfPoints;
do
{
float X;
float Y;
float Z;
X = ptr[0];
Y = ptr[1];
Z = ptr[2];
ptr+=3;
#if defined(AITD_UE4)
*(outPtr2++) = X;
*(outPtr2++) = Y;
*(outPtr2++) = Z;
#else
Z += cameraPerspective;
if( Z<=50 ) // clipping
{
*(outPtr2++) = -10000;
*(outPtr2++) = -10000;
*(outPtr2++) = -10000;
}
else
{
float transformedX = ((X * cameraFovX) / Z) + cameraCenterX;
float transformedY;
*(outPtr2++) = transformedX;
if(transformedX < BBox3D1)
BBox3D1 = (int)transformedX;
if(transformedX > BBox3D3)
BBox3D3 = (int)transformedX;
transformedY = ((Y * cameraFovY) / Z) + cameraCenterY;
*(outPtr2++) = transformedY;
if(transformedY < BBox3D2)
BBox3D2 = (int)transformedY;
if(transformedY > BBox3D4)
BBox3D4 = (int)transformedY;
*(outPtr2++) = Z;
}
#endif
k--;
if(k==0)
{
return(1);
}
}while(renderVar1 == 0);
}
return(0);
}
/*
x - cameraX
y
z - cameraZ
*/
int RotateNuage(int x,int y,int z,int alpha,int beta,int gamma, sBody* pBody)
{
float* outPtr;
renderX = x - translateX;
renderY = y;
renderZ = z - translateZ;
if(!alpha && !beta && !gamma)
{
noModelRotation = true;
}
else
{
noModelRotation = false;
modelCosAlpha = cosTable[alpha&0x3FF];
modelSinAlpha = cosTable[(alpha+0x100)&0x3FF];
modelCosBeta = cosTable[beta&0x3FF];
modelSinBeta = cosTable[(beta+0x100)&0x3FF];
modelCosGamma = cosTable[gamma&0x3FF];
modelSinGamma = cosTable[(gamma+0x100)&0x3FF];
}
outPtr = renderPointList;
for(int i=0; i<pBody->m_vertices.size(); i++)
{
float X = pBody->m_vertices[i].x;
float Y = pBody->m_vertices[i].y;
float Z = pBody->m_vertices[i].z;
if(!noModelRotation)
{
// Y rotation
{
float tempX = X;
float tempZ = Z;
X = (((modelSinBeta * tempX) - (modelCosBeta * tempZ))/65536.f)*2.f;
Z = (((modelCosBeta * tempX) + (modelSinBeta * tempZ))/65536.f)*2.f;
}
// Z rotation
{
float tempX = X;
float tempY = Y;
X = (((modelSinGamma * tempX) - (modelCosGamma * tempY))/65536.f)*2.f;
Y = (((modelCosGamma * tempX) + (modelSinGamma * tempY))/65536.f)*2.f;
}
// X rotation
{
float tempY = Y;
float tempZ = Z;
Y = (((modelSinAlpha * tempY) - (modelCosAlpha * tempZ))/65536.f)*2.f;
Z = (((modelCosAlpha * tempY) + (modelSinAlpha * tempZ))/65536.f)*2.f;
}
}
X += renderX;
Y += renderY;
Z += renderZ;
#if defined(AITD_UE4)
*(outPtr++) = X;
*(outPtr++) = Y;
*(outPtr++) = Z;
#else
if(Y>10000) // height clamp
{
*(outPtr++) = -10000;
*(outPtr++) = -10000;
*(outPtr++) = -10000;
}
else
{
float transformedX;
float transformedY;
Y -= translateY;
transformPoint(&X,&Y,&Z);
Z += cameraPerspective;
transformedX = ((X * cameraFovX) / Z) + cameraCenterX;
*(outPtr++) = transformedX;
if(transformedX < BBox3D1)
BBox3D1 = (int)transformedX;
if(transformedX > BBox3D3)
BBox3D3 = (int)transformedX;
transformedY = ((Y * cameraFovY) / Z) + cameraCenterY;
*(outPtr++) = transformedY;
if(transformedY < BBox3D2)
BBox3D2 = (int)transformedY;
if(transformedY > BBox3D4)
BBox3D4 = (int)transformedY;
*(outPtr++) = Z;
/* *(outPtr++) = X;
*(outPtr++) = Y;
*(outPtr++) = Z; */
}
#endif
}
return(1);
}
char* primVar1;
char* primVar2;
void primFunctionDefault(int primType,char** ptr,char** out)
{
printf("UnHandled primType %d\n",primType);
assert(0);
}
void processPrim_Line(int primType, sPrimitive* ptr, char** out)
{
primEntryStruct* pCurrentPrimEntry = &primTable[positionInPrimEntry];
ASSERT(positionInPrimEntry < NUM_MAX_PRIM_ENTRY);
pCurrentPrimEntry->type = primTypeEnum_Line;
pCurrentPrimEntry->numOfVertices = 2;
pCurrentPrimEntry->color = ptr->m_color;
pCurrentPrimEntry->material = ptr->m_material;
float depth = 32000.f;
ASSERT(pCurrentPrimEntry->numOfVertices < NUM_MAX_VERTEX_IN_PRIM);
for (int i = 0; i < pCurrentPrimEntry->numOfVertices; i++)
{
u16 pointIndex;
pointIndex = ptr->m_points[i] * 6;
ASSERT((pointIndex % 2) == 0);
pCurrentPrimEntry->vertices[i].X = renderPointList[pointIndex / 2];
pCurrentPrimEntry->vertices[i].Y = renderPointList[(pointIndex / 2) + 1];
pCurrentPrimEntry->vertices[i].Z = renderPointList[(pointIndex / 2) + 2];
if (pCurrentPrimEntry->vertices[i].Z < depth)
depth = pCurrentPrimEntry->vertices[i].Z;
}
#if !defined(AITD_UE4)
if (depth > 100)
#endif
{
positionInPrimEntry++;
numOfPrimitiveToRender++;
ASSERT(positionInPrimEntry < NUM_MAX_PRIM_ENTRY);
}
}
void processPrim_Poly(int primType, sPrimitive* ptr, char** out)
{
primEntryStruct* pCurrentPrimEntry = &primTable[positionInPrimEntry];
ASSERT(positionInPrimEntry < NUM_MAX_PRIM_ENTRY);
pCurrentPrimEntry->type = primTypeEnum_Poly;
pCurrentPrimEntry->numOfVertices = ptr->m_points.size();
pCurrentPrimEntry->color = ptr->m_color;
pCurrentPrimEntry->material = ptr->m_material;
float depth = 32000.f;
ASSERT(pCurrentPrimEntry->numOfVertices < NUM_MAX_VERTEX_IN_PRIM);
for (int i = 0; i < pCurrentPrimEntry->numOfVertices; i++)
{
u16 pointIndex;
pointIndex = ptr->m_points[i] * 6;
ASSERT((pointIndex % 2) == 0);
pCurrentPrimEntry->vertices[i].X = renderPointList[pointIndex / 2];
pCurrentPrimEntry->vertices[i].Y = renderPointList[(pointIndex / 2) + 1];
pCurrentPrimEntry->vertices[i].Z = renderPointList[(pointIndex / 2) + 2];
if (pCurrentPrimEntry->vertices[i].Z < depth)
depth = pCurrentPrimEntry->vertices[i].Z;
}
#if !defined(AITD_UE4)
if (depth > 100)
#endif
{
positionInPrimEntry++;
numOfPrimitiveToRender++;
ASSERT(positionInPrimEntry < NUM_MAX_PRIM_ENTRY);
}
}
void processPrim_Point(primTypeEnum primType, sPrimitive* ptr, char** out)
{
primEntryStruct* pCurrentPrimEntry = &primTable[positionInPrimEntry];
ASSERT(positionInPrimEntry < NUM_MAX_PRIM_ENTRY);
pCurrentPrimEntry->type = primType;
pCurrentPrimEntry->numOfVertices = 1;
pCurrentPrimEntry->color = ptr->m_color;
pCurrentPrimEntry->material = ptr->m_material;
float depth = 32000.f;
{
u16 pointIndex;
pointIndex = ptr->m_points[0] * 6;
ASSERT((pointIndex % 2) == 0);
pCurrentPrimEntry->vertices[0].X = renderPointList[pointIndex / 2];
pCurrentPrimEntry->vertices[0].Y = renderPointList[(pointIndex / 2) + 1];
pCurrentPrimEntry->vertices[0].Z = renderPointList[(pointIndex / 2) + 2];
depth = pCurrentPrimEntry->vertices[0].Z;
}
#if !defined(AITD_UE4)
if (depth > 100)
#endif
{
positionInPrimEntry++;
numOfPrimitiveToRender++;
ASSERT(positionInPrimEntry < NUM_MAX_PRIM_ENTRY);
}
}
void processPrim_Sphere(int primType, sPrimitive* ptr, char** out)
{
primEntryStruct* pCurrentPrimEntry = &primTable[positionInPrimEntry];
ASSERT(positionInPrimEntry < NUM_MAX_PRIM_ENTRY);
pCurrentPrimEntry->type = primTypeEnum_Sphere;
pCurrentPrimEntry->numOfVertices = 1;
pCurrentPrimEntry->color = ptr->m_color;
pCurrentPrimEntry->material = ptr->m_material;
pCurrentPrimEntry->size = ptr->m_size;
float depth = 32000.f;
{
u16 pointIndex;
pointIndex = ptr->m_points[0] * 6;
ASSERT((pointIndex % 2) == 0);
pCurrentPrimEntry->vertices[0].X = renderPointList[pointIndex / 2];
pCurrentPrimEntry->vertices[0].Y = renderPointList[(pointIndex / 2) + 1];
pCurrentPrimEntry->vertices[0].Z = renderPointList[(pointIndex / 2) + 2];
depth = pCurrentPrimEntry->vertices[0].Z;
}
#if !defined(AITD_UE4)
if (depth > 100)
#endif
{
positionInPrimEntry++;
numOfPrimitiveToRender++;
ASSERT(positionInPrimEntry < NUM_MAX_PRIM_ENTRY);
}
}
void primType5(int primType, char** ptr, char** out) // draw out of hardClip
{
printf("ignoring prim type 5\n");
return;
int pointNumber;
s16 ax2;
primVar1 = *out;
*(s16*)(*out) = *(s16*)(*ptr);
*out+=2;
*ptr+=3;
pointNumber = *(s16*)(*ptr);
*ptr+=2;
// here, should check for clip on X Y Z
*(float*)(*out) = renderPointList[pointNumber/2]; // X
*out+=sizeof(float);
*(float*)(*out) = renderPointList[pointNumber/2+1]; // Y
*out+=sizeof(float);
*(float*)(*out) = renderPointList[pointNumber/2+2]; // Z
ax2 = (s16)(*(float*)(*out));
*out+=sizeof(float);
primVar2 = *out;
{
numOfPrimitiveToRender++;
*out = renderVar2;
*(s16*)(*out) = ax2;
*out+=2;
*(s16*)(*out) = ax2;
*out+=2;
*(s16*)(*out) = primType;
*out+=2;
*(char**)(*out) = primVar1;
*out+=4;
renderVar2 = *out;
*out = primVar2;
}
}
void line(int x1, int y1, int x2, int y2, char c);
void renderLine(primEntryStruct* pEntry) // line
{
osystem_draw3dLine( pEntry->vertices[0].X,pEntry->vertices[0].Y,pEntry->vertices[0].Z,
pEntry->vertices[1].X,pEntry->vertices[1].Y,pEntry->vertices[1].Z,
pEntry->color);
}
void renderPoly(primEntryStruct* pEntry) // poly
{
osystem_fillPoly((float*)pEntry->vertices,pEntry->numOfVertices, pEntry->color, pEntry->material);
}
void renderZixel(primEntryStruct* pEntry) // point
{
static float pointSize = 20.f;
float transformedSize = ((pointSize * (float)cameraFovX) / (float)(pEntry->vertices[0].Z+cameraPerspective));
osystem_drawPoint(pEntry->vertices[0].X,pEntry->vertices[0].Y,pEntry->vertices[0].Z,pEntry->color,pEntry->material, transformedSize);
}
void renderPoint(primEntryStruct* pEntry) // point
{
static float pointSize = 0.3f; // TODO: better way to compute that?
osystem_drawPoint(pEntry->vertices[0].X,pEntry->vertices[0].Y,pEntry->vertices[0].Z,pEntry->color, pEntry->material, pointSize);
}
void renderBigPoint(primEntryStruct* pEntry) // point
{
static float bigPointSize = 1.f; // TODO: better way to compute that?
osystem_drawPoint(pEntry->vertices[0].X,pEntry->vertices[0].Y,pEntry->vertices[0].Z,pEntry->color, pEntry->material, bigPointSize);
}
void renderSphere(primEntryStruct* pEntry) // sphere
{
float transformedSize;
transformedSize = (((float)pEntry->size * (float)cameraFovX) / (float)(pEntry->vertices[0].Z+cameraPerspective));
osystem_drawSphere(pEntry->vertices[0].X,pEntry->vertices[0].Y,pEntry->vertices[0].Z,pEntry->color, pEntry->material, transformedSize);
}
void defaultRenderFunction(primEntryStruct* buffer)
{
printf("Unsupported renderType\n");
}
typedef void (*renderFunction)(primEntryStruct* buffer);
renderFunction renderFunctions[]={
renderLine, // line
renderPoly, // poly
renderPoint, // point
renderSphere, // sphere
nullptr,
nullptr,
renderBigPoint,
renderZixel,
};
int AffObjet(int x,int y,int z,int alpha,int beta,int gamma, sBody* pBody)
{
int numPrim;
int i;
char* out;
// reinit the 2 static tables
positionInPrimEntry = 0;
//
BBox3D1 = 0x7FFF;
BBox3D2 = 0x7FFF;
BBox3D3 = -0x7FFF;
BBox3D4 = -0x7FFF;
renderVar1 = 0;
numOfPrimitiveToRender = 0;
renderVar2 = renderBuffer;
modelFlags = pBody->m_flags;
if(modelFlags&INFO_ANIM)
{
if(!AnimNuage(x,y,z,alpha,beta,gamma, pBody))
{
BBox3D3 = -32000;
BBox3D4 = -32000;
BBox3D1 = 32000;
BBox3D2 = 32000;
return(2);
}
}
else
if(!(modelFlags&INFO_TORTUE))
{
if(!RotateNuage(x,y,z,alpha,beta,gamma, pBody))
{
BBox3D3 = -32000;
BBox3D4 = -32000;
BBox3D1 = 32000;
BBox3D2 = 32000;
return(2);
}
}
else
{
printf("unsupported model type prerenderFlag4 in renderer !\n");
BBox3D3 = -32000;
BBox3D4 = -32000;
BBox3D1 = 32000;
BBox3D2 = 32000;
return(2);
}
numPrim = pBody->m_primitives.size();
if(!numPrim)
{
BBox3D3 = -32000;
BBox3D4 = -32000;
BBox3D1 = 32000;
BBox3D2 = 32000;
return(2);
}
out = primBuffer;
// create the list of all primitives to render
for(i=0;i<numPrim;i++)
{
sPrimitive* pPrimitive = &pBody->m_primitives[i];
primTypeEnum primType = pPrimitive->m_type;
switch(primType)
{
case primTypeEnum_Line:
processPrim_Line(primType, pPrimitive,&out);
break;
case primTypeEnum_Poly:
processPrim_Poly(primType, pPrimitive,&out);
break;
case primTypeEnum_Point:
case primTypeEnum_BigPoint:
case primTypeEnum_Zixel:
processPrim_Point(primType, pPrimitive,&out);
break;
case primTypeEnum_Sphere:
processPrim_Sphere(primType, pPrimitive,&out);
break;
case processPrim_PolyTexture9:
case processPrim_PolyTexture10:
processPrim_Poly(primType, pPrimitive, &out);
break;
default:
return 0;
assert(0);
}
}
#if 0
// TODO: poly sorting by depth
#ifdef USE_GL2
source = renderBuffer;
#else
inBuffer = renderBuffer;
outBuffer = sortedBuffer;
for(i=0;i<numOfPolyToRender;i++)
{
int j;
int bestIdx;
int bestDepth = -32000;
char* readBuffer = renderBuffer;
for(j=0;j<numOfPolyToRender;j++)
{
int depth = READ_LE_S16(readBuffer);
if(depth>bestDepth)
{
bestIdx = j;
bestDepth = depth;
}
readBuffer+=10;
}
memcpy(outBuffer,renderBuffer+10*bestIdx,10);
*(s16*)(renderBuffer+10*bestIdx) = -32000;
outBuffer+=10;
}
source = sortedBuffer;
#endif
#endif
//
if(!numOfPrimitiveToRender)
{
BBox3D3 = -32000;
BBox3D4 = -32000;
BBox3D1 = 32000;
BBox3D2 = 32000;
return(1); // model ok, but out of screen
}
// source += 10 * 1;
for(i=0;i<numOfPrimitiveToRender;i++)
{
renderFunctions[primTable[i].type](&primTable[i]);
}
//DEBUG
/* for(i=0;i<numPointInPoly;i++)
{
int x;
int y;
x = renderPointList[i*3];
y = renderPointList[i*3+1];
if(x>=0 && x < 319 && y>=0 && y<199)
{
screen[y*320+x] = 15;
}
}*/
//
osystem_flushPendingPrimitives();
return(0);
}
void computeScreenBox(int x, int y, int z, int alpha, int beta, int gamma, sBody* bodyPtr)
{
BBox3D1 = 0x7FFF;
BBox3D2 = 0x7FFF;
BBox3D3 = -0x7FFF;
BBox3D4 = -0x7FFF;
renderVar1 = 0;
numOfPrimitiveToRender = 0;
renderVar2 = renderBuffer;
modelFlags = bodyPtr->m_flags;
if(modelFlags&INFO_ANIM)
{
AnimNuage(x,y,z,alpha,beta,gamma, bodyPtr);
}
}