home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
POLYEDIT.LZH
/
MODEL
/
POLY.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-25
|
8KB
|
345 lines
/*
* ポリゴンデータ管理ライブラリ
*
* Copyright T.Kobayashi 1993.9.5
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <math.h>
#include "lib.h"
#include "alloc.h"
#include "buffer.h"
#include "poly.h"
#include "view.h"
Polygon *CurrentPoly ;
int MaxAttr ;
int MaxVertex ;
Polygon *PolyPtr ;
/* 初期化 */
void PolyInit( bufsize, maxobj, maxatr, maxver )
int bufsize ;
int maxobj ;
int maxatr ;
int maxver ;
{
BufferInit( bufsize );
AttrInit( maxatr );
ObjInit( maxobj );
CurrentPoly = MemoryAlloc( PolySize( maxver ) );
MaxVertex = maxver ;
CurrentPoly->select = OFF ;
CurrentPoly->type = POLY_SIMPLE ;
CurrentPoly->atr = 0 ;
CurrentPoly->obj = 0 ;
CurrentPoly->vers = 0 ;
CurrentPoly->mode = 0 ;
CurrentPoly->vec[0] = CurrentPoly->vec[1] = CurrentPoly->vec[2] = 0;
}
/* 終了処理 */
void PolyExit()
{
BufferExit();
AttrExit();
MemoryFree( CurrentPoly );
}
/* ポリゴンバッファサイズを得る */
int PolySize( vers )
int vers ;
{
assert( 0 < vers && vers < 1024 );
return sizeof( Polygon ) + sizeof( Vertex ) * (vers-1) ;
}
/* ポリゴンの数を得る */
int Polygons()
{
int n ;
Polygon *poly ;
n = 0 ;
poly = PolyTop();
while( poly != NULL )
{
n ++ ;
poly = PolyNext( poly );
}
return n ;
}
/* ポリゴンの登録 */
void PolyAppend()
{
Polygon *dst ;
int coe[3];
dst = BufferAppend( PolySize( CurrentPoly->vers ) );
dst->select = CurrentPoly->select ;
if (dst->select) {
Selects++;
}
Coefficent(coe, CurrentPoly->ver, CurrentPoly->vers);
dst->vec[0] = CurrentPoly->vec[0] = coe[0];
dst->vec[1] = CurrentPoly->vec[1] = coe[1];
dst->vec[2] = CurrentPoly->vec[2] = coe[2];
dst->type = CurrentPoly->type ;
dst->atr = CurrentPoly->atr ;
dst->obj = CurrentPoly->obj ;
dst->vers = CurrentPoly->vers ;
dst->mode = CurrentPoly->mode ;
memcpy( dst->ver, CurrentPoly->ver, sizeof( Vertex ) * CurrentPoly->vers );
ObjData[CurrentPoly->obj].edit = TRUE ;
}
/* 選択されているポリゴンを一時バッファに取り込む */
void *PolyLoad()
{
if ( PolyPtr == NULL )
PolyPtr = (Polygon*)BufferTop();
else
PolyPtr = (Polygon*)BufferNext( PolyPtr );
/* By Taka2 */
if ( PolyPtr == NULL )
return NULL ;
while( PolyPtr->select == OFF )
{
PolyPtr = (Polygon*)BufferNext( PolyPtr );
if ( PolyPtr == NULL )
return NULL ;
}
BufferCopy( CurrentPoly, PolyPtr, PolySize( PolyPtr->vers ) );
return PolyPtr ;
}
void *PolyLoadPtr(void *p)
{
Polygon *poly = p;
if (poly == NULL) {
return NULL;
}
PolyPtr = poly;
BufferCopy( CurrentPoly, PolyPtr, PolySize( PolyPtr->vers ) );
return PolyPtr ;
}
/* 一時バッファからポリゴンを書き戻す */
void PolySave()
{
int i;
int coe[3];
if (PolyPtr != NULL) {
BufferResize( (DataBuffer*)PolyPtr, PolySize( CurrentPoly->vers ) );
BufferCopy( PolyPtr, CurrentPoly, PolySize( CurrentPoly->vers ) );
for (i = 0; i < CurrentPoly->vers; i++) {
if ((PolyPtr->type & POLY_SHADE) == 0) {
PolyPtr->ver[i].vx = 0;
PolyPtr->ver[i].vy = 0;
PolyPtr->ver[i].vz = 0;
}
if ((PolyPtr->type & POLY_UV) == 0) {
PolyPtr->ver[i].u = 0;
PolyPtr->ver[i].v = 0;
}
}
Coefficent(coe, PolyPtr->ver, PolyPtr->vers);
CurrentPoly->vec[0] = PolyPtr->vec[0] = coe[0];
CurrentPoly->vec[1] = PolyPtr->vec[1] = coe[1];
CurrentPoly->vec[2] = PolyPtr->vec[2] = coe[2];
ObjData[CurrentPoly->obj].edit = TRUE ;
}
}
/* セレクトされているポリゴン削除する */
void PolyDelete()
{
Polygon *poly, *next ;
poly = PolyTop();
while( poly != NULL )
{
next = PolyNext( poly );
if ( poly->select == ON )
{
ObjData[poly->obj].edit = TRUE ;
BufferDelete( poly );
}
poly = next ;
}
BufferDeleteCorrect();
/* ObjValid();*/
Selects = 0 ;
}
/* セレクトされているポリゴンを移動する */
void PolyMove( mat )
Matrix mat ;
{
int i, x, y, z ;
Polygon *poly ;
Vertex *ver ;
int imat[5][3], imatit[5][3] ;
float r;
Matrix matit;
MatCopy(matit, mat);
MatInv(matit);
MatTra(matit);
MatToInt( imat, mat );
MatToInt( imatit, matit );
poly = PolyTop();
while( poly != NULL )
{
if ( poly->select == ON )
{
ver = poly->ver ;
for( i = poly->vers ; i > 0 ; i-- )
{
x = (int)ver->x * imat[0][0]
+ (int)ver->y * imat[1][0]
+ (int)ver->z * imat[2][0]
+ imat[4][0] ;
y = (int)ver->x * imat[0][1]
+ (int)ver->y * imat[1][1]
+ (int)ver->z * imat[2][1]
+ imat[4][1] ;
z = (int)ver->x * imat[0][2]
+ (int)ver->y * imat[1][2]
+ (int)ver->z * imat[2][2]
+ imat[4][2] ;
#if 0
if (x > 0) {
ver->x = imat[3][0] + (short)( ( x + 32767) >> 16 );
} else {
ver->x = imat[3][0] - (short)( (-x + 32767) >> 16 );
}
if (y > 0) {
ver->y = imat[3][1] + (short)( ( y + 32767) >> 16 );
} else {
ver->y = imat[3][1] - (short)( (-y + 32767) >> 16 );
}
if (z > 0) {
ver->z = imat[3][2] + (short)( ( z + 32767) >> 16 );
} else {
ver->z = imat[3][2] - (short)( (-z + 32767) >> 16 );
}
#else
ver->x = (short)imat[3][0] + (short)( x >> 16 );
ver->y = (short)imat[3][1] + (short)( y >> 16 );
ver->z = (short)imat[3][2] + (short)( z >> 16 );
#endif
x = (int)ver->vx * imatit[0][0]
+ (int)ver->vy * imatit[1][0]
+ (int)ver->vz * imatit[2][0];
y = (int)ver->vx * imatit[0][1]
+ (int)ver->vy * imatit[1][1]
+ (int)ver->vz * imatit[2][1];
z = (int)ver->vx * imatit[0][2]
+ (int)ver->vy * imatit[1][2]
+ (int)ver->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;
ver->vx = (short)(r * (float)x);
ver->vy = (short)(r * (float)y);
ver->vz = (short)(r * (float)z);
/*
ver->vx = (short)( x >> 16 );
ver->vy = (short)( y >> 16 );
ver->vz = (short)( z >> 16 );
*/
ver ++ ;
}
ObjData[poly->obj].edit = TRUE ;
x = (int)poly->vec[0] * imatit[0][0]
+ (int)poly->vec[1] * imatit[1][0]
+ (int)poly->vec[2] * imatit[2][0];
y = (int)poly->vec[0] * imatit[0][1]
+ (int)poly->vec[1] * imatit[1][1]
+ (int)poly->vec[2] * imatit[2][1];
z = (int)poly->vec[0] * imatit[0][2]
+ (int)poly->vec[1] * imatit[1][2]
+ (int)poly->vec[2] * 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;
/* r = 256.0 / sqrt( x * x + y * y + z * z );*/
poly->vec[0] = (short)(r * (float)x);
poly->vec[1] = (short)(r * (float)y);
poly->vec[2] = (short)(r * (float)z);
}
poly = PolyNext( poly );
}
}
/* セレクトされていないポリゴンを不可視属性にする */
void PolyInvisible( flag )
int flag ;
{
Polygon *poly ;
poly = PolyTop();
while( poly != NULL )
{
if ( flag )
{
if ( poly->select == OFF )
poly->mode |= MODE_INVISIBLE ;
}
else
poly->mode &= ~ MODE_INVISIBLE ;
poly = PolyNext( poly );
}
}
void PolyShiftVertex( int begin )
{
int src, dst;
Vertex *oldver;
oldver = MemoryAlloc(sizeof(Vertex) * CurrentPoly->vers);
memcpy(oldver, CurrentPoly->ver, sizeof(Vertex) * CurrentPoly->vers);
src = begin;
for (dst = 0; dst < CurrentPoly->vers; dst++) {
CurrentPoly->ver[dst] = oldver[src];
if (++src >= CurrentPoly->vers) {
src = 0;
}
}
MemoryFree(oldver);
}
void PolyInvVertex( void )
{
int begin, end;
Vertex v;
begin = 0;
end = CurrentPoly->vers-1;
while (begin < end) {
v = CurrentPoly->ver[begin];
CurrentPoly->ver[begin] = CurrentPoly->ver[end];
CurrentPoly->ver[end] = v;
begin++;
end--;
}
/*
法線の向きも逆にするかどうかは未定。
逆にするときはframe.cでの処理は無くすこと。
*/
}