implemented MaterialList struct

This commit is contained in:
aap 2017-03-16 11:42:59 +01:00
parent 4941711964
commit e3c1f30856
15 changed files with 305 additions and 185 deletions

View File

@ -129,7 +129,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
inst->numVertices = *(uint32*)p; p += 4; inst->numVertices = *(uint32*)p; p += 4;
inst->numIndices = *(uint32*)p; p += 4; inst->numIndices = *(uint32*)p; p += 4;
uint32 matid = *(uint32*)p; p += 4; uint32 matid = *(uint32*)p; p += 4;
inst->material = geometry->materialList[matid]; inst->material = geometry->matList.materials[matid];
inst->vertexShader = *(uint32*)p; p += 4; inst->vertexShader = *(uint32*)p; p += 4;
inst->primType = *(uint32*)p; p += 4; inst->primType = *(uint32*)p; p += 4;
inst->indexBuffer = nil; p += 4; inst->indexBuffer = nil; p += 4;
@ -184,7 +184,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
*(uint32*)p = inst->stride; p += 4; *(uint32*)p = inst->stride; p += 4;
*(uint32*)p = inst->numVertices; p += 4; *(uint32*)p = inst->numVertices; p += 4;
*(uint32*)p = inst->numIndices; p += 4; *(uint32*)p = inst->numIndices; p += 4;
int32 matid = findPointer(inst->material, (void**)geometry->materialList, geometry->numMaterials); int32 matid = geometry->matList.findIndex(inst->material);
*(int32*)p = matid; p += 4; *(int32*)p = matid; p += 4;
*(uint32*)p = inst->vertexShader; p += 4; *(uint32*)p = inst->vertexShader; p += 4;
*(uint32*)p = inst->primType; p += 4; *(uint32*)p = inst->primType; p += 4;
@ -248,9 +248,9 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if(geo->geoflags & Geometry::NATIVE) if(geo->flags & Geometry::NATIVE)
return; return;
geo->geoflags |= Geometry::NATIVE; geo->flags |= Geometry::NATIVE;
InstanceDataHeader *header = new InstanceDataHeader; InstanceDataHeader *header = new InstanceDataHeader;
MeshHeader *meshh = geo->meshHeader; MeshHeader *meshh = geo->meshHeader;
geo->instData = header; geo->instData = header;
@ -295,11 +295,11 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0) if((geo->flags & Geometry::NATIVE) == 0)
return; return;
assert(geo->instData != nil); assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D8); assert(geo->instData->platform == PLATFORM_D3D8);
geo->geoflags &= ~Geometry::NATIVE; geo->flags &= ~Geometry::NATIVE;
geo->allocateData(); geo->allocateData();
geo->meshHeader->allocateIndices(); geo->meshHeader->allocateIndices();
@ -328,7 +328,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0) if((geo->flags & Geometry::NATIVE) == 0)
pipe->instance(atomic); pipe->instance(atomic);
assert(geo->instData != nil); assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D8); assert(geo->instData->platform == PLATFORM_D3D8);
@ -350,8 +350,8 @@ ObjPipeline::ObjPipeline(uint32 platform)
void void
defaultInstanceCB(Geometry *geo, InstanceData *inst) defaultInstanceCB(Geometry *geo, InstanceData *inst)
{ {
inst->vertexShader = makeFVFDeclaration(geo->geoflags, geo->numTexCoordSets); inst->vertexShader = makeFVFDeclaration(geo->flags, geo->numTexCoordSets);
inst->stride = getStride(geo->geoflags, geo->numTexCoordSets); inst->stride = getStride(geo->flags, geo->numTexCoordSets);
inst->vertexBuffer = createVertexBuffer(inst->numVertices*inst->stride, inst->vertexBuffer = createVertexBuffer(inst->numVertices*inst->stride,
inst->vertexShader, D3DPOOL_MANAGED); inst->vertexShader, D3DPOOL_MANAGED);
@ -363,7 +363,7 @@ defaultInstanceCB(Geometry *geo, InstanceData *inst)
inst->numVertices, inst->stride); inst->numVertices, inst->stride);
dst += 12; dst += 12;
if(geo->geoflags & Geometry::NORMALS){ if(geo->flags & Geometry::NORMALS){
instV3d(VERT_FLOAT3, dst, instV3d(VERT_FLOAT3, dst,
&geo->morphTargets[0].normals[3*inst->minVert], &geo->morphTargets[0].normals[3*inst->minVert],
inst->numVertices, inst->stride); inst->numVertices, inst->stride);
@ -371,7 +371,7 @@ defaultInstanceCB(Geometry *geo, InstanceData *inst)
} }
inst->vertexAlpha = 0; inst->vertexAlpha = 0;
if(geo->geoflags & Geometry::PRELIT){ if(geo->flags & Geometry::PRELIT){
inst->vertexAlpha = instColor(VERT_ARGB, dst, &geo->colors[4*inst->minVert], inst->vertexAlpha = instColor(VERT_ARGB, dst, &geo->colors[4*inst->minVert],
inst->numVertices, inst->stride); inst->numVertices, inst->stride);
dst += 4; dst += 4;
@ -394,7 +394,7 @@ defaultUninstanceCB(Geometry *geo, InstanceData *inst)
src, inst->numVertices, inst->stride); src, inst->numVertices, inst->stride);
src += 12; src += 12;
if(geo->geoflags & Geometry::NORMALS){ if(geo->flags & Geometry::NORMALS){
uninstV3d(VERT_FLOAT3, uninstV3d(VERT_FLOAT3,
&geo->morphTargets[0].normals[3*inst->minVert], &geo->morphTargets[0].normals[3*inst->minVert],
src, inst->numVertices, inst->stride); src, inst->numVertices, inst->stride);
@ -402,7 +402,7 @@ defaultUninstanceCB(Geometry *geo, InstanceData *inst)
} }
inst->vertexAlpha = 0; inst->vertexAlpha = 0;
if(geo->geoflags & Geometry::PRELIT){ if(geo->flags & Geometry::PRELIT){
uninstColor(VERT_ARGB, &geo->colors[4*inst->minVert], src, uninstColor(VERT_ARGB, &geo->colors[4*inst->minVert], src,
inst->numVertices, inst->stride); inst->numVertices, inst->stride);
src += 4; src += 4;

View File

@ -32,7 +32,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40)); d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
if(geo->geoflags & Geometry::PRELIT) if(geo->flags & Geometry::PRELIT)
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
device->SetFVF(inst->vertexShader); device->SetFVF(inst->vertexShader);

View File

