home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
MODEL
/
VERSET.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-25
|
8KB
|
385 lines
/*
* エッジ
*
* Copyright T.Kobayashi 1994.7.9
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include "matrix.h"
#include "vector.h"
#include "matclass.h"
#include "strclass.h"
#include "ml.h"
#include "poly.h"
#include "view.h"
extern int VertexSetClassID ;
#define VERTEXALLOCUNIT 256
#ifndef __GNUC__
#define inline
#endif
static inline int VertexEqual(Vertex *v1, Vertex *v2)
{
return memcmp(v1, v2, sizeof(Vertex)) == 0;
}
/* このコードは Vertex がshort x 8 = int * 4 であることに依存*/
static inline int VertexCompare(Vertex *v1, Vertex *v2)
{
int *i1, *i2;
int c;
i1 = (int*)v1;
i2 = (int*)v2;
if ((c = i1[0] - i2[0]) != 0) return c;
if ((c = i1[1] - i2[1]) != 0) return c;
if ((c = i1[2] - i2[2]) != 0) return c;
return i1[3] - i2[3];
}
static VertexSetClass *VertexRealloc(VertexSetClass *verset, int size)
{
VertexSetClass *newverset;
newverset = (VertexSetClass*)ObjectAlloc(sizeof(VertexSetClass) + sizeof(Vertex) * size, VertexSetClassID);
if (size > verset->allocsize) {
memcpy(newverset->ver, verset->ver, sizeof(Vertex) * verset->allocsize);
} else {
memcpy(newverset->ver, verset->ver, sizeof(Vertex) * size);
}
newverset->vers = verset->vers;
newverset->allocsize = size;
ObjectFree((Object*)verset);
return newverset;
}
static VertexSetClass *VertexDeletePos(VertexSetClass *verset, int pos)
{
if (pos < 0 || verset->vers <= pos) {
return verset;
}
if (pos != verset->vers-1) {
memmove(&verset->ver[pos], &verset->ver[pos+1], sizeof(Vertex) * (verset->vers-pos-1));
}
verset->vers--;
return verset;
}
int VertexSearch(VertexSetClass *verset, Vertex *vd)
{
int i, j;
int begin, end;
begin = -1;
end = verset->vers;
while (begin < end-1) {
i = (begin+end)/2;
j = VertexCompare(&verset->ver[i], vd);
if (j == 0) {
return i;
} else if (j < 0) {
end = i;
} else {
begin = i;
}
}
return -1;
}
VertexSetClass *VertexAppend(VertexSetClass *verset, Vertex *vd)
{
int pos;
int j, begin, end;
if (verset->allocsize <= verset->vers) {
verset = VertexRealloc(verset, verset->allocsize + VERTEXALLOCUNIT);
}
begin = -1;
pos = end = verset->vers;
while (begin < end-1) {
pos = (begin+end)/2;
j = VertexCompare(&verset->ver[pos], vd);
if (j == 0) {
/* verset->ver[pos].count++;*/
return verset;
} else if (j < 0) {
end = pos;
} else {
begin = pos;
}
}
pos = end;
if (pos < verset->vers) {
memmove(&verset->ver[pos+1], &verset->ver[pos], sizeof(Vertex) * (verset->vers-pos));
}
verset->ver[pos] = *vd;
verset->vers++;
return verset;
}
VertexSetClass *VertexDelete(VertexSetClass *verset, Vertex *vd)
{
int pos;
if ((pos = VertexSearch(verset, vd)) >= 0) {
verset = VertexDeletePos(verset, pos);
}
return verset;
}
VertexSetClass *VertexAlloc(int size)
{
VertexSetClass *verset;
if (size < VERTEXALLOCUNIT) {
size = VERTEXALLOCUNIT;
} else {
size = ((size / VERTEXALLOCUNIT) + 1) * VERTEXALLOCUNIT;
}
verset = (VertexSetClass*)ObjectAlloc(sizeof(VertexSetClass) + sizeof(Vertex) * size, VertexSetClassID);
verset->allocsize = size;
verset->vers = 0;
return verset;
}
static int VertexSearchPoly(VertexSetClass *verset, Polygon *poly)
{
int i;
int vers = poly->vers ;
for( i = 0 ; i < vers ; i++ )
{
if (VertexSearch(verset, &poly->ver[i]) >= 0) {
return TRUE;
}
}
return FALSE;
}
VertexSetClass *VertexMulMatrix(VertexSetClass *verset, MatrixClass* mat)
{
int imat[5][3];
int imatit[5][3];
Matrix matit;
int i, x, y, z;
Vertex *ed;
MatCopy(matit, mat->mat);
MatInv(matit);
MatTra(matit);
MatToInt( imat, mat->mat );
MatToInt( imatit, matit );
ed = verset->ver;
for (i = 0; i < verset->vers; i++) {
float r;
x = (int)ed->x * imat[0][0]
+ (int)ed->y * imat[1][0]
+ (int)ed->z * imat[2][0]
+ imat[4][0] ;
y = (int)ed->x * imat[0][1]
+ (int)ed->y * imat[1][1]
+ (int)ed->z * imat[2][1]
+ imat[4][1] ;
z = (int)ed->x * imat[0][2]
+ (int)ed->y * imat[1][2]
+ (int)ed->z * imat[2][2]
+ imat[4][2] ;
ed->x = (short)imat[3][0] + (short)( x >> 16 );
ed->y = (short)imat[3][1] + (short)( y >> 16 );
ed->z = (short)imat[3][2] + (short)( z >> 16 );
x = (int)ed->vx * imatit[0][0]
+ (int)ed->vy * imatit[1][0]
+ (int)ed->vz * imatit[2][0];
y = (int)ed->vx * imatit[0][1]
+ (int)ed->vy * imatit[1][1]
+ (int)ed->vz * imatit[2][1];
z = (int)ed->vx * imatit[0][2]
+ (int)ed->vy * imatit[1][2]
+ (int)ed->vz * imatit[2][2];
r = sqrt((float)x * (float)x + (float)y * (float)y + (float)z * (float)z);
if (r > 0.0) r = 256.0 / r;
ed->vx = (short)(r * (float)x);
ed->vy = (short)(r * (float)y);
ed->vz = (short)(r * (float)z);
ed++;
}
return verset;
}
VertexSetClass *VertexLogicalOr(VertexSetClass *e1, VertexSetClass *e2)
{
int i;
for (i = 0; i < e2->vers; i++) {
e1 = VertexAppend(e1, &e2->ver[i]);
}
return e1;
}
VertexSetClass *VertexLogicalSub(VertexSetClass *e1, VertexSetClass *e2)
{
int i, pos;
for (i = 0; i < e2->vers; i++) {
if ((pos = VertexSearch(e1, &e2->ver[i])) >= 0) {
e1 = VertexDeletePos(e1, pos);
}
}
return e1;
}
VertexSetClass *VertexLogicalAnd(VertexSetClass *e1, VertexSetClass *e2)
{
int i, pos;
VertexSetClass *verset;
verset = VertexAlloc(0);
for (i = 0; i < e2->vers; i++) {
if ((pos = VertexSearch(e1, &e2->ver[i])) >= 0) {
verset = VertexAppend(verset, &e1->ver[pos]);
}
}
ObjectFree((Object*)e1);
return verset;
}
VertexSetClass *VertexLogicalXor(VertexSetClass *e1, VertexSetClass *e2)
{
int i, pos;
for (i = 0; i < e2->vers; i++) {
if ((pos = VertexSearch(e1, &e2->ver[i])) >= 0) {
e1 = VertexDeletePos(e1, pos);
} else {
e1 = VertexAppend(e1, &e2->ver[i]);
}
}
return e1;
}
int VertexLogicalEqual(VertexSetClass *e1, VertexSetClass *e2)
{
int i;
if (e1->vers != e2->vers) {
return FALSE;
}
for (i = 0; i < e1->vers; i++) {
if (!VertexEqual(&e1->ver[i], &e2->ver[i])) {
return FALSE;
}
}
return TRUE;
}
VertexSetClass *VertexSelect(void)
{
int i;
VertexSetClass *verset;
Vertex v;
Polygon *poly ;
verset = VertexAlloc(0);
poly = PolyTop();
while( poly != NULL )
{
if ( poly->select == ON ) {
for( i = 0; i < poly->vers; ++i) {
v = poly->ver[i];
if (( poly->type & POLY_SHADE) == 0) {
v.vx = v.vy = v.vz = 0;
}
if (( poly->type & POLY_UV) == 0) {
v.u = v.v = 0;
}
verset = VertexAppend(verset, &v);
}
}
poly = BufferNext( poly );
}
return verset;
}
static void SelectPoly(Polygon *poly, int sel, int flag, int sw )
/* flag : ON | OFF */
/* sw : UPDATE | AND | OR | XOR */
{
if ( poly->mode & MODE_INVISIBLE )
return ;
if ( ! sel )
flag = ! flag ;
switch( sw & SELECT_LOG )
{
case SELECT_UPDATE:
poly->select = flag ;
break ;
case SELECT_AND:
poly->select &= flag ;
break ;
case SELECT_OR:
poly->select |= flag ;
break ;
case SELECT_XOR:
poly->select ^= flag ;
break ;
default:
assert( FALSE );
}
if ( poly->select )
Selects ++ ;
}
void PolySelectVertex( VertexSetClass *verset, int flag, int sw)
{
Polygon *poly ;
PolyPtr = NULL ;
Selects = 0 ;
poly = PolyTop();
while( poly != NULL )
{
SelectPoly( poly, VertexSearchPoly(verset, poly), flag, sw );
poly = BufferNext( poly );
}
}
VertexSetClass *VertexPositionVertex(VertexSetClass *e1)
{
int i, pos;
VertexSetClass *ret;
Vertex v;
memset(&v, 0, sizeof(Vertex));
ret = VertexAlloc(0);
for (i = 0; i < e1->vers; i++) {
v.x = e1->ver[i].x;
v.y = e1->ver[i].y;
v.z = e1->ver[i].z;
ret = VertexAppend(ret, &v);
}
return ret;
}
VertexSetClass *VertexSelectPosition(VertexSetClass *verset, Vertex *v)
{
int i, pos;
VertexSetClass *ret;
ret = VertexAlloc(0);
for (i = 0; i < verset->vers; i++) {
if (verset->ver[i].x == v->x
&& verset->ver[i].y == v->y
&& verset->ver[i].z == v->z) {
ret = VertexAppend(ret, &verset->ver[i]);
}
}
return ret;
}