void LFrustum::CalcFrustumInBasis( const LVector3& Pos, const LVector3& To, const LVector3& Up, float fw, float fh, float nw, float nh ) { LVector3 Z = Pos - To; Z.Normalize(); LVector3 X = Up.Cross( Z ); X.Normalize(); LVector3 Y = Z.Cross( X ); LVector3 nc = Pos - Z * FNearClipPlane; LVector3 fc = Pos - Z * FFarClipPlane; FCornerPoints[FRUSTUM_ntl] = nc + Y * nh - X * nw; FCornerPoints[FRUSTUM_ntr] = nc + Y * nh + X * nw; FCornerPoints[FRUSTUM_nbl] = nc - Y * nh - X * nw; FCornerPoints[FRUSTUM_nbr] = nc - Y * nh + X * nw; FCornerPoints[FRUSTUM_ftl] = fc + Y * fh - X * fw; FCornerPoints[FRUSTUM_ftr] = fc + Y * fh + X * fw; FCornerPoints[FRUSTUM_fbl] = fc - Y * fh - X * fw; FCornerPoints[FRUSTUM_fbr] = fc - Y * fh + X * fw; for ( int i = PLANE_LEFT ; i < PLANE_FAR + 1 ; i++ ) { LVector3 P1 = FCornerPoints[ static_cast<int>( FrustumPlanePoints[i].X ) ]; LVector3 P2 = FCornerPoints[ static_cast<int>( FrustumPlanePoints[i].Y ) ]; LVector3 P3 = FCornerPoints[ static_cast<int>( FrustumPlanePoints[i].Z ) ]; TODO( "store planes as LPlane, not as Vector4 !" ) // FPlanes[i].From3Points(P1, P2, P3); } }
// build the basis of complementary 2-dimensional space void BuildComplementaryBasis( const LVector3& N, LVector3& V1, LVector3& V2 ) { V1 = N.Cross( vec3( 1, 0, 0 ) ); if ( V1.SqrLength() <= Linderdaum::Math::EPSILON ) { V1 = N.Cross( vec3( 0, 1, 0 ) ); if ( V1.SqrLength() <= Linderdaum::Math::EPSILON ) { V1 = N.Cross( vec3( 0, 0, 1 ) ); } } V2 = N.Cross( V1 ); V1.Normalize(); V2.Normalize(); }
void clVAMender::CalculateTBN( clVertexAttribs* CurrentVA, int ForSubMaterial ) { if ( !FTextureFaces.size() ) { return; } // split vertices //LVector3* Tangents = CurrentVA->GetTangents(); //LVector3* Binormals = CurrentVA->GetBinormals(); bool CalcNormals = FNormals.empty(); int Idx = 0; for ( size_t i = 0; i != FFaces.size(); ++i ) { if ( FFacesSubMaterial[i] != ForSubMaterial ) { continue; } int VertexIndex1 = static_cast<int>( FFaces[Idx][0] ); int VertexIndex2 = static_cast<int>( FFaces[Idx][1] ); int VertexIndex3 = static_cast<int>( FFaces[Idx][2] ); int OutputVertexIndex1 = Idx * 3 + 0; int OutputVertexIndex2 = Idx * 3 + 1; int OutputVertexIndex3 = Idx * 3 + 2; int CurrentFaceSG = FFacesSmoothingGroup[ Idx ]; LVector3 p1 = FVertices[VertexIndex1]; LVector3 p2 = FVertices[VertexIndex2]; LVector3 p3 = FVertices[VertexIndex3]; int TextureIndex1 = static_cast<int>( FTextureFaces[Idx][0] ); int TextureIndex2 = static_cast<int>( FTextureFaces[Idx][1] ); int TextureIndex3 = static_cast<int>( FTextureFaces[Idx][2] ); float u1 = FTextureVertices[TextureIndex1].X; float v1 = FTextureVertices[TextureIndex1].Y; float u2 = FTextureVertices[TextureIndex2].X; float v2 = FTextureVertices[TextureIndex2].Y; float u3 = FTextureVertices[TextureIndex3].X; float v3 = FTextureVertices[TextureIndex3].Y; float Tdenom = ( u2 - u1 ) * ( v3 - v1 ) - ( v2 - v1 ) * ( u3 - u1 ); float Bdenom = ( v2 - v1 ) * ( u3 - u1 ) - ( u2 - u1 ) * ( v3 - v1 ); LVector3 LocalBinormal = ( ( u3 - u1 ) * ( p2 - p1 ) - ( u2 - u1 ) * ( p3 - p1 ) ) / Bdenom; LVector3 LocalTangent = ( ( v3 - v1 ) * ( p2 - p1 ) - ( v2 - v1 ) * ( p3 - p1 ) ) / Tdenom; if ( CalcNormals ) { // LVector3* Normals = CurrentVA->GetNormals(); LVector3 LocalNormal = ( p3 - p1 ).Cross( p2 - p1 ); // LVector3 LocalNormal = LocalTangent.Cross(LocalBinormal); LocalNormal.Normalize(); int Index; Index = FSplitVertexToSGVertex_VIndex[ OutputVertexIndex1 ]; FSGN[ CurrentFaceSG ][ Index ] += LocalNormal; Index = FSplitVertexToSGVertex_VIndex[ OutputVertexIndex2 ]; FSGN[ CurrentFaceSG ][ Index ] += LocalNormal; Index = FSplitVertexToSGVertex_VIndex[ OutputVertexIndex3 ]; FSGN[ CurrentFaceSG ][ Index ] += LocalNormal; // Normals[OutputVertexIndex1] = LocalNormal; // Normals[OutputVertexIndex2] = LocalNormal; // Normals[OutputVertexIndex3] = LocalNormal; } Idx++; } LVector3* Normals = CurrentVA->FNormals.GetPtr(); for ( size_t j = 0 ; j != CurrentVA->FVertices.size(); j++ ) { if ( CalcNormals ) { int SG = FSplitVertexToSGVertex_SGNum[ j ]; int Index = FSplitVertexToSGVertex_VIndex[ j ]; Normals[j] = FSGN[ SG ][ Index ]; Normals[j].Normalize(); // Env->Logger->Log( L_DEBUG, "Dumping normal: Vertex: " +LStr::ToStr(j) + "(SG:"+LStr::ToStr(SG)+" Idx:"+LStr::ToStr(Index)+") Normal: " + Vec3ToString( Normals[j], ',' ) ); } } }
//---------------------------------------------------------------------- // //---------------------------------------------------------------------- void CylinderMouseMoveCameraOperator::_doMouseMoveR( lnFloat dx, lnFloat dy, lnFloat width, lnFloat height ) { LVector3 view; LVector3 vup = getTargetCamera()->getUpDirection(); LVector3 pos = getTargetCamera()->getPosition(); LVector3 look_at = getTargetCamera()->getLookAt(); vup.Normalize(); // 注視点中心回転 if ( 1 ) { view = pos - look_at; } // 視点中心回転 else { view = look_at - pos; } LMatrix m; lnFloat d; if ( dx != 0 ) { d = LMath::PI * dx / width; // Y 軸周りの回転を逆にする場合 (右手系) if ( 0 ) // CAMTYPE_REV_ROT_Y { d = -d; } // vup を軸にする場合 //if ( m_type & CAMTYPE_AROUND_UP ) // D3DXMatrixRotationAxis( &m, &vup, D3DXToRadian(d) ); //else // D3DXMatrixRotationY( &m, D3DXToRadian(d) ); m.RotationY( d ); view.TransformCoord( m ); } if ( dy != 0 ) { // 球タイプ if ( 1 ) { LVector3 vaxis = LVector3::Cross(vup, view); vaxis.Normalize(); d = -( LMath::PI * dy / height ); m = LMatrix::RotationAxis(vaxis, d ); view.TransformCoord( m ); //D3DXVec3Cross( &vaxis, &vup, &view ); //D3DXVec3Normalize( &vaxis, &vaxis ); //d = (float)180.0 * (float)dy / (float)prc->bottom; //D3DXMatrixRotationAxis( &m, &vaxis, D3DXToRadian(d) ); //D3DXVec3TransformNormal( &view, &view, &m ); } else { //if( m_type & CAMTYPE_AROUND_UP ) // view += ( vup * (float)dy ); //else // view.y += (float)dy; } } // 注視点中心回転 if ( 1 ) { LVector3 old = pos; pos = look_at + view; // 上または下にドラッグし続けた場合、中天を通り過ぎたところで // XZ上の反対側の象限にカメラが移動して画面がちらちらするのを防ぐ処理 if ( ( ( old.X < 0 && pos.X > 0 ) || ( old.X > 0 && pos.X < 0 ) ) && ( ( old.Z < 0 && pos.Z > 0 ) || ( old.Z > 0 && pos.Z < 0 ) ) ) { pos = old; } } // 視点中心回転 else { pos += view; } getTargetCamera()->setPosition( pos ); }