@ -153,7 +153,7 @@ readNativeData(Stream *stream, int32, void *object, int32, int32)
inst->numIndex = *(uint32*)p; p += 4; inst->numIndex = *(uint32*)p; p += 4;
inst->minVert = *(uint32*)p; p += 4; inst->minVert = *(uint32*)p; p += 4;
uint32 matid = *(uint32*)p; p += 4; uint32 matid = *(uint32*)p; p += 4;
inst->material = geometry->materialList[matid]; inst->material = geometry->matList.materials[matid];
inst->vertexAlpha = *(bool32*)p; p += 4; inst->vertexAlpha = *(bool32*)p; p += 4;
inst->vertexShader = nil; p += 4; inst->vertexShader = nil; p += 4;
inst->baseIndex = 0; p += 4; inst->baseIndex = 0; p += 4;
@ -235,7 +235,7 @@ writeNativeData(Stream *stream, int32 len, void *object, int32, int32)
for(uint32 i = 0; i < header->numMeshes; i++){ for(uint32 i = 0; i < header->numMeshes; i++){
*(uint32*)p = inst->numIndex; p += 4; *(uint32*)p = inst->numIndex; p += 4;
*(uint32*)p = inst->minVert; p += 4; *(uint32*)p = inst->minVert; p += 4;
int32 matid = findPointer(inst->material, (void**)geometry->materialList, geometry->numMaterials); int32 matid = geometry->matList.findIndex(inst->material);
*(int32*)p = matid; p += 4; *(int32*)p = matid; p += 4;
*(bool32*)p = inst->vertexAlpha; p += 4; *(bool32*)p = inst->vertexAlpha; p += 4;
*(uint32*)p = 0; p += 4; // vertex shader *(uint32*)p = 0; p += 4; // vertex shader
@ -312,9 +312,9 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if(geo->geoflags & Geometry::NATIVE) if(geo->flags & Geometry::NATIVE)
return; return;
geo->geoflags |= Geometry::NATIVE; geo->flags |= Geometry::NATIVE;
InstanceDataHeader *header = new InstanceDataHeader; InstanceDataHeader *header = new InstanceDataHeader;
MeshHeader *meshh = geo->meshHeader; MeshHeader *meshh = geo->meshHeader;
geo->instData = header; geo->instData = header;
@ -365,11 +365,11 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0) if((geo->flags & Geometry::NATIVE) == 0)
return; return;
assert(geo->instData != nil); assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D9); assert(geo->instData->platform == PLATFORM_D3D9);
geo->geoflags &= ~Geometry::NATIVE; geo->flags &= ~Geometry::NATIVE;
geo->allocateData(); geo->allocateData();
geo->meshHeader->allocateIndices(); geo->meshHeader->allocateIndices();
@ -398,7 +398,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0) if((geo->flags & Geometry::NATIVE) == 0)
pipe->instance(atomic); pipe->instance(atomic);
assert(geo->instData != nil); assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_D3D9); assert(geo->instData->platform == PLATFORM_D3D9);
@ -439,7 +439,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
uint16 stride = 12; uint16 stride = 12;
s->geometryFlags |= 0x2; s->geometryFlags |= 0x2;
bool isPrelit = (geo->geoflags & Geometry::PRELIT) != 0; bool isPrelit = (geo->flags & Geometry::PRELIT) != 0;
if(isPrelit){ if(isPrelit){
dcl[i].stream = 0; dcl[i].stream = 0;
dcl[i].offset = stride; dcl[i].offset = stride;
@ -464,7 +464,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
stride += 8; stride += 8;
} }
bool hasNormals = (geo->geoflags & Geometry::NORMALS) != 0; bool hasNormals = (geo->flags & Geometry::NORMALS) != 0;
if(hasNormals){ if(hasNormals){
dcl[i].stream = 0; dcl[i].stream = 0;
dcl[i].offset = stride; dcl[i].offset = stride;
@ -540,7 +540,7 @@ defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header)
header->totalNumVertex, header->totalNumVertex,
header->vertexStream[dcl[i].stream].stride); header->vertexStream[dcl[i].stream].stride);
if(geo->geoflags & Geometry::PRELIT){ if(geo->flags & Geometry::PRELIT){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++) for(i = 0; dcl[i].usage != D3DDECLUSAGE_COLOR || dcl[i].usageIndex != 0; i++)
; ;
uninstColor(vertFormatMap[dcl[i].type], uninstColor(vertFormatMap[dcl[i].type],
@ -560,7 +560,7 @@ defaultUninstanceCB(Geometry *geo, InstanceDataHeader *header)
header->vertexStream[dcl[i].stream].stride); header->vertexStream[dcl[i].stream].stride);
} }
if(geo->geoflags & Geometry::NORMALS){ if(geo->flags & Geometry::NORMALS){
for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++) for(i = 0; dcl[i].usage != D3DDECLUSAGE_NORMAL || dcl[i].usageIndex != 0; i++)
; ;
uninstV3d(vertFormatMap[dcl[i].type], uninstV3d(vertFormatMap[dcl[i].type],

View File

@ -37,7 +37,7 @@ defaultRenderCB(Atomic *atomic, InstanceDataHeader *header)
d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40)); d3d::setRenderState(D3DRS_AMBIENT, D3DCOLOR_ARGB(0xFF, 0x40, 0x40, 0x40));
d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL); d3d::setRenderState(D3DRS_AMBIENTMATERIALSOURCE, D3DMCS_MATERIAL);
d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL); d3d::setRenderState(D3DRS_DIFFUSEMATERIALSOURCE, D3DMCS_MATERIAL);
if(geo->geoflags & Geometry::PRELIT) if(geo->flags & Geometry::PRELIT)
d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1); d3d::setRenderState(D3DRS_EMISSIVEMATERIALSOURCE, D3DMCS_COLOR1);
d3d::flushCache(); d3d::flushCache();
device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex, device->DrawIndexedPrimitive((D3DPRIMITIVETYPE)header->primType, inst->baseIndex,

View File

@ -197,9 +197,9 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if(geo->geoflags & Geometry::NATIVE) if(geo->flags & Geometry::NATIVE)
return; return;
geo->geoflags |= Geometry::NATIVE; geo->flags |= Geometry::NATIVE;
InstanceDataHeader *header = new InstanceDataHeader; InstanceDataHeader *header = new InstanceDataHeader;
MeshHeader *meshh = geo->meshHeader; MeshHeader *meshh = geo->meshHeader;
geo->instData = header; geo->instData = header;
@ -247,11 +247,11 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0) if((geo->flags & Geometry::NATIVE) == 0)
return; return;
assert(geo->instData != nil); assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_XBOX); assert(geo->instData->platform == PLATFORM_XBOX);
geo->geoflags &= ~Geometry::NATIVE; geo->flags &= ~Geometry::NATIVE;
geo->allocateData(); geo->allocateData();
geo->meshHeader->allocateIndices(); geo->meshHeader->allocateIndices();
@ -293,7 +293,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
{ {
uint32 *vertexFmt = getVertexFmt(geo); uint32 *vertexFmt = getVertexFmt(geo);
if(*vertexFmt == 0) if(*vertexFmt == 0)
*vertexFmt = makeVertexFmt(geo->geoflags, geo->numTexCoordSets); *vertexFmt = makeVertexFmt(geo->flags, geo->numTexCoordSets);
header->stride = getVertexFmtStride(*vertexFmt); header->stride = getVertexFmtStride(*vertexFmt);
header->vertexBuffer = new uint8[header->stride*header->numVertices]; header->vertexBuffer = new uint8[header->stride*header->numVertices];
uint8 *dst = (uint8*)header->vertexBuffer; uint8 *dst = (uint8*)header->vertexBuffer;

View File

@ -14,6 +14,8 @@
namespace rw { namespace rw {
SurfaceProperties defaultSurfaceProps = { 1.0f, 1.0f, 1.0f };
Geometry* Geometry*
Geometry::create(int32 numVerts, int32 numTris, uint32 flags) Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
{ {
@ -23,11 +25,11 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
return nil; return nil;
} }
geo->object.init(Geometry::ID, 0); geo->object.init(Geometry::ID, 0);
geo->geoflags = flags & 0xFF00FFFF; geo->flags = flags & 0xFF00FFFF;
geo->numTexCoordSets = (flags & 0xFF0000) >> 16; geo->numTexCoordSets = (flags & 0xFF0000) >> 16;
if(geo->numTexCoordSets == 0) if(geo->numTexCoordSets == 0)
geo->numTexCoordSets = (geo->geoflags & TEXTURED) ? 1 : geo->numTexCoordSets = (geo->flags & TEXTURED) ? 1 :
(geo->geoflags & TEXTURED2) ? 2 : 0; (geo->flags & TEXTURED2) ? 2 : 0;
geo->numTriangles = numTris; geo->numTriangles = numTris;
geo->numVertices = numVerts; geo->numVertices = numVerts;
geo->numMorphTargets = 1; geo->numMorphTargets = 1;
@ -36,10 +38,10 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
for(int32 i = 0; i < geo->numTexCoordSets; i++) for(int32 i = 0; i < geo->numTexCoordSets; i++)
geo->texCoords[i] = nil; geo->texCoords[i] = nil;
geo->triangles = nil; geo->triangles = nil;
if(!(geo->geoflags & NATIVE) && geo->numVertices){ if(!(geo->flags & NATIVE) && geo->numVertices){
if(geo->geoflags & PRELIT) if(geo->flags & PRELIT)
geo->colors = new uint8[4*geo->numVertices]; geo->colors = new uint8[4*geo->numVertices];
if((geo->geoflags & TEXTURED) || (geo->geoflags & TEXTURED2)) if((geo->flags & TEXTURED) || (geo->flags & TEXTURED2))
for(int32 i = 0; i < geo->numTexCoordSets; i++) for(int32 i = 0; i < geo->numTexCoordSets; i++)
geo->texCoords[i] = geo->texCoords[i] =
new float32[2*geo->numVertices]; new float32[2*geo->numVertices];
@ -51,13 +53,12 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
m->boundingSphere.radius = 0.0f; m->boundingSphere.radius = 0.0f;
m->vertices = nil; m->vertices = nil;
m->normals = nil; m->normals = nil;
if(!(geo->geoflags & NATIVE) && geo->numVertices){ if(!(geo->flags & NATIVE) && geo->numVertices){
m->vertices = new float32[3*geo->numVertices]; m->vertices = new float32[3*geo->numVertices];
if(geo->geoflags & NORMALS) if(geo->flags & NORMALS)
m->normals = new float32[3*geo->numVertices]; m->normals = new float32[3*geo->numVertices];
} }
geo->numMaterials = 0; geo->matList.init();
geo->materialList = nil;
geo->meshHeader = nil; geo->meshHeader = nil;
geo->instData = nil; geo->instData = nil;
geo->refCount = 1; geo->refCount = 1;
@ -84,10 +85,7 @@ Geometry::destroy(void)
} }
delete[] this->morphTargets; delete[] this->morphTargets;
delete this->meshHeader; delete this->meshHeader;
for(int32 i = 0; i < this->numMaterials; i++) this->matList.deinit();
if(this->materialList[i])
this->materialList[i]->destroy();
delete[] this->materialList;
free(this); free(this);
} }
} }
@ -105,6 +103,9 @@ Geometry::streamRead(Stream *stream)
{ {
uint32 version; uint32 version;
GeoStreamData buf; GeoStreamData buf;
SurfaceProperties surfProps;
MaterialList *ret;
if(!findChunk(stream, ID_STRUCT, nil, &version)){ if(!findChunk(stream, ID_STRUCT, nil, &version)){
RWERROR((ERR_CHUNK, "STRUCT")); RWERROR((ERR_CHUNK, "STRUCT"));
return nil; return nil;
@ -115,12 +116,11 @@ Geometry::streamRead(Stream *stream)
if(geo == nil) if(geo == nil)
return nil; return nil;
geo->addMorphTargets(buf.numMorphTargets-1); geo->addMorphTargets(buf.numMorphTargets-1);
// skip surface properties
if(version < 0x34000) if(version < 0x34000)
stream->seek(12); stream->read(&surfProps, 12);
if(!(geo->geoflags & NATIVE)){ if(!(geo->flags & NATIVE)){
if(geo->geoflags & PRELIT) if(geo->flags & PRELIT)
stream->read(geo->colors, 4*geo->numVertices); stream->read(geo->colors, 4*geo->numVertices);
for(int32 i = 0; i < geo->numTexCoordSets; i++) for(int32 i = 0; i < geo->numTexCoordSets; i++)
stream->read(geo->texCoords[i], stream->read(geo->texCoords[i],
@ -150,24 +150,13 @@ Geometry::streamRead(Stream *stream)
RWERROR((ERR_CHUNK, "MATLIST")); RWERROR((ERR_CHUNK, "MATLIST"));
goto fail; goto fail;
} }
if(!findChunk(stream, ID_STRUCT, nil, nil)){ if(version < 0x34000)
RWERROR((ERR_CHUNK, "STRUCT")); defaultSurfaceProps = surfProps;
ret = MaterialList::streamRead(stream, &geo->matList);
if(version < 0x34000)
defaultSurfaceProps = (SurfaceProperties){ 1.0f, 1.0f, 1.0f };
if(ret == nil)
goto fail; goto fail;
}
geo->numMaterials = stream->readI32();
geo->materialList = new Material*[geo->numMaterials];
stream->seek(geo->numMaterials*4); // material indices...but always -1
Material *m;
for(int32 i = 0; i < geo->numMaterials; i++){
if(!findChunk(stream, ID_MATERIAL, nil, nil)){
RWERROR((ERR_CHUNK, "MATERIAL"));
goto fail;
}
m = Material::streamRead(stream);
if(m == nil)
goto fail;
geo->materialList[i] = m;
}
if(s_plglist.streamRead(stream, geo)) if(s_plglist.streamRead(stream, geo))
return geo; return geo;
@ -183,8 +172,8 @@ geoStructSize(Geometry *geo)
size += sizeof(GeoStreamData); size += sizeof(GeoStreamData);
if(version < 0x34000) if(version < 0x34000)
size += 12; // surface properties size += 12; // surface properties
if(!(geo->geoflags & Geometry::NATIVE)){ if(!(geo->flags & Geometry::NATIVE)){
if(geo->geoflags&geo->PRELIT) if(geo->flags&geo->PRELIT)
size += 4*geo->numVertices; size += 4*geo->numVertices;
for(int32 i = 0; i < geo->numTexCoordSets; i++) for(int32 i = 0; i < geo->numTexCoordSets; i++)
size += 2*geo->numVertices*4; size += 2*geo->numVertices*4;
@ -193,7 +182,7 @@ geoStructSize(Geometry *geo)
for(int32 i = 0; i < geo->numMorphTargets; i++){ for(int32 i = 0; i < geo->numMorphTargets; i++){
MorphTarget *m = &geo->morphTargets[i]; MorphTarget *m = &geo->morphTargets[i];
size += 4*4 + 2*4; // bounding sphere and bools size += 4*4 + 2*4; // bounding sphere and bools
if(!(geo->geoflags & Geometry::NATIVE)){ if(!(geo->flags & Geometry::NATIVE)){
if(m->vertices) if(m->vertices)
size += 3*geo->numVertices*4; size += 3*geo->numVertices*4;
if(m->normals) if(m->normals)
@ -207,13 +196,12 @@ bool
Geometry::streamWrite(Stream *stream) Geometry::streamWrite(Stream *stream)
{ {
GeoStreamData buf; GeoStreamData buf;
uint32 size;
static float32 fbuf[3] = { 1.0f, 1.0f, 1.0f }; static float32 fbuf[3] = { 1.0f, 1.0f, 1.0f };
writeChunkHeader(stream, ID_GEOMETRY, this->streamGetSize()); writeChunkHeader(stream, ID_GEOMETRY, this->streamGetSize());
writeChunkHeader(stream, ID_STRUCT, geoStructSize(this)); writeChunkHeader(stream, ID_STRUCT, geoStructSize(this));
buf.flags = this->geoflags | this->numTexCoordSets << 16; buf.flags = this->flags | this->numTexCoordSets << 16;
buf.numTriangles = this->numTriangles; buf.numTriangles = this->numTriangles;
buf.numVertices = this->numVertices; buf.numVertices = this->numVertices;
buf.numMorphTargets = this->numMorphTargets; buf.numMorphTargets = this->numMorphTargets;
@ -221,8 +209,8 @@ Geometry::streamWrite(Stream *stream)
if(version < 0x34000) if(version < 0x34000)
stream->write(fbuf, sizeof(fbuf)); stream->write(fbuf, sizeof(fbuf));
if(!(this->geoflags & NATIVE)){ if(!(this->flags & NATIVE)){
if(this->geoflags & PRELIT) if(this->flags & PRELIT)
stream->write(this->colors, 4*this->numVertices); stream->write(this->colors, 4*this->numVertices);
for(int32 i = 0; i < this->numTexCoordSets; i++) for(int32 i = 0; i < this->numTexCoordSets; i++)
stream->write(this->texCoords[i], stream->write(this->texCoords[i],
@ -240,7 +228,7 @@ Geometry::streamWrite(Stream *stream)
for(int32 i = 0; i < this->numMorphTargets; i++){ for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &this->morphTargets[i]; MorphTarget *m = &this->morphTargets[i];
stream->write(&m->boundingSphere, 4*4); stream->write(&m->boundingSphere, 4*4);
if(!(this->geoflags & NATIVE)){ if(!(this->flags & NATIVE)){
stream->writeI32(m->vertices != nil); stream->writeI32(m->vertices != nil);
stream->writeI32(m->normals != nil); stream->writeI32(m->normals != nil);
if(m->vertices) if(m->vertices)
@ -255,16 +243,7 @@ Geometry::streamWrite(Stream *stream)
} }
} }
size = 12 + 4; this->matList.streamWrite(stream);
for(int32 i = 0; i < this->numMaterials; i++)
size += 4 + 12 + this->materialList[i]->streamGetSize();
writeChunkHeader(stream, ID_MATLIST, size);
writeChunkHeader(stream, ID_STRUCT, 4 + this->numMaterials*4);
stream->writeI32(this->numMaterials);
for(int32 i = 0; i < this->numMaterials; i++)
stream->writeI32(-1);
for(int32 i = 0; i < this->numMaterials; i++)
this->materialList[i]->streamWrite(stream);
s_plglist.streamWrite(stream, this); s_plglist.streamWrite(stream, this);
return true; return true;
@ -275,9 +254,7 @@ Geometry::streamGetSize(void)
{ {
uint32 size = 0; uint32 size = 0;
size += 12 + geoStructSize(this); size += 12 + geoStructSize(this);
size += 12 + 12 + 4; size += 12 + this->matList.streamGetSize();
for(int32 i = 0; i < this->numMaterials; i++)
size += 4 + 12 + this->materialList[i]->streamGetSize();
size += 12 + s_plglist.streamGetSize(this); size += 12 + s_plglist.streamGetSize(this);
return size; return size;
} }
@ -296,9 +273,9 @@ Geometry::addMorphTargets(int32 n)
MorphTarget *m = &morphTargets[i]; MorphTarget *m = &morphTargets[i];
m->vertices = nil; m->vertices = nil;
m->normals = nil; m->normals = nil;
if(!(this->geoflags & NATIVE)){ if(!(this->flags & NATIVE)){
m->vertices = new float32[3*this->numVertices]; m->vertices = new float32[3*this->numVertices];
if(this->geoflags & NORMALS) if(this->flags & NORMALS)
m->normals = new float32[3*this->numVertices]; m->normals = new float32[3*this->numVertices];
} }
} }
@ -331,11 +308,11 @@ Geometry::calculateBoundingSphere(void)
bool32 bool32
Geometry::hasColoredMaterial(void) Geometry::hasColoredMaterial(void)
{ {
for(int32 i = 0; i < this->numMaterials; i++) for(int32 i = 0; i < this->matList.numMaterials; i++)
if(this->materialList[i]->color.red != 255 || if(this->matList.materials[i]->color.red != 255 ||
this->materialList[i]->color.green != 255 || this->matList.materials[i]->color.green != 255 ||
this->materialList[i]->color.blue != 255 || this->matList.materials[i]->color.blue != 255 ||
this->materialList[i]->color.alpha != 255) this->matList.materials[i]->color.alpha != 255)
return 1; return 1;
return 0; return 0;
} }
@ -343,15 +320,15 @@ Geometry::hasColoredMaterial(void)
void void
Geometry::allocateData(void) Geometry::allocateData(void)
{ {
if(this->geoflags & PRELIT) if(this->flags & PRELIT)
this->colors = new uint8[4*this->numVertices]; this->colors = new uint8[4*this->numVertices];
if((this->geoflags & TEXTURED) || (this->geoflags & TEXTURED2)) if((this->flags & TEXTURED) || (this->flags & TEXTURED2))
for(int32 i = 0; i < this->numTexCoordSets; i++) for(int32 i = 0; i < this->numTexCoordSets; i++)
this->texCoords[i] = this->texCoords[i] =
new float32[2*this->numVertices]; new float32[2*this->numVertices];
MorphTarget *m = this->morphTargets; MorphTarget *m = this->morphTargets;
m->vertices = new float32[3*this->numVertices]; m->vertices = new float32[3*this->numVertices];
if(this->geoflags & NORMALS) if(this->flags & NORMALS)
m->normals = new float32[3*this->numVertices]; m->normals = new float32[3*this->numVertices];
// TODO: morph targets (who cares anyway?) // TODO: morph targets (who cares anyway?)
} }
@ -404,9 +381,7 @@ Geometry::generateTriangles(int8 *adc)
m++; m++;
continue; continue;
} }
int32 matid = findPointer((void*)m->material, int32 matid = this->matList.findIndex(m->material);
(void**)this->materialList,
this->numMaterials);
if(header->flags == MeshHeader::TRISTRIP) if(header->flags == MeshHeader::TRISTRIP)
for(uint32 j = 0; j < m->numIndices-2; j++){ for(uint32 j = 0; j < m->numIndices-2; j++){
if(adc && adcbits[j+2] || if(adc && adcbits[j+2] ||
@ -456,13 +431,13 @@ Geometry::buildMeshes(void)
Triangle *tri; Triangle *tri;
MeshHeader *h = new MeshHeader; MeshHeader *h = new MeshHeader;
this->meshHeader = h; this->meshHeader = h;
if((this->geoflags & Geometry::TRISTRIP) == 0){ if((this->flags & Geometry::TRISTRIP) == 0){
h->flags = 0; h->flags = 0;
h->totalIndices = this->numTriangles*3; h->totalIndices = this->numTriangles*3;
h->numMeshes = this->numMaterials; h->numMeshes = this->matList.numMaterials;
h->mesh = new Mesh[h->numMeshes]; h->mesh = new Mesh[h->numMeshes];
for(uint32 i = 0; i < h->numMeshes; i++){ for(uint32 i = 0; i < h->numMeshes; i++){
h->mesh[i].material = this->materialList[i]; h->mesh[i].material = this->matList.materials[i];
h->mesh[i].numIndices = 0; h->mesh[i].numIndices = 0;
} }
// count indices per mesh // count indices per mesh
@ -496,7 +471,7 @@ Geometry::correctTristripWinding(void)
{ {
MeshHeader *header = this->meshHeader; MeshHeader *header = this->meshHeader;
if(header == nil || header->flags != MeshHeader::TRISTRIP || if(header == nil || header->flags != MeshHeader::TRISTRIP ||
this->geoflags & NATIVE) this->flags & NATIVE)
return; return;
MeshHeader *newhead = new MeshHeader; MeshHeader *newhead = new MeshHeader;
newhead->flags = header->flags; newhead->flags = header->flags;
@ -546,7 +521,6 @@ Geometry::correctTristripWinding(void)
delete header; delete header;
} }
// HAS to be called with an existing mesh
void void
Geometry::removeUnusedMaterials(void) Geometry::removeUnusedMaterials(void)
{ {
@ -556,24 +530,28 @@ Geometry::removeUnusedMaterials(void)
for(uint32 i = 0; i < mh->numMeshes; i++) for(uint32 i = 0; i < mh->numMeshes; i++)
if(mh->mesh[i].indices == nil) if(mh->mesh[i].indices == nil)
return; return;
int32 *map = new int32[this->numMaterials];
Material **matlist = new Material*[this->numMaterials]; int32 *map = new int32[this->matList.numMaterials];
Material **materials = new Material*[this->matList.numMaterials];
int32 numMaterials = 0; int32 numMaterials = 0;
/* Build new material list and map */ /* Build new material list and map */
for(uint32 i = 0; i < mh->numMeshes; i++){ for(uint32 i = 0; i < mh->numMeshes; i++){
Mesh *m = &mh->mesh[i]; Mesh *m = &mh->mesh[i];
if(m->numIndices <= 0) if(m->numIndices <= 0)
continue; continue;
matlist[numMaterials] = m->material; materials[numMaterials] = m->material;
int32 oldid = findPointer((void*)m->material, m->material->refCount++;
(void**)this->materialList, int32 oldid = this->matList.findIndex(m->material);
this->numMaterials);
map[oldid] = numMaterials; map[oldid] = numMaterials;
numMaterials++; numMaterials++;
} }
delete[] this->materialList; for(int32 i = 0; i < this->matList.numMaterials; i++)
this->materialList = matlist; this->matList.materials[i]->destroy();
this->numMaterials = numMaterials; free(this->matList.materials);
this->matList.materials = materials;
this->matList.space = this->matList.numMaterials;
this->matList.numMaterials = numMaterials;
/* Build new meshes */ /* Build new meshes */
MeshHeader *newmh = new MeshHeader; MeshHeader *newmh = new MeshHeader;
newmh->flags = mh->flags; newmh->flags = mh->flags;
@ -602,12 +580,154 @@ Geometry::removeUnusedMaterials(void)
} }
delete this->meshHeader; delete this->meshHeader;
this->meshHeader = newmh; this->meshHeader = newmh;
/* Remap triangle material IDs */ /* Remap triangle material IDs */
for(int32 i = 0; i < this->numTriangles; i++) for(int32 i = 0; i < this->numTriangles; i++)
this->triangles[i].matId = map[this->triangles[i].matId]; this->triangles[i].matId = map[this->triangles[i].matId];
delete[] map; delete[] map;
} }
//
// MaterialList
//
void
MaterialList::init(void)
{
this->materials = nil;
this->numMaterials = 0;
this->space = 0;
}
void
MaterialList::deinit(void)
{
if(this->materials){
for(int32 i = 0; i < this->numMaterials; i++)
this->materials[i]->destroy();
free(this->materials);
}
}
int32
MaterialList::appendMaterial(Material *mat)
{
Material **ml;
int32 space;
if(this->numMaterials >= this->space){
space = this->space + 20;
if(this->materials)
ml = (Material**)realloc(this->materials,
space*sizeof(Material*));
else
ml = (Material**)malloc(space*sizeof(Material*));
if(ml == nil)
return -1;
this->space = space;
this->materials = ml;
}
this->materials[this->numMaterials++] = mat;
mat->refCount++;
return this->numMaterials-1;
}
int32
MaterialList::findIndex(Material *mat)
{
for(int32 i = 0; i < this->numMaterials; i++)
if(this->materials[i] == mat)
return i;
return -1;
}
MaterialList*
MaterialList::streamRead(Stream *stream, MaterialList *matlist)
{
int32 *indices = nil;
int32 numMat;
if(!findChunk(stream, ID_STRUCT, nil, nil)){
RWERROR((ERR_CHUNK, "STRUCT"));
goto fail;
}
matlist->init();
numMat = stream->readI32();
if(numMat == 0)
return matlist;
matlist->materials = (Material**)malloc(numMat*sizeof(Material*));
if(matlist->materials == nil)
goto fail;
matlist->space = numMat;
indices = (int32*)malloc(numMat*4);
stream->read(indices, numMat*4);
Material *m;
for(int32 i = 0; i < numMat; i++){
if(indices[i] >= 0){
m = matlist->materials[indices[i]];
m->refCount++;
}else{
if(!findChunk(stream, ID_MATERIAL, nil, nil)){
RWERROR((ERR_CHUNK, "MATERIAL"));
goto fail;
}
m = Material::streamRead(stream);
if(m == nil)
goto fail;
}
matlist->appendMaterial(m);
m->destroy();
}
free(indices);
return matlist;
fail:
free(indices);
matlist->deinit();
return nil;
}
bool
MaterialList::streamWrite(Stream *stream)
{
uint32 size = this->streamGetSize();
writeChunkHeader(stream, ID_MATLIST, size);
writeChunkHeader(stream, ID_STRUCT, 4 + this->numMaterials*4);
stream->writeI32(this->numMaterials);
int32 idx;
for(int32 i = 0; i < this->numMaterials; i++){
idx = -1;
for(int32 j = i-1; j >= 0; j--)
if(this->materials[i] == this->materials[j]){
idx = j;
break;
}
stream->writeI32(idx);
}
for(int32 i = 0; i < this->numMaterials; i++){
for(int32 j = i-1; j >= 0; j--)
if(this->materials[i] == this->materials[j])
goto found;
this->materials[i]->streamWrite(stream);
found:;
}
return true;
}
uint32
MaterialList::streamGetSize(void)
{
uint32 size = 12 + 4 + this->numMaterials*4;
for(int32 i = 0; i < this->numMaterials; i++){
for(int32 j = i-1; j >= 0; j--)
if(this->materials[i] == this->materials[j])
goto found;
size += 12 + this->materials[i]->streamGetSize();
found:;
}
return size;
}
// //
// Material // Material
// //
@ -622,9 +742,7 @@ Material::create(void)
} }
mat->texture = nil; mat->texture = nil;
memset(&mat->color, 0xFF, 4); memset(&mat->color, 0xFF, 4);
mat->surfaceProps.ambient = 1.0f; mat->surfaceProps = defaultSurfaceProps;
mat->surfaceProps.specular = 1.0f;
mat->surfaceProps.diffuse = 1.0f;
mat->pipeline = nil; mat->pipeline = nil;
mat->refCount = 1; mat->refCount = 1;
s_plglist.construct(mat); s_plglist.construct(mat);
@ -695,17 +813,10 @@ Material::streamRead(Stream *stream)
if(mat == nil) if(mat == nil)
return nil; return nil;
mat->color = buf.color; mat->color = buf.color;
if(version < 0x30400){ if(version < 0x30400)
mat->surfaceProps.ambient = 1.0f; mat->surfaceProps = defaultSurfaceProps;
mat->surfaceProps.specular = 1.0f; else
mat->surfaceProps.diffuse = 1.0f; stream->read(&mat->surfaceProps, sizeof(surfaceProps));
}else{
float32 surfaceProps[3];
stream->read(surfaceProps, sizeof(surfaceProps));
mat->surfaceProps.ambient = surfaceProps[0];
mat->surfaceProps.specular = surfaceProps[1];
mat->surfaceProps.diffuse = surfaceProps[2];
}
if(buf.textured){ if(buf.textured){
if(!findChunk(stream, ID_TEXTURE, &length, nil)){ if(!findChunk(stream, ID_TEXTURE, &length, nil)){
RWERROR((ERR_CHUNK, "TEXTURE")); RWERROR((ERR_CHUNK, "TEXTURE"));

View File

@ -39,14 +39,14 @@ readMesh(Stream *stream, int32 len, void *object, int32, int32)
Mesh *mesh = geo->meshHeader->mesh; Mesh *mesh = geo->meshHeader->mesh;
bool hasData = len > 12+geo->meshHeader->numMeshes*8; bool hasData = len > 12+geo->meshHeader->numMeshes*8;
uint16 *p = nil; uint16 *p = nil;
if(!(geo->geoflags & Geometry::NATIVE) || hasData) if(!(geo->flags & Geometry::NATIVE) || hasData)
p = new uint16[geo->meshHeader->totalIndices]; p = new uint16[geo->meshHeader->totalIndices];
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){ for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
stream->read(buf, 8); stream->read(buf, 8);
mesh->numIndices = buf[0]; mesh->numIndices = buf[0];
mesh->material = geo->materialList[buf[1]]; mesh->material = geo->matList.materials[buf[1]];
mesh->indices = nil; mesh->indices = nil;
if(geo->geoflags & Geometry::NATIVE){ if(geo->flags & Geometry::NATIVE){
// OpenGL stores uint16 indices here // OpenGL stores uint16 indices here
if(hasData){ if(hasData){
mesh->indices = p; mesh->indices = p;
@ -85,11 +85,9 @@ writeMesh(Stream *stream, int32, void *object, int32, int32)
Mesh *mesh = geo->meshHeader->mesh; Mesh *mesh = geo->meshHeader->mesh;
for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){ for(uint32 i = 0; i < geo->meshHeader->numMeshes; i++){
buf[0] = mesh->numIndices; buf[0] = mesh->numIndices;
buf[1] = findPointer((void*)mesh->material, buf[1] = geo->matList.findIndex(mesh->material);
(void**)geo->materialList,
geo->numMaterials);
stream->write(buf, 8); stream->write(buf, 8);
if(geo->geoflags & Geometry::NATIVE){ if(geo->flags & Geometry::NATIVE){
assert(geo->instData != nil); assert(geo->instData != nil);
if(geo->instData->platform == PLATFORM_WDGL) if(geo->instData->platform == PLATFORM_WDGL)
stream->write(mesh->indices, stream->write(mesh->indices,
@ -117,7 +115,7 @@ getSizeMesh(void *object, int32, int32)
if(geo->meshHeader == nil) if(geo->meshHeader == nil)
return -1; return -1;
int32 size = 12 + geo->meshHeader->numMeshes*8; int32 size = 12 + geo->meshHeader->numMeshes*8;
if(geo->geoflags & Geometry::NATIVE){ if(geo->flags & Geometry::NATIVE){
assert(geo->instData != nil); assert(geo->instData != nil);
if(geo->instData->platform == PLATFORM_WDGL) if(geo->instData->platform == PLATFORM_WDGL)
size += geo->meshHeader->totalIndices*2; size += geo->meshHeader->totalIndices*2;

View File

@ -27,9 +27,9 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if(geo->geoflags & Geometry::NATIVE) if(geo->flags & Geometry::NATIVE)
return; return;
geo->geoflags |= Geometry::NATIVE; geo->flags |= Geometry::NATIVE;
InstanceDataHeader *header = new InstanceDataHeader; InstanceDataHeader *header = new InstanceDataHeader;
MeshHeader *meshh = geo->meshHeader; MeshHeader *meshh = geo->meshHeader;
geo->instData = header; geo->instData = header;
@ -87,7 +87,7 @@ render(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0) if((geo->flags & Geometry::NATIVE) == 0)
pipe->instance(atomic); pipe->instance(atomic);
assert(geo->instData != nil); assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_GL3); assert(geo->instData->platform == PLATFORM_GL3);
@ -129,7 +129,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
// Normals // Normals
// TODO: compress // TODO: compress
bool hasNormals = !!(geo->geoflags & Geometry::NORMALS); bool hasNormals = !!(geo->flags & Geometry::NORMALS);
if(hasNormals){ if(hasNormals){
a->index = ATTRIB_NORMAL; a->index = ATTRIB_NORMAL;
a->size = 3; a->size = 3;
@ -141,7 +141,7 @@ defaultInstanceCB(Geometry *geo, InstanceDataHeader *header)
} }
// Prelighting // Prelighting
bool isPrelit = !!(geo->geoflags & Geometry::PRELIT); bool isPrelit = !!(geo->flags & Geometry::PRELIT);
if(isPrelit){ if(isPrelit){
a->index = ATTRIB_COLOR; a->index = ATTRIB_COLOR;
a->size = 4; a->size = 4;

View File

@ -287,7 +287,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
// Normals // Normals
// TODO: compress // TODO: compress
bool hasNormals = !!(geo->geoflags & Geometry::NORMALS); bool hasNormals = !!(geo->flags & Geometry::NORMALS);
if(hasNormals){ if(hasNormals){
a->index = ATTRIB_NORMAL; a->index = ATTRIB_NORMAL;
a->size = 3; a->size = 3;
@ -299,7 +299,7 @@ skinInstanceCB(Geometry *geo, InstanceDataHeader *header)
} }
// Prelighting // Prelighting
bool isPrelit = !!(geo->geoflags & Geometry::PRELIT); bool isPrelit = !!(geo->flags & Geometry::PRELIT);
if(isPrelit){ if(isPrelit){
a->index = ATTRIB_COLOR; a->index = ATTRIB_COLOR;
a->size = 4; a->size = 4;

View File

@ -322,7 +322,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if(geo->geoflags & Geometry::NATIVE) if(geo->flags & Geometry::NATIVE)
return; return;
InstanceDataHeader *header = new InstanceDataHeader; InstanceDataHeader *header = new InstanceDataHeader;
geo->instData = header; geo->instData = header;
@ -331,9 +331,9 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
header->ibo = 0; header->ibo = 0;
header->numAttribs = header->numAttribs =
pipe->numCustomAttribs + 1 + (geo->numTexCoordSets > 0); pipe->numCustomAttribs + 1 + (geo->numTexCoordSets > 0);
if(geo->geoflags & Geometry::PRELIT) if(geo->flags & Geometry::PRELIT)
header->numAttribs++; header->numAttribs++;
if(geo->geoflags & Geometry::NORMALS) if(geo->flags & Geometry::NORMALS)
header->numAttribs++; header->numAttribs++;
int32 offset = 0; int32 offset = 0;
header->attribs = new AttribDesc[header->numAttribs]; header->attribs = new AttribDesc[header->numAttribs];
@ -361,7 +361,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
firstCustom++; firstCustom++;
} }
if(geo->geoflags & Geometry::NORMALS){ if(geo->flags & Geometry::NORMALS){
a->index = 2; a->index = 2;
a->type = 1; a->type = 1;
a->normalized = 1; a->normalized = 1;
@ -372,7 +372,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
firstCustom++; firstCustom++;
} }
if(geo->geoflags & Geometry::PRELIT){ if(geo->flags & Geometry::PRELIT){
a->index = 3; a->index = 3;
a->type = 2; a->type = 2;
a->normalized = 1; a->normalized = 1;
@ -414,7 +414,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
a++; a++;
} }
if(geo->geoflags & Geometry::NORMALS){ if(geo->flags & Geometry::NORMALS){
p = header->data + a->offset; p = header->data + a->offset;
float32 *norm = geo->morphTargets->normals; float32 *norm = geo->morphTargets->normals;
for(int32 i = 0; i < geo->numVertices; i++){ for(int32 i = 0; i < geo->numVertices; i++){
@ -425,7 +425,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
a++; a++;
} }
if(geo->geoflags & Geometry::PRELIT){ if(geo->flags & Geometry::PRELIT){
// TODO: this seems too complicated // TODO: this seems too complicated
p = header->data + a->offset; p = header->data + a->offset;
uint8 *color = geo->colors; uint8 *color = geo->colors;
@ -441,7 +441,7 @@ instance(rw::ObjPipeline *rwpipe, Atomic *atomic)
} }
a++; a++;
} }
geo->geoflags |= Geometry::NATIVE; geo->flags |= Geometry::NATIVE;
} }
static void static void
@ -449,11 +449,11 @@ uninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0) if((geo->flags & Geometry::NATIVE) == 0)
return; return;
assert(geo->instData != nil); assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_WDGL); assert(geo->instData->platform == PLATFORM_WDGL);
geo->geoflags &= ~Geometry::NATIVE; geo->flags &= ~Geometry::NATIVE;
geo->allocateData(); geo->allocateData();
uint8 *p; uint8 *p;

View File

@ -333,8 +333,8 @@ instanceUV(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
{ {
uint16 j; uint16 j;
uint32 *d = (uint32*)g->texCoords[0]; uint32 *d = (uint32*)g->texCoords[0];
if((g->geoflags & Geometry::TEXTURED) || if((g->flags & Geometry::TEXTURED) ||
(g->geoflags & Geometry::TEXTURED2)) (g->flags & Geometry::TEXTURED2))
for(uint32 i = idx; i < idx+n; i++){ for(uint32 i = idx; i < idx+n; i++){
j = m->indices[i]; j = m->indices[i];
*p++ = d[j*2+0]; *p++ = d[j*2+0];
@ -383,7 +383,7 @@ instanceRGBA(uint32 *p, Geometry *g, Mesh *m, uint32 idx, uint32 n)
{ {
uint16 j; uint16 j;
uint32 *d = (uint32*)g->colors; uint32 *d = (uint32*)g->colors;
if((g->geoflags & Geometry::PRELIT)) if((g->flags & Geometry::PRELIT))
for(uint32 i = idx; i < idx+n; i++){ for(uint32 i = idx; i < idx+n; i++){
j = m->indices[i]; j = m->indices[i];
*p++ = d[j]; *p++ = d[j];
@ -402,7 +402,7 @@ instanceNormal(uint32 *wp, Geometry *g, Mesh *m, uint32 idx, uint32 n)
uint16 j; uint16 j;
float *d = g->morphTargets[0].normals; float *d = g->morphTargets[0].normals;
uint8 *p = (uint8*)wp; uint8 *p = (uint8*)wp;
if((g->geoflags & Geometry::NORMALS)) if((g->flags & Geometry::NORMALS))
for(uint32 i = idx; i < idx+n; i++){ for(uint32 i = idx; i < idx+n; i++){
j = m->indices[i]; j = m->indices[i];
*p++ = d[j*3+0]*127.0f; *p++ = d[j*3+0]*127.0f;
@ -742,7 +742,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if(geo->geoflags & Geometry::NATIVE) if(geo->flags & Geometry::NATIVE)
return; return;
InstanceDataHeader *header = new InstanceDataHeader; InstanceDataHeader *header = new InstanceDataHeader;
geo->instData = header; geo->instData = header;
@ -763,7 +763,7 @@ objInstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
m->instance(geo, instance, mesh); m->instance(geo, instance, mesh);
instance->material = mesh->material; instance->material = mesh->material;
} }
geo->geoflags |= Geometry::NATIVE; geo->flags |= Geometry::NATIVE;
} }
static void static void
@ -800,14 +800,14 @@ objUninstance(rw::ObjPipeline *rwpipe, Atomic *atomic)
{ {
ObjPipeline *pipe = (ObjPipeline*)rwpipe; ObjPipeline *pipe = (ObjPipeline*)rwpipe;
Geometry *geo = atomic->geometry; Geometry *geo = atomic->geometry;
if((geo->geoflags & Geometry::NATIVE) == 0) if((geo->flags & Geometry::NATIVE) == 0)
return; return;
assert(geo->instData != nil); assert(geo->instData != nil);
assert(geo->instData->platform == PLATFORM_PS2); assert(geo->instData->platform == PLATFORM_PS2);
InstanceDataHeader *header = (InstanceDataHeader*)geo->instData; InstanceDataHeader *header = (InstanceDataHeader*)geo->instData;
// highest possible number of vertices // highest possible number of vertices
geo->numVertices = geo->meshHeader->totalIndices; geo->numVertices = geo->meshHeader->totalIndices;
geo->geoflags &= ~Geometry::NATIVE; geo->flags &= ~Geometry::NATIVE;
geo->allocateData(); geo->allocateData();
geo->meshHeader->allocateIndices(); geo->meshHeader->allocateIndices();
uint32 *flags = new uint32[geo->numVertices]; uint32 *flags = new uint32[geo->numVertices];
@ -964,9 +964,9 @@ genericUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
} }
uint32 mask = 0x1; // vertices uint32 mask = 0x1; // vertices
if(normals && geo->geoflags & Geometry::NORMALS) if(normals && geo->flags & Geometry::NORMALS)
mask |= 0x10; mask |= 0x10;
if(rgba && geo->geoflags & Geometry::PRELIT) if(rgba && geo->flags & Geometry::PRELIT)
mask |= 0x100; mask |= 0x100;
if((uv || uv2) && geo->numTexCoordSets > 0) if((uv || uv2) && geo->numTexCoordSets > 0)
mask |= 0x1000; mask |= 0x1000;
@ -1027,9 +1027,9 @@ defaultUninstanceCB(MatPipeline *pipe, Geometry *geo, uint32 flags[], Mesh *mesh
uint8 *colors = (uint8*)data[AT_RGBA]; uint8 *colors = (uint8*)data[AT_RGBA];
int8 *norms = (int8*)data[AT_NORMAL]; int8 *norms = (int8*)data[AT_NORMAL];
uint32 mask = 0x1; // vertices uint32 mask = 0x1; // vertices
if(geo->geoflags & Geometry::NORMALS) if(geo->flags & Geometry::NORMALS)
mask |= 0x10; mask |= 0x10;
if(geo->geoflags & Geometry::PRELIT) if(geo->flags & Geometry::PRELIT)
mask |= 0x100; mask |= 0x100;
for(int32 i = 0; i < geo->numTexCoordSets; i++) for(int32 i = 0; i < geo->numTexCoordSets; i++)
mask |= 0x1000 << i; mask |= 0x1000 << i;
@ -1245,7 +1245,7 @@ writeADC(Stream *stream, int32 len, void *object, int32 offset, int32)
ADCData *adc = PLUGINOFFSET(ADCData, object, offset); ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
Geometry *geometry = (Geometry*)object; Geometry *geometry = (Geometry*)object;
writeChunkHeader(stream, ID_ADC, len-12); writeChunkHeader(stream, ID_ADC, len-12);
if(geometry->geoflags & Geometry::NATIVE){ if(geometry->flags & Geometry::NATIVE){
stream->writeI32(0); stream->writeI32(0);
return stream; return stream;
} }
@ -1262,7 +1262,7 @@ getSizeADC(void *object, int32 offset, int32)
ADCData *adc = PLUGINOFFSET(ADCData, object, offset); ADCData *adc = PLUGINOFFSET(ADCData, object, offset);
if(!adc->adcFormatted) if(!adc->adcFormatted)
return 0; return 0;
if(geometry->geoflags & Geometry::NATIVE) if(geometry->flags & Geometry::NATIVE)
return 16; return 16;
return 16 + (adc->numBits+3 & ~3); return 16 + (adc->numBits+3 & ~3);
} }

View File

@ -264,9 +264,9 @@ skinUninstanceCB(MatPipeline*, Geometry *geo, uint32 flags[], Mesh *mesh, uint8
int8 *norms = (int8*)data[AT_NORMAL]; int8 *norms = (int8*)data[AT_NORMAL];
uint32 *wghts = (uint32*)data[AT_NORMAL+1]; uint32 *wghts = (uint32*)data[AT_NORMAL+1];
uint32 mask = 0x1; // vertices uint32 mask = 0x1; // vertices
if(geo->geoflags & Geometry::NORMALS) if(geo->flags & Geometry::NORMALS)
mask |= 0x10; mask |= 0x10;
if(geo->geoflags & Geometry::PRELIT) if(geo->flags & Geometry::PRELIT)
mask |= 0x100; mask |= 0x100;
if(geo->numTexCoordSets > 0) if(geo->numTexCoordSets > 0)
mask |= 0x1000; mask |= 0x1000;

View File

@ -375,11 +375,26 @@ struct Triangle
uint16 matId; uint16 matId;
}; };
struct MaterialList
{
Material **materials;
int32 numMaterials;
int32 space;
void init(void);
void deinit(void);
int32 appendMaterial(Material *mat);
int32 findIndex(Material *mat);
static MaterialList *streamRead(Stream *stream, MaterialList *matlist);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
};
struct Geometry : PluginBase<Geometry> struct Geometry : PluginBase<Geometry>
{ {
enum { ID = 8 }; enum { ID = 8 };
Object object; Object object;
uint32 geoflags; // TODO: rename uint32 flags;
int32 numTriangles; int32 numTriangles;
int32 numVertices; int32 numVertices;
int32 numMorphTargets; int32 numMorphTargets;
@ -390,22 +405,15 @@ struct Geometry : PluginBase<Geometry>
float32 *texCoords[8]; float32 *texCoords[8];
MorphTarget *morphTargets; MorphTarget *morphTargets;
MaterialList matList;
// TODO: struct
int32 numMaterials;
Material **materialList;
MeshHeader *meshHeader; MeshHeader *meshHeader;
InstanceDataHeader *instData; InstanceDataHeader *instData;
int32 refCount; int32 refCount;
static Geometry *create(int32 numVerts, int32 numTris, uint32 flags); static Geometry *create(int32 numVerts, int32 numTris, uint32 flags);
void destroy(void); void destroy(void);
static Geometry *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
void addMorphTargets(int32 n); void addMorphTargets(int32 n);
void calculateBoundingSphere(void); void calculateBoundingSphere(void);
bool32 hasColoredMaterial(void); bool32 hasColoredMaterial(void);
@ -415,6 +423,9 @@ struct Geometry : PluginBase<Geometry>
void buildTristrips(void); void buildTristrips(void);
void correctTristripWinding(void); void correctTristripWinding(void);
void removeUnusedMaterials(void); void removeUnusedMaterials(void);
static Geometry *streamRead(Stream *stream);
bool streamWrite(Stream *stream);
uint32 streamGetSize(void);
enum Flags enum Flags
{ {
@ -446,13 +457,13 @@ struct Atomic : PluginBase<Atomic>
typedef void (*RenderCB)(Atomic *atomic); typedef void (*RenderCB)(Atomic *atomic);
enum { ID = 1 }; enum { ID = 1 };
enum { enum {
// flags
COLLISIONTEST = 0x01, // unused here COLLISIONTEST = 0x01, // unused here
RENDER = 0x04, RENDER = 0x04,
// private // private flags
WORLDBOUNDDIRTY = 0x01 WORLDBOUNDDIRTY = 0x01,
}; // for setGeometry
enum { SAMEBOUNDINGSPHERE = 0x01,
SAMEBOUNDINGSPHERE = 0x01, // for setGeometry
}; };
ObjectWithFrame object; ObjectWithFrame object;

View File

@ -428,7 +428,7 @@ Geometry::buildTristrips(void)
printf("%ld\n", sizeof(StripNode)); printf("%ld\n", sizeof(StripNode));
smesh.nodes = new StripNode[this->numTriangles]; smesh.nodes = new StripNode[this->numTriangles];
for(int32 i = 0; i < this->numMaterials; i++){ for(int32 i = 0; i < this->matList.numMaterials; i++){
smesh.loneNodes.init(); smesh.loneNodes.init();
smesh.endNodes.init(); smesh.endNodes.init();
collectFaces(this, &smesh, i); collectFaces(this, &smesh, i);

View File

@ -115,7 +115,7 @@ void
drawAtomic(rw::Atomic *atomic) drawAtomic(rw::Atomic *atomic)
{ {
rw::Geometry *geo = atomic->geometry; rw::Geometry *geo = atomic->geometry;
if(!(geo->geoflags & rw::Geometry::NATIVE)){ if(!(geo->flags & rw::Geometry::NATIVE)){
if(atomic->pipeline) if(atomic->pipeline)
atomic->pipeline->instance(atomic); atomic->pipeline->instance(atomic);
else else