added sphere struct; implemented texture read and find callbacks

This commit is contained in:
aap 2016-02-18 14:29:04 +01:00
parent 8083f88049
commit 7be2e634fe
4 changed files with 78 additions and 43 deletions

View File

@ -43,10 +43,8 @@ Geometry::create(int32 numVerts, int32 numTris, uint32 flags)
}
geo->morphTargets = new MorphTarget[1];
MorphTarget *m = geo->morphTargets;
m->boundingSphere[0] = 0.0f;
m->boundingSphere[1] = 0.0f;
m->boundingSphere[2] = 0.0f;
m->boundingSphere[3] = 0.0f;
m->boundingSphere.center.set(0.0f, 0.0f, 0.0f);
m->boundingSphere.radius = 0.0f;
m->vertices = NULL;
m->normals = NULL;
if(!(geo->geoflags & NATIVE) && geo->numVertices){
@ -130,7 +128,7 @@ Geometry::streamRead(Stream *stream)
for(int32 i = 0; i < geo->numMorphTargets; i++){
MorphTarget *m = &geo->morphTargets[i];
stream->read(m->boundingSphere, 4*4);
stream->read(&m->boundingSphere, 4*4);
int32 hasVertices = stream->readI32();
int32 hasNormals = stream->readI32();
if(hasVertices)
@ -217,7 +215,7 @@ Geometry::streamWrite(Stream *stream)
for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &this->morphTargets[i];
stream->write(m->boundingSphere, 4*4);
stream->write(&m->boundingSphere, 4*4);
if(!(this->geoflags & NATIVE)){
stream->writeI32(m->vertices != NULL);
stream->writeI32(m->normals != NULL);
@ -288,25 +286,21 @@ Geometry::calculateBoundingSphere(void)
{
for(int32 i = 0; i < this->numMorphTargets; i++){
MorphTarget *m = &this->morphTargets[i];
float32 min[3] = { 1000000.0f, 1000000.0f, 1000000.0f };
float32 max[3] = { -1000000.0f, -1000000.0f, -1000000.0f };
V3d min( 1000000.0f, 1000000.0f, 1000000.0f);
V3d max(-1000000.0f, -1000000.0f, -1000000.0f);
float32 *v = m->vertices;
for(int32 j = 0; j < this->numVertices; j++){
if(v[0] > max[0]) max[0] = v[0];
if(v[0] < min[0]) min[0] = v[0];
if(v[1] > max[1]) max[1] = v[1];
if(v[1] < min[1]) min[1] = v[1];
if(v[2] > max[2]) max[2] = v[2];
if(v[2] < min[2]) min[2] = v[2];
if(v[0] > max.x) max.x = v[0];
if(v[0] < min.x) min.x = v[0];
if(v[1] > max.y) max.y = v[1];
if(v[1] < min.y) min.y = v[1];
if(v[2] > max.z) max.z = v[2];
if(v[2] < min.z) min.z = v[2];
v += 3;
}
m->boundingSphere[0] = (min[0] + max[0])/2.0f;
m->boundingSphere[1] = (min[1] + max[1])/2.0f;
m->boundingSphere[2] = (min[2] + max[2])/2.0f;
max[0] -= m->boundingSphere[0];
max[1] -= m->boundingSphere[1];
max[2] -= m->boundingSphere[2];
m->boundingSphere[3] = sqrt(max[0]*max[0] + max[1]*max[1] + max[2]*max[2]);
m->boundingSphere.center = scale(add(min, max), 1/2.0f);
max = sub(max, m->boundingSphere.center);
m->boundingSphere.radius = length(max);
}
}

View File

@ -105,6 +105,12 @@ TexDictionary::streamGetSize(void)
bool32 loadTextures;
static Texture *defaultFindCB(const char *name);
static Texture *defaultReadCB(const char *name, const char *mask);
Texture *(*Texture::findCB)(const char *name) = defaultFindCB;
Texture *(*Texture::readCB)(const char *name, const char *mask) = defaultReadCB;
Texture*
Texture::create(Raster *raster)
{
@ -135,7 +141,36 @@ Texture::destroy(void)
}
}
// TODO: do this properly, pretty ugly right now
static Texture*
defaultFindCB(const char *name)
{
if(currentTexDictionary)
return currentTexDictionary->find(name);
// TODO: RW searches *all* TXDs otherwise
return NULL;
}
static Texture*
defaultReadCB(const char *name, const char *mask)
{
Texture *tex;
Image *img;
char *n = (char*)malloc(strlen(name) + 5);
strcpy(n, name);
strcat(n, ".tga");
img = readTGA(n);
free(n);
if(img){
tex = Texture::create(Raster::createFromImage(img));
strncpy(tex->name, name, 32);
if(mask)
strncpy(tex->mask, mask, 32);
img->destroy();
return tex;
}else
return NULL;
}
Texture*
Texture::read(const char *name, const char *mask)
{
@ -143,31 +178,28 @@ Texture::read(const char *name, const char *mask)
Raster *raster = NULL;
Texture *tex;
if(currentTexDictionary && (tex = currentTexDictionary->find(name))){
if(tex = Texture::findCB(name)){
tex->refCount++;
return tex;
}
tex = Texture::create(NULL);
strncpy(tex->name, name, 32);
if(mask)
strncpy(tex->mask, mask, 32);
Image *img = NULL;
if(loadTextures){
char *n = (char*)malloc(strlen(name) + 5);
strcpy(n, name);
strcat(n, ".tga");
img = readTGA(n);
free(n);
if(img){
raster = Raster::createFromImage(img);
img->destroy();
}else
raster = Raster::create(0, 0, 0, 0x80);
}else
tex = Texture::readCB(name, mask);
if(tex == NULL)
goto dummytex;
}else{
dummytex:
tex = Texture::create(NULL);
strncpy(tex->name, name, 32);
if(mask)
strncpy(tex->mask, mask, 32);
raster = Raster::create(0, 0, 0, 0x80);
tex->raster = raster;
if(currentTexDictionary)
tex->raster = raster;
}
if(currentTexDictionary){
if(tex->dict)
tex->inDict.remove();
currentTexDictionary->add(tex);
}
return tex;
}
@ -386,7 +418,7 @@ Image::getFilename(const char *name)
{
FILE *f;
char *s, *p = searchPaths;
int len = strlen(name)+1;
size_t len = strlen(name)+1;
if(numSearchPaths == 0){
f = fopen(name, "rb");
if(f){

View File

@ -152,6 +152,12 @@ bool32 matrixInvert(float32 *out, float32 *in);
void matrixPrint(float32 *mat);
bool32 equal(const Matrix &m1, const Matrix &m2);
struct Sphere
{
V3d center;
float32 radius;
};
class Stream
{
public:

View File

@ -318,6 +318,9 @@ struct Texture : PluginBase<Texture>
void streamWriteNative(Stream *stream);
uint32 streamGetSizeNative(void);
static Texture *(*findCB)(const char *name);
static Texture *(*readCB)(const char *name, const char *mask);
enum FilterMode {
NEAREST = 1,
LINEAR,
@ -449,7 +452,7 @@ struct MeshHeader
struct MorphTarget
{
float32 boundingSphere[4];
Sphere boundingSphere;
float32 *vertices;
float32 *normals;
};