static void GeneratePolyGridFresnelAlphaAndCamera(const LTVector& vViewPos, CPolyGridBumpVertex* pVerts, LTPolyGrid* pGrid, uint32 nNumVerts) { //we need to transform the camera position into our view space LTMatrix mInvWorldTrans; mInvWorldTrans.Identity(); mInvWorldTrans.SetTranslation(-pGrid->GetPos()); LTMatrix mOrientation; pGrid->m_Rotation.ConvertToMatrix(mOrientation); mInvWorldTrans = mOrientation * mInvWorldTrans; LTVector vCameraPos = mInvWorldTrans * vViewPos; //now generate the internals of the polygrid CPolyGridBumpVertex* pCurrVert = pVerts; CPolyGridBumpVertex* pEnd = pCurrVert + nNumVerts; //determine the fresnel table that we are going to be using const CFresnelTable* pTable = g_FresnelCache.GetTable(LTMAX(1.0003f, pGrid->m_fFresnelVolumeIOR), pGrid->m_fBaseReflection); //use a vector from the camera to the center of the grid to base our approximations off of. The further //we get to the edges the more likely this error will be, but it is better than another sqrt per vert LTVector vToPGPt; while(pCurrVert < pEnd) { //the correct but slow way, so only do it every once in a while //if((pCurrVert - g_TriVertList) % 4 == 0) { vToPGPt = vCameraPos - pCurrVert->m_Vec; vToPGPt.Normalize(); } pCurrVert->m_fEyeX = vToPGPt.x; pCurrVert->m_fEyeY = vToPGPt.y; pCurrVert->m_fEyeZ = vToPGPt.z; pCurrVert->m_nColor |= pTable->GetValue(vToPGPt.Dot(pCurrVert->m_vBasisUp)); ++pCurrVert; } }
// ------------------------------------------------------------------------ // Draw // use gl to draw the model // ------------------------------------------------------------------------ void CRenderWnd::Draw() { static LTMatrix IdMat; IdMat.Identity(); DrawStruct *pStruct; pStruct = &m_DrawStruct; // Setup with 2 lights. pStruct->m_ViewerPos = m_Camera.m_Position; pStruct->m_LookAt = m_Camera.m_LookAt; pStruct->m_LightPositions[0] = m_LightLocators[0].m_Location; pStruct->m_LightPositions[1] = m_LightLocators[1].m_Location; pStruct->m_LightColors[0].Init(255.0f, 255.0f, 255.0f); pStruct->m_LightColors[1].Init(128.0f, 128.0f, 128.0f); pStruct->m_nLights = 2; SetupViewingParameters((GLMContext*)m_hContext, pStruct ); DrawWorldCoordSys(); // if the model exists if (GetModel() ) { pStruct->m_SelectedPieces = m_SelectedPieces.GetArray(); pStruct->m_SelectedNodes = m_SelectedNodes.GetArray(); pStruct->m_bCalcRadius = m_bCalcRadius; pStruct->m_fModelRadius = 0.0f; pStruct->m_bCalcAndDraw = m_bCalcAndDraw; DrawModel (m_hContext, pStruct); m_fCurRadius = pStruct->m_fModelRadius; } SwapBuffers( (( GLMContext*)m_hContext)->m_hDC); }
void CLoadedPrefab::CalcDims() { LTVector vMin, vMax; vMin.Init(FLT_MAX, FLT_MAX, FLT_MAX); vMax.Init(FLT_MIN, FLT_MIN, FLT_MIN); LTMatrix mIdent; mIdent.Identity(); RecurseAndGrowDims(m_cRegion.GetRootNode(), vMin, vMax, mIdent); // If one of the members didn't get modified, none of them did... if (vMin.x == FLT_MAX) { ASSERT(vMin.y == FLT_MAX && vMin.z == FLT_MAX && vMax.x == FLT_MIN && vMax.y == FLT_MIN && vMax.y == FLT_MIN); // Treat it as an empty set (Which it probably is... All null nodes or something..) vMin.Init(); vMax.Init(); } m_vMin = vMin; m_vMax = vMax; }
void CLightningFX::PreRender( float tmFrameTime ) { LTVector vPulse; LTVector vF(0.0f, 0.0f, 1.0f); LTVector vU(0.0f, 1.0f, 0.0f); LTVector vR(1.0f, 0.0f, 0.0f); // Transform the bolt LTMatrix mCam; if( m_bReallyClose ) { mCam.Identity(); } else { mCam = GetCamTransform(m_pLTClient, m_hCamera); } CLightningBolt *pBolt = LTNULL; LightningBolts::iterator iter; for( iter = m_lstBolts.begin(); iter != m_lstBolts.end(); ++iter ) { pBolt = *iter; // Skip this bolt if there are not enough segments... if( pBolt->m_collPathPts.GetSize() < 2 || !pBolt->m_bActive ) continue; CLinkListNode<PT_TRAIL_SECTION> *pNode = pBolt->m_collPathPts.GetHead(); //as long as some amount of time has passed, apply a pulse onto the bolt to make //it jitter if(tmFrameTime > 0.001f) { while (pNode) { vPulse = pNode->m_Data.m_vPos; vPulse += (vF * GetRandom( -GetProps()->m_fPulse, GetProps()->m_fPulse )); vPulse += (vU * GetRandom( -GetProps()->m_fPulse, GetProps()->m_fPulse )); vPulse += (vR * GetRandom( -GetProps()->m_fPulse, GetProps()->m_fPulse )); if( pNode == pBolt->m_collPathPts.GetHead() || !pNode->m_pNext ) { MatVMul(&pNode->m_Data.m_vTran, &mCam, &pNode->m_Data.m_vPos); } else { MatVMul(&pNode->m_Data.m_vTran, &mCam, &vPulse); } pNode = pNode->m_pNext; } } // Do some precalculations float fScale; CalcScale( pBolt->m_tmElapsed, pBolt->m_fLifetime, &fScale ); float fWidth = pBolt->m_fWidth * fScale; // Setup the colour float r, g, b, a; CalcColour( pBolt->m_tmElapsed, pBolt->m_fLifetime, &r, &g, &b, &a ); int ir = Clamp( (int)(r * 255.0f), 0, 255 ); int ig = Clamp( (int)(g * 255.0f), 0, 255 ); int ib = Clamp( (int)(b * 255.0f), 0, 255 ); int ia = Clamp( (int)(a * 255.0f), 0, 255 ); LTVector vStart, vEnd, vPrev, vBisector; vBisector.z = 0.0f; pNode = pBolt->m_collPathPts.GetHead(); while( pNode ) { if( GetProps()->m_eAllignment == ePTA_Camera ) { // Compute the midpoint vectors if( pNode == pBolt->m_collPathPts.GetHead() ) { vStart = pNode->m_Data.m_vTran; vEnd = pNode->m_pNext->m_Data.m_vTran; vBisector.x = vEnd.y - vStart.y; vBisector.y = -(vEnd.x - vStart.x); } else if( pNode == pBolt->m_collPathPts.GetTail() ) { vEnd = pNode->m_Data.m_vTran; vStart = pNode->m_pPrev->m_Data.m_vTran; vBisector.x = vEnd.y - vStart.y; vBisector.y = -(vEnd.x - vStart.x); } else { vPrev = pNode->m_pPrev->m_Data.m_vTran; vStart = pNode->m_Data.m_vTran; vEnd = pNode->m_pNext->m_Data.m_vTran; float x1 = vEnd.y - vStart.y; float y1 = -(vEnd.x - vStart.x); float z1 = vStart.z - vEnd.z; float x2 = vStart.y - vPrev.y; float y2 = -(vStart.x - vPrev.x); float z2 = vPrev.z - vEnd.z; vBisector.x = (x1 + x2) / 2.0f; vBisector.y = (y1 + y2) / 2.0f; } pNode->m_Data.m_vBisector = vBisector; } // Set the width for this section... pNode->m_Data.m_vBisector.Norm( fWidth ); // Set the color for this section... pNode->m_Data.m_red = ir; pNode->m_Data.m_green = ig; pNode->m_Data.m_blue = ib; pNode->m_Data.m_alpha = ia; pNode = pNode->m_pNext; } } }
//given an animation and a keyframe, this will find the dims that encompass the //model bool CDimensionsDlg::FindAnimDims(Model* pModel, uint32 nAnim, uint32 nKeyFrame, LTVector& vDims) { //clear out the dims to start out with in case we fail vDims.Init(); AnimTracker tracker, *pTracker; tracker.m_TimeRef.Init(pModel, nAnim, nKeyFrame, nAnim, nKeyFrame, 0.0f); AnimInfo *pAnim = &pModel->m_Anims[nAnim]; pTracker = &tracker;//pAnim->m_pAnim; static CMoArray<TVert> tVerts; // Use the model code to setup the vertices. int nTrackers = 1; nTrackers = DMIN(nTrackers, MAX_GVP_ANIMS); GVPStruct gvp; gvp.m_nAnims = 0; for(int i = 0; i < nTrackers; i++) { gvp.m_Anims[i] = pTracker[i].m_TimeRef; gvp.m_nAnims++; } LTMatrix m; m.Identity(); int nWantedVerts = pModel->GetTotalNumVerts() * 2; if(tVerts.GetSize() < nWantedVerts) { if(!tVerts.SetSize(nWantedVerts)) return false; } gvp.m_VertexStride = sizeof(TVert); gvp.m_Vertices = tVerts.GetArray(); gvp.m_BaseTransform = m; gvp.m_CurrentLODDist = 0; if (AlternateGetVertexPositions(pModel, &gvp, true, false, false, false)) { LTVector vMax(0, 0, 0); for (i = 0; i < pModel->GetTotalNumVerts(); i ++) { TVert v = tVerts[i]; if (fabs(v.m_vPos.x) > vMax.x) vMax.x = (float)fabs(v.m_vPos.x); if (fabs(v.m_vPos.y) > vMax.y) vMax.y = (float)fabs(v.m_vPos.y); if (fabs(v.m_vPos.z) > vMax.z) vMax.z = (float)fabs(v.m_vPos.z); } // Setup the new dims.... //round max up to the .1 decimal place vMax.x = (float)(ceil(vMax.x * 10.0) / 10.0); vMax.y = (float)(ceil(vMax.y * 10.0) / 10.0); vMax.z = (float)(ceil(vMax.z * 10.0) / 10.0); vDims = vMax; return true; } //failure return false; }
bool CPolyTubeFX::Update(float tmFrameTime) { // Base class update first if (!CBaseFX::Update(tmFrameTime)) return false; if ((!m_hTexture) && (!m_bLoadFailed)) { m_pLTClient->GetTexInterface()->CreateTextureFromName(m_hTexture, GetProps()->m_sPath); if (m_hTexture) { // Retrieve texture dims uint32 nHeight; m_pLTClient->GetTexInterface()->GetTextureDims(m_hTexture, m_dwWidth, nHeight); } else { m_bLoadFailed = true; } } if ((m_collPathPts.GetSize() < 2) && IsShuttingDown()) { m_collPathPts.RemoveAll(); return true; } float tmAddPtInterval = GetProps()->m_tmAddPtInterval * 2.0f; LTRotation rRot; m_pLTClient->GetObjectRotation( m_hObject, &rRot ); //increase the emission time elapse m_tmElapsedEmission += tmFrameTime; if (!IsShuttingDown() && (m_collPathPts.GetSize() < GetProps()->m_nMaxTrailLength) && ((m_tmElapsedEmission > GetProps()->m_tmAddPtInterval) || (m_collPathPts.GetSize() == 1))) { LTVector vNew = m_vPos; // Only add the new point if it's not the same as the last one.... // Add a new trail section PT_TRAIL_SECTION ts; ts.m_vPos = vNew; ts.m_tmElapsed = 0.0f; switch( GetProps()->m_eAllignment ) { case ePTA_Up: ts.m_vBisector = rRot.Up(); break; case ePTA_Right: ts.m_vBisector = rRot.Right(); break; case ePTA_Forward: ts.m_vBisector = rRot.Forward(); break; case ePTA_Camera: default: ts.m_vBisector.Init(); break; } // Compute u coordinate if (m_collPathPts.GetSize()) { LTVector vPrev = m_collPathPts.GetTail()->m_Data.m_vPos; float fUPrev = m_collPathPts.GetTail()->m_Data.m_uVal; float fWidth = (float)m_dwWidth; float fScalar = fWidth / GetProps()->m_fTrailWidth; ts.m_uVal = fUPrev + ((((vNew - vPrev).Mag()) / fWidth) * fScalar); } else { ts.m_uVal = 0.0f; } m_collPathPts.AddTail(ts); m_tmElapsedEmission = 0.0f; } // Render the tube.... if (m_collPathPts.GetSize() < 2) return true; CLinkListNode<PT_TRAIL_SECTION> *pNode = m_collPathPts.GetHead(); // Fudge the last point to be the current one... if( !IsShuttingDown() ) m_collPathPts.GetTail()->m_Data.m_vPos = m_vPos; // Transform the path LTMatrix mCam; if( m_bReallyClose || (GetProps()->m_eAllignment != ePTA_Camera)) { mCam.Identity(); } else { mCam = GetCamTransform(m_pLTClient, m_hCamera); } while (pNode) { MatVMul(&pNode->m_Data.m_vTran, &mCam, &pNode->m_Data.m_vPos); pNode = pNode->m_pNext; } // Do some precalculations pNode = m_collPathPts.GetHead(); float fCurU = 0.0f; while (pNode) { pNode->m_Data.m_tmElapsed += tmFrameTime; if( GetProps()->m_eAllignment == ePTA_Camera ) { LTVector vBisector; vBisector.z = 0.0f; // Compute the midpoint vectors if (pNode == m_collPathPts.GetHead()) { LTVector vStart = pNode->m_Data.m_vTran; LTVector vEnd = pNode->m_pNext->m_Data.m_vTran; vBisector.x = vEnd.y - vStart.y; vBisector.y = -(vEnd.x - vStart.x); } else if (pNode == m_collPathPts.GetTail()) { LTVector vEnd = pNode->m_Data.m_vTran; LTVector vStart = pNode->m_pPrev->m_Data.m_vTran; vBisector.x = vEnd.y - vStart.y; vBisector.y = -(vEnd.x - vStart.x); } else { LTVector vPrev = pNode->m_pPrev->m_Data.m_vTran; LTVector vStart = pNode->m_Data.m_vTran; LTVector vEnd = pNode->m_pNext->m_Data.m_vTran; float x1 = vEnd.y - vStart.y; float y1 = -(vEnd.x - vStart.x); float z1 = vStart.z - vEnd.z; float x2 = vStart.y - vPrev.y; float y2 = -(vStart.x - vPrev.x); float z2 = vPrev.z - vEnd.z; vBisector.x = (x1 + x2) / 2.0f; vBisector.y = (y1 + y2) / 2.0f; } pNode->m_Data.m_vBisector = vBisector; } LTFLOAT fWidth = CalcCurWidth(); pNode->m_Data.m_vBisector.Norm( fWidth ); // Setup the colour float r, g, b, a; CalcColour(pNode->m_Data.m_tmElapsed, GetProps()->m_tmSectionLifespan, &r, &g, &b, &a); int ir = (int)(r * 255.0f); int ig = (int)(g * 255.0f); int ib = (int)(b * 255.0f); int ia = (int)(a * 255.0f); pNode->m_Data.m_red = Clamp( ir, 0, 255 ); pNode->m_Data.m_green = Clamp( ig, 0, 255 ); pNode->m_Data.m_blue = Clamp( ib, 0, 255 ); pNode->m_Data.m_alpha = Clamp( ia, 0, 255 ); pNode = pNode->m_pNext; } pNode = m_collPathPts.GetHead(); pNode = m_collPathPts.GetHead(); // Delete any dead nodes while (pNode->m_pNext) { CLinkListNode<PT_TRAIL_SECTION> *pDelNode= NULL; if (pNode->m_Data.m_tmElapsed >= GetProps()->m_tmSectionLifespan) { pDelNode = pNode; } pNode = pNode->m_pNext; if (pDelNode) m_collPathPts.Remove(pDelNode); } // Increment the offset m_uOffset += tmFrameTime * GetProps()->m_uAdd; // Success !! return true; }
static void RecurseAndGrowDims(CWorldNode *pNode, LTVector &vMin, LTVector &vMax, LTMatrix& mTransMat) { //sanity check if(pNode == NULL) { return; } // Grow the dims for this node switch (pNode->GetType()) { case Node_Object : { CBaseEditObj *pObject = pNode->AsObject(); LTVector vCenter; mTransMat.Apply(pObject->GetPos(), vCenter); //always include at least the object center VEC_MIN(vMin, vMin, vCenter); VEC_MAX(vMax, vMax, vCenter); #ifdef DIRECTEDITOR_BUILD //see if there are other dims we need for (uint32 nCurDim = pObject->GetNumDims(); nCurDim > 0; --nCurDim) { LTVector vDims = *pObject->GetDim(nCurDim - 1); LTVector vObjMin = vCenter - vDims; LTVector vObjMax = vCenter + vDims; VEC_MIN(vMin, vMin, vObjMin); VEC_MAX(vMax, vMax, vObjMax); } #endif } break; case Node_Brush: { CEditBrush *pBrush = pNode->AsBrush(); CBoundingBox BBox = pBrush->CalcBoundingBox(); //transform the bounding box LTVector vBoxMin, vBoxMax; mTransMat.Apply(BBox.m_Min, vBoxMin); mTransMat.Apply(BBox.m_Max, vBoxMax); VEC_MIN(vMin, vMin, vBoxMin); VEC_MAX(vMax, vMax, vBoxMax); } break; case Node_PrefabRef: { //create the new transformation matrix LTMatrix mRot; ::gr_SetupMatrixEuler(pNode->GetOr(), mRot.m); LTMatrix mTranslate; mTranslate.Identity(); mTranslate.SetTranslation(pNode->GetPos()); LTMatrix mNewTransMat = mTransMat * mTranslate * mRot; RecurseAndGrowDims((CWorldNode*)((CPrefabRef*)pNode)->GetPrefabTree(), vMin, vMax, mNewTransMat); } break; } // Go through the children GPOS iFinger = pNode->m_Children.GetHeadPosition(); while (iFinger) { CWorldNode *pChild = pNode->m_Children.GetNext(iFinger); RecurseAndGrowDims(pChild, vMin, vMax, mTransMat); } }