//------------------------------- // //------------------------------- void Vector3::GetQuaternion( Quaternion& qRot ) { Vector3 vDir; vDir.x = x; vDir.y = y; vDir.z = z; vDir.Normalize(); vDir *= -1; Matrix44 matWorld; matWorld.SetWorld( Vector3( 0.0F, 0.0F, 0.0F ), vDir, Vector3( 0.0F, 0.0F, 1.0F ) ); qRot = matWorld.GetQuaternion(); } //Vector3::GetQuaternion

void State::integrate(State& state, float t, float dt) { Derivative a = Derivative::evaluate(state, t); Derivative b = Derivative::evaluate(state, t, dt*0.5f, a); Derivative c = Derivative::evaluate(state, t, dt*0.5f, b); Derivative d = Derivative::evaluate(state, t, dt, c); state.position += 1.0f/6.0f * dt * (a.velocity + 2.0f*(b.velocity + c.velocity) + d.velocity); state.momentum += 1.0f/6.0f * dt * (a.force + 2.0f*(b.force + c.force) + d.force); state.orientation += 1.0f/6.0f * dt * (a.spin + 2.0f*(b.spin + c.spin) + d.spin); state.angularMomentum += 1.0f/6.0f * dt * (a.torque + 2.0f*(b.torque + c.torque) + d.torque); const float e = 0.2; const float u = 0.97; std::vector<Collision> collision = collisions(state); const float scale = 1.f/float(collision.size()); for(auto& c : collision) { if(c.direction.dot(state.momentum) > 0.f) continue; state.position += c.direction * c.magnitude; const Vector3 r = c.point - state.position; Vector3 velocityAtPoint = state.velocity + state.angularVelocity.cross(r); const float vn = min (0.f, velocityAtPoint.dot(c.direction)); Matrix44 rotation = state.orientation.matrix(); Matrix44 transposeRotation = rotation.transpose(); Matrix44 i = rotation * state.inverseInertiaTensor * transposeRotation; const float k = state.inverseMass + r.cross(c.direction).dot(i * r.cross(c.direction)); const float j = -(1+e) * vn / k; state.momentum += c.direction * j * scale; state.angularMomentum += r.cross(c.direction) * j * scale; Vector3 tangentVelocity = velocityAtPoint - c.direction * velocityAtPoint.dot(c.direction); if(tangentVelocity.lengthSquared() > epsilonSquared) { Vector3 tangent = tangentVelocity.unit(); const float vt = velocityAtPoint.dot(tangent); const float kt = state.inverseMass + r.cross(tangent).dot(i * r.cross(tangent)); float jt = clamp(-vt/kt, -u*j, u*j); state.momentum += tangent * jt * scale; state.angularMomentum += r.cross(tangent) * jt * scale; } } state.recalculate(); }

