// // D3DSkyNode11::VOnRestore - Chapter 16, page 556 // HRESULT D3DSkyNode11::VOnRestore(Scene *pScene) { HRESULT hr; V_RETURN(SceneNode::VOnRestore(pScene) ); m_camera = pScene->GetCamera(); SAFE_RELEASE(m_pVertexBuffer); SAFE_RELEASE(m_pIndexBuffer); V_RETURN (m_VertexShader.OnRestore(pScene) ); V_RETURN (m_PixelShader.OnRestore(pScene) ); m_numVerts = 20; // Fill the vertex buffer. We are setting the tu and tv texture // coordinates, which range from 0.0 to 1.0 D3D11Vertex_UnlitTextured *pVertices = GCC_NEW D3D11Vertex_UnlitTextured[m_numVerts]; GCC_ASSERT(pVertices && "Out of memory in D3DSkyNode11::VOnRestore()"); if (!pVertices) return E_FAIL; // Loop through the grid squares and calc the values // of each index. Each grid square has two triangles: // // A - B // | / | // C - D D3D11Vertex_UnlitTextured skyVerts[4]; D3DCOLOR skyVertColor = 0xffffffff; float dim = 50.0f; skyVerts[0].Pos = Vec3( dim, dim, dim ); skyVerts[0].Uv = Vec2(1.0f, 0.0f); skyVerts[1].Pos = Vec3(-dim, dim, dim ); skyVerts[1].Uv = Vec2(0.0f, 0.0f); skyVerts[2].Pos = Vec3( dim,-dim, dim ); skyVerts[2].Uv = Vec2(1.0f, 1.0f); skyVerts[3].Pos = Vec3(-dim,-dim, dim ); skyVerts[3].Uv = Vec2(0.0f, 1.0f); Vec3 triangle[3]; triangle[0] = Vec3(0.f,0.f,0.f); triangle[1] = Vec3(5.f,0.f,0.f); triangle[2] = Vec3(5.f,5.f,0.f); Vec3 edge1 = triangle[1]-triangle[0]; Vec3 edge2 = triangle[2]-triangle[0]; Vec3 normal; normal = edge1.Cross(edge2); normal.Normalize(); Mat4x4 rotY; rotY.BuildRotationY(GCC_PI/2.0f); Mat4x4 rotX; rotX.BuildRotationX(-GCC_PI/2.0f); m_sides = 5; for (DWORD side = 0; side < m_sides; side++) { for (DWORD v = 0; v < 4; v++) { Vec4 temp; if (side < m_sides-1) { temp = rotY.Xform(Vec3(skyVerts[v].Pos)); } else { skyVerts[0].Uv = Vec2(1.0f, 1.0f); skyVerts[1].Uv = Vec2(1.0f, 1.0f); skyVerts[2].Uv = Vec2(1.0f, 1.0f); skyVerts[3].Uv = Vec2(1.0f, 1.0f); temp = rotX.Xform(Vec3(skyVerts[v].Pos)); } skyVerts[v].Pos = Vec3(temp.x, temp.y, temp.z); } memcpy(&pVertices[side*4], skyVerts, sizeof(skyVerts)); } D3D11_BUFFER_DESC bd; ZeroMemory( &bd, sizeof(bd) ); bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( D3D11Vertex_UnlitTextured ) * m_numVerts; bd.BindFlags = D3D11_BIND_VERTEX_BUFFER; bd.CPUAccessFlags = 0; D3D11_SUBRESOURCE_DATA InitData; ZeroMemory( &InitData, sizeof(InitData) ); InitData.pSysMem = pVertices; hr = DXUTGetD3D11Device()->CreateBuffer( &bd, &InitData, &m_pVertexBuffer ); SAFE_DELETE(pVertices); if( FAILED( hr ) ) return hr; // Loop through the grid squares and calc the values // of each index. Each grid square has two triangles: // // A - B // | / | // C - D WORD *pIndices = GCC_NEW WORD[m_sides * 2 * 3]; WORD *current = pIndices; for (DWORD i=0; i<m_sides; i++) { // Triangle #1 ACB *(current) = WORD(i*4); *(current+1) = WORD(i*4 + 2); *(current+2) = WORD(i*4 + 1); // Triangle #2 BCD *(current+3) = WORD(i*4 + 1); *(current+4) = WORD(i*4 + 2); *(current+5) = WORD(i*4 + 3); current+=6; } bd.Usage = D3D11_USAGE_DEFAULT; bd.ByteWidth = sizeof( WORD ) * m_sides * 2 * 3; // each side has 2 triangles bd.BindFlags = D3D11_BIND_INDEX_BUFFER; bd.CPUAccessFlags = 0; InitData.pSysMem = pIndices; hr = DXUTGetD3D11Device()->CreateBuffer( &bd, &InitData, &m_pIndexBuffer ); SAFE_DELETE_ARRAY(pIndices); if( FAILED( hr ) ) return hr; return S_OK; }
// ----------------------------------------------------------------------------- // Image::UnwrapNonortho() void Image::UnwrapNonortho( Frame& tgtIn, Frame& refIn, PairType const& AtomPairs, Matrix_3x3 const& ucell, Matrix_3x3 const& recip, bool center, bool useMass ) { Vec3 vtgt, vref, boxTrans; // Loop over atom pairs for (PairType::const_iterator atom = AtomPairs.begin(); atom != AtomPairs.end(); ++atom) { int firstAtom = *atom; ++atom; int lastAtom = *atom; if (center) { // Use center of coordinates between first and last atoms. if (useMass) { vtgt = tgtIn.VCenterOfMass(firstAtom, lastAtom); vref = refIn.VCenterOfMass(firstAtom, lastAtom); } else { vtgt = tgtIn.VGeometricCenter(firstAtom, lastAtom); vref = refIn.VGeometricCenter(firstAtom, lastAtom); } } else { // Use position first atom only. vtgt = tgtIn.XYZ( firstAtom ); vref = refIn.XYZ( firstAtom ); } boxTrans.Zero(); // Calculate original distance from the ref (previous) position. Vec3 vd = vtgt - vref; // dx dy dz double minDistanceSquare = vd.Magnitude2(); // Reciprocal coordinates vd = recip * vd ; // recip * dxyz double cx = floor(vd[0]); double cy = floor(vd[1]); double cz = floor(vd[2]); // Loop over all possible translations for (int ix = -1; ix < 2; ++ix) { for (int iy = -1; iy < 2; ++iy) { for (int iz = -1; iz < 2; ++iz) { // Calculate the translation. Vec3 vcc = ucell.TransposeMult( Vec3( cx+(double)ix, cy+(double)iy, cz+(double)iz ) ); // ucell^T * ccxyz // Calc. the potential new coordinate for tgt Vec3 vnew = vtgt - vcc; // Calc. the new distance from the ref (previous) position Vec3 vr = vref - vnew; double distanceSquare = vr.Magnitude2(); // If the orig. distance is greater than the new distance, unwrap. if ( minDistanceSquare > distanceSquare ) { minDistanceSquare = distanceSquare; boxTrans = vcc; } } } } // Translate tgt atoms boxTrans.Neg(); tgtIn.Translate( boxTrans, firstAtom, lastAtom ); // Save new ref positions int i3 = firstAtom * 3; std::copy( tgtIn.xAddress()+i3, tgtIn.xAddress()+(lastAtom*3), refIn.xAddress()+i3 ); } // END loop over atom pairs }
SpritePolygonTest4::SpritePolygonTest4(){ /* 18, 48 33.500000, 73.500000 27.500000, 73.500000 16.500000, 62.500000 30.500000, 44.500000 54.500000, 44.500000 51.500000, 73.500000 60.500000, 87.500000 26.500000, 80.500000 24.500000, 96.500000 57.500000, 108.500000 36.500000, 113.500000 48.500000, 114.500000 36.500000, 114.500000 27.500000, 108.500000 68.500000, 57.500000 57.500000, 73.500000 56.500000, 4.500000 28.500000, 4.500000 0, 1, 2, 3, 0, 2, 4, 0, 3, 5, 0, 4, 5, 6, 0, 0, 6, 7, 8, 7, 6, 6, 9, 8, 9, 10, 8, 9, 11, 10, 11, 12, 10, 8, 10, 13, 14, 5, 4, 15, 5, 14, 4, 3, 16, 3, 17, 16, 0.394118, 0.392562 0.323529, 0.392562 0.194118, 0.483471 0.358824, 0.632231 0.641176, 0.632231 0.605882, 0.392562 0.711765, 0.276859 0.311765, 0.334711 0.288235, 0.202479 0.676471, 0.103306 0.429412, 0.061983 0.570588, 0.053719 0.429412, 0.053719 0.323529, 0.103306 0.805882, 0.524793 0.676471, 0.392562 0.664706, 0.962810 0.335294, 0.962810 */ Vec3 poss[] = {Vec3(33.500000, 73.500000,0), Vec3(27.500000, 73.500000,0), Vec3(16.500000, 62.500000,0), Vec3(30.500000, 44.500000,0), Vec3(54.500000, 44.500000,0), Vec3(51.500000, 73.500000,0), Vec3(60.500000, 87.500000,0), Vec3(26.500000, 80.500000,0), Vec3(24.500000, 96.500000,0), Vec3(57.500000, 108.500000,0), Vec3(36.500000, 113.500000,0), Vec3(48.500000, 114.500000,0), Vec3(36.500000, 114.500000,0), Vec3(27.500000, 108.500000,0), Vec3(68.500000, 57.500000,0), Vec3(57.500000, 73.500000,0), Vec3(56.500000, 4.500000,0), Vec3(28.500000, 4.50000, 0) }; unsigned short idxs[] = {0, 1, 2, 3, 0, 2, 4, 0, 3, 5, 0, 4, 5, 6, 0, 0, 6, 7, 8, 7, 6, 6, 9, 8, 9, 10, 8, 9, 11, 10, 11, 12, 10, 8, 10, 13, 14, 5, 4, 15, 5, 14, 4, 3, 16, 3, 17, 16}; std::vector<unsigned short> indices(idxs, idxs + sizeof idxs / sizeof idxs[0]); Tex2F t2f[] = { Tex2F(0.394118f, 0.392562f), Tex2F(0.323529f, 0.392562f), Tex2F(0.194118f, 0.483471f), Tex2F(0.358824f, 0.632231f), Tex2F(0.641176f, 0.632231f), Tex2F(0.605882f, 0.392562f), Tex2F(0.711765f, 0.276859f), Tex2F(0.311765f, 0.334711f), Tex2F(0.288235f, 0.202479f), Tex2F(0.676471f, 0.103306f), Tex2F(0.429412f, 0.061983f), Tex2F(0.570588f, 0.053719f), Tex2F(0.429412f, 0.053719f), Tex2F(0.323529f, 0.103306f), Tex2F(0.805882f, 0.524793f), Tex2F(0.676471f, 0.392562f), Tex2F(0.664706f, 0.962810f), Tex2F(0.335294f, 0.962810f) }; std::vector<V3F_C4B_T2F> vs; for(int i = 0; i < 18; i++) { V3F_C4B_T2F t = {poss[i],Color4B::WHITE, t2f[i]}; vs.push_back(t); } SpritePolygonCache::getInstance()->removeAllSpritePolygonCache(); _title = "SpritePolygon Creation"; _subtitle = "SpritePolygon::create(\"Images/grossini.png\", vector<V3F_C4B_T2F> v, vector<unsigned short> indices)"; auto s = experimental::SpritePolygon::create(s_pathGrossini, vs, indices); initDefaultSprite(s_pathGrossini, s); }
//------------------------------------------------------------------ void CLam::UpdateFPLaser(float frameTime, CItem* parent) { Vec3 lamPos, dir; if (m_laserActivated) AdjustLaserFPDirection(parent,dir,lamPos); else { // Lam Light lamPos = parent->GetSlotHelperPos(eIGS_FirstPerson,m_laserHelperFP.c_str(),true); Quat lamRot = Quat(parent->GetSlotHelperRotation(eIGS_FirstPerson,m_laserHelperFP.c_str(),true)); dir = lamRot.GetColumn1(); } // float len = m_lamparams.laser_range[eIGS_FirstPerson]; dir.Normalize(); const float nearClipPlaneLimit = 10.0f; Vec3 hitPos(0,0,0); float laserLength = 0.0f; float dotScale = 1.0f; { IPhysicalEntity* pSkipEntity = NULL; if(parent->GetOwner()) pSkipEntity = parent->GetOwner()->GetPhysics(); const int objects = ent_all; const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit); ray_hit hit; if (gEnv->pPhysicalWorld->RayWorldIntersection(lamPos, dir*m_lamparams.laser_range[eIGS_FirstPerson], objects, flags, &hit, 1, &pSkipEntity, pSkipEntity?1:0)) { //Clamp distance below near clip plane limits, if not dot will be overdrawn during rasterization if(hit.dist>nearClipPlaneLimit) { laserLength = nearClipPlaneLimit; m_lastLaserHitPt = lamPos + (nearClipPlaneLimit*dir); } else { laserLength = hit.dist; m_lastLaserHitPt = hit.pt; } m_lastLaserHitSolid = true; if(parent->GetOwnerActor() && parent->GetOwnerActor()->GetActorParams()) dotScale *= max(0.3f,parent->GetOwnerActor()->GetActorParams()->viewFoVScale); } else { m_lastLaserHitSolid = false; m_lastLaserHitPt = lamPos - (dir*3.0f); laserLength = 3.0f; } hitPos = m_lastLaserHitPt; if(g_pGameCVars->i_debug_projectiles!=0) gEnv->pRenderer->GetIRenderAuxGeom()->DrawSphere(hitPos, 0.2f, ColorB(255,0,0)); } if (m_laserActivated && m_dotEffectSlot >= 0) { Matrix34 worldMatrix = GetEntity()->GetWorldTM(); if(laserLength<=0.7f) hitPos = lamPos+(0.7f*dir); CWeapon* pWep = static_cast<CWeapon*>(parent->GetIWeapon()); if(pWep && pWep->IsWeaponLowered()) { hitPos = lamPos+(2.0f*dir); laserLength = 2.0f; } if(laserLength<=2.0f) dotScale *= min(1.0f,(0.35f + ((laserLength-0.7f)*0.5f))); IEntity* pDotEntity = m_pEntitySystem->GetEntity(m_pLaserEntityId); if(pDotEntity) { Matrix34 finalMatrix = Matrix34::CreateTranslationMat(hitPos-(0.2f*dir)); pDotEntity->SetWorldTM(finalMatrix); Matrix34 localScale = Matrix34::CreateIdentity(); localScale.SetScale(Vec3(dotScale,dotScale,dotScale)); pDotEntity->SetSlotLocalTM(m_dotEffectSlot,localScale); } } if (m_laserActivated || m_lightActivated) { float laserAIRange = m_laserActivated ? laserLength : 0.0f; float lightAIRange = m_lightActivated ? min(laserLength, m_lamparams.light_range[eIGS_FirstPerson] * 1.5f) : 0.0f; UpdateAILightAndLaser(lamPos, dir, lightAIRange, m_lamparams.light_fov[eIGS_FirstPerson], laserAIRange); } }
Vec3 Camera::right() const { return Vec3(glm::inverse(orientaion()) * Vec4(1, 0, 0, 1)); }
void MeshParameterization::GenerateTriangleTexelData() { #if ENABLE_DEBUG_DEGENERATES map< float, blah > s_DegenerateList; #endif //Generate texel data per triangle const float uIncrement = 1.f/(float)m_TexSize; const float vIncrement = 1.f/(float)m_TexSize; const float uHalfIncrement = uIncrement*.5f; const float vHalfIncrement = vIncrement*.5f; ParameterizationVertex * p0; ParameterizationVertex * p1; ParameterizationVertex * p2; //0 is smallest y value //1 is smallest x value that's not 0 TriangleTextureMapping toAdd; Vec3 barycentric; float u; float uMax; for( int i = 0; i < (int)m_Faces->size(); i++ ) { TriangleFace &tri = (*m_Faces)[ i ]; bool DangerTriangle = false; //get verts p0 = &(*m_CollapsedMesh)[ tri.index[ 0 ] ]; p1 = &(*m_CollapsedMesh)[ tri.index[ 1 ] ]; p2 = &(*m_CollapsedMesh)[ tri.index[ 2 ] ]; NormalizeUV( p1->generatedU ); NormalizeUV( p1->generatedV ); NormalizeUV( p2->generatedU ); NormalizeUV( p2->generatedV ); NormalizeUV( p0->generatedU ); NormalizeUV( p0->generatedV ); if( p0->generatedV > p1->generatedV ) { SwapPointers( &p0, &p1 ); } if( p0->generatedV > p2->generatedV ) { SwapPointers( &p0, &p2 ); } if( p1->generatedU > p2->generatedU ) { SwapPointers( &p1, &p2 ); } //find slopes float slope1, slope2, slope3, slope4; bool undefinedSlope[4]; undefinedSlope[0] = false; undefinedSlope[1] = false; undefinedSlope[2] = false; undefinedSlope[3] = false; if( fabs( p0->generatedV - p1->generatedV ) <= EPSILON_ZERO ) { undefinedSlope[0] = true; } if( fabs( p0->generatedV - p2->generatedV ) <= EPSILON_ZERO ) { undefinedSlope[1] = true; } if( fabs( p1->generatedV - p2->generatedV ) <= EPSILON_ZERO ) { undefinedSlope[2] = true; } if( fabs( p2->generatedV - p1->generatedV ) <= EPSILON_ZERO ) { undefinedSlope[3] = true; } slope1 = ( p0->generatedU - p1->generatedU )/(p0->generatedV - p1->generatedV ); slope2 = ( p0->generatedU - p2->generatedU )/(p0->generatedV - p2->generatedV ); slope3 = ( p1->generatedU - p2->generatedU )/(p1->generatedV - p2->generatedV ); slope4 = ( p2->generatedU - p1->generatedU )/(p2->generatedV - p1->generatedV ); float maxV = ( p1->generatedV > p2->generatedV ) ? p1->generatedV : p2->generatedV; float maxU = ( p0->generatedU > p2->generatedU ) ? p0->generatedU : p2->generatedU; maxU += uIncrement; maxV += vHalfIncrement; for( float v = p0->generatedV - vHalfIncrement; v <= maxV ; v += vIncrement ) { if( p1->generatedV >= v && p2->generatedV >= v ) { //find endpoints of scanline u = undefinedSlope[0] ? p1->generatedU : p1->generatedU + slope1*( v - p1->generatedV ) - uHalfIncrement; uMax = undefinedSlope[1] ? p2->generatedU : p2->generatedU + slope2*( v - p2->generatedV ) + uHalfIncrement; } else if( p2->generatedV <= v ) { //find endpoints of scanline u = undefinedSlope[0] ? p1->generatedU : p1->generatedU + slope1*( v - p1->generatedV )- uHalfIncrement; uMax = undefinedSlope[3] ? p2->generatedU : p1->generatedU + slope4*( v - p1->generatedV ) + uHalfIncrement; } else // p1->v is smaller than v, we're need a new edge { //find endpoints of scanline u = undefinedSlope[2] ? p1->generatedU : p2->generatedU + slope3*( v - p2->generatedV ) - uHalfIncrement; uMax = undefinedSlope[1] ? p2->generatedU : p2->generatedU + slope2*( v - p2->generatedV ) + uHalfIncrement; } if( u > uMax ){ float temp = u; u = uMax; uMax = temp; } uMax = min( uMax, maxU ); float umin = min( p1->generatedU, p0->generatedU - uIncrement); u = max( u, umin); for( ; u <= uMax; u+= uIncrement ) { //we have u and v, get barycentric: //check if slope will be undefined float qX, qY; float slopeBC, b2, b1, slope; float slopeDenom = u - p0->generatedU; float slopeDenom2 = p1->generatedU - p2->generatedU; if( slopeDenom == 0 && slopeDenom2 != 0) { //vertical line, we know x coordinate slopeBC = ( p1->generatedV - p2->generatedV )/( p1->generatedU - p2->generatedU ); b2 = p1->generatedV - slopeBC*p1->generatedU; //solve for y with known x coordinate qX = p0->generatedU; qY = slopeBC*qX + b2; }else if( slopeDenom2 != 0 && slopeDenom != 0 ) { slope = ( v - p0->generatedV )/slopeDenom; //find other slope, will never be undefined slopeBC = ( p1->generatedV - p2->generatedV )/( p1->generatedU - p2->generatedU ); //now solve for intersect b1 = v - slope*u; b2 = p1->generatedV - slopeBC*p1->generatedU; qX = ( b1 - b2 )/(slopeBC - slope); qY = slope*qX + b1; //now find length for bary }else if( slopeDenom2 == 0 && slopeDenom != 0 ) { slope = ( v - p0->generatedV )/slopeDenom; //now solve for intersect b1 = v - slope*u; qX = p2->generatedU; qY = slope*qX + b1; //now find length for bary }else //both equal 0 { //this should never happen! OutputDebugString("Slopes of two triangle sides are both zero!!!\n"); qX = p2->generatedU; qY = p2->generatedV; } barycentric.z = Vec2Length( p1->generatedU - qX, p1->generatedV - qY ); barycentric.y = Vec2Length( p2->generatedU - qX, p2->generatedV - qY ); //now find t to balance these out at q on p float ratio = Vec2Length( qX - u, qY - v ) /Vec2Length( u - p0->generatedU, v - p0->generatedV); barycentric.x = ( barycentric.y + barycentric.z )*ratio; float normalize = barycentric.x + barycentric.y + barycentric.z; if( normalize != 0 ) { barycentric.x /= normalize; barycentric.y /= normalize; barycentric.z /= normalize; toAdd.localSpaceCoord = p0->originalPosition*barycentric.x + p1->originalPosition*barycentric.y + p2->originalPosition*barycentric.z; if( toAdd.localSpaceCoord.x != toAdd.localSpaceCoord.x ) { DangerTriangle = true; //OutputDebugString( "DANGER WILL ROBINSON\n"); } toAdd.localNormal = p0->normal*barycentric.x + p1->normal*barycentric.y + p2->normal*barycentric.z; toAdd.u = (int)( u*(float)m_TexSize ); toAdd.v = (int)( v*(float)m_TexSize ); if( toAdd.localSpaceCoord.x == toAdd.localSpaceCoord.x && toAdd.u >= 0 && toAdd.u < m_TexSize && toAdd.v >= 0 && toAdd.v < m_TexSize ) { tri.m_Pixels.push_back( toAdd ); } } } static int numcont = 0; numcont++; if( DangerTriangle && numcont < 200 ) { ADDLINEPARAMS LineParam; static CHashString h(_T("none")); LineParam.name = &h; LineParam.blue = 0; LineParam.green = 0; LineParam.red = 255; LineParam.start = p0->originalPosition; LineParam.end = p1->originalPosition; //static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID(); //EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam ); LineParam.start = p0->originalPosition; LineParam.end = p2->originalPosition; //EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam ); LineParam.start = p2->originalPosition; LineParam.end = p1->originalPosition; //EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam ); } } //test code #if ENABLE_DEBUG_DEGENERATES Vec3 edge1 = Vec3( p0->generatedU, p0->generatedV, 0 ) - Vec3( p1->generatedU, p1->generatedV, 0 ); Vec3 edge2 = Vec3( p0->generatedU, p0->generatedV, 0 ) - Vec3( p2->generatedU, p2->generatedV, 0 ); float lengthA = edge1.Length(); float lengthB = (Vec3( p1->generatedU, p1->generatedV, 0 ) - Vec3( p2->generatedU, p2->generatedV, 0 )).Length(); float lengthC = edge2.Length(); float halfPerimeter = (lengthA + lengthB + lengthC)*.500f; float area = halfPerimeter*( halfPerimeter - lengthA )*(halfPerimeter - lengthB )*(halfPerimeter - lengthC); area = sqrt( area ); float numPixels = (float)tri.m_Pixels.size(); edge1.Normalize(); edge2.Normalize(); float flatTriangle = edge2.Dot( edge1 ); //if( fabs( flatTriangle ) < .7f) { area *= (float)(m_TexSize*m_TexSize); float areaRatio = numPixels/area; if( areaRatio < .8f ) //half the uv pixels aren't generate?!#! { blah ref; ref.area = area; ref.pixels = (int)numPixels; ref.index = i; s_DegenerateList.insert( pair< float, blah >( numPixels, ref ) ); } } #endif if( tri.m_Pixels.size() < 2) { //something wrong here //OutputDebugString("Degenerate Triangle\n"); //OutputVector( p0->originalPosition, "p0" ); //OutputVector( p1->originalPosition, "p1" ); //OutputVector( p2->originalPosition, "p2" ); //int a = 0; } } #if ENABLE_DEBUG_DEGENERATES static char buf[1024]; for( map< float, blah >::iterator iter = s_DegenerateList.begin(); iter != s_DegenerateList.end(); ++iter ) { blah &ref = iter->second; TriangleFace &tri = (*m_Faces)[ ref.index ]; //get verts p0 = &(*m_CollapsedMesh)[ tri.index[ 0 ] ]; p1 = &(*m_CollapsedMesh)[ tri.index[ 1 ] ]; p2 = &(*m_CollapsedMesh)[ tri.index[ 2 ] ]; //sprintf( buf, "Degenerate Triangle with area: %f, pixels: %d, index: %d \n", ref.area, ref.pixels, ref.index ); //OutputDebugString( buf ); //OutputVector( p0->originalPosition, "p0" ); //OutputVector( p1->originalPosition, "p1" ); //OutputVector( p2->originalPosition, "p2" ); ADDLINEPARAMS LineParam; static CHashString h(_T("none")); LineParam.name = &h; LineParam.blue = 0; LineParam.green = 0; LineParam.red = 255; LineParam.start = p0->originalPosition; LineParam.end = p1->originalPosition; static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID(); EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam ); LineParam.start = p0->originalPosition; LineParam.end = p2->originalPosition; static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID(); EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam ); LineParam.start = p2->originalPosition; LineParam.end = p1->originalPosition; static DWORD msgHash_AddLine = CHashString(_T("AddLine")).GetUniqueID(); EngineGetToolBox()->SendMessage(msgHash_AddLine,sizeof(LineParam), &LineParam ); } #endif }
//------------------------------------------------------------------------- void CLam::AttachLAMLight(bool attach, CItem* pLightAttach, eGeometrySlot slot) { //GameWarning("CLam::AttachLight"); int id = (slot==eIGS_FirstPerson) ? 0 : 1; if (attach) { if (m_lamparams.light_range[id] == 0.f) return; Vec3 color = m_lamparams.light_color[id] * m_lamparams.light_diffuse_mul[id]; float specular = 1.0f/m_lamparams.light_diffuse_mul[id]; string helper; Vec3 dir(-1,0,0); Vec3 localOffset(0.0f,0.0f,0.0f); if (this != pLightAttach) { SAccessoryParams *params = pLightAttach->GetAccessoryParams(GetEntity()->GetClass()->GetName()); if (!params) return; helper = params->attach_helper.c_str(); if(slot==eIGS_FirstPerson) helper.append("_light"); //Assets don't have same orientation for pistol/rifle.. 8/ dir = (m_lamparams.isLamRifle && id==0) ? Vec3(-0.1f,-1.0f,0.0f) : Vec3(-1.0f,-0.1f,0.0f); dir.Normalize(); } bool fakeLight = false; bool castShadows = false; //Some MP/SP restrictions for lights IRenderNode *pCasterException = NULL; if(CActor *pOwner = pLightAttach->GetOwnerActor()) { if(gEnv->bMultiplayer) { if(!pOwner->IsClient()) fakeLight = true; else castShadows = true; } else { if(pOwner->IsPlayer()) castShadows = true; //castShadows = false; //Not for now } if(castShadows) { if(IEntityRenderProxy* pRenderProxy = static_cast<IEntityRenderProxy*>(pOwner->GetEntity()->GetProxy(ENTITY_PROXY_RENDER))) pCasterException = pRenderProxy->GetRenderNode(); } } m_lightID[id] = pLightAttach->AttachLightEx(slot, 0, true, fakeLight, castShadows, pCasterException, m_lamparams.light_range[id], color, specular, m_lamparams.light_texture[id], m_lamparams.light_fov[id], helper.c_str(), localOffset, dir, m_lamparams.light_material[id].c_str(), m_lamparams.light_hdr_dyn[id]); if (m_lightID[id]) ++s_lightCount; // sounds pLightAttach->PlayAction(g_pItemStrings->enable_light); if (m_lightSoundId == INVALID_SOUNDID) m_lightSoundId = pLightAttach->PlayAction(g_pItemStrings->use_light); //Detach the non-needed light uint8 other = id^1; if (m_lightID[other]) { pLightAttach->AttachLightEx(other, m_lightID[other], false, true), m_lightID[other] = 0; --s_lightCount; } } else { if (m_lightID[id]) { pLightAttach->AttachLightEx(slot, m_lightID[id], false, true); m_lightID[id] = 0; --s_lightCount; PlayAction(g_pItemStrings->disable_light); StopSound(m_lightSoundId); m_lightSoundId = INVALID_SOUNDID; } } //GameWarning("Global light count = %d", s_lightCount); }
#include "utils.hpp" /* ************************************************************************ * Testing suite for BBox. ************************************************************************ */ TEST_CASE("bbox") { // Test for the first constructor SECTION("constructor_1") { BBox bb; REQUIRE(bb.min == Vec3(std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity(), std::numeric_limits<float>::infinity())); REQUIRE(bb.max == Vec3(-std::numeric_limits<float>::infinity(), -std::numeric_limits<float>::infinity(), -std::numeric_limits<float>::infinity())); } // Test for the second constructor SECTION("constructor_2") { BBox bb(Vec3(1.0, -2.5, 0.5), Vec3(8.0, 7.25, 2.0)); REQUIRE(bb.min == Vec3(1.0, -2.5, 0.5)); REQUIRE(bb.max == Vec3(8.0, 7.25, 2.0)); } // Test for the add operator SECTION("add") { BBox bb1(Vec3(1.0, -2.5, 0.5), Vec3(8.0, 7.25, 2.0));
/* * Loader for OBJ models */ int LoadOBJ(string filename, VertexBuffer* vbo) { ifstream file(filename.c_str(), ios::in | ios::binary); // not binary --> size gets reported incorrectly if(!file) return 1; //get filesize streamsize size = 0; if(file.seekg(0, ios::end).good()) size = file.tellg(); if(file.seekg(0, ios::beg).good()) size -= file.tellg(); vector<char> buffer = vector<char>(); //read contents of the file into the vector buffer.resize(size_t(size)); if(size > 0) file.read((char*)(&buffer[0]), size); file.close(); string str = ""; for(unsigned int i = 0; i < buffer.size(); ++i) str += buffer[i]; vector<string> lines = vector<string>(); unsigned int line_finder_pos = 0; vector<string> vertices = vector<string>(); vector<string> normals = vector<string>(); vector<string> texcoords = vector<string>(); vector<string> triangles = vector<string>(); while (line_finder_pos < str.length()) { char c = str[line_finder_pos]; if (c == '\n' || c == '\r') line_finder_pos++; else { int next_a = str.find('\n', line_finder_pos); int next_b = str.find('\r', line_finder_pos); if (next_a != -1 || next_b != -1) { int next = next_a == -1 ? next_b : next_b == -1 ? next_a : min(next_a, next_b); lines.push_back(str.substr(line_finder_pos, next - line_finder_pos)); line_finder_pos = next + 1; } else { lines.push_back(str.substr(line_finder_pos)); line_finder_pos = str.length(); } } } for(unsigned int line_num = 0; line_num < lines.size(); ++line_num) { string line = lines[line_num]; switch ((char)line[0]) { case 'v': switch ((char)line[1]) { case 't': texcoords.push_back(line.substr(line.find(' ', 0) + 1)); break; case 'n': normals.push_back(line.substr(line.find(' ', 0) + 1)); break; default: vertices.push_back(line.substr(line.find(' ', 0) + 1)); break; } break; case 'f': triangles.push_back(line.substr(line.find(' ', 0) + 1)); break; default: break; // entry doesn't matter, so don't try to handle it } } vector<Vec3> xyz = vector<Vec3>(), uv = vector<Vec3>(), nxyz = vector<Vec3>(); float x, y, z, u, v, nx, ny, nz; unsigned int i; for (i = 0; i < vertices.size(); ++i) { string line = vertices[i]; int start = 0, end = line.find(' ', start); x = (float)atof(line.substr(start, end - start).c_str()); start = end + 1; end = line.find(' ', start); end = end != -1 ? end : line.length(); y = (float)atof(line.substr(start, end - start).c_str()); start = end + 1; end = line.find(' ', start); end = end != -1 ? end : line.length(); z = (float)atof(line.substr(start, end - start).c_str()); xyz.push_back(Vec3(x, y, z)); } for (i = 0; i < texcoords.size(); ++i) { string line = texcoords[i]; int start = 0, end = line.find(' ', start); u = (float)atof(line.substr(start, end - start).c_str()); start = end + 1; end = line.find(' ', start); end = end != -1 ? end : line.length(); v = (float)atof(line.substr(start, end - start).c_str()); uv.push_back(Vec3(u, v, 0.0f)); } for (i = 0; i < normals.size(); ++i) { string line = normals[i]; int start = 0, end = line.find(' ', start); nx = (float)atof(line.substr(start, end - start).c_str()); start = end + 1; end = line.find(' ', start); end = end != -1 ? end : line.length(); ny = (float)atof(line.substr(start, end - start).c_str()); start = end + 1; end = line.find(' ', start); end = end != -1 ? end : line.length(); nz = (float)atof(line.substr(start, end - start).c_str()); nxyz.push_back(Vec3(nx, ny, nz)); } int xyz_index, uv_index, n_index; vbo->SetAllocatedSize(triangles.size() * 3); for (i = 0; i < triangles.size(); ++i) { string line = triangles[i]; int start = 0, end = line.find('/', start); xyz_index = atoi(line.substr(start, end - start).c_str()) - 1; start = end + 1; end = line.find('/', start); end = end != -1 ? end : line.length(); uv_index = atoi(line.substr(start, end - start).c_str()) - 1; start = end + 1; end = line.find(' ', start); end = end != -1 ? end : line.length(); n_index = atoi(line.substr(start, end - start).c_str()) - 1; VTNTT v_a = VTNTT(xyz[xyz_index], uv[uv_index], nxyz[n_index]); start = end + 1; end = line.find('/', start); end = end != -1 ? end : line.length(); xyz_index = atoi(line.substr(start, end - start).c_str()) - 1; start = end + 1; end = line.find('/', start); end = end != -1 ? end : line.length(); uv_index = atoi(line.substr(start, end - start).c_str()) - 1; start = end + 1; end = line.find(' ', start); end = end != -1 ? end : line.length(); n_index = atoi(line.substr(start, end - start).c_str()) - 1; VTNTT v_b = VTNTT(xyz[xyz_index], uv[uv_index], nxyz[n_index]); start = end + 1; end = line.find('/', start); end = end != -1 ? end : line.length(); xyz_index = atoi(line.substr(start, end - start).c_str()) - 1; start = end + 1; end = line.find('/', start); end = end != -1 ? end : line.length(); uv_index = atoi(line.substr(start, end - start).c_str()) - 1; start = end + 1; end = line.find(' ', start); end = end != -1 ? end : line.length(); n_index = atoi(line.substr(start, end - start).c_str()) - 1; VTNTT v_c = VTNTT(xyz[xyz_index], uv[uv_index], nxyz[n_index]); AddTriangleVertexInfo(vbo, v_a, v_b, v_c); } return 0; }
Vec3 Ray::pointAtDistance(float d) { return Vec3(Ray::origin.x + (Ray::direction.x*d), Ray::origin.y + (Ray::direction.y*d), Ray::origin.z + (Ray::direction.z*d)); }
OpenSteer::Vec3 OpenSteer::Color::convertToVec3() const { return Vec3( r_, g_, b_ ); }
Vec3 Node::getPosition3D() const { return Vec3(_position.x, _position.y, _positionZ); }
Fence(const Vec3 &pos, const Size<double> &size, const double height) : height(height) { double w = size.width / 2, h = size.height / 2; std::vector<Vec3> list = { Vec3(w, 0, -h),Vec3(-w, 0, -h), Vec3(-w, 0, h), Vec3(w, 0, h) }; double c = 0; for (auto &_pos : list) { VERTEX3D vertex; vertex.pos = pos + _pos; vertex.dif = Color(1); vertex.spc = Color(0); vertex.u = static_cast<double>(c), vertex.v = 1; vertices.emplace_back(vertex); vertex.pos += (VECTOR)Vec3(0, height, 0); vertex.u = static_cast<double>(c), vertex.v = 0; vertices.emplace_back(vertex); c += 1.0 / 4.0; } auto v1 = *(vertices.begin() + 0); auto v2 = *(vertices.begin() + 1); v1.u = v2.u = c; vertices.emplace_back(v1); vertices.emplace_back(v2); /* for (const auto i : Rep(vertices.size() / 2 - 1)) { auto vertex = vertices[i * 4 + 2]; vertex.u = 0, vertex.v = 1; vertices.insert(vertices.begin() + (i * 4 + 2 + 0), vertex); vertex = vertices[i * 4 + 2 + 1]; vertex.u = 0, vertex.v = 0; vertices.insert(vertices.begin() + (i * 4 + 2 + 1), vertex); } */ }
Fence(const Size<double> &size, const double height) { *this = Fence(Vec3(0), size, height); }
// ax + by + cz + d = 0 Plane::Plane(Real a, Real b, Real c, Real d) : mNormal(Vec3(a, b, c)) , mConstant(-d) // ax + by + cz = -d { }
/* * Loader for AAM models */ int LoadAAM(string filename, VertexBuffer* vbo) { ifstream file(filename.c_str(), ios::in | ios::binary); if(!file) return 1; // loading the compressed form of the data vector<Vec3> vertices = vector<Vec3>(); vector<Vec3> texcoords = vector<Vec3>(); vector<Vec3> normals = vector<Vec3>(); unsigned int vertex_count = ReadUInt32(file); for(unsigned int i = 0; i < vertex_count; ++i) { float x = ReadSingle(file); float y = ReadSingle(file); float z = ReadSingle(file); vertices.push_back(Vec3(x, y, z)); } unsigned int texcoord_count = ReadUInt32(file); for(unsigned int i = 0; i < texcoord_count; ++i) { float u = ReadSingle(file); float v = ReadSingle(file); texcoords.push_back(Vec3(u, v, 0)); // third texcoord always 0 } unsigned int normal_count = ReadUInt32(file); for(unsigned int i = 0; i < normal_count; ++i) { float x = ReadSingle(file); float y = ReadSingle(file); float z = ReadSingle(file); normals.push_back(Vec3(x, y, z)); } // load and apply the decompression indices unsigned int vinfo_count = ReadUInt32(file); VTNTT verts[3]; int target_vert = 0; vbo->SetAllocatedSize(vinfo_count); for(unsigned int i = 0; i < vinfo_count; ++i) { unsigned int x_index = ReadUInt32(file); unsigned int uv_index = ReadUInt32(file); unsigned int n_index = ReadUInt32(file); verts[target_vert++] = VTNTT(vertices[x_index], texcoords[uv_index], normals[n_index]); if(target_vert == 3) { AddTriangleVertexInfo(vbo, verts[0], verts[1], verts[2]); target_vert = 0; } } file.close(); // success! return 0; }
REGISTER_MESSAGE_HANDLER(GetCache, GetCache, MeshParameterization); REGISTER_MESSAGE_HANDLER(SetCache, SetCache, MeshParameterization); REGISTER_MESSAGE_HANDLER(GetCollapsedMesh, OnGetCollapsedMesh, MeshParameterization); REGISTER_MESSAGE_HANDLER(GetTriangleFaces, OnGetTriangleFaces, MeshParameterization); REGISTER_MESSAGE_HANDLER(GetMeshTransform, OnGetMeshTransform, MeshParameterization); REGISTER_MESSAGE_HANDLER(GetMeshInverseTransform, OnGetMeshInverseTransform, MeshParameterization); REGISTER_MESSAGE_HANDLER(GetAABB, OnGetAABB, MeshParameterization); REGISTER_MESSAGE_HANDLER(GenerateBounds, OnGenerateBounds, MeshParameterization); REGISTER_MESSAGE_HANDLER(IntersectRayTriangle, OnIntersectRayTriangle, MeshParameterization); REGISTER_MESSAGE_HANDLER(GenerateTriangleTexelData, OnGenerateTriangleTexelData, MeshParameterization); REGISTER_MESSAGE_HANDLER(GetBaseColorAtTriangleIntersection, OnGetBaseColorAtTriangleIntersection, MeshParameterization); REGISTER_MESSAGE_HANDLER(SetNoClone, OnSetNoClone, MeshParameterization); //values for non-class specific callback static Ray mp_Ray(Vec3(0,0,0), Vec3(0,0,0)); static double mp_T; static double mp_U; static double mp_V; static bool mp_Intersected = false; static MeshParameterization * mp_MeshP = NULL; static int mp_TriIndex; struct paramVertex { float x; float y; float z; float nx; float ny; float nz;
/* * Loader for AAK files */ int LoadAAK(string filename, vector<MaterialModelPair>& material_model_pairs, vector<string>& material_names, Skeleton*& skeleton) { ifstream file(filename.c_str(), ios::in | ios::binary); if(!file) return 1; unsigned int materials_count = ReadUInt32(file); for(unsigned int i = 0; i < materials_count; ++i) { unsigned int mat_name_len = ReadByte(file); string mat_name = ""; for(unsigned int j = 0; j < mat_name_len; ++j) mat_name += ReadByte(file); material_names.push_back(mat_name); VertexBuffer* vbo = new VertexBuffer(Triangles); MaterialModelPair mmp = MaterialModelPair(); mmp.material_index = i; mmp.vbo = vbo; unsigned int vinfo_count = ReadUInt32(file); int target = 0; SkinVInfo tri[3]; vbo->SetAllocatedSize(vinfo_count); for(unsigned int j = 0; j < vinfo_count; ++j) { float x = ReadSingle(file); float y = ReadSingle(file); float z = ReadSingle(file); float u = ReadSingle(file); float v = ReadSingle(file); float nx = ReadSingle(file); float ny = ReadSingle(file); float nz = ReadSingle(file); unsigned char indices[4]; unsigned char weights[4]; for(int k = 0; k < 4; ++k) { indices[k] = ReadByte(file); weights[k] = ReadByte(file); } tri[target++] = SkinVInfo(Vec3(x, y, z), Vec3(u, v, 0.0f), Vec3(nx, ny, nz), indices, weights); if(target == 3) { AddTriangleVertexInfo(vbo, tri[0], tri[1], tri[2]); target = 0; } } material_model_pairs.push_back(mmp); } Skeleton* temp_skel; Skeleton::ReadSkeleton(file, &temp_skel); skeleton = temp_skel; return 0; }
HarvestingEffect::HarvestingEffect(EyeCandy* _base, bool* _dead, Vec3* _pos, const HarvestingType _type, const Uint16 _LOD) { if (EC_DEBUG) std::cout << "HarvestingEffect (" << this << ") created (" << type << ")." << std::endl; base = _base; dead = _dead; pos = _pos; effect_center = *pos; type = _type; LOD = base->last_forced_LOD; desired_LOD = _LOD; spawner = NULL; bounds = NULL; mover = NULL; spawner2 = NULL; mover2 = NULL; direction = Vec3(0.0, 0.0, 0.0); switch (type) { case TOOL_BREAK: { // handled in other constructor break; } case RADON_POUCH: { effect_center.y += 0.5; spawner = new FilledSphereSpawner(0.9); mover = new GravityMover(this, &effect_center, 8e9); while ((int)particles.size() < LOD * 50) { const Vec3 coords = spawner->get_new_coords() + effect_center; Vec3 velocity; velocity.randomize(); velocity.normalize(0.8); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 5.25, 0.5, 0.6, 0.7, 0.2, EC_FLARE, LOD, type); p->state = 0; if (!base->push_back_particle(p)) break; } while ((int)particles.size() < LOD * 100) { const Vec3 coords = spawner->get_new_coords() + effect_center; Vec3 velocity; velocity.randomize(); velocity.normalize(1.5); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 4.5, 0.5 + randalpha(0.4), 0.7, 0.6, 0.5, EC_WATER, LOD, type); p->state = 1; if (!base->push_back_particle(p)) break; } break; } case CAVERN_WALL: { effect_center.y += 15.0; spawner = new FilledSphereSpawner(1.0); mover = new ParticleMover(this); while ((int)particles.size() < LOD * 50) { Vec3 coords = spawner->get_new_coords(); coords.y *= 8.0; Vec3 velocity; velocity.randomize(); velocity.normalize(0.2); velocity.y *= 3.0; velocity.y -= 9.0; coords += effect_center; const color_t scalar= randcolor(0.4); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 8.0 + randcoord(12.0), 1.0, scalar + randcolor(0.1), scalar + randcolor(0.1), scalar + randcolor(0.1), EC_SIMPLE, LOD, type); if (!base->push_back_particle(p)) break; } while ((int)particles.size() < LOD * 100) { Vec3 coords = spawner->get_new_coords(); coords.y *= 8.0; Vec3 velocity; velocity.randomize(); velocity.normalize(0.2); velocity.y *= 3.0; velocity.y -= 9.0; coords += effect_center; Particle * p = new HarvestingParticle(this, mover, coords, velocity, 3.0 + randcoord(6.0), 0.4 + randalpha(0.4), 0.2 + randcolor(0.2), 0.2 + randcolor(0.2), 0.2 + randcolor(0.2), EC_WATER, LOD, type); if (!base->push_back_particle(p)) break; } break; } case MOTHER_NATURE: { effect_center.y += 0.2; spawner = new HollowDiscSpawner(0.1); mover = new SpiralMover(this, &effect_center, 18.0, 11.0); while ((int)particles.size() < LOD * 100) { const Vec3 coords = spawner->get_new_coords() + effect_center; Vec3 velocity; velocity.randomize(0.3); velocity.y *= 3; velocity.y += 1.4; Particle * p = new HarvestingParticle(this, mover, coords, velocity, 3.0, 0.2, 1.0, 0.5 + randcolor(0.5), 0.5, EC_TWINFLARE, LOD, type); if (!base->push_back_particle(p)) break; } break; } case QUEEN_OF_NATURE: { effect_center.y += 0.2; spawner = new FilledDiscSpawner(0.5); mover = new ParticleMover(this); while ((int)particles.size() < LOD * 100) { Vec3 coords = spawner->get_new_coords() + effect_center; coords.y += (coord_t)(randfloat(2.0) * randfloat(2.0) * randfloat(2.0)); const Vec3 velocity(0.0, 0.0, 0.0); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 2.0 + randcoord(1.0), 1.0, randcolor(1.0), randcolor(1.0), randcolor(1.0), EC_SHIMMER, LOD, type); if (!base->push_back_particle(p)) break; } break; } case BEES: { spawner = new FilledSphereSpawner(0.75); mover = new GravityMover(this, &effect_center, 8e9); direction.randomize(); direction.y = 0; while ((int)particles.size() < LOD * 4) { const Vec3 coords = spawner->get_new_coords() + effect_center - direction; Vec3 velocity; velocity.randomize(); velocity.normalize(0.75); velocity.x += randfloat(direction.x); velocity.z += randfloat(direction.z); Particle * p = new HarvestingParticle(this, mover, coords, velocity, 0.5 + randfloat(0.25), 1.0, 0.9, 0.7, 0.3, EC_TWINFLARE, LOD, type); if (!base->push_back_particle(p)) break; } break; } case BAG_OF_GOLD: { mover = new GravityMover(this, &effect_center, 2e10); spawner = new HollowSphereSpawner(0.3); for (int i = 0; i < LOD * 60; i++) { Vec3 coords = spawner->get_new_coords(); const Vec3 velocity = coords / 10.0; coords += effect_center; Particle* p = new HarvestingParticle(this, mover, coords, velocity, 1.05, 0.75, randcolor(0.3) + 0.7, randcolor(0.3) + 0.5, randcolor(0.3) + 0.3, EC_FLARE, LOD, type); p->state = 1; if (!base->push_back_particle(p)) break; } Particle* p = new HarvestingParticle(this, mover, effect_center, Vec3(0.0, 0.0, 0.0), 8.0, 1.0, 0.8, 0.7, 0.3, EC_SHIMMER, LOD, type); base->push_back_particle(p); break; } case RARE_STONE: { mover = new ParticleMover(this); spawner = new HollowSphereSpawner(0.3); for (int i = 0; i < LOD * 60; i++) { Vec3 coords = spawner->get_new_coords(); const Vec3 velocity = coords / 10.0; coords += effect_center; Particle* p = new HarvestingParticle(this, mover, coords, velocity, 0.75, 0.05, randcolor(0.3) + 0.7, randcolor(0.3) + 0.5, randcolor(0.3) + 0.3, EC_FLARE, LOD, type); p->state = 1; if (!base->push_back_particle(p)) break; } Particle* p = new HarvestingParticle(this, mover, effect_center, Vec3(0.0, 0.0, 0.0), 7.5, 1.0, 1.0, 1.0, 1.0, EC_VOID, LOD, type); if (!base->push_back_particle(p)) break; p = new HarvestingParticle(this, mover, effect_center, Vec3(0.0, 0.01, 0.0), 7.5, 1.0, 1.0, 1.0, 1.0, EC_VOID, LOD, type); base->push_back_particle(p); break; } } }
bool CCameraTracking::IdentifyObstacle(const Vec3 &vCamDir, const CPlayer &hero) { //check player direction Vec3 newDir = -hero.GetEntity()->GetForwardDir(); newDir.z += vCamDir.z; newDir.normalize(); //compute rotation speed const float fHeroSpeedModifier = clamp(hero.GetActorStats()->speedFlat / 4.0f, 0.3f, 1.0f); const float fNewSpeed = g_pGameCVars->cl_cam_tracking_rotation_speed * m_fFrameTime * fHeroSpeedModifier; m_fSpeed = InterpolateTo(m_fSpeed, fNewSpeed, (fNewSpeed>m_fSpeed)?0.1f:0.3f); //m_fSpeed = (g_fInterpolationRate * m_fSpeed + speed) * g_fInterpolationWeight; //get ray data from camera ray tests ray_hit *pRayHit = m_pCamRayScan->GetHit(eRAY_TOP_RIGHT); if(!pRayHit || pRayHit->dist == 0.0f) pRayHit = m_pCamRayScan->GetHit(eRAY_BOTTOM_RIGHT); bool bHitsRight = (pRayHit && pRayHit->dist > 0.0f); Vec3 dirRight = (pRayHit)?-(m_pCamRayScan->GetRayDir(eRAY_TOP_RIGHT)):Vec3(ZERO); //ray data left side pRayHit = m_pCamRayScan->GetHit(eRAY_TOP_LEFT); if(!pRayHit || pRayHit->dist == 0.0f) pRayHit = m_pCamRayScan->GetHit(eRAY_BOTTOM_LEFT); bool bHitsLeft = (pRayHit && pRayHit->dist > 0.0f); Vec3 dirLeft = (pRayHit)?-(m_pCamRayScan->GetRayDir(eRAY_TOP_LEFT)):Vec3(ZERO); //left or right if(bHitsRight ^ bHitsLeft) { //find rotation direction if(!bHitsRight && !bHitsLeft) { if(m_eLastDirYaw == eTD_LEFT) //continue last direction newDir = dirLeft; else newDir = dirRight; } else if(!bHitsRight) { m_eLastDirYaw = eTD_RIGHT; newDir = dirRight; } else { m_eLastDirYaw = eTD_LEFT; newDir = dirLeft; } //compute yaw/pitch for target position float newYaw = 0.0f; float newPitch = 0.0f; float newDist = 0.0f; CartesianToSpherical(newDir * m_curCamOrientation.m_fDist, newYaw, newPitch, newDist); newYaw += gf_PI; //now interpolate to target //compute delta yaw m_fYawDelta = (newYaw - m_curCamOrientation.m_fYaw) * m_fSpeed; if(m_eLastDirYaw == eTD_RIGHT && m_fYawDelta < 0.0f || m_eLastDirYaw == eTD_LEFT && m_fYawDelta > 0.0f) m_fYawDelta *= -1.0f; } //compute top/bottom rotation //ray data top side pRayHit = m_pCamRayScan->GetHit(eRAY_TOP_CENTER); bool bHitsTop = (pRayHit && pRayHit->dist > 0.0f)?true:false; Vec3 vDirTop = (pRayHit)?-(m_pCamRayScan->GetRayDir(eRAY_TOP_CENTER)):Vec3(ZERO); //ray data bottom side pRayHit = m_pCamRayScan->GetHit(eRAY_BOTTOM_CENTER); bool bHitsBottom = (pRayHit && pRayHit->dist > 0.0f)?true:false; Vec3 vDirBottom = (pRayHit)?-(m_pCamRayScan->GetRayDir(eRAY_BOTTOM_CENTER)):Vec3(ZERO); //top or bottom (if not left or right) if(g_pGameCVars->cl_cam_tracking_allow_pitch && (bHitsTop ^ bHitsBottom) && !(bHitsRight ^ bHitsLeft)) { //find rotation direction if(!bHitsTop && !bHitsBottom) { if(m_eLastDirPitch == eTD_TOP) //continue last direction newDir = vDirTop; else newDir = vDirBottom; } else if(!bHitsBottom) { m_eLastDirPitch = eTD_BOTTOM; newDir = vDirBottom; } else { m_eLastDirPitch = eTD_TOP; newDir = vDirTop; } //compute yaw/pitch for target position float newYaw = 0.0f; float newPitch = 0.0f; float newDist = 0.0f; //newdist (raydist) will be ignored CartesianToSpherical(newDir, newYaw, newPitch, newDist); //compute delta pitch m_fPitchDelta = (newPitch - m_curCamOrientation.m_fPitch) * m_fSpeed * 10.0f; } //if all rays hit - don't bother! //this is a termination condition when the camera is pulled through geometry if(bHitsLeft & bHitsRight & bHitsBottom & bHitsTop) { if(m_bViewCovered) { //if obstacle behind player //if(g_rHit.dist > 0.0f) //this is a strange fix, but it's working better and is much cheaper than a raycast if(fabsf(m_fYawDelta) < 0.01f && fabsf(m_fPitchDelta) > 0.001f) return false; } m_bViewCovered = true; } else m_bViewCovered = false; return true; }
//------------------------------------------------------------------ void CLam::UpdateTPLaser(float frameTime, CItem* parent) { FUNCTION_PROFILER(GetISystem(), PROFILE_GAME); const int frameId = gEnv->pRenderer->GetFrameID(); if (s_lastUpdateFrameId != frameId) { // Check how many LAMs to update this frame. float dt = frameTime; // + s_laserUpdateTimeError; const int n = s_lasers.size(); int nActive = 0; for (int i = 0; i < n; ++i) { if (!s_lasers[i]->IsLaserActivated() && !s_lasers[i]->IsLightActivated()) continue; nActive++; } float updatedPerSecond = (nActive / LASER_UPDATE_TIME) + s_laserUpdateTimeError; int updateCount = (int)floorf(updatedPerSecond * dt); if(dt==0.0f) s_laserUpdateTimeError = 0.0f; else s_laserUpdateTimeError = updatedPerSecond - updateCount/dt; s_curLaser %= n; for (int i = 0, j = 0; i < n && j < updateCount ; ++i) { s_curLaser = (s_curLaser + 1) % n; if (!s_lasers[s_curLaser]->IsLaserActivated() && !s_lasers[s_curLaser]->IsLightActivated()) continue; s_lasers[s_curLaser]->SetAllowUpdate(); ++j; } s_lastUpdateFrameId = frameId; } IEntity* pRootEnt = GetEntity(); if (!pRootEnt) return; IEntity *pLaserEntity = m_pEntitySystem->GetEntity(m_pLaserEntityId); // if(!pLaserEntity) // return; const CCamera& camera = gEnv->pRenderer->GetCamera(); Vec3 lamPos = pRootEnt->GetWorldPos(); //pLaserEntity->GetParent()->GetWorldPos(); Vec3 dir = pRootEnt->GetWorldRotation().GetColumn1(); //pLaserEntity->GetParent()->GetWorldRotation().GetColumn1(); bool charNotVisible = false; float dsg1Scale = 1.0f; //If character not visible, laser is not correctly updated if(parent) { if(CActor* pOwner = parent->GetOwnerActor()) { ICharacterInstance* pCharacter = pOwner->GetEntity()->GetCharacter(0); if(pCharacter && !pCharacter->IsCharacterVisible()) charNotVisible = true; } if(parent->GetEntity()->GetClass()==CItem::sDSG1Class) dsg1Scale = 3.0f; } // if (!pLaserEntity->GetParent()) // return; Vec3 hitPos(0,0,0); float laserLength = 0.0f; // HACK??: Use player movement controller locations, or else the laser // pops all over the place when character out of the screen. CActor *pActor = parent->GetOwnerActor(); if (pActor && (!pActor->IsPlayer() || charNotVisible)) { if (IMovementController* pMC = pActor->GetMovementController()) { SMovementState state; pMC->GetMovementState(state); if(!charNotVisible) lamPos = state.weaponPosition; else { float oldZPos = lamPos.z; lamPos = state.weaponPosition; if(m_lastZPos>0.0f) lamPos.z = m_lastZPos; //Stabilize somehow z position (even if not accurate) else lamPos.z = oldZPos; } const float angleMin = DEG2RAD(3.0f); const float angleMax = DEG2RAD(7.0f); const float thr = cosf(angleMax); float dot = dir.Dot(state.aimDirection); if (dot > thr) { float a = acos_tpl(dot); float u = 1.0f - clamp((a - angleMin) / (angleMax - angleMin), 0.0f, 1.0f); dir = dir + u * (state.aimDirection - dir); dir.Normalize(); } } } if(!charNotVisible) m_lastZPos = lamPos.z; lamPos += (dir*0.10f); if (m_allowUpdate) { m_allowUpdate = false; IPhysicalEntity* pSkipEntity = NULL; if(parent->GetOwner()) pSkipEntity = parent->GetOwner()->GetPhysics(); const float range = m_lamparams.laser_range[eIGS_ThirdPerson]*dsg1Scale; // Use the same flags as the AI system uses for visbility. const int objects = ent_terrain|ent_static|ent_rigid|ent_sleeping_rigid|ent_independent; //ent_living; const int flags = (geom_colltype_ray << rwi_colltype_bit) | rwi_colltype_any | (10 & rwi_pierceability_mask) | (geom_colltype14 << rwi_colltype_bit); ray_hit hit; if (gEnv->pPhysicalWorld->RayWorldIntersection(lamPos, dir*range, objects, flags, &hit, 1, &pSkipEntity, pSkipEntity ? 1 : 0)) { laserLength = hit.dist; m_lastLaserHitPt = hit.pt; m_lastLaserHitSolid = true; } else { m_lastLaserHitSolid = false; m_lastLaserHitPt = lamPos + dir * range; laserLength = range + 0.1f; } // Hit near plane if (dir.Dot(camera.GetViewdir()) < 0.0f) { Plane nearPlane; nearPlane.SetPlane(camera.GetViewdir(), camera.GetPosition()); nearPlane.d -= camera.GetNearPlane()+0.15f; Ray ray(lamPos, dir); Vec3 out; m_lastLaserHitViewPlane = false; if (Intersect::Ray_Plane(ray, nearPlane, out)) { float dist = Distance::Point_Point(lamPos, out); if (dist < laserLength) { laserLength = dist; m_lastLaserHitPt = out; m_lastLaserHitSolid = true; m_lastLaserHitViewPlane = true; } } } hitPos = m_lastLaserHitPt; } else { laserLength = Distance::Point_Point(m_lastLaserHitPt, lamPos); hitPos = lamPos + dir * laserLength; } if (m_smoothLaserLength < 0.0f) m_smoothLaserLength = laserLength; else { if (laserLength < m_smoothLaserLength) m_smoothLaserLength = laserLength; else m_smoothLaserLength += (laserLength - m_smoothLaserLength) * min(1.0f, 10.0f * frameTime); } float laserAIRange = 0.0f; if (m_laserActivated && pLaserEntity) { // Orient the laser towards the point point. Matrix34 parentTMInv; parentTMInv = pRootEnt->GetWorldTM().GetInverted(); Vec3 localDir = parentTMInv.TransformPoint(hitPos); float finalLaserLen = localDir.NormalizeSafe(); Matrix33 rot; rot.SetIdentity(); rot.SetRotationVDir(localDir); pLaserEntity->SetLocalTM(rot); laserAIRange = finalLaserLen; const float assetLength = 2.0f; finalLaserLen = CLAMP(finalLaserLen,0.01f,m_lamparams.laser_max_len*dsg1Scale); float scale = finalLaserLen / assetLength; // Scale the laser based on the distance. if (m_laserEffectSlot >= 0) { Matrix33 scl; scl.SetIdentity(); scl.SetScale(Vec3(1,scale,1)); pLaserEntity->SetSlotLocalTM(m_laserEffectSlot, scl); } if (m_dotEffectSlot >= 0) { if (m_lastLaserHitSolid) { Matrix34 mt = Matrix34::CreateTranslationMat(Vec3(0,finalLaserLen,0)); if(m_lastLaserHitViewPlane) mt.Scale(Vec3(0.2f,0.2f,0.2f)); pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, mt); } else { Matrix34 scaleMatrix; scaleMatrix.SetIdentity(); scaleMatrix.SetScale(Vec3(0.001f,0.001f,0.001f)); pLaserEntity->SetSlotLocalTM(m_dotEffectSlot, scaleMatrix); } } } float lightAIRange = 0.0f; if (m_lightActivated) { float range = clamp(m_smoothLaserLength, 0.5f, m_lamparams.light_range[eIGS_ThirdPerson]); lightAIRange = range * 1.5f; if (m_lightID[eIGS_ThirdPerson] && m_smoothLaserLength > 0.0f) { CItem* pLightEffect = this; if (IItem *pOwnerItem = m_pItemSystem->GetItem(GetParentId())) pLightEffect = (CItem *)pOwnerItem; pLightEffect->SetLightRadius(range, m_lightID[eIGS_ThirdPerson]); } } if (laserAIRange > 0.0001f || lightAIRange > 0.0001f) UpdateAILightAndLaser(lamPos, dir, lightAIRange, m_lamparams.light_fov[eIGS_ThirdPerson], laserAIRange); }
int GameLayerMapBorder::initQuadMap() { if(_isInitQuadMap)return 0; _isInitQuadMap = true; memset(&_sRawQuad, 0, sizeof(_sRawQuad)); QuadVec quad; Size unit = GameRuntime::getInstance()->getMapGridUnitPixelSize(); quad.rb = Vec3(2*unit.width,0,0); quad.rt = Vec3(2*unit.width,unit.height,0); quad.lb = quad.rb + Vec3(-BORDER_WIDTH,0,0); quad.lt = quad.rt + Vec3(-BORDER_WIDTH,0,0); TABLE(r_rb_rt); //// quad.rb = Vec3(2*unit.width,0,0); quad.rt = quad.rb; quad.lb = quad.rb + Vec3(-BORDER_WIDTH,0,0); quad.lt = MathHelper::getRotatePosition(quad.rb, quad.lb, 45); TABLE(r_rb); //// quad.rb = Vec3(unit.width,-unit.width,0); quad.rt = Vec3(2* unit.width,0,0); quad.lb = quad.rb + Vec3(-BORDER_WIDTH,0,0); quad.lb = MathHelper::getRotatePosition(quad.rb,quad.lb,45); quad.lt = quad.rt + Vec3(-BORDER_WIDTH,0,0); quad.lt = MathHelper::getRotatePosition(quad.rt,quad.lt,45); TABLE(rb_r_b); //// quad.rb = Vec3(unit.width,-unit.width,0); quad.rt = quad.rb; quad.lb = quad.rb + Vec3(-BORDER_WIDTH,0,0); quad.lb = MathHelper::getRotatePosition(quad.rb,quad.lb,45); quad.lt = quad.rt + Vec3(0,BORDER_WIDTH,0); TABLE(b_rb); /// quad.rb = Vec3(0,-unit.width,0); quad.rt = Vec3(unit.width,-unit.width,0); quad.lb = quad.rb + Vec3(0,BORDER_WIDTH,0); quad.lt = quad.rt + Vec3(0,BORDER_WIDTH,0); TABLE(b_lb_rb); /// quad.rb = Vec3(0,-unit.width,0); quad.rt = quad.rb ; quad.lb = quad.rb + Vec3(0,BORDER_WIDTH,0); quad.lt = MathHelper::getRotatePosition(quad.rb,quad.lb,45); TABLE(b_lb); /// quad.rb = Vec3(-unit.width,0,0); quad.rt = Vec3(0,-unit.height,0); quad.lb = quad.rb + Vec3(0,BORDER_WIDTH,0); quad.lb = MathHelper::getRotatePosition(quad.rb,quad.lb,45); quad.lt = quad.rt + Vec3(0,BORDER_WIDTH,0); quad.lt = MathHelper::getRotatePosition(quad.rt,quad.lt,45); TABLE(lb_l_b); /// quad.rb = Vec3(-unit.width,0,0); quad.rt = quad.rb; quad.lb = quad.rb + Vec3(0,BORDER_WIDTH,0); quad.lb = MathHelper::getRotatePosition(quad.rb,quad.lb,45); quad.lt = quad.rt + Vec3(BORDER_WIDTH,0,0); TABLE(l_lb); /// quad.rb = Vec3(-unit.width,unit.width,0); quad.rt = Vec3(-unit.width,0,0); quad.lb = quad.rb + Vec3(BORDER_WIDTH,0,0); quad.lt = quad.rt + Vec3(BORDER_WIDTH,0,0); TABLE(l_lb_lt); /// quad.rb = Vec3(-unit.width,unit.width,0); quad.rt = quad.rb; quad.lb = quad.rb + Vec3(BORDER_WIDTH,0,0); quad.lt = MathHelper::getRotatePosition(quad.rb,quad.lb,45); TABLE(l_lt); /// quad.rb = Vec3(0,2*unit.width,0); quad.rt = Vec3(-unit.width,unit.width,0); quad.lb = quad.rb + Vec3(BORDER_WIDTH,0,0); quad.lb = MathHelper::getRotatePosition(quad.rb,quad.lb,45); quad.lt = quad.rt + Vec3(BORDER_WIDTH,0,0); quad.lt = MathHelper::getRotatePosition(quad.rt,quad.lt,45); TABLE(lt_l_t); /// quad.rb = Vec3(0,2*unit.width,0); quad.rt = quad.rb; quad.lb = quad.rb + Vec3(BORDER_WIDTH,0,0); quad.lb = MathHelper::getRotatePosition(quad.rb,quad.lb,45); quad.lt = quad.rt + Vec3(0,-BORDER_WIDTH,0); TABLE(t_lt); /// quad.rb = Vec3(unit.width,2*unit.width,0); quad.rt = Vec3(0,2*unit.width,0); quad.lb = quad.rb + Vec3(0,-BORDER_WIDTH,0); quad.lt = quad.rt + Vec3(0,-BORDER_WIDTH,0); TABLE(t_lt_rt); /// quad.rb = Vec3(unit.width,2*unit.width,0); quad.rt = quad.rb; quad.lb = quad.rb + Vec3(0,-BORDER_WIDTH,0); quad.lt = MathHelper::getRotatePosition(quad.rb,quad.lb,45); TABLE(t_rt); /// quad.rb = Vec3(2*unit.width,unit.width,0); quad.rt = Vec3(unit.width,2*unit.width,0); quad.lb = quad.rb + Vec3(0,-BORDER_WIDTH,0); quad.lb = MathHelper::getRotatePosition(quad.rb,quad.lb,45); quad.lt = quad.rt + Vec3(0,-BORDER_WIDTH,0); quad.lt = MathHelper::getRotatePosition(quad.rt,quad.lt,45); TABLE(rt_r_t); /// quad.rb = Vec3(2*unit.width,unit.width,0); quad.rt = quad.rb; quad.lb = quad.rb + Vec3(0,-BORDER_WIDTH,0); quad.lb = MathHelper::getRotatePosition(quad.rb,quad.lb,45); quad.lt = quad.rt + Vec3(-BORDER_WIDTH,0,0); TABLE(r_rt); /// ////////////// quad.rb = Vec3(unit.width,2*unit.width,0); quad.rt = Vec3(-unit.width,unit.width,0); quad.lb = quad.rb + Vec3(0,-BORDER_WIDTH,0); quad.lt = quad.lb; TABLE(lt_l_t_rt); ///// quad.rb = Vec3(0,2*unit.width,0); quad.rt = Vec3(-unit.width,0,0); quad.lb = quad.rt + Vec3(BORDER_WIDTH,0,0); quad.lt = quad.lb; TABLE(lt_l_t_lb); /// quad.rb = Vec3(2*unit.width,unit.width,0); quad.rt = Vec3(0,2*unit.width,0); quad.lb = quad.rt + Vec3(0,-BORDER_WIDTH,0); quad.lt = quad.lb; TABLE(rt_r_t_lt); ///// quad.rb = Vec3(2*unit.width,0,0); quad.rt = Vec3(unit.width,2*unit.width,0); quad.lb = quad.rb + Vec3(-BORDER_WIDTH,0,0); quad.lt = quad.lb; TABLE(rt_r_t_rb); /// quad.rb = Vec3(-unit.width,0,0); quad.rt = Vec3(unit.width,-unit.width,0); quad.lb = quad.rt + Vec3(0,BORDER_WIDTH,0); quad.lt = quad.lb; TABLE(lb_l_b_rb); ///// quad.rb = Vec3(-unit.width,unit.width,0); quad.rt = Vec3(0,-unit.width,0); quad.lb = quad.rb + Vec3(BORDER_WIDTH,0,0); quad.lt = quad.lb; TABLE(lb_l_b_lt); /// quad.rb = Vec3(0,-unit.width,0); quad.rt = Vec3(2*unit.width,0,0); quad.lb = quad.rb + Vec3(0,BORDER_WIDTH,0); quad.lt = quad.lb; TABLE(rb_r_b_lb); ///// quad.rb = Vec3(unit.width,-unit.width,0); quad.rt = Vec3(2*unit.width,unit.width,0); quad.lb = quad.rt + Vec3(-BORDER_WIDTH,0,0); quad.lt = quad.lb; TABLE(rb_r_b_rt); ///// quad.rb = Vec3(unit.width,2*unit.width,0); quad.rt = Vec3(-unit.width,0,0); quad.lb = quad.rt + Vec3(BORDER_WIDTH,0,0); quad.lt = quad.lb; TABLE(lt_l_t_lb_rt); quad.rb = Vec3(-unit.width,unit.width,0); quad.rt = Vec3(unit.width,-unit.width,0); quad.lb = quad.rb + Vec3(BORDER_WIDTH,0,0); quad.lt = quad.rt + Vec3(0,BORDER_WIDTH,0); TABLE(lb_l_b_lt_rb); quad.rb = Vec3(0,-unit.width,0); quad.rt = Vec3(unit.width*2,unit.width,0); quad.lb = quad.rb + Vec3(0,BORDER_WIDTH,0); quad.lt = quad.rt + Vec3(-BORDER_WIDTH,0,0); TABLE(rb_r_b_lb_rt); quad.rb = Vec3(2*unit.width,0,0); quad.rt = Vec3(0,unit.width*2,0); quad.lb = quad.rb + Vec3(-BORDER_WIDTH,0,0); quad.lt = quad.rt + Vec3(0,-BORDER_WIDTH,0); TABLE(rt_r_t_rb_lt); return 0; }
Vec3 Camera::forward() const { return Vec3(glm::inverse(orientaion()) * Vec4(0, 0, -1, 1)); }
void addVertex(initializer_list<double > pt) { addVertex(Vec3(pt)); }
Vec3 Camera::up() const { return Vec3(glm::inverse(orientaion()) * Vec4(0, 1, 0, 1)); }
/** Sets all start positions depending on the quad graph. The number of * entries needed is defined by the size of the start_transform (though all * entries will be overwritten). * E.g. the karts will be placed as: * 1 \ * 2 +-- row with three karts, each kart is 'sidewards_distance' * 3 / to the right of the previous kart, and * 4 'forwards_distance' behind the previous kart. * 5 The next row starts again with the kart being * 6 'forwards_distance' behind the end of the previous row. * etc. * \param start_transforms A vector sized to the needed number of start * positions. The values will all be overwritten with the * default start positions. * \param karts_per_row How many karts to place in each row. * \param forwards_distance Distance in forward (Z) direction between * each kart. * \param sidewards_distance Distance in sidewards (X) direction between * karts. */ void QuadGraph::setDefaultStartPositions(AlignedArray<btTransform> *start_transforms, unsigned int karts_per_row, float forwards_distance, float sidewards_distance, float upwards_distance) const { // We start just before the start node (which will trigger lap // counting when reached). The first predecessor is the one on // the main driveline. int current_node = m_all_nodes[getStartNode()]->getPredecessor(0); float distance_from_start = 0.1f+forwards_distance; // Maximum distance to left (or right) of centre line const float max_x_dist = 0.5f*(karts_per_row-0.5f)*sidewards_distance; // X position relative to the centre line float x_pos = -max_x_dist + sidewards_distance*0.5f; unsigned int row_number = 0; for(unsigned int i=0; i<(unsigned int)start_transforms->size(); i++) { if (current_node == -1) { (*start_transforms)[i].setOrigin(Vec3(0,0,0)); (*start_transforms)[i].setRotation(btQuaternion(btVector3(0, 1, 0), 0)); } else { // First find on which segment we have to start while(distance_from_start > getNode(current_node).getNodeLength()) { distance_from_start -= getNode(current_node).getNodeLength(); // Only follow the main driveline, i.e. first predecessor current_node = getNode(current_node).getPredecessor(0); } const GraphNode &gn = getNode(current_node); Vec3 center_line = gn.getLowerCenter() - gn.getUpperCenter(); center_line.normalize(); Vec3 horizontal_line = gn[2] - gn[3]; horizontal_line.normalize(); Vec3 start = gn.getUpperCenter() + center_line * distance_from_start + horizontal_line * x_pos; // Add a certain epsilon to the height in case that the // drivelines are beneath the track. (*start_transforms)[i].setOrigin(start+Vec3(0,upwards_distance,0)); (*start_transforms)[i].setRotation( btQuaternion(btVector3(0, 1, 0), gn.getAngleToSuccessor(0))); if(x_pos >= max_x_dist-sidewards_distance*0.5f) { x_pos = -max_x_dist; // Every 2nd row will be pushed sideways by half the distance // between karts, so that a kart can drive between the karts in // the row ahead of it. row_number ++; if(row_number % 2 == 0) x_pos += sidewards_distance*0.5f; } else x_pos += sidewards_distance; distance_from_start += forwards_distance; } } // for i<stk_config->m_max_karts } // setStartPositions
////////////////////////////////////////////////////////////////////// // constructor ////////////////////////////////////////////////////////////////////// WTURBULENCE::WTURBULENCE(int xResSm, int yResSm, int zResSm, int amplify, int noisetype, int init_fire, int init_colors) { // if noise magnitude is below this threshold, its contribution // is negilgible, so stop evaluating new octaves _cullingThreshold = 1e-3; // factor by which to increase the simulation resolution _amplify = amplify; // manually adjust the overall amount of turbulence // DG - RNA-fied _strength = 2.; // add the corresponding octaves of noise _octaves = (int)(log((float)_amplify) / log(2.0f) + 0.5f); // XXX DEBUG/ TODO: int casting correct? - dg // noise resolution _xResBig = _amplify * xResSm; _yResBig = _amplify * yResSm; _zResBig = _amplify * zResSm; _resBig = Vec3Int(_xResBig, _yResBig, _zResBig); _invResBig = Vec3(1.0f/(float)_resBig[0], 1.0f/(float)_resBig[1], 1.0f/(float)_resBig[2]); _slabSizeBig = _xResBig*_yResBig; _totalCellsBig = _slabSizeBig * _zResBig; // original / small resolution _xResSm = xResSm; _yResSm = yResSm; _zResSm = zResSm; _resSm = Vec3Int(xResSm, yResSm, zResSm); _invResSm = Vec3(1.0f/(float)_resSm[0], 1.0f/(float)_resSm[1], 1.0f/(float)_resSm[2] ); _slabSizeSm = _xResSm*_yResSm; _totalCellsSm = _slabSizeSm * _zResSm; // allocate high resolution density field _totalStepsBig = 0; _densityBig = new float[_totalCellsBig]; _densityBigOld = new float[_totalCellsBig]; for(int i = 0; i < _totalCellsBig; i++) { _densityBig[i] = _densityBigOld[i] = 0.; } /* fire */ _flameBig = _fuelBig = _fuelBigOld = NULL; _reactBig = _reactBigOld = NULL; if (init_fire) { initFire(); } /* colors */ _color_rBig = _color_rBigOld = NULL; _color_gBig = _color_gBigOld = NULL; _color_bBig = _color_bBigOld = NULL; if (init_colors) { initColors(0.0f, 0.0f, 0.0f); } // allocate & init texture coordinates _tcU = new float[_totalCellsSm]; _tcV = new float[_totalCellsSm]; _tcW = new float[_totalCellsSm]; _tcTemp = new float[_totalCellsSm]; // map all const float dx = 1.0f/(float)(_resSm[0]); const float dy = 1.0f/(float)(_resSm[1]); const float dz = 1.0f/(float)(_resSm[2]); int index = 0; for (int z = 0; z < _zResSm; z++) for (int y = 0; y < _yResSm; y++) for (int x = 0; x < _xResSm; x++, index++) { _tcU[index] = x*dx; _tcV[index] = y*dy; _tcW[index] = z*dz; _tcTemp[index] = 0.; } // noise tiles _noiseTile = new float[noiseTileSize * noiseTileSize * noiseTileSize]; /* std::string noiseTileFilename = std::string("noise.wavelets"); generateTile_WAVELET(_noiseTile, noiseTileFilename); */ setNoise(noisetype); /* std::string noiseTileFilename = std::string("noise.fft"); generatTile_FFT(_noiseTile, noiseTileFilename); */ }
std::pair<Vec3, Vec3> Plane::Clip(const Vec3& pa, const Vec3& pb) const { if (pa == pb) { auto whichSide = WhichSide(pa); if (whichSide >= 0) { return{ Vec3(FLT_MAX), Vec3(FLT_MAX) }; } else { return{ Vec3(-FLT_MAX), Vec3(-FLT_MAX) }; } } // Get the projection of the segment onto the plane. auto direction = pb - pa; auto ldotv = mNormal.Dot(direction); // Are the line and plane parallel? if (ldotv == 0) // line and plane are parallel and maybe coincident { auto whichSide = WhichSide(pa); if (whichSide > 0) { return{ Vec3(FLT_MAX), Vec3(FLT_MAX) }; } else if (whichSide == 0.f) { return{ pa, pb }; } else { return{ Vec3(-FLT_MAX), Vec3(-FLT_MAX) }; } } // Not parallel so the line intersects. But does the segment intersect? Real t = -Dot(Vec4(pa)) / ldotv; // ldots / ldotv // segment does not intersect if (t < 0 || t > 1){ auto whichSide = WhichSide(pa); if (whichSide >= 0) { return{ Vec3(FLT_MAX), Vec3(FLT_MAX) }; } else { return{ Vec3(-FLT_MAX), Vec3(-FLT_MAX) }; } } auto p = pa + direction * t; if (ldotv > 0) return { p, pb }; else return { pa, p }; }
bool BillBoard::calculateBillbaordTransform() { //Get camera world position auto camera = Camera::getVisitingCamera(); const Mat4& camWorldMat = camera->getNodeToWorldTransform(); //TODO: use math lib to calculate math lib Make it easier to read and maintain if (memcmp(_camWorldMat.m, camWorldMat.m, sizeof(float) * 16) != 0 || memcmp(_mvTransform.m, _modelViewTransform.m, sizeof(float) * 16) != 0 || _modeDirty || true) { //Rotate based on anchor point Vec3 anchorPoint(_anchorPointInPoints.x , _anchorPointInPoints.y , 0.0f); Mat4 localToWorld = _modelViewTransform; localToWorld.translate(anchorPoint); //Decide billboard mode Vec3 camDir; switch (_mode) { case Mode::VIEW_POINT_ORIENTED: camDir.set(localToWorld.m[12] - camWorldMat.m[12], localToWorld.m[13] - camWorldMat.m[13], localToWorld.m[14] - camWorldMat.m[14]); break; case Mode::VIEW_PLANE_ORIENTED: camWorldMat.transformVector(Vec3(0.0f, 0.0f, -1.0f), &camDir); break; default: CCASSERT(false, "invalid billboard mode"); break; } _modeDirty = false; if (camDir.length() < MATH_TOLERANCE) { camDir.set(camWorldMat.m[8], camWorldMat.m[9], camWorldMat.m[10]); } camDir.normalize(); Quaternion rotationQuaternion; this->getNodeToWorldTransform().getRotation(&rotationQuaternion); Mat4 rotationMatrix; rotationMatrix.setIdentity(); Vec3 upAxis(rotationMatrix.m[4],rotationMatrix.m[5],rotationMatrix.m[6]); Vec3 x, y; camWorldMat.transformVector(upAxis, &y); Vec3::cross(camDir, y, &x); x.normalize(); Vec3::cross(x, camDir, &y); y.normalize(); float xlen = sqrtf(localToWorld.m[0] * localToWorld.m[0] + localToWorld.m[1] * localToWorld.m[1] + localToWorld.m[2] * localToWorld.m[2]); float ylen = sqrtf(localToWorld.m[4] * localToWorld.m[4] + localToWorld.m[5] * localToWorld.m[5] + localToWorld.m[6] * localToWorld.m[6]); float zlen = sqrtf(localToWorld.m[8] * localToWorld.m[8] + localToWorld.m[9] * localToWorld.m[9] + localToWorld.m[10] * localToWorld.m[10]); Mat4 billboardTransform; billboardTransform.m[0] = x.x * xlen; billboardTransform.m[1] = x.y * xlen; billboardTransform.m[2] = x.z * xlen; billboardTransform.m[4] = y.x * ylen; billboardTransform.m[5] = y.y * ylen; billboardTransform.m[6] = y.z * ylen; billboardTransform.m[8] = -camDir.x * zlen; billboardTransform.m[9] = -camDir.y * zlen; billboardTransform.m[10] = -camDir.z * zlen; billboardTransform.m[12] = localToWorld.m[12]; billboardTransform.m[13] = localToWorld.m[13]; billboardTransform.m[14] = localToWorld.m[14]; billboardTransform.translate(-anchorPoint); _mvTransform = _modelViewTransform = billboardTransform; _camWorldMat = camWorldMat; return true; } return false; }
// // D3DSkyNode9::VOnRestore - 3rd Edition, Chapter 14, page 500 // HRESULT D3DSkyNode9::VOnRestore(Scene *pScene) { // Call the base class's restore SceneNode::VOnRestore(pScene); m_camera = pScene->GetCamera(); // added post press! m_numVerts = 20; SAFE_RELEASE(m_pVerts); if( FAILED( DXUTGetD3D9Device()->CreateVertexBuffer( m_numVerts*sizeof(D3D9Vertex_ColoredTextured), D3DUSAGE_WRITEONLY, D3D9Vertex_ColoredTextured::FVF, D3DPOOL_MANAGED, &m_pVerts, NULL ) ) ) { return E_FAIL; } // Fill the vertex buffer. We are setting the tu and tv texture // coordinates, which range from 0.0 to 1.0 D3D9Vertex_ColoredTextured* pVertices; if( FAILED( m_pVerts->Lock( 0, 0, (void**)&pVertices, 0 ) ) ) return E_FAIL; // Loop through the grid squares and calc the values // of each index. Each grid square has two triangles: // // A - B // | / | // C - D D3D9Vertex_ColoredTextured skyVerts[4]; D3DCOLOR skyVertColor = 0xffffffff; float dim = 50.0f; skyVerts[0].position = Vec3( dim, dim, dim ); skyVerts[0].color=skyVertColor; skyVerts[0].tu=1; skyVerts[0].tv=0; skyVerts[1].position = Vec3(-dim, dim, dim ); skyVerts[1].color=skyVertColor; skyVerts[1].tu=0; skyVerts[1].tv=0; skyVerts[2].position = Vec3( dim,-dim, dim ); skyVerts[2].color=skyVertColor; skyVerts[2].tu=1; skyVerts[2].tv=1; skyVerts[3].position = Vec3(-dim,-dim, dim ); skyVerts[3].color=skyVertColor; skyVerts[3].tu=0; skyVerts[3].tv=1; Vec3 triangle[3]; triangle[0] = Vec3(0.f,0.f,0.f); triangle[1] = Vec3(5.f,0.f,0.f); triangle[2] = Vec3(5.f,5.f,0.f); Vec3 edge1 = triangle[1]-triangle[0]; Vec3 edge2 = triangle[2]-triangle[0]; Vec3 normal; normal = edge1.Cross(edge2); normal.Normalize(); Mat4x4 rotY; rotY.BuildRotationY(GCC_PI/2.0f); Mat4x4 rotX; rotX.BuildRotationX(-GCC_PI/2.0f); m_sides = 5; for (DWORD side = 0; side < m_sides; side++) { for (DWORD v = 0; v < 4; v++) { Vec4 temp; if (side < m_sides-1) { temp = rotY.Xform(Vec3(skyVerts[v].position)); } else { skyVerts[0].tu=1; skyVerts[0].tv=1; skyVerts[1].tu=1; skyVerts[1].tv=0; skyVerts[2].tu=0; skyVerts[2].tv=1; skyVerts[3].tu=0; skyVerts[3].tv=0; temp = rotX.Xform(Vec3(skyVerts[v].position)); } skyVerts[v].position = Vec3(temp.x, temp.y, temp.z); } memcpy(&pVertices[side*4], skyVerts, sizeof(skyVerts)); } m_pVerts->Unlock(); return S_OK; }