//----------------------------------------------------------------------------- // Purpose: // Input : *pPatch - // *pPoints - // &vecNormal - // flArea - //----------------------------------------------------------------------------- bool CVRADDispColl::InitPatch( int iPatch, int iParentPatch, int iChild, Vector *pPoints, int *pIndices, float &flArea ) { // Get the current patch. CPatch *pPatch = &g_Patches[iPatch]; if ( !pPatch ) return false; // Clear the patch data. memset( pPatch, 0, sizeof( CPatch ) ); // Setup the parent if we are not the parent. CPatch *pParentPatch = NULL; if ( iParentPatch != g_Patches.InvalidIndex() ) { // Get the parent patch. pParentPatch = &g_Patches[iParentPatch]; if ( !pParentPatch ) return false; } // Attach the face to the correct lists. if ( !pParentPatch ) { // This is a parent. pPatch->ndxNext = g_FacePatches.Element( GetParentIndex() ); g_FacePatches[GetParentIndex()] = iPatch; pPatch->faceNumber = GetParentIndex(); } else { pPatch->ndxNext = g_Patches.InvalidIndex(); pPatch->faceNumber = pParentPatch->faceNumber; // Attach to the parent patch. if ( iChild == 0 ) { pParentPatch->child1 = iPatch; } else { pParentPatch->child2 = iPatch; } } // Initialize parent and children indices. pPatch->child1 = g_Patches.InvalidIndex(); pPatch->child2 = g_Patches.InvalidIndex(); pPatch->ndxNextClusterChild = g_Patches.InvalidIndex(); pPatch->ndxNextParent = g_Patches.InvalidIndex(); pPatch->parent = iParentPatch; // Get triangle edges. Vector vecEdges[3]; vecEdges[0] = pPoints[1] - pPoints[0]; vecEdges[1] = pPoints[2] - pPoints[0]; vecEdges[2] = pPoints[2] - pPoints[1]; // Find the longest edge. // float flEdgeLength = 0.0f; // for ( int iEdge = 0; iEdge < 3; ++iEdge ) // { // if ( flEdgeLength < vecEdges[iEdge].Length() ) // { // flEdgeLength = vecEdges[iEdge].Length(); // } // } // Calculate the triangle normal and area. Vector vecNormal = vecEdges[1].Cross( vecEdges[0] ); flArea = VectorNormalize( vecNormal ); flArea *= 0.5f; // Initialize the patch scale. pPatch->scale[0] = pPatch->scale[1] = 1.0f; // Set the patch chop - minchop (that is what the minimum area is based on). pPatch->chop = dispchop; // Displacements are not sky! pPatch->sky = false; // Copy the winding. Vector vecCenter( 0.0f, 0.0f, 0.0f ); pPatch->winding = AllocWinding( 3 ); pPatch->winding->numpoints = 3; for ( int iPoint = 0; iPoint < 3; ++iPoint ) { VectorCopy( pPoints[iPoint], pPatch->winding->p[iPoint] ); VectorAdd( pPoints[iPoint], vecCenter, vecCenter ); pPatch->indices[iPoint] = static_cast<short>( pIndices[iPoint] ); } // Set the origin and normal. VectorScale( vecCenter, ( 1.0f / 3.0f ), vecCenter ); VectorCopy( vecCenter, pPatch->origin ); VectorCopy( vecNormal, pPatch->normal ); // Create the plane. pPatch->plane = new dplane_t; if ( !pPatch->plane ) return false; VectorCopy( vecNormal, pPatch->plane->normal ); pPatch->plane->dist = vecNormal.Dot( pPoints[0] ); pPatch->plane->type = PlaneTypeForNormal( pPatch->plane->normal ); pPatch->planeDist = pPatch->plane->dist; // Set the area. pPatch->area = flArea; // Calculate the mins/maxs. Vector vecMin( FLT_MAX, FLT_MAX, FLT_MAX ); Vector vecMax( FLT_MIN, FLT_MIN, FLT_MIN ); for ( int iPoint = 0; iPoint < 3; ++iPoint ) { for ( int iAxis = 0; iAxis < 3; ++iAxis ) { vecMin[iAxis] = MIN( vecMin[iAxis], pPoints[iPoint][iAxis] ); vecMax[iAxis] = MAX( vecMax[iAxis], pPoints[iPoint][iAxis] ); } } VectorCopy( vecMin, pPatch->mins ); VectorCopy( vecMax, pPatch->maxs ); if ( !pParentPatch ) { VectorCopy( vecMin, pPatch->face_mins ); VectorCopy( vecMax, pPatch->face_maxs ); } else { VectorCopy( pParentPatch->face_mins, pPatch->face_mins ); VectorCopy( pParentPatch->face_maxs, pPatch->face_maxs ); } // Check for bumpmap. dface_t *pFace = dfaces + pPatch->faceNumber; texinfo_t *pTexInfo = &texinfo[pFace->texinfo]; pPatch->needsBumpmap = pTexInfo->flags & SURF_BUMPLIGHT ? true : false; // Misc... pPatch->m_IterationKey = 0; // Get the base light for the face. if ( !pParentPatch ) { BaseLightForFace( &g_pFaces[pPatch->faceNumber], pPatch->baselight, &pPatch->basearea, pPatch->reflectivity ); } else { VectorCopy( pParentPatch->baselight, pPatch->baselight ); pPatch->basearea = pParentPatch->basearea; pPatch->reflectivity = pParentPatch->reflectivity; } return true; }
//----------------------------------------------------------------------------- // Purpose: // Input : iPatch - // iParentPatch - // iChild - // *pPoints - // *pIndices - // &flArea - // Output : Returns true on success, false on failure. //----------------------------------------------------------------------------- bool CVRADDispColl::InitParentPatch( int iPatch, Vector *pPoints, float &flArea ) { // Get the current patch. CPatch *pPatch = &g_Patches[iPatch]; if ( !pPatch ) return false; // Clear the patch data. memset( pPatch, 0, sizeof( CPatch ) ); // This is a parent. pPatch->ndxNext = g_FacePatches.Element( GetParentIndex() ); g_FacePatches[GetParentIndex()] = iPatch; pPatch->faceNumber = GetParentIndex(); // Initialize parent and children indices. pPatch->child1 = g_Patches.InvalidIndex(); pPatch->child2 = g_Patches.InvalidIndex(); pPatch->parent = g_Patches.InvalidIndex(); pPatch->ndxNextClusterChild = g_Patches.InvalidIndex(); pPatch->ndxNextParent = g_Patches.InvalidIndex(); Vector vecEdges[2]; vecEdges[0] = pPoints[1] - pPoints[0]; vecEdges[1] = pPoints[3] - pPoints[0]; // Calculate the triangle normal and area. Vector vecNormal = vecEdges[1].Cross( vecEdges[0] ); flArea = VectorNormalize( vecNormal ); // Initialize the patch scale. pPatch->scale[0] = pPatch->scale[1] = 1.0f; // Set the patch chop - minchop (that is what the minimum area is based on). pPatch->chop = dispchop; // Displacements are not sky! pPatch->sky = false; // Copy the winding. Vector vecCenter( 0.0f, 0.0f, 0.0f ); pPatch->winding = AllocWinding( 4 ); pPatch->winding->numpoints = 4; for ( int iPoint = 0; iPoint < 4; ++iPoint ) { VectorCopy( pPoints[iPoint], pPatch->winding->p[iPoint] ); VectorAdd( pPoints[iPoint], vecCenter, vecCenter ); } // Set the origin and normal. VectorScale( vecCenter, ( 1.0f / 4.0f ), vecCenter ); VectorCopy( vecCenter, pPatch->origin ); VectorCopy( vecNormal, pPatch->normal ); // Create the plane. pPatch->plane = new dplane_t; if ( !pPatch->plane ) return false; VectorCopy( vecNormal, pPatch->plane->normal ); pPatch->plane->dist = vecNormal.Dot( pPoints[0] ); pPatch->plane->type = PlaneTypeForNormal( pPatch->plane->normal ); pPatch->planeDist = pPatch->plane->dist; // Set the area. pPatch->area = flArea; // Calculate the mins/maxs. Vector vecMin( FLT_MAX, FLT_MAX, FLT_MAX ); Vector vecMax( FLT_MIN, FLT_MIN, FLT_MIN ); for ( int iPoint = 0; iPoint < 4; ++iPoint ) { for ( int iAxis = 0; iAxis < 3; ++iAxis ) { vecMin[iAxis] = MIN( vecMin[iAxis], pPoints[iPoint][iAxis] ); vecMax[iAxis] = MAX( vecMax[iAxis], pPoints[iPoint][iAxis] ); } } VectorCopy( vecMin, pPatch->mins ); VectorCopy( vecMax, pPatch->maxs ); VectorCopy( vecMin, pPatch->face_mins ); VectorCopy( vecMax, pPatch->face_maxs ); // Check for bumpmap. dface_t *pFace = dfaces + pPatch->faceNumber; texinfo_t *pTexInfo = &texinfo[pFace->texinfo]; pPatch->needsBumpmap = pTexInfo->flags & SURF_BUMPLIGHT ? true : false; // Misc... pPatch->m_IterationKey = 0; // Calculate the base light, area, and reflectivity. BaseLightForFace( &g_pFaces[pPatch->faceNumber], pPatch->baselight, &pPatch->basearea, pPatch->reflectivity ); return true; }
void CSpeedTreeWrapper::RenderLeaves(void) const { #ifdef WRAPPER_USE_GPU_LEAF_PLACEMENT m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_LeafGeometry, -1, -1, 0); #endif m_pSpeedTree->GetGeometry(*m_pGeometryCache, SpeedTree_LeafGeometry); // update the LOD level vertex arrays we need #if defined(WRAPPER_USE_GPU_LEAF_PLACEMENT) && defined(WRAPPER_USE_GPU_WIND) // do nothing #else #if !defined WRAPPER_USE_NO_WIND || defined WRAPPER_USE_CPU_LEAF_PLACEMENT // might need to draw 2 LOD's for (unsigned int i = 0; i < 2; ++i) { // reference to leaves structure const CSpeedTreeRT::SGeometry::SLeaf* pLeaf = (i == 0) ? &m_pGeometryCache->m_sLeaves0 : &m_pGeometryCache->m_sLeaves1; int unLod = pLeaf->m_nDiscreteLodLevel; #if defined WRAPPER_USE_GPU_LEAF_PLACEMENT if (pLeaf->m_bIsActive && !m_pLeavesUpdatedByCpu[unLod]) { // update the centers SFVFLeafVertex* pVertex = NULL; m_pLeafVertexBuffer[unLod]->Lock(0, 0, reinterpret_cast<void**>(&pVertex), 0); for (unsigned int unLeaf = 0; unLeaf < pLeaf->m_usLeafCount; ++unLeaf) { D3DXVECTOR3 vecCenter(&(pLeaf->m_pCenterCoords[unLeaf * 3])); (pVertex++)->m_vPosition = vecCenter; // vertex 0 (pVertex++)->m_vPosition = vecCenter; // vertex 1 (pVertex++)->m_vPosition = vecCenter; // vertex 2 (pVertex++)->m_vPosition = vecCenter; // vertex 0 (pVertex++)->m_vPosition = vecCenter; // vertex 2 (pVertex++)->m_vPosition = vecCenter; // vertex 3 } m_pLeafVertexBuffer[unLod]->Unlock( ); m_pLeavesUpdatedByCpu[unLod] = true; } #else if (pLeaf->m_bIsActive) { // update the vertices SFVFLeafVertex* pVertex = NULL; m_pLeafVertexBuffer[unLod]->Lock(0, 0, reinterpret_cast<void**>(&pVertex),0); for (unsigned int unLeaf = 0; unLeaf < pLeaf->m_usLeafCount; ++unLeaf) { D3DXVECTOR3 vecCenter(&(pLeaf->m_pCenterCoords[unLeaf * 3])); D3DXVECTOR3 vec0(&pLeaf->m_pLeafMapCoords[unLeaf][0]); D3DXVECTOR3 vec1(&pLeaf->m_pLeafMapCoords[unLeaf][4]); D3DXVECTOR3 vec2(&pLeaf->m_pLeafMapCoords[unLeaf][8]); D3DXVECTOR3 vec3(&pLeaf->m_pLeafMapCoords[unLeaf][12]); (pVertex++)->m_vPosition = vecCenter + vec0; // vertex 0 (pVertex++)->m_vPosition = vecCenter + vec1; // vertex 1 (pVertex++)->m_vPosition = vecCenter + vec2; // vertex 2 (pVertex++)->m_vPosition = vecCenter + vec0; // vertex 0 (pVertex++)->m_vPosition = vecCenter + vec2; // vertex 2 (pVertex++)->m_vPosition = vecCenter + vec3; // vertex 3 } m_pLeafVertexBuffer[unLod]->Unlock( ); } #endif } #endif #endif PositionTree( ); // might need to draw 2 LOD's for (unsigned int unLeafLevel = 0; unLeafLevel < 2; ++unLeafLevel) { const CSpeedTreeRT::SGeometry::SLeaf* pLeaf = (unLeafLevel == 0) ? &m_pGeometryCache->m_sLeaves0 : pLeaf = &m_pGeometryCache->m_sLeaves1; int unLod = pLeaf->m_nDiscreteLodLevel; // if this LOD is active and has leaves, draw it if (unLod > -1 && pLeaf->m_bIsActive && pLeaf->m_usLeafCount > 0) { m_pDx->SetStreamSource(0, m_pLeafVertexBuffer[unLod], 0, sizeof(SFVFLeafVertex)); m_pDx->SetRenderState(D3DRS_ALPHAREF, DWORD(pLeaf->m_fAlphaTestValue)); m_pDx->DrawPrimitive(D3DPT_TRIANGLELIST, 0, pLeaf->m_usLeafCount * 2); } } }
void ProgressBar::doRender(const RenderState &rs) { if (_progress == 0) return; if (((_direction != __dir_radial_ccw) && (_direction != dir_radial_cw)) || (_progress == 1.0f)) { Sprite::doRender(rs); return; } _vstyle._apply(rs); const Diffuse &df = _frame.getDiffuse(); if (df.base) { rs.renderer->setDiffuse(df); unsigned int rgba = rs.renderer->getPrimaryColor().rgba(); RectF destRect = Sprite::getDestRect(); RectF srcRect = _frame.getSrcRect(); float u = srcRect.pos.x; float v = srcRect.pos.y; float du = srcRect.size.x; float dv = srcRect.size.y; u += du / 2.f; v += dv / 2.f; Vector2 pos = destRect.pos; const Vector2 &size = destRect.size; pos += size / 2.f; float maxSide = std::max( size.x, size.y ); Vector2 vecCenter( pos.x, pos.y ); Vector2 vdiag = Vector2( pos.x + size.x / 2.f, pos.y - size.y / 2.f ) - vecCenter; Vector2 vdiag2 = Vector2( pos.x + size.x / 2.f, pos.y + size.y / 2.f ) - vecCenter; float lenDiag = vdiag.length(); Vector2 vecCircle( pos.x, pos.y - lenDiag ); Vector2 vecRad = vecCircle - vecCenter; float progress = _progress; float fP = MATH_PI * 2.f * progress; rotateVector( vecRad, fP ); Vector2 p1(0.f, 0.f); Vector2 p2(0.f, 0.f); Vector2 p3(0.f, 0.f); Vector2 vert( 0.f, -1.f ); float fA1 = Angle( vdiag, &vert ); float fA2 = Angle( vdiag2, &vdiag ); const int MAX_TRI = 6; float u1,v1,u2,v2,u3,v3; float result = 0.f; float angles[ 6 ]; angles[ 0 ] = fA1; angles[ 1 ] = fA2; angles[ 2 ] = fA1; angles[ 3 ] = fA1; angles[ 4 ] = fA2; angles[ 5 ] = fA1; for ( int i = 0; i < MAX_TRI; i++ ) { float limitLo = 0.f; float limitHi = 0.f; for (int j = 0; j < i; j++) limitLo += angles[ j ]; limitHi = limitLo + angles[ i ]; bool bOverHi = fP > limitHi; bool bOverLo = fP < limitLo; if ( i && bOverLo ) continue; vertexPCT2 vertices[4]; vertexPCT2* pv = vertices; switch (i) { case 0: { result = bOverHi ? size.x / 2.f : vecRad.x; p1 = Vector2(pos.x, pos.y); p2 = Vector2(pos.x, pos.y - size.y / 2.f); p3 = Vector2(pos.x + result, pos.y - size.y / 2.f); float fPercent = result / size.x; float fDU = du * fPercent; u1 = u; v1 = v; u2 = u; v2 = ( v - dv / 2.f ); u3 = ( u + fDU ); v3 = ( v - dv / 2.f ); } break; case 1: { result = bOverHi ? size.y / 2.f : ( vecRad.y ) ; p1 = Vector2(pos.x, pos.y); p2 = Vector2(pos.x + size.x / 2.f, pos.y - size.y / 2.f); p3 = Vector2(pos.x + size.x / 2.f, pos.y + result ); float fPercent = result /size.y; float fDV = dv * fPercent; u2 = u + du / 2.f; v2 = ( v - dv / 2.f ); u3 = u + du / 2.f; v3 = ( v + fDV ); } break; case 2: { result = bOverHi ? 0.f : vecRad.x ; p1 = Vector2(pos.x, pos.y); p2 = Vector2(pos.x + size.x / 2.f, pos.y + size.y / 2.f); p3 = Vector2(pos.x + result, pos.y + size.y / 2.f ); float fPercent = result/size.x; float fDU = du * fPercent; u2 = u + du / 2.f; v2 = ( v + dv / 2.f ); u3 = u + fDU; v3 = ( v + dv / 2.f ); } break; case 3: { result = bOverHi ? ( -size.x / 2.f ) : vecRad.x ; p1 = Vector2(pos.x, pos.y); p2 = Vector2(pos.x , pos.y + size.y / 2.f); p3 = Vector2(pos.x + result, pos.y + size.y / 2.f ); float fPercent = result / size.x; float fDU = du * fPercent; u2 = u; v2 = ( v + dv / 2.f ); u3 = u + fDU; v3 = ( v + dv / 2.f ); } break; case 4: { result = bOverHi ? ( -size.y / 2.f ) : vecRad.y ; p1 = Vector2(pos.x, pos.y); p2 = Vector2(pos.x - ( size.x / 2.f ) , pos.y + size.y / 2.f); p3 = Vector2(pos.x - ( size.x / 2.f ), pos.y + result ); float fPercent = result / size.y; float fDV = dv * fPercent; u2 = u - du / 2.f; v2 = ( v + dv / 2.f ); u3 = u - du / 2.f; v3 = ( v + fDV ); } break; case 5: { result = bOverHi ? ( 0.f ) : vecRad.x ; p1 = Vector2(pos.x, pos.y); p2 = Vector2(pos.x - ( size.x / 2.f ), pos.y - ( size.y / 2.f )); p3 = Vector2(pos.x + result, pos.y - ( size.y / 2.f ) ); float fPercent = result / size.x; float fDU = du * fPercent; u2 = u - du / 2.f; v2 = ( v - dv / 2.f ); u3 = u + fDU; v3 = ( v - dv / 2.f ); } break; default: continue; } u1 = u; v1 = v; p1 = rs.transform.transform(p1); p2 = rs.transform.transform(p2); p3 = rs.transform.transform(p3); fill_tex_coord(*pv, rgba, p1, u1, v1); pv++; fill_tex_coord(*pv, rgba, p2, u2, v2); pv++; fill_tex_coord(*pv, rgba, p3, u3, v3); pv++; fill_tex_coord(*pv, rgba, p2, u2, v2); pv++; rs.renderer->draw(vertices, sizeof(vertices), VERTEX_PCT2); } } }
void CNormalGenerator::NormalizeHeightValue(size_t x, size_t y) { if (!m_avecTextureTexels.size()) return; float flHiScale = ((m_iNormal2Width+m_iNormal2Height)/2.0f)/200.0f * m_flNormalTextureDepth; float flMidScale = ((m_iNormal2Width+m_iNormal2Height)/2.0f)/100.0f * m_flNormalTextureDepth; float flLowScale = ((m_iNormal2Width+m_iNormal2Height)/2.0f)/50.0f * m_flNormalTextureDepth; size_t iTexel; Texel(x, y, iTexel, m_iNormal2Width, m_iNormal2Height, false); tvector<Vector> avecHeights; float flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; float flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; float flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecCenter((float)x, (float)y, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); Vector vecNormal(0,0,0); if (Texel(x+1, y, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor(x+1.0f, (float)y, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(0, 1, 0)); } if (Texel(x-1, y, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor(x-1.0f, (float)y, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(0, -1, 0)); } if (Texel(x, y+1, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor((float)x, y+1.0f, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(-1, 0, 0)); } if (Texel(x, y-1, iTexel, m_iNormal2Width, m_iNormal2Height, false)) { flHeight = m_avecTextureTexels[iTexel].Average() * flHiScale; flMidPass = m_aflMidPassTexels[iTexel] * flMidScale; flLowPass = m_aflLowPassTexels[iTexel] * flLowScale; Vector vecNeighbor((float)x, y-1.0f, flHeight*m_flNormalTextureHiDepth + flMidPass*m_flNormalTextureMidDepth + flLowPass*m_flNormalTextureLoDepth); vecNormal += (vecNeighbor-vecCenter).Normalized().Cross(Vector(1, 0, 0)); } vecNormal.Normalize(); for (size_t i = 0; i < 3; i++) vecNormal[i] = RemapVal(vecNormal[i], -1.0f, 1.0f, 0.0f, 0.99f); // Don't use 1.0 because of integer overflow. // Don't need to lock the data because we're guaranteed never to access the same texel twice due to the generation method. m_avecNormal2Texels[iTexel] = vecNormal; }