gh::Vector3 GetCameraPointingVector( const Vector3& eulerAngles ) { //rotate about z Matrix44 pitchMat = Matrix44::CreatePitchRotationMatrixDegrees( eulerAngles.y ); //roll goes about x, from y to z, this is the vertical sweeping in this camera Matrix44 rollMat = Matrix44::CreateRollRotationMatrixDegrees( eulerAngles.x ); Matrix44 currentRotation = pitchMat * rollMat; Vector3 zv = Vector3( 0.f, 0.f, -1.f ); Vector3 direction = currentRotation.transformDirection( zv ); return direction; }

/** TODO: avoid recalculating when nothing changed */ Matrix44 Entity2D::GetCenterTransformationMatrix() { Matrix44 matrix = Matrix44::Identity; matrix.Scale(Vector3::Create(m_vScale.X, m_vScale.Y, 1.0f)); matrix.Rotate(Vector3::Create(0.0f, 0.0f, m_fRotation*Math::DegToRadFactor)); matrix.Translate(Vector3::Create(m_vPosition.X, m_vPosition.Y, 0.0f)); // TODO: use type checking at initialization time in AddChild() and only use static_cast here if(Entity2D* pEntity2D = GetAncestor<Entity2D>()) { matrix *= pEntity2D->GetTransformationMatrix(); } return matrix; }

const Matrix44 CreateBoundsTransform( const Vector2& top_left, const Vector2& bottom_right ) { Matrix44 result; result.clear(); result(0, 0) = 1.0 / (bottom_right(0) - top_left(0)); result(0, 3) = -top_left(0) * result(0, 0); result(1, 1) = 1.0 / (bottom_right(1) - top_left(1)); result(1, 3) = -top_left(1) * result(1, 1); result(2, 3) = 0.5; result(3, 3) = 1; return result; }

//what to do when the image has to be draw void Game::render(void) { //set the clear color (the background color) glClearColor(0.0, 0.0, 0.0, 1.0); // Clear the window and the depth buffer glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); //set the camera as default camera->enable(); //set flags glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); glDisable(GL_CULL_FACE); //create model matrix for cube Matrix44 m; m.rotate(time, Vector3(0, 1, 0)); if(shader) { //enable shader shader->enable(); //upload uniforms shader->setUniform("u_color", Vector4(1,1,1,1)); shader->setUniform("u_viewprojection", camera->viewprojection_matrix ); shader->setUniform("u_texture", texture); shader->setUniform("u_model", m); shader->setUniform("u_time", time); //do the draw call mesh->render( GL_TRIANGLES ); //disable shader shader->disable(); } //Draw the floor grid drawGrid(); //render the FPS, Draw Calls, etc drawText(2, 2, getGPUStats(), Vector3(1, 1, 1), 2); //swap between front buffer and back buffer SDL_GL_SwapWindow(this->window); }

void bhkTransformShape::CalcMassProperties(float density, bool solid, float &mass, float &volume, Vector3 ¢er, InertiaMatrix& inertia) { center = transform.GetTranslation(); mass = 0.0f, volume = 0.0f; inertia = InertiaMatrix::IDENTITY; if (shape != NULL) { Matrix44 transform_transposed = transform.Transpose(); shape->CalcMassProperties(density, solid, mass, volume, center, inertia); center = transform * center; Matrix44 tm(inertia.Submatrix(0, 0)); Matrix44 im = transform_transposed * tm * transform; inertia = InertiaMatrix(im.GetRotation()); } }

void Matrix44::Transpose( Matrix44& out ) const { float tmp[ 16 ]; tmp[ 0 ] = m[ 0 ]; tmp[ 1 ] = m[ 4 ]; tmp[ 2 ] = m[ 8 ]; tmp[ 3 ] = m[ 12 ]; tmp[ 4 ] = m[ 1 ]; tmp[ 5 ] = m[ 5 ]; tmp[ 6 ] = m[ 9 ]; tmp[ 7 ] = m[ 13 ]; tmp[ 8 ] = m[ 2 ]; tmp[ 9 ] = m[ 6 ]; tmp[ 10 ] = m[ 10 ]; tmp[ 11 ] = m[ 14 ]; tmp[ 12 ] = m[ 3 ]; tmp[ 13 ] = m[ 7 ]; tmp[ 14 ] = m[ 11 ]; tmp[ 15 ] = m[ 15 ]; out.InitFrom( tmp ); #if DEBUG ae3d::CheckNaN( out ); #endif }

int ParticleGenerator::TesselateLine(Particle* pParticle, Vertex3D* pVertices, int current, const Vector3& vScale) { Vector3 vDir = (pParticle->Pos - pParticle->PreviousPos).Normalized(); pVertices[current+0].UV = Vector2::Zero; pVertices[current+0].Pos = Vector3::Zero; pVertices[current+1].UV = Vector2::One; pVertices[current+1].Pos = vDir*vScale*m_fSparkFactor; pParticle->PreviousPos = pParticle->Pos; Matrix44 transform = Matrix44::Identity; transform.SetTranslation(m_bApplyWorldTransform ? super::GetWorldTransform().TransformVect(pParticle->Pos) : pParticle->Pos); for(int i=0; i<2; ++i) { pVertices[current+i].Pos = transform.TransformVect(pVertices[current+i].Pos); pVertices[current+i].color = Color::Create(m_ParticleColor.R, m_ParticleColor.G, m_ParticleColor.B, pParticle->Alpha); } return 2; }

Matrix44 SimpleSceneGraph::calculateRelativeTransform(const Matrix44& absoluteTransform) const { if (parent == nullptr) { return absoluteTransform; } /* * Find the transform for this graph (Gr) relative to the absolute parent transform (Pa) that matches the * absolute transform (Ga) i.e. such that: Ga = Pa * Gr or Gr = Ga * Pa-1 */ Matrix44 inverseParentAbsoluteTransform = parent->getAbsoluteTransform(); inverseParentAbsoluteTransform.invert(); return absoluteTransform * inverseParentAbsoluteTransform; }

btTransform toBtTransform(const Matrix44& original) { btTransform transform; transform.setFromOpenGLMatrix(original.getData()); return transform; }

/** @brief @date 2014-04-17 */ bool cParticle::Move(int elapseTime) { const float dt = (float)elapseTime * 0.001f; m_Velocity += Vector3(0, 3000.f * dt, 0); m_Pos += m_Velocity * dt; m_tm.SetWorld(m_Pos); Matrix44 mat; mat.SetRotationZ(m_Torq * dt); m_localTm *= mat; if (m_Pos.y > 1000.f) return false; return true; }

void UpdateCamera() { Vector3 dir = g_lookAtPos - g_camPos; dir.Normalize(); g_matView.SetView(g_camPos, dir, Vector3(0,1,0)); graphic::GetDevice()->SetTransform(D3DTS_VIEW, (D3DXMATRIX*)&g_matView); }

//--------------------- //For a local rotation you have to: //1. Put the Matrix at 0,0,0 world coordinates after memorizing the original position //2. Make a normal rotation //3. Put back Matrix to its original position //--------------------- void Matrix44::rotateLocal(double radians, Vector axis){ //1 Matrix44 r = Matrix44(); r.setRotationMatrix(radians,axis); Vector pos= Vector(3); pos.takePosition(*this); setPosition(0,0,0); //2 operator=(r*(*this)); //3 setPosition(pos[0], pos[1], pos[2]); }

//랜더 void Render(int timeDelta) { //화면 청소 if (SUCCEEDED(g_pDevice->Clear( 0, //청소할 영역의 D3DRECT 배열 갯수 ( 전체 클리어 0 ) NULL, //청소할 영역의 D3DRECT 배열 포인터 ( 전체 클리어 NULL ) D3DCLEAR_TARGET | D3DCLEAR_ZBUFFER | D3DCLEAR_STENCIL, //청소될 버퍼 플레그 ( D3DCLEAR_TARGET 컬러버퍼, D3DCLEAR_ZBUFFER 깊이버퍼, D3DCLEAR_STENCIL 스텐실버퍼 D3DCOLOR_XRGB(255, 255, 255), //컬러버퍼를 청소하고 채워질 색상( 0xAARRGGBB ) 1.0f, //깊이버퍼를 청소할값 ( 0 ~ 1 0 이 카메라에서 제일가까운 1 이 카메라에서 제일 먼 ) 0 //스텐실 버퍼를 채울값 ))) { //화면 청소가 성공적으로 이루어 졌다면... 랜더링 시작 g_pDevice->BeginScene(); static float y = 0; y += timeDelta / 1000.f; // 각도가 2*PI 에 이르면 0으로 초기화한다. if (y >= 6.28f) y = 0; Matrix44 rx, ry, r; rx.SetRotationX(MATH_PI/4.f); // x축으로 45도 회전시킨다. ry.SetRotationY(y); // y축으로 회전 r = rx*ry; g_pDevice->SetTransform(D3DTS_WORLD, (D3DXMATRIX*)&r); Matrix44 rry; rry.SetRotationY(-y); // y축으로 회전 Vector3 dir = global->lightDir * rry; global->light.Direction = *(D3DXVECTOR3*)&dir; g_pDevice->SetLight(0, &global->light); // 광원 설정. g_pDevice->SetMaterial(&global->mtrl); g_pDevice->SetStreamSource( 0, global->vb, 0, sizeof(Vertex) ); g_pDevice->SetIndices(global->ib); g_pDevice->SetFVF( Vertex::FVF ); g_pDevice->DrawIndexedPrimitive( D3DPT_TRIANGLELIST, 0, 0, global->vtxSize, 0, global->faceSize); //랜더링 끝 g_pDevice->EndScene(); //랜더링이 끝났으면 랜더링된 내용 화면으로 전송 g_pDevice->Present( NULL, NULL, NULL, NULL ); } }

bool RendererServices::get_inverse_matrix (Matrix44 &result, TransformationPtr xform) { bool ok = get_matrix (result, xform); if (ok) result.invert (); return ok; }

void Init() { ReadModelFile("../../media/model_normal.dat", g_vertices, g_indices, g_normals); g_matWorld1.SetTranslate(Vector3(0,0,0)); Vector3 dir = g_cameraLookat - g_cameraPos; dir.Normalize(); g_matView.SetView(g_cameraPos, dir, Vector3(0,1,0)); g_matProjection.SetProjection( MATH_PI / 4.f, 1.0f, 1.0f, 100.0f ); RECT cr; ::GetClientRect(g_hWnd, &cr); const float width = (float)(cr.right-cr.left); const float height = (float)(cr.bottom - cr.top); g_matViewPort.SetViewport(width, height); }

inline void CGLFixedFunctionPipelineManager::SetWorldViewProjectionTransform( const Matrix44& matWorld, const Matrix44& matView, const Matrix44& matProj ) { m_matView = matView; m_matWorld = matWorld; m_matProjection = matProj; Matrix44 matWorldView = matView * matWorld; glMatrixMode( GL_MODELVIEW ); glLoadMatrixf( matWorldView.GetData() ); // glLoadIdentity(); // debug - reset the projection matrix glMatrixMode( GL_PROJECTION ); glLoadMatrixf( matProj.GetData() ); // glLoadIdentity(); // debug - reset the projection matrix }

bool RendererServices::get_inverse_matrix (Matrix44 &result, ustring to) { bool ok = get_matrix (result, to); if (ok) result.invert (); return ok; }

void Plane::shoot(bool thrownByPlayer){ if(bulletsShoot >= numBullets) return; double time = (SDL_GetTicks() - lastBulletThrown) * 0.001; Matrix44 A = matrix_; A.traslateLocal(-2,0,0); Matrix44 B = A; A.traslateLocal(4, 0,0); if(time > cadencia){ (BulletManager::getInstance())->shoot(A,thrownByPlayer); (BulletManager::getInstance())->shoot(B,thrownByPlayer); bulletsShoot+=2; lastBulletThrown = SDL_GetTicks(); BASS_ChannelPlay(bulletSampleChannel,true); } }

Common::Plane Transform_Plane_By_Mat44(const Plane& plane, const Matrix44& mat) { Vector4 v(plane.n, plane.d); // To transform normal, we can not use the matrix directly // See: http://www.songho.ca/opengl/gl_normaltransform.html Matrix44 matInvTranspose = mat.Inverse(); matInvTranspose.Transpose(); v = Common::Transform_Vec4_By_Mat44(v, matInvTranspose); Plane ret; ret.n = v.GetVec3(); ret.d = v.w / ret.n.Normalize(); return ret; }

void Impl_CameraController_FirstPerson::UpdateRotating(float dx, float dy) { using namespace math; Matrix44 local = m_pObject->GetLocalTransform(); Matrix44 parent = MatrixIdentity(); if(m_pObject->GetParent()) { parent = m_pObject->GetParent()->GetWorldTransform(); } Vector3 axis_x = local.GetRow3(0); axis_x.Normalize(); Vector3 axis_y = parent.GetRow3(1); axis_y.Normalize(); Vector3 pos = local.GetRow3(3); local.SetRow3(3, Vector3(0, 0, 0)); float step = D2R(0.1); local = local * MatrixRotationAxis(axis_x, dy * step) * MatrixRotationAxis(axis_y, dx * step); local.SetRow3(3, pos); m_pObject->SetLocalTransform(local); m_pCameraData->UpdateCamera(); }

// screen pixel 좌표 pos 값이 스프라이트 안에 있다면 true를 리턴한다. bool cSprite::IsContain(const Vector2 &pos) { Vector3 leftTop(0,0,0); Vector3 rightBottom = Vector3(m_rect.Width(), m_rect.Height(), 0); Matrix44 S; S.SetScale(m_scale); Matrix44 C; C.SetTranslate(-m_center); Matrix44 tm = S * C * m_accTM; leftTop *= tm; rightBottom *= tm; return ((leftTop.x <= pos.x) && (leftTop.y <= pos.y) && (rightBottom.x >= pos.x) && (rightBottom.y >= pos.y)); }

bool RendererServices::get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result, ustring to) { bool ok = get_matrix (sg, result, to); if (ok) result.invert (); return ok; }

bool RendererServices::get_inverse_matrix (ShaderGlobals *sg, Matrix44 &result, TransformationPtr xform, float time) { bool ok = get_matrix (sg, result, xform, time); if (ok) result.invert (); return ok; }

SimpleRenderer::SimpleRenderer () { Matrix44 M; M.makeIdentity(); camera_params (M, u_perspective, 90.0f, 0.1f, 1000.0f, 256, 256); // Set up getters m_attr_getters[ustring("camera:resolution")] = &SimpleRenderer::get_camera_resolution; m_attr_getters[ustring("camera:projection")] = &SimpleRenderer::get_camera_projection; m_attr_getters[ustring("camera:pixelaspect")] = &SimpleRenderer::get_camera_pixelaspect; m_attr_getters[ustring("camera:screen_window")] = &SimpleRenderer::get_camera_screen_window; m_attr_getters[ustring("camera:fov")] = &SimpleRenderer::get_camera_fov; m_attr_getters[ustring("camera:clip")] = &SimpleRenderer::get_camera_clip; m_attr_getters[ustring("camera:clip_near")] = &SimpleRenderer::get_camera_clip_near; m_attr_getters[ustring("camera:clip_far")] = &SimpleRenderer::get_camera_clip_far; m_attr_getters[ustring("camera:shutter")] = &SimpleRenderer::get_camera_shutter; m_attr_getters[ustring("camera:shutter_open")] = &SimpleRenderer::get_camera_shutter_open; m_attr_getters[ustring("camera:shutter_close")] = &SimpleRenderer::get_camera_shutter_close; }

void PrimitiveBatch::begin_3d(const Matrix44& view_proj) { R_ASSERT(m_ready_to_draw==false); Matrix44 mat_transposed = view_proj.transposed(); m_vsc_mat_viewproj[0] = mat_transposed.rows[0]; m_vsc_mat_viewproj[1] = mat_transposed.rows[1]; m_vsc_mat_viewproj[2] = mat_transposed.rows[2]; m_vsc_mat_viewproj[3] = mat_transposed.rows[3]; m_ready_to_draw = true; }

int ParticleGenerator::TesselateQuad(Particle* pParticle, Vertex3D* pVertices, int current, const Vector3& vScale) { auto halfSize = pParticle->Size; pVertices[current+0].UV = Vector2::Create(0.0f, 1.0f); pVertices[current+0].Pos = Vector3::Create(-halfSize, -halfSize, 0.0f)*vScale; pVertices[current+1].UV = Vector2::Create(0.0f, 0.0f); pVertices[current+1].Pos = Vector3::Create(-halfSize, halfSize, 0.0f)*vScale; pVertices[current+2].UV = Vector2::Create(1.0f, 0.0f); pVertices[current+2].Pos = Vector3::Create(halfSize, halfSize, 0.0f)*vScale; pVertices[current+3].UV = Vector2::Create(0.0f, 1.0f); pVertices[current+3].Pos = Vector3::Create(-halfSize, -halfSize, 0.0f)*vScale; pVertices[current+4].UV = Vector2::Create(1.0f, 0.0f); pVertices[current+4].Pos = Vector3::Create(halfSize, halfSize, 0.0f)*vScale; pVertices[current+5].UV = Vector2::Create(1.0f, 1.0f); pVertices[current+5].Pos = Vector3::Create(halfSize, -halfSize, 0.0f)*vScale; Matrix44 transform = m_ViewInverse; transform.SetTranslation(m_bApplyWorldTransform ? super::GetWorldTransform().TransformVect(pParticle->Pos) : pParticle->Pos); for(int i=0; i<6; ++i) { pVertices[current+i].Pos = transform.TransformVect(pVertices[current+i].Pos); pVertices[current+i].color = Color::Create(m_ParticleColor.R, m_ParticleColor.G, m_ParticleColor.B, pParticle->Alpha); } return 6; }

Dvoid Camera::Yaw() { if (m_MouseMoveInterval.x == 0) return; m_bMove = true; Matrix44 matRot; Vector3 vUp(0, 1, 0); float fAngle = m_MouseMoveInterval.x * m_fMouseSens * m_fTimeDelta; matRot.Rotation(vUp, fAngle); for (Duint i = 0; i < CD_MAX; ++i) { m_vDir[i] = Vec4ToVec3(matRot * Vector4(m_vDir[i], 0), Vector4::W_IGNORE); m_vDir[i].Normalize(); } }

void cStage_IngameEnd::Update(const float elapseTime) { graphic::cCharacter* pMe = m_user == 1 ? character1 : character2; // if( m_camDirOriginal.DotProduct(pMe->GetCamera()->GetDirection()) < 1 ) // pMe->GetCamera()- if( m_nextStage ) { m_tick += elapseTime; if( m_tick >= 5.f ) { m_tick = 0.f; GetStageMgr()->SetStage( GetStageMgr()->ENDING ); GetStageMgr()->GetStage()->Init(); } } // bool bAniState1 = character1->Move(elapseTime); // bool bAniState2 = character2->Move(elapseTime); bool bAniState = pMe->Move(elapseTime); // if( bAniState1 == false && bAniState2 == false ) if( bAniState == false ) { m_nextStage = true; // character1->GetBoneMgr()->SetAniLoop(true); // character1->SetAnimation( "..\\media\\ani\\valle\\valle1_normal.ani" ); // character2->GetBoneMgr()->SetAniLoop(true); // character2->SetAnimation( "..\\media\\ani\\valle\\valle1_normal.ani" ); pMe->GetBoneMgr()->SetAniLoop(true); pMe->SetAnimation( "..\\media\\ani\\valle\\valle1_normal.ani" ); Matrix44 matR; matR.SetRotationY( MATH_PI ); // character1->SetTM( matR * character1->GetTM() ); // character2->SetTM( matR * character2->GetTM() ); pMe->SetTM( matR * pMe->GetTM() ); } }