Re #691: splitOb(): put new utility methods to use in splitOb() (Boris)

Now the splitting of texture channel arrays is encapsulated in
separate functions. This way adding new texture channels
for splitting is done mostly outside of splitOb() itself.

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

Former-commit-id: d8a5924d34ca4a93171dc77f352edfed47b96d97
Former-commit-id: ede10ea47eb3869d34a060aa4f6d986af8549968
This commit is contained in:
kmetykog 2012-08-17 22:12:24 +00:00
parent 50da3edbb1
commit e6c20fd69f
2 changed files with 132 additions and 50 deletions

View file

@ -214,10 +214,14 @@ ob_t * createObjectSplitCopy(int splitid, ob_t * srcobj, ob_t * tmpob)
memset(retob->norm, 0, size_pts); memset(retob->norm, 0, size_pts);
retob->snorm = (point_t*) malloc(size_pts); retob->snorm = (point_t*) malloc(size_pts);
memset(retob->snorm, 0, size_pts); memset(retob->snorm, 0, size_pts);
retob->vertexarray = (tcoord_t *) malloc(size_idx);
/*retob->vertexarray = (tcoord_t *) malloc(size_idx);
memset(retob->vertexarray, 0, size_idx); memset(retob->vertexarray, 0, size_idx);
retob->textarray = (double *) malloc(size_texcoord); retob->textarray = (double *) malloc(size_texcoord);
memset(retob->textarray, 0, size_texcoord); memset(retob->textarray, 0, size_texcoord);
*/
allocTexChannelArrays(retob, tmpob);
retob->name = (char *) malloc(strlen(srcobj->name) + 10); retob->name = (char *) malloc(strlen(srcobj->name) + 10);
@ -244,46 +248,61 @@ ob_t * createObjectSplitCopy(int splitid, ob_t * srcobj, ob_t * tmpob)
return retob; return retob;
} }
void copyTexChannel(double * desttextarray, tcoord_t * destvertexarray, tcoord_t * srcvert,
/** Copies the data of a single vertex from srcob to destob. int storedptidx, int destptidx, int destvertidx)
* In particular the vertexarray and textarray variables of destob will be modified.
* This includes the data of additional texture channels.
*
* This function is used in splitting specifically.
*
* @param destob the destination object
* @param srcob the source object
* @param storedptidx the value of the indice variable in the destination vertex
* @param destptidx the index in the "vertex" array to be used for modifying the textarray
* @param destvertidx the index in the destination's vertexarray to be modified
* @param srcvertidx the index in the vertexarray in the source object to take the data from
*/
void copySingleVertexData(ob_t * destob, ob_t * srcob,
int storedptidx, int destptidx, int destvertidx, int srcvertidx)
{ {
tcoord_t * srcvert = &(srcob->vertexarray[srcvertidx]); desttextarray[destptidx * 2] = srcvert->u;
desttextarray[destptidx * 2 + 1] = srcvert->v;
destob->textarray[destptidx * 2] = srcvert->u; storeTexCoord(&(destvertexarray[destvertidx]),
destob->textarray[destptidx * 2 + 1] = srcvert->v;
storeTexCoord(&(destob->vertexarray[destvertidx]),
storedptidx, srcvert->u, srcvert->v, 0); storedptidx, srcvert->u, srcvert->v, 0);
} }
/** Clears the saved flag for a single entry in ob's vertexarray and does so void copySingleVertexData(ob_t * destob, ob_t * srcob,
* for all texture channels. int storedptidx, int destptidx, int destvertidx, int srcvertidx)
*/ {
tcoord_t * srcvert;
/* channel 0 */
srcvert = &(srcob->vertexarray[srcvertidx]);
copyTexChannel(destob->textarray, destob->vertexarray, srcvert,
storedptidx, destptidx, destvertidx);
/* channel 1 */
if(destob->textarray1 != NULL)
{
srcvert = &(srcob->vertexarray1[srcvertidx]);
copyTexChannel(destob->textarray1, destob->vertexarray1, srcvert,
storedptidx, destptidx, destvertidx);
}
/* channel 2 */
if(destob->textarray2 != NULL)
{
srcvert = &(srcob->vertexarray2[srcvertidx]);
copyTexChannel(destob->textarray2, destob->vertexarray2, srcvert,
storedptidx, destptidx, destvertidx);
}
/* channel 3 */
if(destob->textarray3 != NULL)
{
srcvert = &(srcob->vertexarray3[srcvertidx]);
copyTexChannel(destob->textarray3, destob->vertexarray3, srcvert,
storedptidx, destptidx, destvertidx);
}
}
void clearSavedInVertexArrayEntry(ob_t * ob, int vertidx) void clearSavedInVertexArrayEntry(ob_t * ob, int vertidx)
{ {
ob->vertexarray[vertidx].saved = 0; ob->vertexarray[vertidx].saved = 0;
} }
/** Creates vertexarray{,1,2,3} and textarray{,1,2,3} in ob based on the given channel void allocSingleTexChannelArrays(ob_t * ob, int channel, int numpt, int numvert)
* and on the given number of vertices.
*
* @param channel which texture channel, value in range [0,3]
*/
void allocTexChannelArrays(ob_t * ob, int channel, int numvert)
{ {
tcoord_t * va = (tcoord_t *) calloc(numvert, sizeof(tcoord_t)); tcoord_t * va = (tcoord_t *) calloc(numvert, sizeof(tcoord_t));
double* ta = (double *) calloc(2*numvert, sizeof(double)); double* ta = (double *) calloc(2*numvert, sizeof(double));
@ -309,6 +328,22 @@ void allocTexChannelArrays(ob_t * ob, int channel, int numvert)
} }
} }
void allocTexChannelArrays(ob_t * destob, ob_t * srcob)
{
int numvert = srcob->numsurf * 3;
int numpt = srcob->numvertice;
if(srcob->vertexarray != NULL)
allocSingleTexChannelArrays(destob, 0, numpt, numvert);
if(srcob->vertexarray1 != NULL)
allocSingleTexChannelArrays(destob, 1, numpt, numvert);
if(srcob->vertexarray2 != NULL)
allocSingleTexChannelArrays(destob, 2, numpt, numvert);
if(srcob->vertexarray3 != NULL)
allocSingleTexChannelArrays(destob, 3, numpt, numvert);
}
int computeNorm(point_t * pv1, point_t *pv2, point_t *pv3, point_t *norm) int computeNorm(point_t * pv1, point_t *pv2, point_t *pv3, point_t *norm)
{ {
double p1, p2, p3, q1, q2, q3, dd; double p1, p2, p3, q1, q2, q3, dd;
@ -695,7 +730,8 @@ int splitOb(ob_t **object)
{ {
int *oldva = 0; int *oldva = 0;
int curtri = 0; int curtri = 0;
int n = 0; int numptstored = 0; /* number of vertices stored */
int oldnumptstored = 0; /* temporary placeholder for numptstored */
/* The object we use as storage during splitting. /* The object we use as storage during splitting.
* Following attribs will be used: vertexarray, vertex, snorm, textarray * Following attribs will be used: vertexarray, vertex, snorm, textarray
@ -729,17 +765,18 @@ int splitOb(ob_t **object)
workob = (ob_t *) malloc(sizeof(ob_t)); workob = (ob_t *) malloc(sizeof(ob_t));
memset(workob, 0, sizeof(ob_t)); memset(workob, 0, sizeof(ob_t));
workob->vertexarray = (tcoord_t *) calloc(orignumverts, sizeof(tcoord_t));
workob->vertex = (point_t *) calloc(orignumverts, sizeof(point_t)); workob->vertex = (point_t *) calloc(orignumverts, sizeof(point_t));
workob->snorm = (point_t *) calloc(orignumverts, sizeof(point_t)); workob->snorm = (point_t *) calloc(orignumverts, sizeof(point_t));
workob->textarray = (double *) calloc(2*orignumverts, sizeof(double));
// create texture channels
allocTexChannelArrays(workob, *object);
while (mustcontinue == 1) while (mustcontinue == 1)
{ {
numvertstored = 0; numvertstored = 0;
numtristored = 0; numtristored = 0;
n = 0; /* number of vertices stored */ numptstored = 0;
mustcontinue = 0; mustcontinue = 0;
firstTri = 0; firstTri = 0;
atleastone = 1; atleastone = 1;
@ -760,7 +797,7 @@ int splitOb(ob_t **object)
{ {
copyTexCoord(&curvertex[i], &((*object)->vertexarray[curvert+i])); copyTexCoord(&curvertex[i], &((*object)->vertexarray[curvert+i]));
curstoredidx[i] = findIndice(curvertex[i].indice, oldva, n); curstoredidx[i] = findIndice(curvertex[i].indice, oldva, numptstored);
} }
if (curstoredidx[0] == -1 && curstoredidx[1] == -1 && curstoredidx[2] == -1) if (curstoredidx[0] == -1 && curstoredidx[1] == -1 && curstoredidx[2] == -1)
@ -798,24 +835,23 @@ int splitOb(ob_t **object)
/* not yet in the array : store it at the current position */ /* not yet in the array : store it at the current position */
for(i = 0; i < 3; i++) for(i = 0; i < 3; i++)
{ {
oldnumptstored = numptstored;
if (curstoredidx[i] == -1) if (curstoredidx[i] == -1)
{ {
oldva[n] = curvertex[i].indice; /* remember the value of the vertice already saved */ copyPoint(&(workob->vertex[numptstored]), &((*object)->vertex[curvertex[i].indice]));
workob->textarray[n * 2] = curvertex[i].u; copyPoint(&(workob->snorm[numptstored]), &((*object)->norm[curvertex[i].indice]));
workob->textarray[n * 2 + 1] = curvertex[i].v;
curstoredidx[i] = n;
n++;
(*object)->vertexarray[curvert+i].saved = 0; clearSavedInVertexArrayEntry(*object, curvert+i);
copyPoint(&workob->vertex[curstoredidx[i]],
&((*object)->vertex[curvertex[i].indice])); oldva[numptstored] = curvertex[i].indice; /* remember the value of the vertice already saved */
copyPoint(&workob->snorm[curstoredidx[i]], curstoredidx[i] = numptstored;
&((*object)->norm[curvertex[i].indice])); numptstored++;
} }
workob->vertexarray[numvertstored].indice = curstoredidx[i]; copySingleVertexData(workob, *object, curstoredidx[i],
workob->vertexarray[numvertstored].u = curvertex[i].u; oldnumptstored, numvertstored, curvert+i);
workob->vertexarray[numvertstored].v = curvertex[i].v;
numvertstored++; numvertstored++;
} }
@ -831,7 +867,7 @@ int splitOb(ob_t **object)
continue; continue;
/* must saved the object */ /* must saved the object */
workob->numvertice = n; workob->numvertice = numptstored;
workob->numsurf = numvertstored/3; workob->numsurf = numvertstored/3;
tob = createObjectSplitCopy(numob++, *object, workob); tob = createObjectSplitCopy(numob++, *object, workob);

View file

@ -163,12 +163,57 @@ typedef struct mat
struct mat * next; struct mat * next;
} mat_t; } mat_t;
/** 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()
*/
void copyTexChannel(double * desttextarray, tcoord_t * destvertexarray, tcoord_t * srcvert,
int storedptidx, int destptidx, int destvertidx);
/** Copies the data of a single vertex from srcob to destob.
* In particular the vertexarray and textarray variables of destob will be modified.
* This includes the data of additional texture channels.
*
* This function is used in splitting specifically.
*
* @param destob the destination object
* @param srcob the source object
* @param storedptidx the value of the indice variable in the destination vertex
* @param destptidx the index in the "vertex" array to be used for modifying the textarray
* @param destvertidx the index in the destination's vertexarray to be modified
* @param srcvertidx the index in the vertexarray in the source object to take the data from
*/
void copySingleVertexData(ob_t * destob, ob_t * srcob,
int storedptidx, int destptidx, int destvertidx, int srcvertidx);
/** Clears the saved flag for a single entry in ob's vertexarray and does so
* for all texture channels.
*/
void clearSavedInVertexArrayEntry(ob_t * ob, int vertidx);
/** Allocates all texture channels in destob based on the texture channels present in srcob.
* In particular, srcob's vertexarray properties determine whether a texture channel is present
* and from numsurf and numvertice the number of points/indices are calculated.
*/
void allocTexChannelArrays(ob_t * destob, ob_t * srcob);
/** Creates vertexarray{,1,2,3} and textarray{,1,2,3} in ob based on the given channel
* and on the given number of vertices.
*
* @param ob the object in which to allocate the texture channel
* @param channel which texture channel, value in range [0,3]
* @param numpt number of points, in ob_t corresponds to numvertice
* @param numvert number of index points, in ob_t corresponds to numsurf*3
*/
void allocSingleTexChannelArrays(ob_t * ob, int channel, int numpt, int numvert);
extern int typeConvertion; extern int typeConvertion;
extern ob_t * root_ob; extern ob_t * root_ob;
extern int terrainSplitOb(ob_t **object); extern int terrainSplitOb(ob_t **object);
extern int mergeSplitted(ob_t **object); extern int mergeSplitted(ob_t **object);
extern int distSplit; extern int distSplit;
/** Whether to split objects during loading, i.e. calls to loadAC() and loadACo(). /** Whether to split objects during loading, i.e. calls to loadAC() and loadACo().
* The default behavior is to split them during loading * The default behavior is to split them during loading
* (splitObjectsDuringLoad != 0). However, in loadAndGroup() * (splitObjectsDuringLoad != 0). However, in loadAndGroup()
@ -177,6 +222,7 @@ extern int distSplit;
* (splitObjectsDuringLoad == 0). * (splitObjectsDuringLoad == 0).
*/ */
extern int splitObjectsDuringLoad; extern int splitObjectsDuringLoad;
/** Go through all given objects, check whether a normal split or a terrain /** Go through all given objects, check whether a normal split or a terrain
* split is necessary and execute the split. * split is necessary and execute the split.
*/ */