Re #691: refactored terrainSplitOb() (Boris)

o moved found_a_tri to it's local scope
o renamed numtri to numSurf and removed usage of it, where it is not the
  number of surfaces

o moved bare creation of ob_t to own method
o up to now inits mem to zero and max,min values appropriately

o refactored a for-loop
o added comments
o moved init of textarray and calculation for spacial extend to own methods
o reordered init of temporary object

o moved texture name copying to own method
o added ob's min/max default init to obInitSpacialExtend()
o renamed triIndex to oldSurftoNewObjMap
o renamed numNewSurf to numNewObjs: false name before
o removed numob: covered by for-loop variable already

o gave temporary point/normal arrays variable size instead of fixed to some
  number
o renamed some variables

o put all multitexture setting stuff to own methods.

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@4937 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: e0d5a524d351a481902483b14d2137e584c66ece
Former-commit-id: d6c9fe12c245f7baedb6400f3aaa0ae7b3f80d3d
This commit is contained in:
kmetykog 2012-09-11 21:20:20 +00:00
parent f47de46c40
commit 2a661f5472
2 changed files with 188 additions and 132 deletions

View file

@ -30,6 +30,7 @@
#define _GNU_SOURCE
#endif
#include <math.h>
#include <float.h>
#include "portability.h"
#include "accc.h"
@ -73,6 +74,77 @@ void storeTexCoord(tcoord_t * dest, int indice, double u, double v, int saved)
dest->saved = saved;
}
ob_t * obCreate()
{
ob_t * ob = (ob_t *) malloc(sizeof(ob_t));
memset(ob, 0, sizeof(ob_t));
return ob;
}
void obInitSpacialExtend(ob_t * ob)
{
ob->x_min = ob->y_min = ob->z_min = DBL_MAX;
ob->x_max = ob->y_max = ob->z_max = DBL_MIN;
for (int v = 0; v < ob->numvertice; v++)
{
if (ob->vertex[v].x > ob->x_max)
ob->x_max = ob->vertex[v].x;
if (ob->vertex[v].x < ob->x_min)
ob->x_min = ob->vertex[v].x;
if (ob->vertex[v].y > ob->y_max)
ob->y_max = ob->vertex[v].y;
if (ob->vertex[v].y < ob->y_min)
ob->y_min = ob->vertex[v].y;
if (ob->vertex[v].z > ob->z_max)
ob->z_max = ob->vertex[v].z;
if (ob->vertex[v].z < ob->z_min)
ob->z_min = ob->vertex[v].z;
}
}
void obCreateTextArrays(ob_t * ob)
{
ob->textarray = (double *) calloc(ob->numvertice * 2, sizeof(tcoord_t));
for (int i = 0; i < ob->numsurf * 3; i++)
{
tcoord_t * idx = &ob->vertexarray[i];
int fstIdx = idx->indice * 2;
ob->textarray[fstIdx] = idx->u;
ob->textarray[fstIdx + 1] = idx->v;
}
// TODO: add other texture channels
}
void obCreateVertexArrays(ob_t * ob)
{
int numEls = ob->numsurf * 3;
ob->vertexarray = (tcoord_t *) calloc(numEls, sizeof(tcoord_t));
// TODO: add other texture channels
}
void obCopyTextureNames(ob_t * destob, ob_t * srcob)
{
destob->texture = strdup(srcob->texture);
// TODO: add other texture channels
}
void obSetVertexArraysIndex(ob_t * ob, int vaIdx, int newIndex)
{
ob->vertexarray[vaIdx].indice = newIndex;
// TODO: add other texture channels
}
#ifndef M_PI
#define M_PI 3.14159267
#endif
@ -167,6 +239,20 @@ verbaction_t verbTab[] =
{ CREASE, doCrease },
{ "END", NULL } };
void copyVertexArraysSurface(ob_t * destob, int destSurfIdx, ob_t * srcob, int srcSurfIdx)
{
int firstDestIdx = destSurfIdx * 3;
int firstSrcIdx = srcSurfIdx * 3;
for(int off = 0; off < 3; off++)
{
copyTexCoord(&(destob->vertexarray[firstDestIdx + off]),
&(srcob->vertexarray[firstSrcIdx + off]));
// TODO: add other texture channels
}
}
/** copy the (u,v) coords from srcidxarr to the corresponding position in destarr.
* destarr needs to have 2 * number of vertices entries.
*/
@ -523,17 +609,9 @@ int findIndice(int indice, int *oldva, int n)
int terrainSplitOb(ob_t **object)
{
int numob = 0;
point_t pttmp[10000];
point_t snorm[10000];
ob_t * tob = NULL;
ob_t * tob0 = NULL;
ob_t * tobnext = (*object)->next;
int *triIndex;
int numtri;
int found_a_tri = 0;
int m1 = -1;
int indice1 = 0;
printf("terrain splitting %s \n", (*object)->name);
if (((*object)->x_max - (*object)->x_min) < 2 * distSplit)
@ -542,20 +620,18 @@ int terrainSplitOb(ob_t **object)
return 0;
printf("terrain splitting %s started\n", (*object)->name);
numtri = (*object)->numsurf;
triIndex = (int *) malloc(sizeof(int) * numtri);
memset(triIndex, 0, sizeof(int) * numtri);
int numSurf = (*object)->numsurf;
int *oldSurfToNewObjMap = (int *) calloc(numSurf, sizeof(int));
int numNewObjs = 0;
for (double curXPos = (*object)->x_min; curXPos < (*object)->x_max; curXPos += distSplit)
{
found_a_tri = 0;
for (double curYPos = (*object)->y_min; curYPos < (*object)->y_max; curYPos += distSplit)
{
numtri = 0;
found_a_tri = 0;
int numTriFound = 0;
int found_a_tri = 0;
for (int curObjSurf = 0; curObjSurf < (*object)->numsurf; curObjSurf++)
{
@ -567,15 +643,15 @@ int terrainSplitOb(ob_t **object)
if (surfCentroid.y >= curYPos && surfCentroid.y < curYPos + distSplit)
{
found_a_tri = 1;
triIndex[curObjSurf] = numNewObjs;
numtri++;
oldSurfToNewObjMap[curObjSurf] = numNewObjs;
numTriFound++;
}
}
}
if (found_a_tri)
{
printf("surface num %d : numtri : %d\n", numNewObjs, numtri);
printf("surface num %d : numtri : %d\n", numNewObjs, numTriFound);
numNewObjs++;
}
}
@ -589,157 +665,101 @@ int terrainSplitOb(ob_t **object)
/* find the number of surface */
for (int curSurf = 0; curSurf < (*object)->numsurf; curSurf++)
{
if (triIndex[curSurf] != curNewObj)
if (oldSurfToNewObjMap[curSurf] != curNewObj)
continue;
numNewSurf++;
}
tob = (ob_t *) malloc(sizeof(ob_t));
memset(tob, 0, sizeof(ob_t));
tob->x_min = 1000000;
tob->y_min = 1000000;
tob->z_min = 1000000;
/* initial creation of tob */
tob = obCreate();
tob->numsurf = numNewSurf;
tob->vertexarray = (tcoord_t *) malloc(sizeof(tcoord_t) * numNewSurf * 3);
tob->attrSurf = (*object)->attrSurf;
tob->attrMat = (*object)->attrMat;
if ((*object)->data)
tob->data = strdup((*object)->data);
tob->name = (char *) malloc(strlen((*object)->name) + 10);
tob->type = strdup((*object)->type);
sprintf(tob->name, "%s__split__%d", (*object)->name, curNewObj);
obCopyTextureNames(tob, *object);
/* store the index data in tob's vertexarray */
obCreateVertexArrays(tob);
int curNewSurf = 0;
for (int curSurf = 0; curSurf < (*object)->numsurf; curSurf++)
{
if (triIndex[curSurf] != curNewObj)
if (oldSurfToNewObjMap[curSurf] != curNewObj)
continue;
tob->vertexarray[curNewSurf * 3].indice =
(*object)->vertexarray[curSurf * 3].indice;
tob->vertexarray[curNewSurf * 3].u = (*object)->vertexarray[curSurf * 3].u;
tob->vertexarray[curNewSurf * 3].v = (*object)->vertexarray[curSurf * 3].v;
tob->vertexarray[curNewSurf * 3 + 1].indice = (*object)->vertexarray[curSurf * 3
+ 1].indice;
tob->vertexarray[curNewSurf * 3 + 1].u = (*object)->vertexarray[curSurf * 3 + 1].u;
tob->vertexarray[curNewSurf * 3 + 1].v = (*object)->vertexarray[curSurf * 3 + 1].v;
tob->vertexarray[curNewSurf * 3 + 2].indice = (*object)->vertexarray[curSurf * 3
+ 2].indice;
tob->vertexarray[curNewSurf * 3 + 2].u = (*object)->vertexarray[curSurf * 3 + 2].u;
tob->vertexarray[curNewSurf * 3 + 2].v = (*object)->vertexarray[curSurf * 3 + 2].v;
copyVertexArraysSurface(tob, curNewSurf, *object, curSurf);
curNewSurf++;
}
numtri = tob->numsurf;
/* create a list with temporal points and smoothed normals and store the index
* to them in tob's vertexarray.indice property.
*/
/** keep a list of the indices of points stored in the new object.
/* temporal storage for points and smoothed normals. Temporal because
* we don't know the size, so we allocate the same number as in the
* source object.
*/
point_t* pttmp = (point_t*) calloc((*object)->numvertice, sizeof(point_t));
point_t* snorm = (point_t*) calloc((*object)->numvertice, sizeof(point_t));
/* storedPtIdxArr: keep a list of the indices of points stored in the new object.
* If an index is contained in storedPtIdxArr we don't store the point itself,
* but only the index in the vertexarray of the new object.
*/
int* storedPtIdxArr = (int*) calloc((*object)->numvertice, sizeof(int));
int curNewPtIdx = 0;
for (int curNewSurf = 0; curNewSurf < tob->numsurf; curNewSurf++)
for (int curNewIdx = 0; curNewIdx < numNewSurf * 3; curNewIdx++)
{
indice1 = tob->vertexarray[curNewSurf * 3].indice;
m1 = findIndice(indice1, storedPtIdxArr, curNewPtIdx);
if (m1 == -1)
{
storedPtIdxArr[curNewPtIdx] = indice1;
m1 = curNewPtIdx;
pttmp[curNewPtIdx].x = (*object)->vertex[indice1].x;
pttmp[curNewPtIdx].y = (*object)->vertex[indice1].y;
pttmp[curNewPtIdx].z = (*object)->vertex[indice1].z;
snorm[curNewPtIdx].x = (*object)->norm[indice1].x;
snorm[curNewPtIdx].y = (*object)->norm[indice1].y;
snorm[curNewPtIdx].z = (*object)->norm[indice1].z;
curNewPtIdx++;
}
tob->vertexarray[curNewSurf * 3].indice = m1;
int idx = tob->vertexarray[curNewIdx].indice;
indice1 = tob->vertexarray[curNewSurf * 3 + 1].indice;
m1 = findIndice(indice1, storedPtIdxArr, curNewPtIdx);
if (m1 == -1)
int storedIdx = findIndice(idx, storedPtIdxArr, curNewPtIdx);
if (storedIdx == -1)
{
storedPtIdxArr[curNewPtIdx] = indice1;
m1 = curNewPtIdx;
pttmp[curNewPtIdx].x = (*object)->vertex[indice1].x;
pttmp[curNewPtIdx].y = (*object)->vertex[indice1].y;
pttmp[curNewPtIdx].z = (*object)->vertex[indice1].z;
snorm[curNewPtIdx].x = (*object)->norm[indice1].x;
snorm[curNewPtIdx].y = (*object)->norm[indice1].y;
snorm[curNewPtIdx].z = (*object)->norm[indice1].z;
storedPtIdxArr[curNewPtIdx] = idx;
storedIdx = curNewPtIdx;
copyPoint(&(pttmp[curNewPtIdx]), &((*object)->vertex[idx]));
copyPoint(&(snorm[curNewPtIdx]), &((*object)->norm[idx]));
curNewPtIdx++;
}
tob->vertexarray[curNewSurf * 3 + 1].indice = m1;
indice1 = tob->vertexarray[curNewSurf * 3 + 2].indice;
m1 = findIndice(indice1, storedPtIdxArr, curNewPtIdx);
if (m1 == -1)
{
storedPtIdxArr[curNewPtIdx] = indice1;
m1 = curNewPtIdx;
pttmp[curNewPtIdx].x = (*object)->vertex[indice1].x;
pttmp[curNewPtIdx].y = (*object)->vertex[indice1].y;
pttmp[curNewPtIdx].z = (*object)->vertex[indice1].z;
snorm[curNewPtIdx].x = (*object)->norm[indice1].x;
snorm[curNewPtIdx].y = (*object)->norm[indice1].y;
snorm[curNewPtIdx].z = (*object)->norm[indice1].z;
curNewPtIdx++;
}
tob->vertexarray[curNewSurf * 3 + 2].indice = m1;
obSetVertexArraysIndex(tob, curNewIdx, storedIdx);
}
free(storedPtIdxArr);
int numNewPts = curNewPtIdx;
tob->norm = (point_t*) calloc(numNewPts, sizeof(point_t));
tob->snorm = (point_t*) calloc(numNewPts, sizeof(point_t));
tob->vertex = (point_t*) calloc(numNewPts, sizeof(point_t));
tob->textarray = (double *) calloc(numtri * 2, sizeof(tcoord_t));
tob->attrSurf = (*object)->attrSurf;
tob->attrMat = (*object)->attrMat;
memcpy(tob->vertex, pttmp, numNewPts * sizeof(point_t));
memcpy(tob->snorm, snorm, numNewPts * sizeof(point_t));
memcpy(tob->norm, snorm, numNewPts * sizeof(point_t));
if ((*object)->data)
{
tob->data = strdup((*object)->data);
}
else
{
tob->data = 0;
}
tob->kids = 0;
for (int curNewIdx = 0; curNewIdx < numtri * 3; curNewIdx++)
{
tob->textarray[tob->vertexarray[curNewIdx].indice * 2] =
tob->vertexarray[curNewIdx].u;
tob->textarray[tob->vertexarray[curNewIdx].indice * 2 + 1] =
tob->vertexarray[curNewIdx].v;
}
tob->name = (char *) malloc(strlen((*object)->name) + 10);
tob->texture = strdup((*object)->texture);
tob->type = strdup((*object)->type);
sprintf(tob->name, "%s__split__%d", (*object)->name, numob++);
tob->numsurf = numtri;
tob->numvert = numNewPts;
tob->numvertice = numNewPts;
for (int curNewVert = 0; curNewVert < tob->numvert; curNewVert++)
{
if (tob->vertex[curNewVert].x > tob->x_max)
tob->x_max = tob->vertex[curNewVert].x;
if (tob->vertex[curNewVert].x < tob->x_min)
tob->x_min = tob->vertex[curNewVert].x;
if (tob->vertex[curNewVert].y > tob->y_max)
tob->y_max = tob->vertex[curNewVert].y;
if (tob->vertex[curNewVert].y < tob->y_min)
tob->y_min = tob->vertex[curNewVert].y;
/* create and store tob's norm, snorm, vertex and textarray data */
if (tob->vertex[curNewVert].z > tob->z_max)
tob->z_max = tob->vertex[curNewVert].z;
if (tob->vertex[curNewVert].z < tob->z_min)
tob->z_min = tob->vertex[curNewVert].z;
tob->norm = (point_t*) calloc(numNewPts, sizeof(point_t));
memcpy(tob->norm, snorm, numNewPts * sizeof(point_t));
tob->snorm = (point_t*) calloc(numNewPts, sizeof(point_t));
memcpy(tob->snorm, snorm, numNewPts * sizeof(point_t));
tob->vertex = (point_t*) calloc(numNewPts, sizeof(point_t));
memcpy(tob->vertex, pttmp, numNewPts * sizeof(point_t));
free(pttmp);
free(snorm);
obCreateTextArrays(tob);
obInitSpacialExtend(tob);
}
tob->next = NULL;
if (tob0 == NULL)
{
tob0 = tob;

View file

@ -142,6 +142,33 @@ typedef struct ob
int inkids_o;
} ob_t;
/** Creates an instance of the ob_t struct and zeroes it.
*/
ob_t * obCreate();
/** Initializes the min and max properties of the given object
* must be set: numvertice, vertex
*/
void obInitSpacialExtend(ob_t * ob);
/** Creates and zeroes the "vertexarray" properties.
* must be set: "texture" properties (decide whether to create arrays), numsurf
*/
void obCreateVertexArrays(ob_t * ob);
/** Creates and initializes ob's textarray properties, based on the "vertexarray" data
* must be set: numsurf, numvertice, vertexarray
*/
void obCreateTextArrays(ob_t * ob);
/** copies the "texture" properties from srcob to destob. */
void obCopyTextureNames(ob_t * destob, ob_t * srcob);
/** Assigns the given "newIndex" to the indice property of all active "vertexarray"s at index
* "vaIdx".
*/
void obSetVertexArraysIndex(ob_t * ob, int vaIdx, int newIndex);
typedef struct ob_groups
{
struct ob * kids;
@ -179,6 +206,15 @@ typedef struct mat
struct mat * next;
} mat_t;
/** Copies a single surface from the "vertexarray" attributes of srcob to the ones of destob.
* It decides whether to copy multitexture data based on srcob's "vertexarray" attributes.
*
* In particular it copies 3 entries starting at srcSurfIdx * 3 from srcob->vertexarray
* to entries starting at destSurfIdx * 3 in destob->vertexarray. The same goes for the
* multitexture entries.
*/
void copyVertexArraysSurface(ob_t * destob, int destSurfIdx, ob_t * srcob, int srcSurfIdx);
/** Helper function for copySingleVertexData(). Stores a single texture channel, i.e. copies
* data from the srcvert into the destination arrays based on the given indices.
* @sa copySingleVertexData()