Esempio n. 1
0
//------------------------------------------------------------------------
void FlyMatrix::LookAt(FlyVector vcPos, FlyVector vcLookAt,FlyVector vcWorldUp)
{
	FlyVector vcDir = vcLookAt - vcPos;
	FlyVector vcUp, vcRight; 
	float     fAngle=0.0f;

	vcDir.Normalize();

	fAngle = vcWorldUp * vcDir;

	vcUp = vcWorldUp - (vcDir * fAngle);
	vcUp.Normalize();

	vcRight.Cross(vcUp, vcDir);

	_11 = vcRight.x; _21 = vcUp.x; _31 = vcDir.x;
	_12 = vcRight.y; _22 = vcUp.y; _32 = vcDir.y;
	_13 = vcRight.z; _23 = vcUp.z; _33 = vcDir.z;

	_41 = vcPos.x;
	_42 = vcPos.y;
	_43 = vcPos.z;

	_14=0.0f; _24=0.0f; _34=0.0f; _44=1.0f;
}
Esempio n. 2
0
//------------------------------------------------------------------------
// Notify the camera's state, Decide the lod of this tile.
// ----------------------------------------------------------------------
// Param -> IN:
//      FlyCameraBase*:     Pointer to the current camera.
//------------------------------------------------------------------------
void etTile::NotifyCamera( FlyCameraBase* pCamera )
{
    FlySceneObject::NotifyCamera( pCamera );

    FlyVector vDiff = pCamera->GetPosition()-m_WorldBBox.GetCenter();
    float fL = vDiff.GetSqrLength();

    m_nLodLevel = -1;
    for( int i=0;i<m_pLevel->GetMaxLodLevel();i++ )
    {
        if( m_pLevel->GetLodSqrDist(i) > fL )
        {
            m_nLodLevel = i - 1;
            break;
        }
    }

    if( m_nLodLevel < 0 )
        m_nLodLevel = m_pLevel->GetMaxLodLevel() - 1;
}
Esempio n. 3
0
//------------------------------------------------------------------------
// Initialize the terrain tile.
// ----------------------------------------------------------------------
// Param -> IN:
//      int,int:        Position where we start to read the height data.
//      const float*:   Pointer to the height data.
//------------------------------------------------------------------------
HRESULT etTile::Initialize( int startx,int startz,const float* pHeightData )
{
    m_nStartX = startx;
    m_nStartZ = startz;

    // Get the resourceManager.
    FlyResourceManager* pResMgr = etCoreManager::Instance().GetResourceManager();

    // Create the shared vertex buffer.
    UINT nTileSize = m_pLevel->GetTileSize();
    m_pVB = pResMgr->MakeVertexBuffer( (nTileSize+1)*(nTileSize+1)*sizeof(VERTEX2T),
        BU_WRITEONLY,MM_MANAGED );
    if( !m_pVB ) return FLY_CREATEBUFFER;

    float fMinHeight = 0.0f;
    float fMaxHeight = 0.0f;

    int endx = startx + nTileSize + 1;
    int endz = startz + nTileSize + 1;
    VERTEX2T* pVerts = (VERTEX2T*)m_pVB->Lock( 0,(nTileSize+1)*(nTileSize+1)*sizeof(VERTEX2T),LOCK_NORMAL );

    for( int j=startz;j<endz;j++ )
    {
        for( int i=startx;i<endx;i++ )
        {
            float fHeight = pHeightData[j*(m_pLevel->GetTerrainSize()+1)+i];
            fHeight *= m_pLevel->GetHeightScale();

            pVerts->x = (float)i * m_pLevel->GetLengthPerUnit();
            pVerts->y = fHeight;
            pVerts->z = (float)j * m_pLevel->GetLengthPerUnit();
            pVerts->vN[0] = 0.0f;
            pVerts->vN[1] = 1.0f;
            pVerts->vN[2] = 0.0f;
            pVerts->tu0 = ((float)i / (float)nTileSize);
            pVerts->tv0 = ((float)j / (float)nTileSize);
            pVerts->tu1 = ((float)i / (float)m_pLevel->GetTerrainSize());
            pVerts->tv1 = ((float)j / (float)m_pLevel->GetTerrainSize());
            pVerts++;

            if( fHeight < fMinHeight ) fMinHeight = fHeight;
            if( fHeight > fMaxHeight ) fMaxHeight = fHeight;
        }
    }

    m_pVB->Unlock();

    // Set the boundingBox.
    m_Bounds.vcMin.x = (float)startx * m_pLevel->GetLengthPerUnit();
    m_Bounds.vcMin.y = fMinHeight - 1.0f;
    m_Bounds.vcMin.z = (float)startz * m_pLevel->GetLengthPerUnit();
    m_Bounds.vcMax.x = (float)(endx-1) * m_pLevel->GetLengthPerUnit();
    m_Bounds.vcMax.y = fMaxHeight + 1.0f;
    m_Bounds.vcMax.z = (float)(endz-1) * m_pLevel->GetLengthPerUnit();

    // Set the boundingRect.
    m_BRect.SetMinPoint( m_Bounds.vcMin.x,m_Bounds.vcMin.z );
    m_BRect.SetMaxPoint( m_Bounds.vcMax.x,m_Bounds.vcMax.z );

    // Create the renderable object for the tile.
    m_pRenderable = new etTileRenderable( this );
    m_pRenderable->m_BBox = m_Bounds;
    m_pRenderable->m_pVB = m_pVB;
    m_pRenderable->m_nNumVerts = (nTileSize+1)*(nTileSize+1);

    // Create the renderable object when tile is selected.
    m_pSelected = new etTileSelected( this );
    m_pSelected->BuildGeometry();

    FlyRenderEffect* pEffect = etCoreManager::Instance().GetTerrainFX();
    m_pRenderable->m_pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(0) );
    m_pRenderable->m_pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(1) );
    m_pRenderable->m_pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(2) );
    m_pRenderable->m_pMaterial->AddNewTechnique( pEffect->GetTechniqueByIndex(3) );
    m_pRenderable->m_pMaterial->SetActiveTechnique( 0 );

    // Initialize the default GPU parameters.
    FlyRenderEffectInstance* pGPUProgram;
    FlyVector vLightDir = m_pManager->GetLightDirection();
    vLightDir.Normalize();
    for( int i=0;i<4;i++ )
    {
        pGPUProgram = m_pRenderable->m_pMaterial->GetRenderEffectInstance(i);
        *pGPUProgram->GetParameterByIndex(0) = m_pMainTexture;
        *pGPUProgram->GetParameterByIndex(1) = m_pLevel->GetDetailLayer()->GetTexture();
        *pGPUProgram->GetParameterByIndex(2) = m_pDetails[0];
        *pGPUProgram->GetParameterByIndex(3) = m_pDetails[1];
        *pGPUProgram->GetParameterByIndex(4) = m_pDetails[2];
        *pGPUProgram->GetParameterByIndex(5) = m_pDetails[3];
        *pGPUProgram->GetParameterByIndex(6) = m_fMainScale;
        *pGPUProgram->GetParameterByIndex(7) = m_fDetailScale[0];
        *pGPUProgram->GetParameterByIndex(8) = m_fDetailScale[1];
        *pGPUProgram->GetParameterByIndex(9) = m_fDetailScale[2];
        *pGPUProgram->GetParameterByIndex(10) = m_fDetailScale[3];
        *pGPUProgram->GetParameterByIndex(11) = m_pManager->GetLightingMode();
        *pGPUProgram->GetParameterByIndex(12) = vLightDir;
        *pGPUProgram->GetParameterByIndex(13) = *((FlyVector*)&m_pManager->GetLightAmbient());
        *pGPUProgram->GetParameterByIndex(14) = *((FlyVector*)&m_pManager->GetLightDiffuse());
        *pGPUProgram->GetParameterByIndex(16) = *((FlyVector*)&m_pManager->GetWireColor());
    }

    return FLY_OK;
}
Esempio n. 4
0
//------------------------------------------------------------------------
// Test the intersect with a segment.
// ----------------------------------------------------------------------
// Param -> IN:
//      const FlyVector&:   First point of the segment.
//      const FlyVector&:   Second point of the segment.
//      FlyVector*:         To store the point of intersection.
//------------------------------------------------------------------------
bool etTile::IntersectSegment( const FlyVector& vStart,const FlyVector& vEnd,
                               FlyVector* pOut )
{
    FlyVector vDir = vEnd - vStart;
    FlyVector vRay = vStart;

    // 1. Special case...
    if( vDir.x == 0 && vDir.z == 0 )
    {
        float h = m_pLevel->GetScaledHeightValue( vRay.x,vRay.z );

        if( (vStart.y <= h && vEnd.y >= h) ||
            (vStart.y >= h && vEnd.y <= h) )
        {
            if( pOut )
            {
                *pOut = vRay;
                pOut->y = h;
            }

            return true;
        }
        else
        {
            if( pOut ) *pOut = FlyVector( -1.0f,-1.0f,-1.0f );

            return false;
        }
    }

    vDir.Normalize();
    vRay += vDir;

    float h = m_pLevel->GetScaledHeightValue( vRay.x,vRay.z );
    while( vRay.x >= m_Bounds.vcMin.x &&
        vRay.x <= m_Bounds.vcMax.x &&
        vRay.z >= m_Bounds.vcMin.z &&
        vRay.z <= m_Bounds.vcMax.z )
    {
        if( vRay.y <= h )
        {
            if( pOut ) *pOut = vRay;

            return true;
        }
        else
        {
            vRay += vDir;
        }

        if( vRay.y - vEnd.y < 1.0f ) break;
    }

    if( vRay.x < m_Bounds.vcMin.x && m_pNeighbors[NB_WEST] != NULL )
        return m_pNeighbors[NB_WEST]->IntersectSegment( vRay,vEnd,pOut );
    else if( vRay.z < m_Bounds.vcMin.z && m_pNeighbors[NB_SOUTH] != NULL )
        return m_pNeighbors[NB_SOUTH]->IntersectSegment( vRay,vEnd,pOut );
    else if( vRay.x > m_Bounds.vcMax.x && m_pNeighbors[NB_EAST] != NULL )
        return m_pNeighbors[NB_EAST]->IntersectSegment( vRay,vEnd,pOut );
    else if( vRay.z > m_Bounds.vcMax.z && m_pNeighbors[NB_NORTH] != NULL )
        return m_pNeighbors[NB_NORTH]->IntersectSegment( vRay,vEnd,pOut );
    else
    {
        if( pOut ) *pOut = FlyVector( -1.0f,-1.0f,-1.0f );

        return false;
    }
}
Esempio n. 5
0
//------------------------------------------------------------------------
// Transform the vertices with the bone's matrix.
//------------------------------------------------------------------------
HRESULT FlyAnimation::AnimationVertices(void)
{
    bool bChanged = false;
    AVERTEX* pVertex;
    sVertexOrig* pVertex_Orig;
    FlyMatrix matA,matB;
    FlyVector sVectorA,sVectorB;
    FlyVector vFinal;

    // Get the current animation node.
    sAnimNode* pCurNode = &m_AnimGroup[m_nAnimID];

    FlyVector vBoxMin = FlyVector(  999999.0f, 999999.0f, 999999.0f );
    FlyVector vBoxMax = FlyVector( -999999.0f,-999999.0f,-999999.0f );

    for( UINT i=0;i<m_sHeader.nNumVerts;i++ )
    {
        pVertex = &m_pVertices[i];
        pVertex_Orig = &m_pVertices_Orig[i];

        vFinal.Set( 0.0f,0.0f,0.0f );

        // The first bone's effect.
        if( pVertex->fBone1 != (float)NULL_BONEID )
        {
            matA = pCurNode->pJoints[(UINT)pVertex->fBone1].mMatrix_Absolute;
            sVectorA.x = pVertex_Orig->fXYZ[0];
            sVectorA.y = pVertex_Orig->fXYZ[1];
            sVectorA.z = pVertex_Orig->fXYZ[2];
            sVectorA.RotateWith( matA );
            sVectorA += matA.GetTranslation();
            bChanged = true;
        }

        // The second bone's effect.
        if( pVertex->fBone2 != (float)NULL_BONEID )
        {
            matB = pCurNode->pJoints[(UINT)pVertex->fBone2].mMatrix_Absolute;
            sVectorB.x = pVertex_Orig->fXYZ[0];
            sVectorB.y = pVertex_Orig->fXYZ[1];
            sVectorB.z = pVertex_Orig->fXYZ[2];
            sVectorB.RotateWith( matB );
            sVectorB += matB.GetTranslation();
            bChanged = true;
        }

        // Blend the final position.
        vFinal = sVectorA*pVertex->fWeight1 + sVectorB*pVertex->fWeight2;

        if( bChanged )
        {
            pVertex->x = vFinal.x;
            pVertex->y = vFinal.y;
            pVertex->z = vFinal.z;
        }

//         pVertex->x = pVertex_Orig->fXYZ[0];
//         pVertex->y = pVertex_Orig->fXYZ[1];
//         pVertex->z = pVertex_Orig->fXYZ[2];

        // Calculate the boundingBox.
        if( pVertex->x < vBoxMin.x ) vBoxMin.x = pVertex->x;
        if( pVertex->y < vBoxMin.y ) vBoxMin.y = pVertex->y;
        if( pVertex->z < vBoxMin.z ) vBoxMin.z = pVertex->z;
        if( pVertex->x > vBoxMax.x ) vBoxMax.x = pVertex->x;
        if( pVertex->y > vBoxMax.y ) vBoxMax.y = pVertex->y;
        if( pVertex->z > vBoxMax.z ) vBoxMax.z = pVertex->z;

        bChanged = false;
    }

    m_BBox.vcMin = vBoxMin;
    m_BBox.vcMax = vBoxMax;

    return FLY_OK;
}