home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
REND.LZH
/
READER
/
OBJREAD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1996-07-09
|
11KB
|
527 lines
/*
形状ファイル入力関数
Copyright T.Kobayashi
*/
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <assert.h>
#include "reader.h"
#include "word.h"
#define POINT_UNIT 4
#define ATR_UNIT 10
#define OLD_FASION 1
#define PRIVATE_OP 2
#define ALREADY_EXIST 11
#define NOT_FOUND 12
#define BAD_EXIST 13
#define NOT_SUF_MODEL 14
#define NOT_IMPLIMENTED 15
#define ATR_NOT_FOUND 16
#define OBJ_NOT_FOUND 17
#define LESS_POINT 18
#define ATR_NO_EXIST 19
#define UNEXPECTED_EOF 21
#define NOT_OBJ_FILE 22
static AtrName *atrname ;
static int atrnum ;
static Pointer(Object*) top ;
static int matflag ;
/*
proto -s objread.c > temp
*/
static void get_obj_data( Object*, int, Matrix );
static void get_prim_data( Poly*, Matrix );
static void coefficent( Float[4], Point*, int );
static Pointer(Object*) search_obj( char* );
static int search_atr( char* );
static void objerror( int, char* );
Pointer(Object*) objread( filename, objlist )
char *filename ;
Pointer(Object*) objlist ;
{
Pointer(Poly*) pp ;
Object obj, *objp ;
Point *point ;
Poly *poly ;
Matrix c_mat ;
int i, j, k, n ;
Pointer(AtrName*) cp ;
/* エラー処理の初期化 */
errlevel = 1 ;
/* ファイルのオープン */
fileopen( filename );
if ( wordid != WORD_OBJ )
objerror( NOT_OBJ_FILE, "" );
top = objlist ;
#if 1
if (objlist != NULL) {
while (objlist->next != NULL) {
objlist = objlist->next;
}
}
#endif
while( ! end_of_file )
{
/* obj の検出 */
if ( wordid != WORD_OBJ )
{
objerror( NOT_FOUND, "obj" ) ;
skip( "obj" );
if ( end_of_file )
break ;
}
get() ;
/* private の検出(警告) */
if ( wordid == WORD_PRIVATE )
{
objerror( PRIVATE_OP, "" );
get() ;
}
/* suf の検出 */
if ( wordid != WORD_SUF )
objerror( NOT_SUF_MODEL, "" ) ;
else
get() ;
/* オブジェクト名のリード */
getname( obj.name );
for( objp = pointer(top) ; objp != NULL ; objp = pointer(objp->next) )
{
if ( strcmpi( objp->name, obj.name ) == 0 )
objerror( ALREADY_EXIST, obj.name );
}
if ( wordid != WORD_OPEN2 )
objerror( NOT_FOUND, "{" );
else
get() ;
/* オブジェクト本体のリード */
m_unit( c_mat ) ;
matflag = FALSE ;
atrnum = 0 ;
obj.polynum = 0 ;
obj.poly = NULL ;
obj.objpos = NULL ;
get_obj_data( &obj, 0, c_mat );
/* アトリビュート名配列の設定 */
obj.atrnum = atrnum ;
obj.atrname = dataalloc( sizeof( AtrName ) * atrnum );
cp = pointer( obj.atrname );
memcpy( cp, atrname, sizeof( AtrName ) * atrnum );
tempfree( atrname );
/* 各座標の最大値、最小値の計算 */
pp = obj.poly ;
poly = pointer( pp );
point = (Point*)pointer( poly->point );
v_copy( obj.max, point[0] );
v_copy( obj.min, point[0] );
for( i = 0 ; i < obj.polynum ; ++i )
{
poly = pointer( pp );
pp = poly->next ;
n = poly->pointnum ;
point = (Point*)pointer( poly->point );
for( j = 0 ; j < n ; ++j )
{
for( k = 0 ; k < 3 ; ++k )
{
if ( point[j][k] > obj.max[k] )
obj.max[k] = point[j][k];
if ( point[j][k] < obj.min[k] )
obj.min[k] = point[j][k];
}
}
}
/* リストの結合 */
#if 0
obj.next = top ;
po = dataalloc( sizeof( Object ) );
memcpy( pointer( po ), &obj, sizeof( Object ) );
top = po ;
#else
obj.next = NULL;
objp = dataalloc( sizeof( Object ) );
memcpy( pointer( objp ), &obj, sizeof( Object ) );
if (objlist == NULL) {
objlist = top = objp;
} else {
objlist->next = objp;
objlist = objlist->next;
}
#endif
}
fileclose() ;
if ( errlevel < 10 )
return( top ) ;
return( NULL ) ;
}
static void get_obj_data( obj, atrid, mat )
Object *obj ;
int atrid ;
Matrix mat ;
{
Matrix c_mat, m ;
char name[MAXWORD] ;
Pointer(Poly*) pp ;
Pointer(ObjPos*) pop;
Poly *poly ;
ObjPos *objpos ;
int lockid ;
m_copy( c_mat, mat ) ;
while( wordid != WORD_CLOSE2 )
{
switch( wordid )
{
case WORD_ATR :
get() ;
getname( name );
#if 0
if ( strcmpi( name, "no" ) == 0 )
objerror( ATR_NO_EXIST, "" );
#endif
atrid = search_atr( name );
break ;
case WORD_PRIM :
get() ;
++ obj->polynum ;
pp = dataalloc( sizeof( Poly ) );
poly = pointer( pp );
lockid = datalock();
poly->atr = NULL ;
poly->atrid = atrid ;
poly->next = obj->poly ;
get_prim_data( poly, c_mat );
dataunlock( lockid );
obj->poly = pp ;
break ;
case WORD_PARTS :
get() ;
getname( name );
pop = dataalloc( sizeof( ObjPos ) );
objpos = pointer( pop );
lockid = datalock();
objpos->obj = search_obj( name );
m_copy( objpos->mat, c_mat );
objpos->next = obj->objpos ;
dataunlock( lockid );
obj->objpos = pop ;
break ;
case WORD_OPEN2 :
get() ;
get_obj_data( obj, atrid, c_mat ) ;
break ;
default :
getmat( m );
m_mult( c_mat, m, c_mat ) ;
matflag = TRUE ;
break ;
}
}
get() ;
}
#ifdef V70
static int bufsize = 0 ;
static Point *point, *vec, *uv ;
#endif
static void get_prim_data( poly, c_mat )
Poly *poly ;
Matrix c_mat ;
{
int n, i ;
Point *pp ;
#ifndef V70
static int bufsize = 0 ;
static Point *point, *vec, *uv ;
#endif
if ( bufsize == 0 )
{
bufsize = POINT_UNIT ;
point = (Point*)tempalloc( sizeof( Point ) * bufsize );
vec = (Vector*)tempalloc( sizeof( Vector ) * bufsize );
uv = (Point*)tempalloc( sizeof( Point ) * bufsize );
}
switch( wordid )
{
case WORD_POLY :
poly->type = POLY ;
break ;
case WORD_SHADE :
poly->type = SHADE ;
break ;
case WORD_UVPOLY :
poly->type = UVPOLY ;
break ;
case WORD_UVSHADE :
poly->type = UVSHADE ;
break ;
default :
objerror( BAD_EXIST, nextword ) ;
}
get() ;
if ( wordid != WORD_OPEN1 )
objerror( NOT_FOUND, "(" ) ;
get() ;
/* 頂点数のカウントとテンポラリへの保存 */
for( n = 0 ; ; ++n )
{
if ( end_of_file )
objerror( UNEXPECTED_EOF, "" );
if ( wordid == WORD_CLOSE1 )
break ;
/* サイズの確認 */
if ( n == bufsize )
{
bufsize += POINT_UNIT ;
point = (Point*)temprealloc( point, sizeof( Point ) * bufsize ); vec = (Vector*)temprealloc( vec, sizeof( Vector ) * bufsize );
uv = (Point*)temprealloc( uv, sizeof( Point ) * bufsize );
}
assert( n < bufsize );
/* データリード */
getvector( point[n] ) ; /* 頂点座標 */
if ( poly->type & SHADE )
getvector( vec[n] ) ; /* 法線ベクトル */
if ( poly->type & UVPOLY )
{
uv[n][0] = getFloat() ; /* UV座標 */
uv[n][1] = getFloat() ;
}
}
/* エラーチェック */
if ( n <= 2 )
{
objerror( LESS_POINT, "" );
return ;
}
poly->pointnum = n ;
get() ;
/* データバッファの確保 */
poly->point = dataalloc( sizeof( Point ) * n );
if ( poly->type & SHADE )
poly->vec = dataalloc( sizeof( Vector ) * n );
if ( poly->type & UVPOLY )
poly->uv = dataalloc( sizeof( Vector ) * n );
/* 頂点データのコピー */
pp = (Point*)pointer( poly->point );
for( i = 0 ; i < n ; ++i )
v_copy( pp[i], point[i] ) ;
if ( poly->type & SHADE )
{
pp = (Vector*)pointer( poly->vec );
for( i = 0 ; i < n ; ++i )
v_copy( pp[i], vec[i] ) ;
}
if ( poly->type & UVPOLY )
{
pp = (Point*)pointer( poly->uv );
for( i = 0 ; i < n ; ++i )
{
pp[i][0] = uv[i][0] ;
pp[i][1] = uv[i][1] ;
}
}
/* 座標変換 */
if ( matflag )
{
pp = (Point*)pointer( poly->point );
vec_mult_mat( pp, pp, c_mat, n, 1 );
if ( poly->type & SHADE )
{
pp = (Vector*)pointer( poly->vec );
vec_mult_mat( pp, pp, c_mat, n, 0 );
}
}
/* 係数の計算 */
pp = (Point*)pointer( poly->point );
coefficent( poly->coe, pp, n );
}
/* 係数の計算(規格化する) */
static void coefficent( coe, point, n )
Float coe[4] ;
Point *point ;
int n ;
{
int i ;
Point *p1, *p2 ;
p1 = point ;
p2 = point + 1 ;
coe[0] = coe[1] = coe[2] = 0.0 ;
for( i = 0 ; i < n-1 ; ++i )
{
coe[0] += ( p1[0][1] - p2[0][1] ) * ( p1[0][2] + p2[0][2] ) ;
coe[1] += ( p1[0][2] - p2[0][2] ) * ( p1[0][0] + p2[0][0] ) ;
coe[2] += ( p1[0][0] - p2[0][0] ) * ( p1[0][1] + p2[0][1] ) ;
++p1 ;
++p2 ;
}
p2 = point ;
coe[0] += ( p1[0][1] - p2[0][1] ) * ( p1[0][2] + p2[0][2] ) ;
coe[1] += ( p1[0][2] - p2[0][2] ) * ( p1[0][0] + p2[0][0] ) ;
coe[2] += ( p1[0][0] - p2[0][0] ) * ( p1[0][1] + p2[0][1] ) ;
v_unit( coe, coe );
coe[3] = 0.0 ;
for( i = 0 ; i < 3 ; ++i )
coe[3] -= coe[i] * point[0][i] ;
}
static Pointer(Object*) search_obj( name )
char *name ;
{
Pointer(Object*) p ;
Object *obj ;
for( p = top ; p != NULL ; p = obj->next )
{
obj = pointer( p );
if ( strcmpi( obj->name, name ) == 0 )
break ;
}
if ( p == NULL )
objerror( OBJ_NOT_FOUND, name );
return( p );
}
/* アトリビュート名の検索 */
static int search_atr( name )
char *name ;
{
int i ;
AtrName *an ;
for( i = 0 ; i < atrnum ; ++i )
{
if ( strcmpi( atrname[i], name ) == 0 )
break ;
}
if ( i == atrnum )
{
if ( atrnum % ATR_UNIT == 0 )
{
an = atrname ;
atrname =
(AtrName*)tempalloc( sizeof( AtrName ) * (atrnum+ATR_UNIT) );
if ( atrnum > 0 )
{
memcpy( atrname, an, sizeof( AtrName )*atrnum );
tempfree( an );
}
}
strcpy( atrname[ atrnum++ ], name );
}
return( i );
}
static void objerror( n, arg )
int n ;
char *arg ;
{
char *msg ;
int level ;
switch( n )
{
case OLD_FASION :
msg = "警告:古い規格の書式です。:%s" ;
level = 1 ;
break ;
case PRIVATE_OP :
msg = "警告:private 処理はサポートしていません。" ;
level = 3 ;
break ;
case ALREADY_EXIST :
msg = "オブジェクト名 %s が二度宣言されています。" ;
level = 10 ;
break ;
case NOT_FOUND :
msg = " %s がありません。" ;
level = 10 ;
break ;
case BAD_EXIST :
msg = " %s が存在します。" ;
level = 10 ;
break ;
case NOT_SUF_MODEL :
msg = "サーフィスモデルではありません。" ;
level = 10 ;
break ;
case NOT_IMPLIMENTED :
msg = " %s はサポートしていません。" ;
level = 10 ;
break ;
case ATR_NOT_FOUND :
msg = "アトリビュート名 %s は登録されていません。" ;
level = 10 ;
break ;
case OBJ_NOT_FOUND :
msg = "オブジェクト名 %s は登録されていません。" ;
level = 10 ;
break ;
case LESS_POINT :
msg = "多角形の頂点が2つ以下しかありません。" ;
level = 10 ;
break ;
case ATR_NO_EXIST :
msg = "atr no があります。" ;
level = 10 ;
break ;
case UNEXPECTED_EOF :
msg = "エンドオブファイルになりました" ;
level = 20 ;
break ;
case NOT_OBJ_FILE :
msg = "形状ファイルではありません。" ;
level = 20 ;
break ;
default :
msg = "エラーコードの誤り。( objread.c )" ;
level = 20 ;
break ;
}
errormessage( level, msg, arg );
}