home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
DOS/V Power Report 1997 March
/
VPR9703A.ISO
/
VPR_DATA
/
DOGA
/
SOURCES
/
REND.LZH
/
READER
/
FRAMREAD.C
< prev
next >
Wrap
C/C++ Source or Header
|
1995-11-07
|
14KB
|
745 lines
/*
フレームファイル入力関数
Copyright T.Kobayashi
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include "reader.h"
#include "word.h"
#ifdef V70
#define RAD 0.0174532925199
#else
#define RAD (3.14159265358979/180.0)
#endif
#define OLD_FASION 1
#define NOT_FOUND 11
#define BAD_EXIST 12
#define NOT_IMPLIMENTED 13
#define OBJ_NOT_FOUND 14
#define GRAD_TOO_LONG 15
#define TOO_MANY 16
#define BAD_MATRIX 17
#define UNEXPECTED_EOF 21
#define NOT_FRAME_FILE 22
static Environ env ; /* 環境 */
static Frame frame ; /* フレーム */
static Pointer(Object*) objtop ; /* オブジェクトリストの先頭 */
static int eyestat ; /* 視点の使用フラグ */
static int targetstat ; /* ターゲットの使用フラグ */
static Point target ; /* ターゲットの位置 */
#if 1 /* 1995.08.08 */
#define MAXOBJNAMEBUF 10000
#define MAXOBJNAMES 1000
static char objnamebuf[ MAXOBJNAMEBUF ];
static char *objnames[ MAXOBJNAMES ];
static char *curobjnamebuf ;
static int nobjnames;
#endif
/*
proto -s framread.c > temp
*/
static void getenviron( void );
static void getframe( Matrix );
static void getobj( Matrix );
static void geteye( Matrix );
static void getlight( Matrix );
static void envclear( void );
static void frameerror( int, char* );
#if 1 /* 1995.08.08 */
static void getframe2( Matrix );
static void getobj2( Matrix );
#endif
/*
フレームファイルのオープン
戻り値 1:正常
0:エラー
*/
int frameopen( framefile )
char *framefile ;
{
errlevel = 0 ;
if ( fileopen( framefile ) == 0 )
return( 0 );
if ( wordid != WORD_ENV && wordid != WORD_FRAM )
{
frameerror( NOT_FRAME_FILE, "" );
fileclose() ;
return( 0 );
}
envclear() ;
#if 1 /* 1995.08.09 */
curobjnamebuf = objnamebuf;
nobjnames = 0;
objnamebuf[0] = '\0';
#endif
return( 1 );
}
/* フレームファイルのクローズ */
void frameclose()
{
fileclose();
}
/*
フレームデータのスキップ
戻り値 0 : エラー
1 : 正常終了
*/
int frameskip()
{
errlevel = 0 ;
/* 環境のリード */
if ( wordid == WORD_ENV )
getenviron() ;
/* fram のリード */
if ( wordid != WORD_FRAM )
frameerror( NOT_FOUND, "fram" );
get() ;
/* fram までスキップ */
while( wordid != WORD_FRAM && wordid != WORD_ENV )
get() ;
if ( errlevel >= 10 )
return( 0 );
return( 1 );
}
#if 1 /* 1995.08.09 */
/* フレームファイルのリード */
Frame *frameread2( nnames, names )
int *nnames;
char ***names;
{
Matrix mat, dmy ;
int i ;
Vector vx, vz, e ;
objtop = NULL ;
errlevel = 0 ;
/* 環境のリード */
if ( wordid == WORD_ENV )
getenviron() ;
/* fram のリード */
if ( wordid != WORD_FRAM )
frameerror( NOT_FOUND, "fram" );
get() ;
/* { のリード */
if ( wordid != WORD_OPEN2 )
{
frameerror( NOT_FOUND, "{" );
skip( "{" );
}
else
get() ;
/* frame の初期化 */
frame.env = env ;
frame.lightnum = 0 ;
frame.objpos = NULL ;
m_unit( mat );
eyestat = 0 ;
targetstat = 0 ;
/* フレーム本体のリード */
getframe2( mat ) ;
/* 視点、ターゲットの処理 */
if ( eyestat == 0 )
frameerror( NOT_FOUND, "視点指定" );
if ( targetstat == 1 )
{
/* 視点の位置 */
v_copy( e, frame.eye.mat[3] );
/* 視線方向のベクトル */
for( i = 0 ; i < 3 ; ++i )
vx[i] = target[i] - e[i] ;
/* 視線上方向のベクトル */
v_copy( vz, frame.eye.mat[2] );
/* 変換行列の変更 */
m_vec( frame.eye.mat, vx, vz );
v_copy( frame.eye.mat[3], e );
/* エラーチェック */
if ( m_inv( dmy, frame.eye.mat ) == 0 )
frameerror( BAD_MATRIX, "" );
}
/* リターン処理 */
if ( errlevel < 10 )
{
*nnames = nobjnames;
*names = objnames;
return( &frame );
}
return( NULL );
}
#endif
/* フレームファイルのリード */
Frame *frameread( pobj )
Pointer(Object*) pobj ; /* オブジェクトリスト */
{
Matrix mat, dmy ;
int i ;
Vector vx, vz, e ;
objtop = pobj ;
errlevel = 0 ;
/* 環境のリード */
if ( wordid == WORD_ENV )
getenviron() ;
/* fram のリード */
if ( wordid != WORD_FRAM )
frameerror( NOT_FOUND, "fram" );
get() ;
/* { のリード */
if ( wordid != WORD_OPEN2 )
{
frameerror( NOT_FOUND, "{" );
skip( "{" );
}
else
get() ;
/* frame の初期化 */
frame.env = env ;
frame.lightnum = 0 ;
frame.objpos = NULL ;
m_unit( mat );
eyestat = 0 ;
targetstat = 0 ;
/* フレーム本体のリード */
getframe( mat ) ;
/* 視点、ターゲットの処理 */
if ( eyestat == 0 )
frameerror( NOT_FOUND, "視点指定" );
if ( targetstat == 1 )
{
/* 視点の位置 */
v_copy( e, frame.eye.mat[3] );
/* 視線方向のベクトル */
for( i = 0 ; i < 3 ; ++i )
vx[i] = target[i] - e[i] ;
/* 視線上方向のベクトル */
v_copy( vz, frame.eye.mat[2] );
/* 変換行列の変更 */
m_vec( frame.eye.mat, vx, vz );
v_copy( frame.eye.mat[3], e );
/* エラーチェック */
if ( m_inv( dmy, frame.eye.mat ) == 0 )
frameerror( BAD_MATRIX, "" );
}
/* リターン処理 */
if ( errlevel < 10 )
return( &frame );
return( NULL );
}
static void getenviron()
{
int i ;
/* 環境の初期化 */
memset( &env, 0, sizeof( Environ ) );
get() ;
/* { のリード */
if ( wordid != WORD_OPEN2 )
{
frameerror( NOT_FOUND, "{" );
skip( "{" );
}
else
get() ;
while( wordid != WORD_CLOSE2 )
{
switch( wordid )
{
case WORD_BACK :
isopen1() ;
getcolor( env.back ) ;
break ;
case WORD_STAR :
isopen1() ;
env.star = (int )getFloat() ;
break ;
case WORD_GLAD :
isopen1() ;
env.grad.gradtype = 1 ;
getvector( env.grad.vec );
i = 0 ;
do
{
getcolor( env.grad.col[i] );
env.grad.degree[i] = getFloat() ;
++i ;
if ( i == MAXGRAD )
{
frameerror( GRAD_TOO_LONG, "" );
skip( ")" );
break ;
}
}
while( wordid != WORD_CLOSE1 ) ;
env.grad.colnum = i ;
break ;
case WORD_DEPTH :
isopen1() ;
env.depth = getFloat() ;
getcolor( env.depthcol ) ;
break ;
case WORD_MAP :
isopen1() ;
strcpy( env.map, nextword );
get() ;
break ;
default :
frameerror( BAD_EXIST, nextword );
get() ;
}
isclose1() ;
}
get();
}
#if 1 /* 1995.08.09 */
static void getframe2( mat )
Matrix mat;
{
Matrix c_mat, m ;
m_copy( c_mat, mat );
while( wordid != WORD_CLOSE2 )
{
switch( wordid )
{
case WORD_OBJ :
get() ;
getobj2( c_mat ) ;
break ;
case WORD_EYE :
get() ;
geteye( c_mat ) ;
break ;
case WORD_LIGHT :
get() ;
getlight( c_mat ) ;
break ;
case WORD_TARGET :
get() ;
if ( targetstat == 1 )
frameerror( TOO_MANY, "ターゲット指定" );
targetstat = 1 ;
v_copy( target, c_mat[3] );
break ;
case WORD_OPEN2 :
get() ;
getframe2( c_mat );
break ;
default :
getmat( m );
m_mult( c_mat, m, c_mat ) ;
break ;
}
}
get() ;
}
#endif
static void getframe( mat )
Matrix mat ;
{
Matrix c_mat, m ;
m_copy( c_mat, mat );
while( wordid != WORD_CLOSE2 )
{
switch( wordid )
{
case WORD_OBJ :
get() ;
getobj( c_mat ) ;
break ;
case WORD_EYE :
get() ;
geteye( c_mat ) ;
break ;
case WORD_LIGHT :
get() ;
getlight( c_mat ) ;
break ;
case WORD_TARGET :
get() ;
if ( targetstat == 1 )
frameerror( TOO_MANY, "ターゲット指定" );
targetstat = 1 ;
v_copy( target, c_mat[3] );
break ;
case WORD_OPEN2 :
get() ;
getframe( c_mat );
break ;
default :
getmat( m );
m_mult( c_mat, m, c_mat ) ;
break ;
}
}
get() ;
}
#if 1
/* 1995.08.08 */
static void add_to_objnamebuf( char *name )
{
int i;
int len;
for ( i=0 ; i<nobjnames ; i++ )
{
if ( strcmpi( objnames[i], name ) == 0 )
break;
}
if ( i < nobjnames )
return;
if ( nobjnames >= MAXOBJNAMES )
return;
len = strlen(name) + 1;
if ( curobjnamebuf + len >= objnamebuf + MAXOBJNAMEBUF )
return;
strcpy( curobjnamebuf, name );
objnames[ nobjnames++ ] = curobjnamebuf;
curobjnamebuf += len;
return;
}
/* 1995.08.11 */
static void getobj2( c_mat )
Matrix c_mat ;
{
ObjPos *objpos ;
Object *obj ;
Pointer(ObjPos*) p;
Pointer(Object*) pobj ;
char name[MAXWORD] ;
int lockid ;
/* オブジェクト名 */
getname( name );
/* オブジェクトリストの確保 */
p = dataalloc( sizeof( ObjPos ) );
objpos = pointer( p );
lockid = datalock();
m_copy( objpos->mat, c_mat );
/* オブジェクト名の登録1 */
add_to_objnamebuf( name );
/* オブジェクト名の登録2 */
for ( pobj=objtop ; pobj!=NULL ; pobj=obj->next )
{
obj = pointer( pobj );
if ( strcmpi( obj->name, name ) == 0 )
break;
}
if ( pobj == NULL )
{
pobj = dataalloc( sizeof( Object ) );
obj = pointer( pobj );
strcpy( obj->name, name );
obj->next = objtop;
objtop = obj;
}
objpos->obj = pobj ;
/* リストの結合 */
objpos->next = frame.objpos ;
frame.objpos = p ;
dataunlock( lockid );
}
#endif
static void getobj( c_mat )
Matrix c_mat ;
{
ObjPos *objpos ;
Object *obj ;
Pointer(ObjPos*) p;
Pointer(Object*) pobj ;
char name[MAXWORD] ;
int lockid ;
/* オブジェクト名 */
getname( name );
if ( objtop == NULL )
return ;
/* オブジェクトリストの確保 */
p = dataalloc( sizeof( ObjPos ) );
objpos = pointer( p );
lockid = datalock();
m_copy( objpos->mat, c_mat );
/* オブジェクト名の照合 */
for( pobj = objtop ; pobj != NULL ; pobj = obj->next )
{
obj = pointer( pobj );
if ( strcmpi( obj->name, name ) == 0 )
break ;
}
if ( pobj == NULL )
frameerror( OBJ_NOT_FOUND, name );
objpos->obj = pobj ;
/* リストの結合 */
objpos->next = frame.objpos ;
frame.objpos = p ;
dataunlock( lockid );
}
static void geteye( c_mat )
Matrix c_mat ;
{
Float dist, size, deg ;
/* 視点指定の回数チェック */
if ( eyestat == 1 )
frameerror( TOO_MANY, "視点指定" );
eyestat = 1 ;
/* ( のチェック */
m_copy( frame.eye.mat, c_mat ) ;
if ( wordid == WORD_OPEN1 )
{
frameerror( OLD_FASION, "( の位置が違います。" );
get() ;
}
switch( wordid )
{
case WORD_DEG :
get();
if ( wordid == WORD_OPEN1 )
get() ;
deg = getFloat() ;
frame.eye.dist = 0.5 / tan( deg * RAD / 2.0 ) ;
break ;
case WORD_SCR :
get();
if ( wordid == WORD_OPEN1 )
get() ;
dist = getFloat() ;
size = getFloat() ;
frame.eye.dist = dist / size ;
break ;
default :
frameerror( BAD_EXIST, nextword );
skip( ")" );
return ;
}
/* ) のチェック */
if ( wordid != WORD_CLOSE1 )
frameerror( NOT_FOUND, ")" ) ;
else
get() ;
}
static void getlight( c_mat )
Matrix c_mat ;
{
int n ;
Matrix mit ;
Vector lvec ;
n = frame.lightnum ;
m_inv( mit, c_mat );
m_trans( mit, mit );
/* 光源の最大値チェック */
if ( frame.lightnum < MAXLIGHT )
frame.lightnum ++ ;
else
frameerror( TOO_MANY, "光源指定" );
/* ( のチェック */
if ( wordid == WORD_OPEN1 )
{
frameerror( OLD_FASION, "( の位置が違います。" );
get() ;
}
switch( wordid )
{
case WORD_POINT :
get();
frame.light[n].type = LIGHT_POINT ;
v_copy( frame.light[n].point, c_mat[3] );
if ( wordid == WORD_OPEN1 )
get() ;
getcolor( frame.light[n].col );
frame.light[n].dist = getFloat() ;
break ;
case WORD_PAL :
get();
frame.light[n].type = LIGHT_PAL ;
if ( wordid == WORD_OPEN1 )
get() ;
getcolor( frame.light[n].col );
getvector( lvec );
vec_mult_mat( (Vector*)lvec, (Vector*)lvec, mit, 1, 0 );
v_unit( frame.light[n].vec, lvec );
break ;
case WORD_SPOT :
get();
frame.light[n].type = LIGHT_SPOT ;
v_copy( frame.light[n].point, c_mat[3] );
if ( wordid == WORD_OPEN1 )
get() ;
getcolor( frame.light[n].col );
getvector( lvec );
vec_mult_mat( (Vector*)lvec, (Vector*)lvec, mit, 1, 0 );
v_unit( frame.light[n].vec, lvec );
frame.light[n].size = getFloat() ;
if (wordid != WORD_CLOSE1) {
frame.light[n].dist = getFloat() ;
} else {
frame.light[n].dist = 0.0;
}
break ;
case WORD_OBJ :
frameerror( NOT_IMPLIMENTED, "物体光源" );
get();
frame.light[n].type = LIGHT_OBJ ;
v_copy( frame.light[n].point, c_mat[3] );
if ( wordid == WORD_OPEN1 )
get() ;
getname( frame.light[n].name );
getcolor( frame.light[n].col );
frame.light[n].dist = getFloat() ;
break ;
default :
skip( ")" );
return ;
}
/* ) のチェック */
if ( wordid != WORD_CLOSE1 )
frameerror( NOT_FOUND, ")" ) ;
else
get() ;
}
static void envclear()
{
env.back[0] = env.back[1] = env.back[2] = 0L ;
env.star = 0 ;
env.grad.gradtype = 0 ;
env.depth = 0.0 ;
strcpy( env.map, "" );
}
static void frameerror( n, arg )
int n ;
char *arg ;
{
char *msg ;
int level ;
switch( n )
{
case OLD_FASION :
msg = "警告:古い規格の書式です。:%s" ;
level = 1 ;
break ;
case NOT_FOUND :
msg = " %s がありません。" ;
level = 10 ;
break ;
case BAD_EXIST :
msg = " %s が存在します。" ;
level = 10 ;
break ;
case NOT_IMPLIMENTED :
msg = " %s はサポートしていません。" ;
level = 10 ;
break ;
case OBJ_NOT_FOUND :
msg = "オブジェクト名 %s は登録されていません。" ;
level = 10 ;
break ;
case GRAD_TOO_LONG :
msg = "グラデーションの色データが多すぎます。" ;
level = 10 ;
break ;
case TOO_MANY :
msg = "%sが多すぎます。" ;
level = 10 ;
break ;
case BAD_MATRIX :
msg = "ターゲット指定がおかしい。" ;
level = 10 ;
break ;
case UNEXPECTED_EOF :
msg = "エンドオブファイルになりました" ;
level = 20 ;
break ;
case NOT_FRAME_FILE :
msg = "フレームファイルではありません。" ;
level = 20 ;
break ;
default :
msg = "エラーコードの誤り。( framread.c )" ;
level = 20 ;
break ;
}
errormessage( level, msg, arg );
}