void TransformMath::CalcTransform(Trans& outputTrans, Node* node, Node* parent, TransformEnt& entity, int gridWidth, int gridHeight) { Trans& parentTrans = parent->GetTransform(); // calculate scale ofVec2f scale = CalcScale(node, parent, entity.size.x, entity.size.y, entity.sType, gridWidth, gridHeight); // calculate position ofVec2f absPos = CalcPosition(node, parent, entity.pos, entity.pType, gridWidth, gridHeight); auto shape = node->GetMesh(); // fix position according to the anchor absPos.x += (0.0f - entity.anchor.x) * shape->GetWidth()*scale.x; absPos.y += (0.0f - entity.anchor.y) * shape->GetHeight()*scale.y; int zIndex = entity.zIndex; // if zIndex is equal to 0, the value will be taken from the parent if (zIndex == 0) zIndex = (int)parentTrans.localPos.z; // set transformation outputTrans.localPos = ofVec3f(absPos.x, absPos.y, (float)zIndex); outputTrans.scale = ofVec3f(scale.x, scale.y, 1); outputTrans.rotationCentroid = ofVec2f(shape->GetWidth(), shape->GetHeight()) * entity.rotationCentroid * (scale); // multiply by abs scale outputTrans.rotation = entity.rotation; }
void cFlipper::CalcRotate() { float diffX, diffY; uInt32 lt, rt; if(mCurrentTrack == 0) lt = (*mPath)[mZ].size()-1; else lt = mCurrentTrack-1; if(mCurrentTrack == (*mPath)[mZ].size()-1) rt = 0; else rt = mCurrentTrack+1; diffX = (*mPath)[mZ][lt].x - (*mPath)[mZ][rt].x; diffY = (*mPath)[mZ][lt].y - (*mPath)[mZ][rt].y; mAngle = atan( Abs( diffY/diffX ) )*_180_PI; if(mPathType == Polygon_Closed) { if((*mPath)[mZ][mCurrentTrack].y > 0) mAngle = 180 - mAngle; if((*mPath)[mZ][mCurrentTrack].x < 0) mAngle *= -1; } else { if(diffX != 0) { if(diffY/diffX <= 0) mAngle *= -1; } else { if((*mPath)[mZ][mCurrentTrack].x < 0) mAngle *= -1; } } CalcScale(); }
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; } } }
bool CLTBBouncyChunkFX::Init(ILTClient *pClientDE, FX_BASEDATA *pBaseData, const CBaseFXProps *pProps) { // Perform base class initialisation if (!CBaseFX::Init(pClientDE, pBaseData, pProps)) return false; LTVector vChunkDir = GetProps()->m_vChunkDir; if (pBaseData->m_bUseTargetData) { vChunkDir = pBaseData->m_vTargetNorm; } LTVector vPos; LTRotation rRot; if (m_hParent) { m_pLTClient->GetObjectPos(m_hParent, &vPos); m_pLTClient->GetObjectRotation(m_hParent, &rRot); } else { vPos = m_vCreatePos; rRot = m_rCreateRot; } float scale; CalcScale(m_tmElapsed, GetProps()->m_tmLifespan, &scale); LTVector vScale(scale, scale, scale); ObjectCreateStruct ocs; INIT_OBJECTCREATESTRUCT(ocs); ocs.m_ObjectType = OT_MODEL; ocs.m_Flags = FLAG_NOLIGHT | FLAG_VISIBLE; ocs.m_Pos = vPos + GetProps()->m_vOffset; ocs.m_Rotation = rRot; ocs.m_Scale = vScale; strcpy(ocs.m_Filename, GetProps()->m_sModelName); strcpy(ocs.m_SkinName, GetProps()->m_sSkinName); m_hBouncyChunk = m_pLTClient->CreateObject(&ocs); // Setup an initial vector for the velocity LTVector vOther; vOther.x = 1.0f; vOther.y = 0.0f; vOther.z = 1.0f; vOther.Norm(); LTVector vRight = vChunkDir.Cross(vOther); LTVector vUp = vRight.Cross(vOther); m_vVel = vRight * (-GetProps()->m_fChunkSpread + (float)(rand() % (int)(GetProps()->m_fChunkSpread * 2.0f))); m_vVel += vUp * (-GetProps()->m_fChunkSpread + (float)(rand() % (int)(GetProps()->m_fChunkSpread * 2.0f))); m_vVel += vChunkDir * GetProps()->m_fChunkSpeed; m_vVel.Norm(GetProps()->m_fChunkSpeed); // Create the base object CreateDummyObject(); // Success !! return true; }
/////////////////////////////////////////////////////////////////////////////////////////////// // handles changes in images or ctrl void PixRasterBaseCtrl::Layout(void) { // this to avoid recursion static bool inside = false; // if no associated PixRaster or no pages to display, hides scrollbar and return if(!pixRasterCtrl->GetPixBase() || !pixRasterCtrl->GetPageCount()) { hScrollBar.Hide(); vScrollBar.Hide(); return; } // if already doing layout, just return if(inside) return; // marks inside layout inside = true; // stores scroll positions, in order to go on right position // after zoom operations int hScrollPos = hScrollBar.Get(); int hScrollMax = hScrollBar.GetTotal(); int vScrollPos = vScrollBar.Get(); int vScrollMax = vScrollBar.GetTotal(); // gets the PixRaster object PixBase *pixBase = pixRasterCtrl->GetPixBase(); // calculates max width and height // and total Tiff height, for all pages, with no gaps by now int rasterWidth = 0; int rasterHeight = 0; int maxHeight = 0; int pageCount = pixBase->GetPageCount(); for(int i = 0 ; i < pageCount ; i++) { // sets current page pixBase->SeekPage(i); // gets page size Size sz = pixBase->GetSizeEx(i); // updates width, maximum height and total height if(sz.cx > rasterWidth) rasterWidth = sz.cx; if(sz.cy > maxHeight) maxHeight = sz.cy; rasterHeight += sz.cy; } // calculates image scale factor imageScale = CalcScale(imageScale, rasterWidth, maxHeight); // stops layouting if imagescale is null if(!imageScale) { inside = false; return; } // now calculate gaps to be exactly 10 pixels in every zoom factor int gapSize = ScaleToPage(10); // adds total gaps sizes to total height rasterHeight += (pageCount -1) * gapSize; // and finally, sets up scrollbars and shows them // and calculate cache sizes int scaledRasterHeight = ScaleToView(rasterHeight); int cacheHeight; vScrollBar.SetPage(GetSize().cy); vScrollBar.SetTotal(scaledRasterHeight); if(vScrollMax) vScrollBar.Set(iscale(vScrollPos, scaledRasterHeight, vScrollMax)); else vScrollBar.Set(0); if(GetSize().cy <= scaledRasterHeight) { if(hasVScrollBar) vScrollBar.Show(); cacheHeight = GetSize().cy; } else { vScrollBar.Hide(); cacheHeight = scaledRasterHeight; } int scaledRasterWidth = ScaleToView(rasterWidth); int cacheWidth; hScrollBar.SetPage(GetSize().cx); hScrollBar.SetTotal(scaledRasterWidth); if(hScrollMax) hScrollBar.Set(iscale(hScrollPos, scaledRasterWidth, hScrollMax)); else hScrollBar.Set(0); if(GetSize().cx <= scaledRasterWidth) { if(hasHScrollBar) hScrollBar.Show(); cacheWidth = GetSize().cx; } else { hScrollBar.Hide(); cacheWidth = scaledRasterWidth; } // creates cache image, empty by now imageCache.Init(Size(cacheWidth, cacheHeight)); // updates image Refresh(); // mark layout terminated inside = false; } // END PixRasterBaseCtrl::Layout()
bool CFallingStuffFX::Update(float tmFrameTime) { // Base class update first m_vLastPos = m_vPos; if (!CBaseFX::Update(tmFrameTime)) return false; //increment our emission time by the elapsed frame time m_tmElapsedEmission += tmFrameTime; if (!IsShuttingDown() && !IsSuspended() && (m_tmElapsedEmission > GetProps()->m_tmFallingStuffFXEmission)) { ObjectCreateStruct ocs; INIT_OBJECTCREATESTRUCT(ocs); LTVector vScale; vScale.Init(m_scale, m_scale, m_scale); LTVector vInterp; LTVector vInterpCur = m_vPos; // Calculate interpolant for particle system if (GetProps()->m_nFallingStuffFXEmission) { vInterp = m_vPos - m_vLastPos; vInterp /= (float)GetProps()->m_nFallingStuffFXEmission; } for (uint32 i = 0; i < GetProps()->m_nFallingStuffFXEmission; i ++) { ocs.m_ObjectType = OT_SPRITE; ocs.m_Flags = FLAG_VISIBLE | FLAG_NOLIGHT | FLAG_ROTATABLESPRITE; // Compute the initial position float xRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f); float zRand = GetProps()->m_fRadius * ((-10000.0f + (rand() % 20000)) / 10000.0f); ocs.m_Pos = m_vPos + (m_vRight * xRand) + (m_vUp * zRand); ocs.m_Scale = vScale; strcpy(ocs.m_Filename, GetProps()->m_sSpriteName); // Move the start point vInterpCur += vInterp; HLOCALOBJ hNewSprite = m_pLTClient->CreateObject(&ocs); if (hNewSprite) { // Create a new sprite FALLING_THING *pNewSprite = debug_new( FALLING_THING ); if (GetProps()->m_nImpactCreate) { if (g_dwSplash > (uint32)GetProps()->m_nImpactCreate) { pNewSprite->m_bSplash = true; g_dwSplash = 0; } else { pNewSprite->m_bSplash = false; } } else { pNewSprite->m_bSplash = false; } g_dwSplash ++; if (pNewSprite) { LTVector v; // Compute the initial velocity v = m_vPlaneDir * GetProps()->m_fVel; pNewSprite->m_hObject = hNewSprite; pNewSprite->m_vVel = v; pNewSprite->m_tmElapsed = 0.0f; pNewSprite->m_vPos = ocs.m_Pos; pNewSprite->m_vLastPos = ocs.m_Pos; m_collSprites.AddTail(pNewSprite); } } } m_tmElapsedEmission = 0.0f; // And store the last position m_vLastPos = m_vPos; } LTMatrix mSpin; if (GetProps()->m_bUseSpin) { // Setup rotation LTMatrix vRight; LTMatrix vUp; LTMatrix vForward; LTMatrix vTmp; Mat_SetupRot(&vRight, &m_vRight, m_xRot); Mat_SetupRot(&vUp, &m_vUp, m_yRot); Mat_SetupRot(&vForward, &m_vPlaneDir, m_zRot); MatMul(&vTmp, &vRight, &vUp); MatMul(&mSpin, &vTmp, &vForward); m_xRot += GetProps()->m_vRotAdd.x * tmFrameTime; m_yRot += GetProps()->m_vRotAdd.y * tmFrameTime; m_zRot += GetProps()->m_vRotAdd.z * tmFrameTime; } // Get the camera rotation LTRotation orient; m_pLTClient->GetObjectRotation(m_hCamera, &orient); LTRotation dRot(orient); LTVector vF = orient.Forward(); float rot = (float)atan2(vF.x, vF.z); // Update the sprites.... CLinkListNode<FALLING_THING *> *pNode = m_collSprites.GetHead(); CLinkListNode<FALLING_THING *> *pDelNode; while (pNode) { pDelNode = NULL; FALLING_THING *pSprite = pNode->m_Data; //adjust our elapsed time pSprite->m_tmElapsed += tmFrameTime; // Check for expiration if (pSprite->m_tmElapsed > GetProps()->m_tmSpriteLifespan) { // Destroy this object m_pLTClient->RemoveObject(pSprite->m_hObject); pDelNode = pNode; } else { // Update !! pSprite->m_vLastPos = pSprite->m_vPos; pSprite->m_vPos += (pSprite->m_vVel * tmFrameTime); // Rotate if neccessary TVector3<float> vPos = pSprite->m_vPos; if (GetProps()->m_bUseSpin) { MatVMul_InPlace(&mSpin, &vPos); } // Add in wind vPos += (GetProps()->m_vWind * GetProps()->m_fWindAmount) * tmFrameTime; // Setup the new sprite position LTVector vPos2 = vPos; m_pLTClient->SetObjectPos(pSprite->m_hObject, &vPos2); // Setup the colour float r, g, b, a; m_pLTClient->GetObjectColor(pSprite->m_hObject, &r, &g, &b, &a); CalcColour(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &r, &g, &b, &a); m_pLTClient->SetObjectColor(pSprite->m_hObject, r, g, b, a); // Setup the scale float scale = 0.1f; CalcScale(pSprite->m_tmElapsed, GetProps()->m_tmSpriteLifespan, &scale); LTVector vScale; vScale.Init(scale, scale * GetProps()->m_fStretchMul, scale); m_pLTClient->SetObjectScale(pSprite->m_hObject, &vScale); // Setup the rotation dRot = LTRotation(0, 0, 0, 1); LTRotation orient(dRot); orient.Rotate( orient.Up(), rot ); m_pLTClient->SetObjectRotation(pSprite->m_hObject, &orient); // Check to see if we need to start a splash sprite if (pSprite->m_bSplash) { ClientIntersectQuery ciq; ClientIntersectInfo cii; ciq.m_From = pSprite->m_vLastPos; ciq.m_To = pSprite->m_vPos; if ((GetProps()->m_sImpactSpriteName[0]) && (m_pLTClient->IntersectSegment(&ciq, &cii))) { // Create a splash sprite SPLASH *pSplash = debug_new( SPLASH ); ObjectCreateStruct ocs; INIT_OBJECTCREATESTRUCT(ocs); LTVector vScale; vScale.Init(0.0f, 0.0f, 0.0f); ocs.m_ObjectType = OT_SPRITE; ocs.m_Flags = FLAG_VISIBLE | FLAG_ROTATABLESPRITE | FLAG_NOLIGHT; ocs.m_Pos = cii.m_Point + (cii.m_Plane.m_Normal * 2.0f); ocs.m_Scale = vScale; LTRotation dOrient( cii.m_Plane.m_Normal, LTVector(0.0f, 1.0f, 0.0f) ); strcpy(ocs.m_Filename, GetProps()->m_sImpactSpriteName); pSplash->m_hObject = m_pLTClient->CreateObject(&ocs); pSplash->m_scale = 0.0f; LTRotation orient(dRot); m_pLTClient->SetObjectRotation(pSplash->m_hObject, &orient); pSplash->m_tmElapsed = 0.0f; m_collSplashes.AddTail(pSplash); // Destroy this object m_pLTClient->RemoveObject(pSprite->m_hObject); // Delete the sprite pDelNode = pNode; } } } pNode = pNode->m_pNext; if (pDelNode) m_collSprites.Remove(pDelNode); } // Update our splashes CLinkListNode<SPLASH *> *pSplashNode = m_collSplashes.GetHead(); while (pSplashNode) { CLinkListNode<SPLASH *> *pDelNode = NULL; SPLASH *pSplash = pSplashNode->m_Data; //update the elapsed time on the splash pSplash->m_tmElapsed += tmFrameTime; // Calculate the new scale float scale = GetProps()->m_fImpactScale1 + ((GetProps()->m_fImpactScale2 - GetProps()->m_fImpactScale1) * (pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan)); LTVector vScale(scale, scale, scale); m_pLTClient->SetObjectScale(pSplash->m_hObject, &vScale); float r, g, b, a; m_pLTClient->GetObjectColor(pSplash->m_hObject, &r, &g, &b, &a); a = (float)(int)(pSplash->m_tmElapsed / GetProps()->m_tmImpactLifespan); if (a < 0.0f) a = 0.0f; if (a > 1.0f) a = 1.0f; m_pLTClient->SetObjectColor(pSplash->m_hObject, r, g, b, a); if (pSplash->m_tmElapsed > GetProps()->m_tmImpactLifespan) { m_pLTClient->RemoveObject(pSplash->m_hObject); pDelNode = pSplashNode; } pSplashNode = pSplashNode->m_pNext; if (pDelNode) m_collSplashes.Remove(pDelNode); } // Success !! return true; }