void Node::draw( const Matrix44& pvm, const Matrix34& parentWm, const Vector3& lightVector, const Vector3& lightColor, const Vector3& ambient ) const { Matrix34 wm; wm.setTranslation( mTranslation ); wm.rotateY( mRotation.y ); wm.rotateX( mRotation.x ); wm.rotateZ( mRotation.z ); wm.scale( mScale ); wm.setMul( parentWm, wm ); if ( mBatch ){ mBatch->draw( pvm, wm, lightVector, lightColor, ambient, mColor ); } //子へ受け継ぐ for ( int i = 0; i < mChildNumber; ++i ){ ASSERT( mChildren[ i ] ); //0が入ってたら異常。 mChildren[ i ]->draw( pvm, wm, lightVector, lightColor, ambient ); } }
void Bullet::update( const Vector3& enemyPos ){ //敵の方に向ける。 Vector3 dir; Vector3 p = *mModel->getPosition(); Vector3 a = *mModel->getAngle(); if ( mHoming ){ dir.setSub( enemyPos, *mModel->getPosition() ); //自分から敵へ //Y軸角度はatan2( x, z )。 float ty = atan2( dir.x, dir.z ); //180度以上差があれば+-360度して逆回し if ( ty - a.y > 180.f ){ ty -= 2.f * 180.f; }else if ( a.y - ty > 180.f ){ ty += 2.f * 180.f; } //X軸角度はY/(X,Z)。 float zxLength = sqrt( dir.x * dir.x + dir.z * dir.z ); float tx = atan2( dir.y, zxLength ); //X軸角度はそもそも範囲が(-90,90)で180度以上離れることはない。そのままで良い。 float hx = mHomingX; float hy = mHomingY; //ホーミング範囲内ならそのものに if ( tx - a.x < hx && a.x - tx < hx ){ a.x = tx; }else if ( tx < a.x ){ a.x -= hx; }else{ a.x += hx; } if ( ty - a.y < hy && a.y - ty < hy ){ a.y = ty; }else if ( ty < a.y ){ a.y -= hy; }else{ a.y += hy; } } //おもろいのでz回転つけとくか a.z += 20.0; //角度更新 mModel->setAngle( a ); //位置はこの方向の回転行列で(0,0,1)を変換して足してやる Vector3 v( 0.0, 0.0, mSpeed ); Matrix34 m; m.setRotationY( a.y ); m.rotateX( -a.x ); m.mul( &v, v ); p += v; mModel->setPosition( p ); ++mCount; if ( mCount >= mLife ){ mCount = -1; } }
void Model::draw() const { Matrix34 wm; wm.setTranslation( mPosition ); wm.rotateY( mAngle.y ); wm.rotateX( mAngle.x ); wm.rotateZ( mAngle.z ); wm.scale( mScale ); GameLib::Graphics::Manager::instance().setWorldMatrix( wm ); mBatch->draw(); }
void Model::draw( const Matrix44& pvm ) const { Matrix34 wm; wm.setTranslation( mPosition ); wm.rotateY( mAngle.y ); wm.rotateX( mAngle.x ); wm.rotateZ( mAngle.z ); wm.scale( mScale ); Matrix44 transform; transform.setMul( pvm, wm ); mBatch->draw( transform ); }
void Tree::draw( const Matrix44& pvm, const Vector3& lightVector, const Vector3& lightColor, const Vector3& ambient ) const { Matrix34 wm; wm.setTranslation( mPosition ); wm.rotateY( mAngle.y ); wm.rotateX( mAngle.x ); wm.rotateZ( mAngle.z ); wm.scale( mScale ); //根ノードへ渡す if ( mNodes ){ mNodes[ 0 ].draw( pvm, wm, lightVector, lightColor, ambient ); } }
void Framework::update(){ WindowCreator wc = WindowCreator::instance(); if ( gFirst ){ const char* filename = wc.commandLineString(); if ( filename && filename[ 0 ] != '\0' ){ load( filename ); } gFirst = false; }else{ //ドラッグアンドドロップを処理する int dropN = wc.droppedItemNumber(); if ( dropN > 0 ){ const char* filename = wc.droppedItem( 0 ); //0番以外無視 load( filename ); wc.clearDroppedItem(); //これを呼ぶとfilenameもこわれるので最後に。 } } //カメラ入力反映 Input::Manager im = Input::Manager::instance(); Input::Mouse mouse = im.mouse(); Input::Keyboard keyboard = im.keyboard(); if ( mouse.isOn( Input::Mouse::BUTTON_MIDDLE ) ){ Graphics::Manager().captureScreen( "capture.tga" ); } //ビュー行列を作ろう Vector3 eyePosition = gEyeTarget; eyePosition.z += gEyeDistance; Matrix34 rm; rm.setRotationY( gAngleY ); rm.rotateX( gAngleX ); Vector3 tv( 0.f, 0.f, 1.f ); rm.mul( &tv, tv ); eyePosition.setMadd( gEyeTarget, tv, gEyeDistance ); Matrix34 zrm; zrm.setRotationZ( gAngleZ ); Vector3 up( 0.f, 1.f, 0.f ); zrm.mul( &up, up ); Matrix34 vm; vm.setViewTransform( eyePosition, gEyeTarget, up ); if ( gContainer ){ float x = static_cast< float >( mouse.velocityX() ); float y = static_cast< float >( mouse.velocityY() ); if ( mouse.isOn( Input::Mouse::BUTTON_LEFT ) && mouse.isOn( Input::Mouse::BUTTON_RIGHT ) ){ //両ボタンでZ回転 gAngleZ -= 0.2f * x; gAngleZ -= 0.2f * y; }else if ( mouse.isOn( Input::Mouse::BUTTON_LEFT ) ){ //左ボタン回転 gAngleX -= 0.2f * y; if ( gAngleX > 89.9f ){ gAngleX = 89.9f; }else if ( gAngleX < -89.9f ){ gAngleX = -89.9f; } gAngleY -= 0.5f * x; }else if ( mouse.isOn( Input::Mouse::BUTTON_RIGHT ) ){ //右ボタン、注視点移動 Vector3 xv( vm.m00, vm.m01, vm.m02 ); xv *= x; Vector3 yv( vm.m10, vm.m11, vm.m12 ); yv *= y; gEyeTarget.madd( xv, -0.003f * gEyeDistance ); gEyeTarget.madd( yv, 0.003f * gEyeDistance ); } int w = mouse.wheel(); if ( w < 0 ){ gEyeDistance *= 0.9f; }else if ( w > 0 ){ gEyeDistance *= 1.1f; } } //透視変換行列 Matrix44 pm; pm.setPerspectiveTransform( 60.f, static_cast< float >( width() ), static_cast< float >( height() ), gEyeDistance * 0.01f, gEyeDistance * 10.f ); //次にPVを作る pm *= vm; if ( keyboard.isOn( 'G' ) ){ gAngleX = gAngleY = gAngleZ = 0.f; gEyeTarget = 0.f; } //ライトでもうごかそか Graphics::Manager gm = Graphics::Manager::instance(); gm.setProjectionViewMatrix( pm ); gm.setLightingMode( LIGHTING_PER_PIXEL ); gm.enableDepthTest( true ); gm.enableDepthWrite( true ); gm.setLightColor( 0, Vector3( 1.f, 1.f, 1.f ) ); //白 gm.setLightColor( 1, Vector3( 1.f, 0.7f, 0.7f ) ); //赤 gm.setLightColor( 2, Vector3( 0.7f, 1.f, 0.7f ) ); //緑 gm.setLightColor( 3, Vector3( 0.7f, 0.7f, 1.f ) ); //青 gm.setAmbientColor( Vector3( 0.2f, 0.2f, 0.2f ) ); gm.setEyePosition( eyePosition ); float t = gEyeDistance * 0.4f; float lightIntensity[ 4 ]; for ( int i = 0; i < 4; ++i ){ lightIntensity[ i ] = t; } Vector3 lightPositions[ 4 ]; for ( int i = 0; i < 4; ++i ){ float t = static_cast< float >( gCount * ( i + 1 ) ) / 5.f; float d = gEyeDistance * 2.f; lightPositions[ i ].set( sin( t )*cos( t ) * d, sin( t )*sin( t ) * d, cos( t ) * d ); lightPositions[ i ] += gEyeTarget; } for ( int i = 0; i < 4; ++i ){ gm.setLightPosition( i, lightPositions[ i ] ); gm.setLightIntensity( i, lightIntensity[ i ] ); } for ( int i = 0; i < gModels.size(); ++i ){ gModels[ i ].draw(); } //アニメ切り替え if ( keyboard.isTriggered( ' ' ) ){ if ( gContainer.animationNumber() > 0 ){ ++gAnimationIndex; if ( gAnimationIndex >= gContainer.animationNumber() ){ gAnimationIndex = 0; } for ( int i = 0; i < gTrees.size(); ++i ){ gTrees[ i ].setAnimation( gContainer.animation( gAnimationIndex ) ); } } } for ( int i = 0; i < gTrees.size(); ++i ){ gTrees[ i ].updateAnimation(); gTrees[ i ].draw(); } if ( isEndRequested() ){ gModels.clear(); gTrees.clear(); gContainer.release(); } ++gCount; }