|
|
发表于 2006-3-28 16:04:00
|
显示全部楼层
Re:求教高手如何让摄象机在原地坐自我旋转.
看光线游戏引擎的示例源代码吧,或许对你有帮助:
#include "main.h"
player_t player;
// 初始化玩家信息
int InitialPlayer( void )
{
char string[MAX_PATH];
int num, p = 0;
//num = gGetMapStringNumber( 0 );
//sprintf( string, "实体数:%d", num );
gGetMapString( string, "origin", 3, 0 );
player.pos[0] = atof( &string[p] );
while( string[p++] != ' ' );
player.pos[1] = atof( &string[p] );
while( string[p++] != ' ' );
player.pos[2] = atof( &string[p] );
player.rotate[0] = 0;
player.rotate[1] = 0;
player.mouse_speed = 500;
player.viewline = 150;
player.forward = 0;
player.right = 0;
player.move = 0;
player.velocity = (float)250/1000;
player.sequence = 1;
//////////////////////
// 防止地面摩擦
player.pos[2] +=5;
//////////////////////
// 将骨骼动画文件读入内存
player.model = gLoadModel( "..\\resource\\girl.mdl" );
if ( player.model < 0 )
return 1;
// 设置模型动作
gSetModelSequence( player.model, 1 );
// 设置模型位置
gSetModelPos( player.model, player.pos[0], player.pos[1], player.pos[2] );
// 设置模型旋转角度
//gSetModelRotate( player.model, 270, 0, 0 );
player.step[0] = gLoadSound( "..\\resource\\pl_step1.wav" );
player.step[1] = gLoadSound( "..\\resource\\pl_step2.wav" );
player.step[2] = gLoadSound( "..\\resource\\pl_step3.wav" );
player.step[3] = gLoadSound( "..\\resource\\pl_step4.wav" );
player.m4a1[0] = gLoadSound( "..\\resource\\m4a1_unsil-2.wav" );
gSetSoundMinDistance( player.step[1], 50 );
gSetSoundMinDistance( player.m4a1[0], 100 );
// 读取弹痕纹理
player.crater[0] = gLoadImage( "..\\resource\\temp16-rle.tga" );
player.crater[1] = gLoadImage( "..\\resource\\crater2.bmp" );
player.crater[2] = gLoadImage( "..\\resource\\crater3.bmp" );
player.crater[3] = gLoadImage( "..\\resource\\crater4.bmp" );
return 0;
}
// 处理玩家输入
int InputPlayer( void )
{
POINT point;
int x, y, cx, cy;
double rotate[3];
float xy;
vec3_t upright;
gGetCursorPos( &point );
cx = 400;
cy = 300;
gSetCursorPos( cx, cy );
x = point.x - cx;
y = point.y - cy;
rotate[0] = player.rotate[0] + (float)x / player.mouse_speed;
rotate[1] = player.rotate[1] - (float)y / player.mouse_speed;
if( rotate[0] > 2 * G_PI )
rotate[0] -= 2 * G_PI;
if( rotate[0] < 0 )
rotate[0] += 2 * G_PI;
/*if( rotate[1] > 0.5 * G_PI )
rotate[1] = 0.5 * G_PI;
if( rotate[1] < - 0.5 * G_PI )
rotate[1] = - 0.5 * G_PI;*/
if( rotate[1] > 0.075 * G_PI )
rotate[1] = 0.075 * G_PI;
if( rotate[1] < -0.5 * G_PI )
rotate[1] = -0.5 * G_PI;
//xy = (float)cos( rotate[1] );
//player.eyes[0] = (float)sin( rotate[0] ) * xy;
//player.eyes[1] = (float)cos( rotate[0] ) * xy;
//player.eyes[2] = (float)sin( rotate[1] );
xy = (float)cos( rotate[1] ) * player.viewline;
player.eyes[0] = -(float)sin( rotate[0] ) * xy;
player.eyes[1] = -(float)cos( rotate[0] ) * xy;
player.eyes[2] = -(float)sin( rotate[1] ) * player.viewline;
player.direction[0] = (float)sin( rotate[0] );
player.direction[1] = (float)cos( rotate[0] );
player.direction[2] = 0;
upright[0] = player.eyes[1];
upright[1] = - player.eyes[0];
upright[2] = 0;
gCrossProduct( upright, player.eyes, player.up );
// 移动玩家
int time;
float s, temp;
vec3_t vects, sv;
vec3_t p1;
time = gGetTickCount();
if( player.forward || player.right )
{
// 保存玩家原来坐标
gVectorCopy ( player.pos, p1 );
s = (float)player.velocity * ( time - player.lasttime );
sv[0] = (float)player.right;
sv[1] = (float)player.forward;
sv[2] = 0;
gVectorNormalize( sv );
gVectorScale( sv, s, sv );
// forward 产生的位移
//gVectorScale( player.eyes, sv[1], vects );
gVectorScale( player.direction, sv[1], vects );
gVectorAdd( player.pos, vects, player.pos );
// right 产生的位移
gVectorCopy( player.direction, vects );
temp = vects[0]; // 向量旋转 -90 度
vects[0] = vects[1];
vects[1] = -temp;
gVectorNormalize( vects );
//gVectorScale( vects, sv[0], vects );
gVectorScale( vects, sv[0] * 0.4, vects );
gVectorAdd( player.pos, vects, player.pos );
// 进行碰撞检测,并计算碰撞后坐标
gModelCollideMap ( p1, player.pos, player.model, 0 );
// 设置模型动作
if ( player.sequence != 4 )
{
player.sequence = 4;
gSetModelSequence( player.model, 4 );
}
// 播放脚步声
if( time - player.steptime > 300 )
{
gSetSoundPos( player.step[1], player.pos[0], player.pos[1], player.pos[2] );
gPlaySound( player.step[1] );
player.steptime = time;
}
}
else
{
// 设置模型动作
if ( player.sequence != 1 )
{
player.sequence = 1;
gSetModelSequence( player.model, 1 );
}
}
// 射击处理
if( player.shoot )
{
if( time - player.shoottime > 100 )
{
gSetSoundPos( player.m4a1[0], player.pos[0], player.pos[1], player.pos[2] );
gPlaySound( player.m4a1[0] );
player.shoottime = time;
}
}
player.lasttime = time;
player.eyes[0] += player.pos[0];
player.eyes[1] += player.pos[1];
player.eyes[2] += player.pos[2];
player.rotate[0] = rotate[0];
player.rotate[1] = rotate[1];
return 0;
}
// 场景漫游演示程序
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
unsigned int key;
float angle;
int model1;
float a[3][4], b[3][4], c[3][4];
// 启动光线游戏引擎
gLightStartup();
// 设置显示模式为窗口模式
//gSetWindowMode(200, 150, 400, 300, 0);
gSetDisplayMode( 0, 0, 0, 0, 0 );
gInitialInput();
gInitialSound();
gSetColorKey( 255, 0, 0 );
gEnable( G_COLOR_KEY );
// 显示正在读取资料的提示信息
gColor( 0, 255, 0 );
gSetTextPos( 290, 280 );
gDrawText( "正在读取资料,请稍候......" );
gUpdateDisplay();
// 读取地图文件
gLoadMap( "..\\resource\\cs_bloodstrike.bsp" );
gOpenVideo( "..\\resource\\back.mp3" );
//gVideoPlay();
// 读取挖掘机模型
vec3_t pos;
int p = 0;
char string[100];
model1 = gLoadModel( "..\\resource\\w_m4a1.mdl" );
gGetMapString( string, "origin", 9, 0 );
pos[0] = atof( &string[p] );
while( string[p++] != ' ' );
pos[1] = atof( &string[p] );
while( string[p++] != ' ' );
//pos[2] = atof( &string[p] ) - 35;
pos[2] = atof( &string[p] );
gSetModelPos( model1, pos[0], pos[1], pos[2] );
//gSetModelPos( model1, 0, 0, 0 );
// 设置模型矩阵
gRotateXMatrix( 90, a );
gRotateZMatrix( 270, b );
gMultiplyMatrix( a, b, c );
gRotateYMatrix( 340, a );
gMultiplyMatrix( a, c, b );
pos[0] = 11;
pos[1] = 0;
pos[2] = 0;
gTranslateMatrix( pos, a );
gMultiplyMatrix( a, b, c );
gSetModelMatrix( model1, c );
// 初始化玩家信息
InitialPlayer();
// 将武器绑定到玩家身上
gAttachmentModel( model1, player.model, 0 );
ShowCursor( TRUE );
gSetCursorPos( 400, 300 );
// 计算弹痕多边形
vertex_t vertex[4];
gVectorCopy( player.pos, vertex[0].vertex );
gVectorCopy( player.pos, vertex[1].vertex );
gVectorCopy( player.pos, vertex[2].vertex );
gVectorCopy( player.pos, vertex[3].vertex );
vertex[1].vertex[0] += 50;
vertex[2].vertex[0] += 50;
vertex[2].vertex[2] -= 50;
vertex[3].vertex[2] -= 50;
for( int i=0; i<4; i++ )
{
vertex.normal[0] = 0;
vertex.normal[1] = -1;
vertex.normal[2] = 0;
}
vertex[0].texcoord[0] = 0;
vertex[0].texcoord[1] = 0;
vertex[1].texcoord[0] = 1;
vertex[1].texcoord[1] = 0;
vertex[2].texcoord[0] = 1;
vertex[2].texcoord[1] = 1;
vertex[3].texcoord[0] = 0;
vertex[3].texcoord[1] = 1;
// 设置听众位置
gSetListenerPos( player.pos[0], player.pos[1], player.pos[2] );
// 设置距离因子
//gSetRolloffFactor( 0.035 );
do
{ // 清除屏幕内容
gClearDisplay();
// 设置摄像机位置
gLookAt( player.eyes[0], player.eyes[1], player.eyes[2],
player.pos[0], player.pos[1], player.pos[2] + 50,
player.up[0], player.up[1], player.up[2] );
// 显示地图
gDrawMap( 0 );
// 设置模型位置
gSetModelPos( player.model, player.pos[0], player.pos[1], player.pos[2] );
// 设置模型旋转角度
//angle = player.rotate[0] * (( float)180 / G_PI ) + 270;
angle = 360 - (player.rotate[0] * (( float)180 / G_PI )) + 90;
gSetModelRotate( player.model, angle, 0, 0 );
// 显示骨骼动画
gDrawModel( player.model );
gDrawModel( model1 );
// 显示弹痕多边形
//gEnable( G_BLEND );
//gPolygon( vertex, 4, player.crater[0] );
//gDisable( G_BLEND );
// 显示布告板
gBillboard( vertex[0].vertex, 50, 50, player.crater[0] );
//gParticle( vertex[0].vertex, 50, 50, player.crater[0] );
// 处理玩家指令
InputPlayer();
// 碰撞检测
/*vec3_t vert[2], cross;
vert[0][0] = player.pos[0] + player.direction[0] * 50;
vert[0][1] = player.pos[1] + player.direction[1] * 50;
vert[0][2] = player.pos[2] + player.direction[2] * 50;
vert[1][0] = player.pos[0];
vert[1][1] = player.pos[1];
vert[1][2] = player.pos[2];
gColor( 255, 0, 0 );
gLines( vert, 2 );
gColor( 0, 255, 0 );
if( gLineCrossMap( vert[0], vert[1], cross ) )
{
gPoints( &cross, 1 );
//MessageBox( 0, "", "", MB_OK );
}*/
// 显示帧速(FPS)
char fps[100];
sprintf( fps, "帧速: %d 帧/秒", gGetFramePerSecond() );
gColor( 0, 255, 0 );
gSetTextPos( 40, 550 );
gDrawText( fps );
sprintf( fps, "\"光线游戏引擎\"演示", gGetFramePerSecond() );
gSetTextPos( 500, 490 );
gDrawText( fps );
sprintf( fps, "http://light.gameres.com", gGetFramePerSecond() );
gSetTextPos( 500, 520 );
gDrawText( fps );
sprintf( fps, "按键:W S A D 和 鼠标左键", gGetFramePerSecond() );
gSetTextPos( 500, 550 );
gDrawText( fps );
// 显示准星
gLineRaster( 390,300, 395,300);
gLineRaster( 405,300, 410,300);
gLineRaster( 400,290, 400,295);
gLineRaster( 400,305, 400,310);
// 更新显示
gUpdateDisplay();
// 读取按键信息
player.forward = 0;
player.right = 0;
player.shoot = 0;
key = gGetKey();
if( gGetKeyState( KEY_W ) )
player.forward = 1;
else
if( gGetKeyState( KEY_S ) )
player.forward = -1;
if( gGetKeyState( KEY_A ) )
player.right = -1;
else
if( gGetKeyState( KEY_D ) )
player.right = 1;
if( gGetKeyState( KEY_MOUSE_BUTTON0 ) )
player.shoot = 1;
}
// 配送消息
while( key != KEY_ESCAPE && gDispatchMessage() );
gCloseVideo();
// 从内存中释放地图文件
gUnloadMap( 0 );
// 从内存中释放模型文件
gUnloadModel( player.model );
// 退出光线游戏引擎
gLightCleanup();
return 0;
} |
|