PlaneIntergrationMaker() { D3DXVECTOR3 vNormal(1,1,1); D3DXVec3Normalize(&vNormal, &vNormal); FLOAT fNear = (FLOAT)em_mesh_range / 4; D3DXPlaneFromPointNormal(&plane, &D3DXVECTOR3(fNear, 0,0), &vNormal); }
MMatrix ropeGenerator::getMatrixFromParamCurve( MFnNurbsCurve &curveFn, float param, float twist, MAngle divTwist ) { MPoint pDivPos; //Here we control the tangent of the rope curveFn.getPointAtParam( param, pDivPos, MSpace::kWorld ); MVector vTangent( curveFn.tangent( param, MSpace::kWorld ).normal() ); MVector vNormal( curveFn.normal( param, MSpace::kWorld ).normal() ); if ( MAngle( PrevNormal.angle( vNormal ) ).asDegrees() > 90 ) //fprintf(stderr, "Angle = %g\n",MAngle( PrevNormal.angle( vNormal )).asDegrees()); vNormal = vNormal * -1; PrevNormal = vNormal; //if ( vNormal.angle( ) ) MQuaternion qTwist( twist * divTwist.asRadians(), vTangent ); vNormal = vNormal.rotateBy( qTwist ); MVector vExtra( vNormal ^ vTangent ); vNormal.normalize(); vTangent.normalize(); vExtra.normalize(); double dTrans[4][4] ={ {vNormal.x, vNormal.y, vNormal.z, 0.0f}, {vTangent.x, vTangent.y, vTangent.z, 0.0f}, {vExtra.x, vExtra.y, vExtra.z, 0.0f}, {pDivPos.x,pDivPos.y,pDivPos.z, 1.0f}}; MMatrix mTrans( dTrans ); return mTrans; }
LTBOOL CProjectile::TestInsideObject(HOBJECT hTestObj, AmmoType eAmmoType) { if (!hTestObj) return LTFALSE; // TO DO??? // NOTE: This code may need to be updated to use test the dims // of the CharacterHitBox instead of the dims of the object... // TO DO??? // See if we are inside the test object... LTVector vTestPos, vTestDims; g_pLTServer->GetObjectPos(hTestObj, &vTestPos); g_pLTServer->GetObjectDims(hTestObj, &vTestDims); if (m_vFirePos.x < vTestPos.x - vTestDims.x || m_vFirePos.x > vTestPos.x + vTestDims.x || m_vFirePos.y < vTestPos.y - vTestDims.y || m_vFirePos.y > vTestPos.y + vTestDims.y || m_vFirePos.z < vTestPos.z - vTestDims.z || m_vFirePos.z > vTestPos.z + vTestDims.z) { return LTFALSE; } // We're inside the object, so we automatically hit the object... if (eAmmoType == PROJECTILE) { Detonate(hTestObj); } else { if (eAmmoType == VECTOR) { if (IsCharacter(hTestObj)) { CCharacter *pChar = (CCharacter*) g_pLTServer->HandleToObject(hTestObj); if (!pChar) return LTFALSE; ModelNode eModelNode = g_pModelButeMgr->GetSkeletonDefaultHitNode(pChar->GetModelSkeleton()); pChar->SetModelNodeLastHit(eModelNode); m_fInstDamage *= pChar->ComputeDamageModifier(eModelNode); } ImpactDamageObject(m_hFiredFrom, hTestObj); } LTVector vNormal(0, 1, 0); AddImpact(hTestObj, m_vFlashPos, vTestPos, vNormal, GetSurfaceType(hTestObj)); } RemoveObject(); return LTTRUE; }
//***************************************************************************** BVector BTerrainBlock::GetNormalAtTile(int nX, int nY, int nRes) { // Returns the normal at the given resolution-specific point // Normal is the average of the neighboring normals: // // Y // // ^ // | A B C // | D xy E // | F G H // +---------> X // BVector vToA, vToB, vToC, vToD, vToE, vToF, vToG, vToH; BVector vNormal(0, 0, 0); int nTileSize = 1 << (m_nMaxRes - nRes); double dTileSize = m_dSize / double(2 << nRes); double dTileSize2 = m_dSize / double(2 << m_nMaxRes); double dHeightAtXY = HeightAt(nX, nY); // First calculate vectors to neighboring points vToA.Set(-dTileSize, dTileSize, dHeightAtXY - HeightAt(nX - nTileSize, nY + nTileSize, true, dTileSize2)); vToA.ToUnitLength(); vToB.Set(0, dTileSize, dHeightAtXY - HeightAt(nX, nY + nTileSize, true, dTileSize2)); vToB.ToUnitLength(); vToC.Set(dTileSize, dTileSize, dHeightAtXY - HeightAt(nX + nTileSize, nY + nTileSize, true, dTileSize2)); vToC.ToUnitLength(); vToF.Set(-dTileSize, -dTileSize, dHeightAtXY - HeightAt(nX - nTileSize, nY - nTileSize, true, dTileSize2)); vToF.ToUnitLength(); vToG.Set(0, -dTileSize, dHeightAtXY - HeightAt(nX, nY - nTileSize, true, dTileSize2)); vToG.ToUnitLength(); vToH.Set(dTileSize, -dTileSize, dHeightAtXY - HeightAt(nX + nTileSize, nY - nTileSize, true, dTileSize2)); vToH.ToUnitLength(); vToD.Set(-dTileSize, 0, dHeightAtXY - HeightAt(nX - nTileSize, nY, true, dTileSize2)); vToD.ToUnitLength(); vToE.Set(dTileSize, 0, dHeightAtXY - HeightAt(nX + nTileSize, nY, true, dTileSize2)); vToE.ToUnitLength(); // Then create and sum normals together vNormal += vToA.CrossProduct(vToB); vNormal += vToB.CrossProduct(vToC); vNormal += vToG.CrossProduct(vToF); vNormal += vToH.CrossProduct(vToG); vNormal += vToE.CrossProduct(vToH); vNormal += vToC.CrossProduct(vToE); vNormal += vToF.CrossProduct(vToD); vNormal += vToD.CrossProduct(vToA); vNormal.ToUnitLength(); return vNormal; }
BOOL CRVTrackerPolyScale::OnUpdate(const CUIEvent &cEvent) { // Only update on idle events if (cEvent.GetType() != UIEVENT_NONE) return TRUE; // Don't update if it hasn't moved if (m_cCurPt == m_cLastPt) return TRUE; CVector newVert; DWORD i; // Do the autoscroll of the window DoAutoScroll(); CVector vNormal(0.0f,0.0f,0.0f); vNormal = m_vPerpNormal; if (m_bPerp) { for( i=0; i < m_cMovingVerts; i++ ) { m_cMovingVerts[i]() -= vNormal * (CReal)(m_cCurPt.y - m_cLastPt.y); } } else { CReal scaleFactor = ((CReal)(m_cLastPt.y - m_cCurPt.y)) / 100.0f; for( i=0; i < m_cMovingVerts; i++ ) { CEditVert &vert = m_cMovingVerts[i](); CVector vDiff = vert - m_vScaleRefPt; vDiff -= vNormal * vNormal.Dot(vDiff); vert += vDiff * scaleFactor; } } if( GetApp()->m_bFullUpdate ) { m_pView->GetDocument()->UpdateAllViews(m_pView); m_pView->DrawRect(); } m_cLastPt = m_cCurPt; return TRUE; }
FbxVector4 FBXScene::GetNormal(FbxMesh* pFBXMesh, int nLayerIndex, int nPolygonIndex, int nPolygonVertexIndex, int nVertexIndex) { FbxVector4 vNormal(0, 0, 0, 0); int nLayerCount = pFBXMesh->GetLayerCount(); if( nLayerIndex < nLayerCount )//for( int i = 0; i < nLayerCount; ++i ) { FbxLayer* pFBXLayer = pFBXMesh->GetLayer(nLayerIndex); if( pFBXLayer ) { FbxLayerElementNormal* pNormals = pFBXLayer->GetNormals(); if( pNormals ) { int nIdx = 0; if( pNormals->GetReferenceMode( ) == FbxLayerElement::EReferenceMode::eDirect ) { nIdx = nVertexIndex; } if( pNormals->GetReferenceMode( ) == FbxLayerElement::EReferenceMode::eIndexToDirect ) { nIdx = pNormals->GetIndexArray( ).GetAt( nVertexIndex ); } const FbxLayerElementArrayTemplate<FbxVector4>& pNormalArray = pNormals->GetDirectArray(); if( nIdx < pNormalArray.GetCount() ) { vNormal = pNormalArray.GetAt(nIdx); vNormal.Normalize(); } } } } return vNormal; }
//---フィールド頂点を初期化 CRBATINIT_API int crbatInitFieldVertex(void) { int a,x,y; D3DVECTOR vNormal( D3DVAL(0.0f), D3DVAL(1.0f), D3DVAL(0.0f) ); D3DVECTOR vNormal2( D3DVAL(0.0f), D3DVAL(-1.0f), D3DVAL(0.0f) ); D3DVECTOR p1(D3DVAL(-0.5f) , D3DVAL(0.0f) , D3DVAL(-0.5f)); D3DVECTOR p2( D3DVAL(0.5f) , D3DVAL(0.0f) , D3DVAL(-0.5f)); D3DVECTOR p3(D3DVAL(-0.5f) , D3DVAL(0.0f) , D3DVAL( 0.5f)); D3DVECTOR p4( D3DVAL(0.5f) , D3DVAL(0.0f) , D3DVAL( 0.5f)); /* D3DVECTOR vNormal( D3DVAL(0.0f), D3DVAL(1.0f), D3DVAL(0.0f) ); D3DVECTOR vNormal2( D3DVAL(0.0f), D3DVAL(-1.0f), D3DVAL(0.0f) ); D3DVECTOR p1(D3DVAL(-0.5f) , D3DVAL(-0.5f) , D3DVAL(0.0f)); D3DVECTOR p2( D3DVAL(0.5f) , D3DVAL(-0.5f) , D3DVAL(0.0f)); D3DVECTOR p3(D3DVAL(-0.5f) , D3DVAL(0.5f) , D3DVAL( 0.0f)); D3DVECTOR p4( D3DVAL(0.5f) , D3DVAL(0.5f) , D3DVAL( 0.0f)); */ for(y = 0;y < BATTLEFIELD_VERTEXCOUNT_Y;y ++){ for(x = 0;x < BATTLEFIELD_VERTEXCOUNT_X;x ++){ BattleField[x][y].Vertex[0] = D3DVERTEX( p1, vNormal,D3DVAL(0.0f),D3DVAL(0.0f)); BattleField[x][y].Vertex[1] = D3DVERTEX( p2, vNormal,D3DVAL(1.0f),D3DVAL(0.0f)); BattleField[x][y].Vertex[2] = D3DVERTEX( p3, vNormal,D3DVAL(0.0f),D3DVAL(1.0f)); BattleField[x][y].Vertex[3] = D3DVERTEX( p4, vNormal,D3DVAL(1.0f),D3DVAL(1.0f)); for(a = 0;a < 4;a ++){ BattleField[x][y].Vertex[a].x += (float)((float)x * 1.0f); BattleField[x][y].Vertex[a].z += (float)((float)y * 1.0f); } // BattleField[x][y].TextureNumber = eiRnd(2); } } return 1; }
void CProjectile::Detonate(HOBJECT hObj) { if (m_bDetonated) return; // Make sure we don't detonate if a cinematic is playing (i.e., // make sure the user doesn't disrupt the cinematic)... if (Camera::IsActive()) { RemoveObject(); return; } m_bDetonated = LTTRUE; SurfaceType eType = ST_UNKNOWN; LTVector vPos; g_pLTServer->GetObjectPos(m_hObject, &vPos); // Determine the normal of the surface we are impacting on... LTVector vNormal(0.0f, 1.0f, 0.0f); if (hObj) { if (IsMainWorld(hObj) || g_pLTServer->GetObjectType(hObj) == OT_WORLDMODEL) { CollisionInfo info; g_pLTServer->GetLastCollision(&info); if (info.m_hPoly) { eType = GetSurfaceType(info.m_hPoly); } LTPlane plane = info.m_Plane; vNormal = plane.m_Normal; // Calculate where we really hit the plane... LTVector vVel, vP0, vP1, vDir; g_pLTServer->GetVelocity(m_hObject, &vVel); vDir = vVel; vDir.Norm(); vP1 = vPos; vVel *= g_pLTServer->GetFrameTime(); vP0 = vP1 - vVel; vP1 += vVel; // Make sure we don't tunnel through an object... IntersectInfo iInfo; IntersectQuery qInfo; qInfo.m_Flags = INTERSECT_HPOLY | INTERSECT_OBJECTS | IGNORE_NONSOLID; qInfo.m_From = vP0; qInfo.m_To = vPos; qInfo.m_FilterFn = SpecificObjectFilterFn; qInfo.m_pUserData = m_hObject; if (g_pLTServer->IntersectSegment(&qInfo, &iInfo)) { vPos = iInfo.m_Point - vDir; eType = GetSurfaceType(iInfo); vNormal = iInfo.m_Plane.m_Normal; } else { //g_pLTServer->CPrint("P0 = %.2f, %.2f, %.2f", VEC_EXPAND(vP0)); //g_pLTServer->CPrint("P1 = %.2f, %.2f, %.2f", VEC_EXPAND(vP1)); //LTVector vDist = vP1 - vP0; //g_pLTServer->CPrint("Distance from P0 to P1: %.2f", vDist.Mag()); LTFLOAT fDot1 = VEC_DOT(vNormal, vP0) - info.m_Plane.m_Dist; LTFLOAT fDot2 = VEC_DOT(vNormal, vP1) - info.m_Plane.m_Dist; if (fDot1 < 0.0f && fDot2 < 0.0f || fDot1 > 0.0f && fDot2 > 0.0f) { vPos = vP1; } else { LTFLOAT fPercent = -fDot1 / (fDot2 - fDot1); //g_pLTServer->CPrint("Percent: %.2f", fPercent); VEC_LERP(vPos, vP0, vP1, fPercent); } } LTRotation rRot; g_pLTServer->AlignRotation(&rRot, &vNormal, LTNULL); g_pLTServer->SetObjectRotation(m_hObject, &rRot); // g_pLTServer->CPrint("Pos = %.2f, %.2f, %.2f", VEC_EXPAND(vPos)); } } else { // Since hObj was null, this means the projectile's lifetime was up, // so we just blew-up in the air. eType = ST_AIR; } if (eType == ST_UNKNOWN) { eType = GetSurfaceType(hObj); } AddImpact(hObj, m_vFlashPos, vPos, vNormal, eType); // Handle impact damage... if (hObj) { HOBJECT hDamager = m_hFiredFrom ? m_hFiredFrom : m_hObject; ImpactDamageObject(hDamager, hObj); } //g_pLTServer->CPrint("Server end pos (%.2f, %.2f, %.2f)", vPos.x, vPos.y, vPos.z); //g_pLTServer->CPrint("Server fly time %.2f", g_pLTServer->GetTime() - m_fStartTime); // Remove projectile from world... RemoveObject(); }
bool CGutModel::CreateSphere(float radius, sVertexDecl *pVertexDecl, int stacks, int slices) { Release(); m_pMeshArray = new sModelMesh[1]; sModelMesh *pMesh = m_pMeshArray; if ( NULL==pMesh ) return false; m_pMeshArray[0].m_pVertexChunks = new sModelVertexChunk[1]; sModelVertexChunk *pVertexChunk = m_pMeshArray[0].m_pVertexChunks; if ( NULL==pVertexChunk ) return false; if ( pVertexDecl ) pVertexChunk->m_VertexDecl = *pVertexDecl; int num_vertices = (stacks+1)*(slices+1); int num_triangles = stacks*slices*2; int num_indices = num_triangles * 3; m_pMeshArray[0].m_iNumVertexChunks = 1; pVertexChunk->m_pVertexArray = new sModelVertex[num_vertices]; sModelVertex *pVertices = pVertexChunk->m_pVertexArray; if ( NULL==pVertices ) return false; pVertexChunk->m_pBatchArray = new sModelBatch[1]; sModelBatch *pBatch = pVertexChunk->m_pBatchArray; if ( NULL==pBatch ) return false; m_iNumMeshes = 1; m_iNumFaces = num_triangles; m_iNumVertices = num_vertices; pMesh->m_iNumFaces = num_triangles; pMesh->m_iNumVertices = num_vertices; pBatch->m_iNumIndices = num_indices; pBatch->m_iNumPrimitives = num_triangles; pBatch->m_iNumVertices = num_vertices; pBatch->m_iIndexArrayBegin = 0; pBatch->m_iIndexArrayEnd = num_indices; pVertexChunk->m_iNumBatches = 1; pVertexChunk->m_iNumIndices = num_indices; pVertexChunk->m_iNumVertices = num_vertices; pVertexChunk->m_iNumPrimitives = num_triangles; Vector4 vDefaultColor(1.0f); Vector4 vRadius(radius); const float theta_start_degree = 0.0f; const float theta_end_degree = 360.0f; const float phi_start_degree = -90.0f; const float phi_end_degree = 90.0f; float ts = FastMath::DegToRad(theta_start_degree); float te = FastMath::DegToRad(theta_end_degree); float ps = FastMath::DegToRad(phi_start_degree); float pe = FastMath::DegToRad(phi_end_degree); float theta_total = te - ts; float phi_total = pe - ps; float theta_inc = theta_total/stacks; float phi_inc = phi_total/slices; float ty_start = 1.0f; float ty_step = -1.0f/(float)slices; float tx_start = 1.0f; float tx_step = -1.0f/(float)stacks; Vector4 vTexcoord(tx_start, ty_start, 0.0f); int i,j; int index = 0; float theta = ts; for ( i=0; i<=stacks; i++ ) { float phi = ps; float sin_theta, cos_theta; FastMath::SinCos(theta, sin_theta, cos_theta); for ( j=0; j<=slices; j++, index++ ) { float sin_phi, cos_phi; FastMath::SinCos(phi, sin_phi, cos_phi); Vector4 vNormal(cos_phi * cos_theta, sin_phi, cos_phi * sin_theta); // Position pVertices[index].m_Position = vRadius * vNormal; // Normal pVertices[index].m_Normal = vNormal; // Color pVertices[index].m_Color = vDefaultColor; // Texcoord pVertices[index].m_Texcoord[0] = vTexcoord; // inc phi phi += phi_inc; // inc texcoord vTexcoord[1] += ty_step; } // inc theta theta += theta_inc; // reset & inc texcoord vTexcoord[0] += tx_step; vTexcoord[1] = ty_start; } // build index array unsigned short *pIndices = new unsigned short[num_triangles*3]; if ( pIndices==NULL ) { delete [] pVertices; return false; } pVertexChunk->m_pIndexArray = pIndices; int base = 0; index = 0; // triangle list for ( i=0; i<stacks; i++ ) { for ( j=0; j<slices; j++ ) { pIndices[index++] = base; pIndices[index++] = base+1; pIndices[index++] = base+slices+1; pIndices[index++] = base+1; pIndices[index++] = base+slices+2; pIndices[index++] = base+slices+1; base++; } base++; } return true; }
void CSphereCallback::FillMeshData(Engine::Graphics::IMesh *pMesh) { // Declaration SVertexElement elems[4]; elems[0] = SVertexElement(0, ETYPE_FLOAT3, USG_POSITION, 0); elems[1] = SVertexElement(sizeof(float) * 3, ETYPE_FLOAT3, USG_NORMAL, 0); elems[2] = SVertexElement(sizeof(float) * 6, ETYPE_FLOAT2, USG_TEXCOORD, 0); elems[3] = END_DECLARATION(); pMesh->SetVertexDeclaration(elems); pMesh->setPrimitiveType(PT_INDEXED_TRIANGLE_LIST); // Data const int n_verts = (mRings + 1) * (mSegments + 1); const int n_indcs = 6 * mRings * (mSegments + 1); void *vertices, *indices; IBuffer* vb = pMesh->GetVertexBuffer(); IBuffer* ib = pMesh->GetIndexBuffer(); vb->Resize(n_verts * sizeof(float) * 8); ib->Resize(n_indcs * sizeof(int)); vb->Lock(&vertices, LOCK_DISCARD); ib->Lock(&indices, LOCK_DISCARD); const float PI = 3.1415926f; float fDeltaRingAngle = (PI / mRings); float fDeltaSegAngle = (2.0f * PI / mSegments); unsigned short wVerticeIndex = 0 ; float* pVertex = (float*)vertices; int* pIndices = (int*)indices; // Generate the group of rings for the sphere for(int ring = 0; ring <= mRings; ring++) { float r0 = mRadius * sinf (ring * fDeltaRingAngle); float y0 = mRadius * cosf (ring * fDeltaRingAngle); // Generate the group of segments for the current ring for(int seg = 0; seg <= mSegments; seg++) { float x0 = r0 * sinf(seg * fDeltaSegAngle); float z0 = r0 * cosf(seg * fDeltaSegAngle); // Position *pVertex++ = x0; *pVertex++ = y0; *pVertex++ = z0; // Normal VML::Vector3 vNormal(x0, y0, z0); vNormal.normalize(); *pVertex++ = vNormal.getX(); *pVertex++ = vNormal.getY(); *pVertex++ = vNormal.getZ(); // Texture coordinates *pVertex++ = 1.0f - (float) seg / (float) mSegments; *pVertex++ = (float) ring / (float) mRings; if (ring != mRings) { // each vertex (except the last) has six indices pointing to it *pIndices++ = wVerticeIndex + mSegments + 1; *pIndices++ = wVerticeIndex; *pIndices++ = wVerticeIndex + mSegments; *pIndices++ = wVerticeIndex + mSegments + 1; *pIndices++ = wVerticeIndex + 1; *pIndices++ = wVerticeIndex; wVerticeIndex ++; } } // end for seg } // end for ring vb->Unlock(); ib->Unlock(); // Subset IGeometry::TInterval vi(0, n_verts); IGeometry::TInterval ii(0, n_indcs); pMesh->AddSubset(vi, ii); SBoundingVolume bv(VML::Vector3(0), mRadius); pMesh->SetBoundingVolume(bv); }
bool GenerateGrids(int x_grids, int y_grids, Vertex_VCN **ppVertices, int *pNum_Vertices, unsigned short **ppIndices, int *pNum_Indices, int *num_triangles) { const int triangles_per_row = x_grids * 2; const int indices_per_row = triangles_per_row + 2; *num_triangles = triangles_per_row * y_grids; int num_vertices = (x_grids + 1) * (y_grids + 1); *pNum_Vertices = num_vertices; Vertex_VCN *pVertices = (Vertex_VCN *) Allocate16BytesAlignedMemory(sizeof(Vertex_VCN)*num_vertices); *ppVertices = pVertices; if ( pVertices==NULL ) return false; int num_indices = indices_per_row * y_grids; *pNum_Indices = num_indices; unsigned short *pIndices = new unsigned short[num_indices]; *ppIndices = pIndices; if ( pIndices==NULL ) { Release16BytesAlignedMemory(pVertices); return false; } Vector4 vCorner(-0.5f, 0.5f, 0.0f, 1.0f); Vector4 vStep(1.0f/float(x_grids), -1.0f/float(y_grids), 0.0f, 0.0f); Vector4 vPosition = vCorner; Vector4 vNormal(0.0f, 0.0f, 1.0f); Vector4 vColor(1.0f, 1.0f, 1.0f, 1.0f); int x,y; int vertex_index = 0; for ( y=0; y<=y_grids; y++) { vPosition[0] = vCorner[0]; for ( x=0; x<=x_grids; x++, vertex_index++) { pVertices[vertex_index].m_Position = vPosition; pVertices[vertex_index].m_Normal = vNormal; pVertices[vertex_index].m_Color = vColor; vPosition[0] += vStep[0]; } vPosition[1] += vStep[1]; } const int vertices_per_row = x_grids + 1; bool from_left_to_right = true; int index_index = 0; vertex_index = 0; for ( y=0; y<y_grids; y++ ) { if ( from_left_to_right ) { pIndices[index_index++] = y * vertices_per_row; pIndices[index_index++] = y * vertices_per_row + vertices_per_row; for ( x=0; x<x_grids; x++ ) { vertex_index = y * vertices_per_row + x; pIndices[index_index++] = vertex_index + 1; pIndices[index_index++] = vertex_index + 1 + vertices_per_row; } } else { pIndices[index_index++] = y * vertices_per_row + x_grids; pIndices[index_index++] = (y+1) * vertices_per_row + x_grids; for ( x=x_grids; x>0; x-- ) { vertex_index = y * vertices_per_row + x; pIndices[index_index++] = vertex_index - 1; pIndices[index_index++] = vertex_index - 1 + vertices_per_row; } } from_left_to_right = !from_left_to_right; } return true; }
//------------------------------------------------------------------------------ void CLocalSplitMapSaver::SaveAsSplitLocal() { COperator *pOperator = NULL; pOperator = CMapEditApp::GetInst()->GetOperator(); if( pOperator == NULL ) return; CMapCommonDataSaver::GetInst()->SetOperator(pOperator); CMapCommonDataSaver::GetInst()->SetTerrainMesh(terrain); CMapEditApp::GetInst()->SetEditingMesh(sqr::EEM_TERRAIN); locale loc; use_facet<ctype<TCHAR> >( loc ).tolower ( &m_strMapPathName[0], &m_strMapPathName[m_strMapPathName.length()] ); string strLocalPath = m_strMapPathName + ".local"; FILE * fp = fopen(strLocalPath.c_str(),"wb"); int SceneLightCount = 0; //记录场景点光源个数 int nSpotLightCount = 0; //记录场景聚光灯个数 if ( fp ) { set<DWORD> eraseGrids; // header fwrite("LOCL",4,1,fp); // version DWORD dwVersion = LOCAL_VERSION; fwrite(&dwVersion,sizeof(DWORD),1,fp); ///游戏客户端服务器端文件ID号 DWORD dwGameClientID = 0; fwrite(&dwGameClientID,sizeof(DWORD),1,fp); DWORD dwGameServerID = 0; fwrite(&dwGameServerID,sizeof(DWORD),1,fp); // background music string str = CSceneEnvMgr::GetInst()->GetBackGroundMusic(); DWORD dwFileNameLen = str.length(); fwrite(&dwFileNameLen,sizeof(DWORD),1,fp); fwrite(str.c_str(),dwFileNameLen,1,fp); // main player CToolMainPlayer::GetInst()->Save(fp); // camera CMapEditCamera * pCamera = CCameraManager::GetInst()->GetMapEditCamera(); CVector3f vView = pCamera->GetTarget(); fwrite(&vView,sizeof(CVector3f),1,fp); //fov float fov = pCamera->GetFovY(); fwrite(&fov,sizeof(float),1,fp); //yaw float yaw = pCamera->GetYaw(); fwrite(&yaw,sizeof(float),1,fp); //pitch float pitch = pCamera->GetPitch(); fwrite(&pitch,sizeof(float),1,fp); CMapCommonDataSaver::GetInst()->SaveEnvInfo(fp); ///背景图移动相关信息 CMapCommonDataSaver::GetInst()->SaveBackPictureInfo(fp); // fog mode int fogMode = CSceneEnvMgr::GetInst()->GetFogMode(); fwrite(&fogMode,sizeof(int),1,fp); //全屏泛光 CSceneEnvMgr::GetInst()->SaveGaussParamsInfo(fp); // wave info CMapCommonDataSaver::GetInst()->SaveWaveInfo(fp); // ambient fx info CMapEffect::GetInst()->SaveAmbientFXInfo(fp); // width depth fwrite(&m_dwSplitMapWidth,sizeof(DWORD),1,fp); fwrite(&m_dwSplitMapDepth,sizeof(DWORD),1,fp); ////////////////////////////////////////////////////////////////////////// ///write main road texture name and weight CMapCommonDataSaver::GetInst()->SaveMainRoadWeightInfo(fp); ////////////////////////////////////////////////////////////////////////// // rgn mask int newGridCnt = 0, SceneLightCount = 0; DWORD newVertexCnt = 0; DWORD dwMapWidth = m_dwSplitMapWidth * REGION_SPACE; DWORD dwMapDepth = m_dwSplitMapDepth * REGION_SPACE; newGridCnt = dwMapWidth * dwMapDepth; newVertexCnt = (dwMapWidth + 1) * (dwMapDepth + 1); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// CTerrainMesh *pTerrainNew = NULL; pTerrainNew = new CTerrainMesh; pTerrainNew->Create(m_dwSplitMapWidth, m_dwSplitMapDepth, m_strDefaultTerrainTexName, false, false); if( pTerrainNew == NULL ) return; DWORD gridSplitedW = pTerrainNew->GetWidth(); DWORD gridSplitedH = pTerrainNew->GetDepth(); DWORD gridReadW = terrain->GetWidth(); int nSplitGridStartX = m_dwSplitStartX * REGION_SPACE; int nSplitGridStartZ = m_dwSplitStartZ * REGION_SPACE; int nNewVertexIndex = 0, nOldVertexIndex = 0; DWORD dwNewGridIndex = 0, dwOldGridIndex = 0; for ( DWORD z = 0 ; z < gridSplitedH; z++ ) { for ( DWORD x = 0 ; x < gridSplitedW ; x++ ) { dwNewGridIndex = x + z * gridSplitedW; dwOldGridIndex = x + nSplitGridStartX + (nSplitGridStartZ + z) * gridReadW; // int col = x + nSaveGridStartX; // int row = (nSaveGridStartZ + z) * gridSaveW; if( pTerrainNew->IsValid(dwNewGridIndex) ) { SGrid * pGridNew = &pTerrainNew->GetGrid(dwNewGridIndex); SGrid * pGridOld = &terrain->GetGrid(dwOldGridIndex); this->mapSplitMapGridIndex[dwNewGridIndex] = dwOldGridIndex; this->mapRevertSplitMapGridIndex[dwOldGridIndex] = dwNewGridIndex; pOperator->m_SplitOldMapGridIndexMap[dwOldGridIndex] = dwNewGridIndex; //DebugOut("Read reg index %d, save %d\n", nReadDivideRegionIndex, nSaveDivideRegionIndex); for( int m = 0; m < 4; ++m ) { nOldVertexIndex = pGridOld->dwVertexIndex[m]; nNewVertexIndex = pGridNew->dwVertexIndex[m]; this->mapSplitMapVertexIndex[nNewVertexIndex] = nOldVertexIndex; //DebugOut("old vertex %d, new %d\n", nReadVertexIndex, nSaveVertexIndex); } } else MessageBox(NULL,"越界,请注意","提示",MB_OK); } } ////////////////////////////////////////////////////////////////////////// #pragma region VERTEX ///顶点信息 map<int, int>::iterator vertexiter; for ( DWORD n = 0; n < newVertexCnt; ++n ) { DWORD dwVertexIndexOld = 0, oColor = VERTEX_COLOR, sColor = VERTEX_COLOR; float fPositionY = 0.0f; CVector3f vNormal(0.0, 1.0f, 0.0f); short sLogicHeight = 0; vertexiter = this->mapSplitMapVertexIndex.find(n); if ( vertexiter != this->mapSplitMapVertexIndex.end() ) { SVertex &VertexOld = terrain->GetVertex(vertexiter->second); oColor = VertexOld.oColor; sColor = VertexOld.sColor; fPositionY = VertexOld.vPosition.y; vNormal = VertexOld.vNormal; sLogicHeight = short(VertexOld.fLogicHeight); } else { char c[10]; sprintf(c, "%d", n); string str = c; str = str + "顶点切割失败"; MessageBox(NULL,str.c_str(),"提示",MB_OK); } CMapCommonDataSaver::GetInst()->SaveEachVertexInfo(fp, fPositionY, vNormal, oColor, sColor, sLogicHeight); } #pragma endregion VERTEX ////////////////////////////////////////////////////////////////////////// ///model property version CMapCommonDataSaver::GetInst()->SaveGridModeProVersion(fp); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// ///记录格子纹理索引 int nGridCnt = terrain->GetGridCount(); map<string, int16> terrainTextureNames;///用于记录地图中用到的所有纹理的名字,保存各层纹理信息则保存index就行 CMapCommonDataSaver::GetInst()->SaveTerrainGridTexIndex(fp, nGridCnt, terrainTextureNames); ////////////////////////////////////////////////////////////////////////// #pragma region GRID // grids string strName = ""; SGrid * pGridOld = NULL; int16 nFirstTextureIndex = 0, nSecondTextureIndex = 0; DWORD dwGridIndexOld = 0; float delta = 0.001f; float U[2][4] = { {delta, 0.5f, 0.5f, delta}, {0.5f, 1.0f - delta, 1.0f - delta, 0.5f} }; float V[2][4] = { {1.0f - delta, 1.0f - delta, 0.5f, 0.5f}, {0.5f, 0.5f, delta, delta} }; map<int, int>::iterator griditer; for (int i = 0; i < newGridCnt; ++i ) { int x = i % dwMapWidth; int z = i / dwMapWidth; int nX = x % 2; int nZ = z % 2; SGrid * pGridNew = &pTerrainNew->GetGrid(i); pGridNew->dwGridIndex = i; griditer = this->mapSplitMapGridIndex.find(i); if ( griditer != this->mapSplitMapGridIndex.end() ) { dwGridIndexOld = griditer->second; pGridOld = &terrain->GetGrid(dwGridIndexOld); pGridNew->bGridHide = pGridOld->bGridHide; pGridNew->nBlockType = pGridOld->nBlockType; pGridNew->nodeInfo.strTextureNames[0] = pGridOld->nodeInfo.strTextureNames[0]; pGridNew->nodeInfo.strTextureNames[1] = pGridOld->nodeInfo.strTextureNames[1]; pGridNew->bCliffLayerOne = pGridOld->bCliffLayerOne; for (int m = 0; m < 4; ++m) { pGridNew->uv[0][m] = pGridOld->uv[0][m]; pGridNew->uv[1][m] = pGridOld->uv[1][m]; } pGridNew->vCenter.y = pGridOld->vCenter.y; pGridNew->vecCenterObjects = pGridOld->vecCenterObjects; pGridNew->bEffectByVertexColor = pGridOld->bEffectByVertexColor; } else { char c[10]; sprintf(c, "%d", i); string str = c; str = str + "格子切割失败"; MessageBox(NULL,str.c_str(),"提示",MB_OK); pGridNew->nodeInfo.strTextureNames[0] = m_strDefaultTerrainTexName; pGridNew->nodeInfo.strTextureNames[1] = ""; for (int m = 0; m < 4; ++m) { pGridNew->uv[0][m].x = U[nX][m]; pGridNew->uv[0][m].y = V[nZ][m]; } } //grid hide mask fwrite(&pGridNew->bGridHide,sizeof(bool),1,fp); //1 strName = pGridNew->nodeInfo.strTextureNames[0]; nFirstTextureIndex = terrainTextureNames[strName]; fwrite(&nFirstTextureIndex,sizeof(nFirstTextureIndex),1,fp); //2 strName = pGridNew->nodeInfo.strTextureNames[1]; nSecondTextureIndex = terrainTextureNames[strName]; fwrite(&nSecondTextureIndex,sizeof(nSecondTextureIndex),1,fp); ///////////////////////////////////////////////////////////////// CMapCommonDataSaver::GetInst()->SaveEachGridInfo(fp, pGridNew, SceneLightCount, nSpotLightCount, false, true); } #pragma endregion GRID ////////////////////////////////////////////////////////////////////////// // block lines this->SaveSplitMapBlockInfo(newGridCnt); ///pTerrain size_t erasebloclsize = 0; fwrite( &erasebloclsize, sizeof(size_t), 1, fp ); ////////////////////////////////////////////////////////////////////////// // water CTerrainMesh * pWater = terrain->GetWater(); set<int> setGridIndicesVisibleWater = pWater->GetGridIndicesVisibleWater(); map< CRiver*, vector<int> > mapRivers; map<int, int>::iterator splitRevertGriditer; for ( set<int>::iterator iter = setGridIndicesVisibleWater.begin(); iter != setGridIndicesVisibleWater.end(); ) { int nGridIndex = *iter; SGrid & gridW = pWater->GetGrid(nGridIndex); ++iter; Ast(gridW.bVisible); if ( gridW.pRiver ) { setGridIndicesVisibleWater.erase(nGridIndex); splitRevertGriditer = this->mapRevertSplitMapGridIndex.find(nGridIndex); if( splitRevertGriditer != this->mapRevertSplitMapGridIndex.end() ) nGridIndex = splitRevertGriditer->second; else { //DebugOut("Grid %d\n", nGridIndex); continue; } mapRivers[gridW.pRiver].push_back(nGridIndex); } } DWORD dwCnt = mapRivers.size(); fwrite(&dwCnt,sizeof(DWORD),1,fp); // visible and occupied for ( map< CRiver*, vector<int> >::iterator iterMapRivers = mapRivers.begin(); iterMapRivers != mapRivers.end(); ++iterMapRivers ) { CRiver * pRiver = iterMapRivers->first; string strItemName = pRiver->GetItemName(); DWORD dw = strItemName.size(); fwrite(&dw,sizeof(int),1,fp); fwrite(strItemName.c_str(),dw,1,fp); dwCnt = iterMapRivers->second.size(); fwrite(&dwCnt,sizeof(DWORD),1,fp); for (size_t i = 0; i < iterMapRivers->second.size(); ++i ) { int nGridIndex = iterMapRivers->second[i]; fwrite(&nGridIndex,sizeof(DWORD),1,fp);///切割后格子索引 ///得到被切割地图对应索引,将该格子得到,取得水的高度值 splitRevertGriditer = this->mapSplitMapGridIndex.find(nGridIndex); if( splitRevertGriditer != this->mapSplitMapGridIndex.end() ) nGridIndex = splitRevertGriditer->second; else { nGridIndex = 0; MessageBox(NULL,"地图切割水的地方有问题,请注意","提示",MB_OK); } SGrid & gridW = pWater->GetGrid(nGridIndex); fwrite(&gridW.vCenter.y,sizeof(float),1,fp); for ( int j = 0; j < 4; ++j ) { int nVertexIndex = gridW.dwVertexIndex[j]; SVertex & vertex = pWater->GetVertex(nVertexIndex); fwrite(&vertex.vPosition.y, sizeof(float),1,fp); fwrite(&vertex.oColor,sizeof(DWORD),1,fp); } } } set<int>::iterator end = setGridIndicesVisibleWater.end(); int nOldGridIndex = 0, nNewGridIndex = 0; for ( set<int>::iterator beg = setGridIndicesVisibleWater.begin(); beg != end; ++beg ) { nOldGridIndex = *beg; splitRevertGriditer = this->mapRevertSplitMapGridIndex.find(nOldGridIndex); if( splitRevertGriditer != this->mapRevertSplitMapGridIndex.end() ) { nNewGridIndex = splitRevertGriditer->second; if( nNewGridIndex < newGridCnt ) setGridIndicesVisibleWater.erase(nOldGridIndex); } } // unoccupied but visible dwCnt = setGridIndicesVisibleWater.size(); fwrite(&dwCnt,sizeof(DWORD),1,fp); for ( set<int>::iterator iter = setGridIndicesVisibleWater.begin(); iter != setGridIndicesVisibleWater.end(); ++iter ) { int nGridIndex = *iter; fwrite(&nGridIndex,sizeof(DWORD),1,fp);///切割后格子索引 ///得到被切割地图对应索引,将该格子得到,取得水的高度值 splitRevertGriditer = this->mapSplitMapGridIndex.find(nGridIndex); if( splitRevertGriditer != this->mapSplitMapGridIndex.end() ) nGridIndex = splitRevertGriditer->second; else { nGridIndex = 0; MessageBox(NULL,"地图切割水的地方有问题,请注意","提示",MB_OK); } SGrid & gridW = pWater->GetGrid(nGridIndex); fwrite(&gridW.vCenter.y,sizeof(float),1,fp); for ( int j = 0; j < 4; ++j ) { int nVertexIndex = gridW.dwVertexIndex[j]; SVertex & vertex = pWater->GetVertex(nVertexIndex); fwrite(&vertex.vPosition.y,sizeof(float),1,fp); fwrite(&vertex.oColor,sizeof(DWORD),1,fp); } } /////////////////// //--- 增加 SceneLight 数据块 ///save point light bool bSceneLightCntEqual = true; this->SavePointLightInfo(fp, SceneLightCount); ///////////////////////--- 增加cave数据块,用来保存是否是“室内” int tLength = 6; fwrite( &tLength, sizeof(int), 1, fp); fwrite( "bCave", 6, 1, fp); // cave? no shadow bool bCave = false; fwrite(&bCave,sizeof(bool),1,fp); ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// DWORD dwNewVersion = SPECULAR_LIGHT_PARA; fwrite(&dwNewVersion,sizeof(DWORD),1,fp); ////////////////////////////////////////////////////////////////////////// //save specular light parameter for (size_t i = 0; i < 4; ++i) { // light DWORD dwSceneSpecurlarColor = CSceneEnvMgr::GetInst()->GetSceneSpecurlarColor(); fwrite(&dwSceneSpecurlarColor,sizeof(DWORD),1,fp); DWORD dwPlayerSpecurlarColor = CSceneEnvMgr::GetInst()->GetPlayerSpecurlarColor(); fwrite(&dwSceneSpecurlarColor, sizeof(DWORD), 1, fp); } float fSceneSPower = CSceneEnvMgr::GetInst()->GetSpecularReflectionPower(0); fwrite(&fSceneSPower, sizeof(fSceneSPower), 1, fp); float fNpcSPower = CSceneEnvMgr::GetInst()->GetSpecularReflectionPower(1); fwrite(&fNpcSPower, sizeof(fNpcSPower), 1, fp); ////////////////////////////////////////////////////////////////////////// /// 保存格子材质索引值 this->SaveSplitMapGridMatIndexInfo(fp, newGridCnt); //保存不播放动画的信息 this->SaveOffAnimateModelIndex(fp); //保存精确阻挡信息 this->SaveSplitMapExactBlockInfo(fp, newGridCnt); // 保存格子浪花标记 this->SaveWaveSideInfo(fp, newGridCnt); ///保存聚光灯的信息 this->SaveSpotLightInfo(fp, nSpotLightCount); ////////////////////////////////////////////////////////////////////////// // ---------------------------------------------------------------------------- // 保存摄像机路径信息 CToolRecord::GetInst()->Save(fp); fclose(fp); this->SaveAsAudio(); MessageBox(NULL,"地图已分割完成,如果要看分割后的地图,请重新打开该地图","提示",MB_OK); MessageBox(NULL,"打开分割地图后,请重新生成lightmap,否则调出主角走到会爆掉","提示",MB_OK); delete pTerrainNew; pTerrainNew = NULL; } else { MessageBox(NULL,"写入文件错误,有可能文件被锁住了","错误",MB_OK); } }
void Mesh::load(Scene *scene, BSDF *b, char *fileName, const bool fnormals, const bool fwinding, const bool fix, const bool recenter) { Timer meshTimer; // Stores pointers needed s = scene; hasVertexNormals = false; fixNormals = fix; startVertex = s->v.size() - 1; startNormal = s->vn.size() - 1; startTriangle = s->t.size() - 1; startTex = s->tex.size() - 1; bsdf = b; curbsdf = NULL; flipWinding = fwinding; flipNormals = fnormals; meshTimer.reset(); GLMmodel *model = glmReadOBJ(fileName); // Could not load model, print error and quit program if (model == 0) { printf("Error opening file %s", fileName); exit(1); } // Allocate storage for mats. loadmats(model); // Load in all the verticies for (unsigned int i = 1; i <= model->numvertices; ++i) { s->v.Add(Vec3(model->vertices[i*3+0], model->vertices[i*3+1], model->vertices[i*3+2])); } vertFaces.resize(model->numvertices); // Load all vetex normals for (unsigned int i = 1; i <= model->numnormals; ++i) { s->vn.Add(Vec3(model->normals[i*3+0], model->normals[i*3+1], model->normals[i*3+2])); s->vn[s->vn.size() - 1].Normalize(); } if (model->numnormals > 0) { hasVertexNormals = true; } // Load all texture co-ords for (unsigned int i = 1; i <= model->numtexcoords; ++i) { s->tex.Add(Vec3(model->texcoords[i*2+0], model->texcoords[i*2+1], 0.0f)); } GLMgroup *group = model->groups; while (group != 0) { const int total_faces = group->numtriangles; if (group->mat < model->nummats) curbsdf = bsdfs[group->mat]; else curbsdf = NULL; for (int i = 0; i < total_faces; ++i) { addTriangle(model->triangles[ group->triangles[i] ].vindices[0], model->triangles[ group->triangles[i] ].vindices[1], model->triangles[ group->triangles[i] ].vindices[2], model->triangles[ group->triangles[i] ].nindices[0], model->triangles[ group->triangles[i] ].nindices[1], model->triangles[ group->triangles[i] ].nindices[2], model->triangles[ group->triangles[i] ].tindices[0], model->triangles[ group->triangles[i] ].tindices[1], model->triangles[ group->triangles[i] ].tindices[2]); } group = group->next; } // Flip normals if needed if (flipNormals) { for (int i = startTriangle + 1; i < s->t.size(); i++) s->t[i].normal *= -1.0f; } // Check if vertex normals exist and if not than generate them // TODO: Currently adds too many vertex normals (none are shared) // need to check how to do this efficently if (!hasVertexNormals) { printf("Have to generate vertex normals\n"); int vNormals[3]; for (int i = startTriangle + 1; i < s->index.size(); i++) { for (int v = 0; v < 3; v++) { Vec3 vNormal(0,0,0); for (unsigned int t = 0; t < vertFaces[s->index[i].index[v] - startVertex - 1].size(); t++) { MollerTriangle* obj = &s->t[vertFaces[s->index[i].index[v] - startVertex - 1][t]]; if (s->t[i].normal.Dot(obj->normal) > 0.75f) { vNormal += obj->normal; } } // Add vertex normal, assign it to the right triangle vNormal.Normalize(); s->vn.Add(vNormal); s->t.objs[i].n[v] = &s->vn[s->vn.size() - 1]; vNormals[v] = s->vn.size() - 1; } // Add vertex normal index for last three normals added and link // to relevant triangle s->vnIndex[i].Set(vNormals[0], vNormals[1], vNormals[2]); } } // Clear vertFaces vector (no longer needed) for (int i = 0; i < (int)vertFaces.size(); i++) vertFaces[i].clear(); vertFaces.clear(); AABB bbox; bbox.reset(); for (int i = startVertex + 1; i < s->v.size(); i++) // Calculate bbox and centre for model bbox.extendByPoint(s->v[i]); const Vec3 centre = bbox.min + (bbox.max - bbox.min) * 0.5f; for (int i = startVertex + 1; i < s->v.size(); i++) { s->v[i] -= centre; // centre at (0,0,0) s->v[i] *= scale; // scale vertex towards centre } #if defined(DEBUG_OUTPUT) printf("Offset by (%.2f, %.2f %.2f)\n", centre[0], centre[1], centre[2]); #endif // Do rotation/translation of model if asked for if (rot.MagnitudeSquare() != 0) { Matrix3x3 m[4]; // Generate seperate matrices for each rotation m[0].RotateX(rot[0]); m[1].RotateY(rot[1]); m[2].RotateZ(rot[2]); // Combine into final matrix m[3] = m[2] * m[1] * m[0]; // Rotate all verticies and normals Vec3 vert; for (int i = startVertex + 1; i < s->v.size(); i++) { vert = s->v[i]; vert = m[3] * vert; // rotate s->v[i] = vert; } for (int i = startNormal + 1; i < s->vn.size(); i++) s->vn[i] = m[3] * s->vn[i]; } // Translate all vertices for (int i = startVertex + 1; i < s->v.size(); i++) { s->v[i] += trans; if (!recenter) s->v[i] += centre * scale; // centre at (0,0,0) } bbox.reset(); for (int i = startVertex + 1; i < s->v.size(); i++) bbox.extendByPoint(s->v[i]); // Add model info to list s->models.Add(Model(startVertex + 1, s->v.size(), startTriangle + 1, s->t.size(), bbox)); #if defined(DEBUG_OUTPUT) printf("Mesh Load: %.5fs (VN:%d ST:%d ET:%d (%d) VS:%d VE:%d)\n", meshTimer.time(), hasVertexNormals, startTriangle, s->t.size() - 1, s->t.size() - startTriangle, startVertex + 1, s->v.size() - 1); printf("Bbox: (%.2f, %.2f, %.2f) -> (%.2f, %.2f, %.2f)\n", bbox.min[0], bbox.min[1], bbox.min[2], bbox.max[0], bbox.max[1], bbox.max[2]); #endif //glmDelete(model); }
void CEnlargetMapData::CreateTransformTerrainMesh( string strTitle, DWORD dwWidth, DWORD dwDepth ) { string strMapName(""); size_t npos = strTitle.rfind("\\"); if( npos != -1 ) strMapName = strTitle.substr(npos+1, strTitle.length()); npos = strMapName.rfind("."); if( npos != -1 ) strMapName = strMapName.substr(0, npos); if( strMapName.empty() ) { MessageBox(NULL,"需要切割的地图名为空,请重新选择","提示",MB_OK); return; } // rgn mask int newGridCnt = 0, SceneLightCount = 0; DWORD newVertexCnt = 0; DWORD dwMapWidth = dwWidth * REGION_SPACE; DWORD dwMapDepth = dwDepth * REGION_SPACE; newGridCnt = dwMapWidth * dwMapDepth; newVertexCnt = (dwMapWidth + 1) * (dwMapDepth + 1); ////////////////////////////////////////////////////////////////////////// CMapEditApp::GetInst()->GetDataScene()->SetWidth( uint16(dwWidth) ); CMapEditApp::GetInst()->GetDataScene()->SetHeight( uint16(dwDepth) ); CMapEditApp::GetInst()->GetDataScene()->Create(); CSyncSystem::BeginSyncFun(); CMapEditApp::GetInst()->InitNewRenderScene(); CMapEditApp::GetInst()->GetRenderScene()->InitSceneRes(); CTerrainMesh *pTerrainNew = NULL; pTerrainNew = new CTerrainMesh; pTerrainNew->Create(dwWidth,dwDepth,m_strDefaultTerrainTexName,false,false); if( pTerrainNew == NULL ) return; CTerrainMesh * pWaterNew = new CTerrainMesh; pWaterNew->Create(dwWidth,dwDepth,m_strDefaultWaterTexName,true,false); pTerrainNew->SetWater(pWaterNew); pTerrainNew->m_strMapName = strMapName; Ast(newVertexCnt == pTerrainNew->GetVertexCount()); int nNewVertexIndex = 0, nOldVertexIndex = 0; DWORD dwNewGridIndex = 0, dwOldGridIndex = 0; ////////////////////////////////////////////////////////////////////////// ///顶点信息 uint8 uReSizeMapType = terrain->GetResizeMapType(); for ( DWORD n = 0; n < newVertexCnt; ++n ) { DWORD dwVertexIndexOld = 0, oColor = VERTEX_COLOR, sColor = VERTEX_COLOR; float fPositionY = 0.0f; CVector3f vNormal(0.0, 1.0f, 0.0f); short sLogicHeight = 0; if ( terrain->IsOverlappingByVertexIndex(dwWidth, dwDepth, n, dwVertexIndexOld, uReSizeMapType) ) { SVertex &VertexOld = terrain->GetVertex(dwVertexIndexOld); SVertex &VertexNew = pTerrainNew->GetVertex(n); VertexNew.oColor = VertexOld.oColor; VertexNew.sColor = VertexOld.sColor; VertexNew.vPosition.y = VertexOld.vPosition.y; VertexNew.vNormal = VertexOld.vNormal; VertexNew.fLogicHeight = short(VertexOld.fLogicHeight); pWaterNew->GetVertex(n).vPosition.y = VertexNew.vPosition.y + WATER_LAYER_BASE; } } ////////////////////////////////////////////////////////////////////////// // grids string strName = ""; SGrid * pGridOld = NULL; float delta = 0.001f; float U[2][4] = { {delta, 0.5f, 0.5f, delta}, {0.5f, 1.0f - delta, 1.0f - delta, 0.5f} }; float V[2][4] = { {1.0f - delta, 1.0f - delta, 0.5f, 0.5f}, {0.5f, 0.5f, delta, delta} }; map<int, int>::iterator iiter; bool bOldMapStart = true; int nOldSatrtGridInNewIndex = 0; for (int i = 0; i < newGridCnt; ++i ) { int x = i % dwMapWidth; int z = i / dwMapWidth; int nX = x % 2; int nZ = z % 2; DWORD dwGridIndexOld = 0; int nOldDivideRegionIndex = 0, nNewDivideRegionIndex = 0; SGrid * pGridNew = &pTerrainNew->GetGrid(i); pGridNew->dwGridIndex = i; if ( terrain->IsOverlappingByGridIndex(dwWidth, dwDepth, i, dwGridIndexOld, uReSizeMapType) ) { if( bOldMapStart ) { nOldSatrtGridInNewIndex = i; bOldMapStart = false; } pGridOld = &terrain->GetGrid(dwGridIndexOld); nOldDivideRegionIndex = pGridOld->m_nDivideRegionIndex; pGridNew->bGridHide = pGridOld->bGridHide; pGridNew->nBlockType = pGridOld->nBlockType; pGridNew->nodeInfo.strTextureNames[0] = pGridOld->nodeInfo.strTextureNames[0]; pGridNew->nodeInfo.strTextureNames[1] = pGridOld->nodeInfo.strTextureNames[1]; pGridNew->bCliffLayerOne = pGridOld->bCliffLayerOne; pGridNew->nMaterialIndex = pGridOld->nMaterialIndex; pGridNew->bMatNotEffectByTileSets = pGridOld->bMatNotEffectByTileSets;///强行设置该格子不受图素包设置影响,默认为受影响 for (int m = 0; m < 4; ++m) { pGridNew->uv[0][m] = pGridOld->uv[0][m]; pGridNew->uv[1][m] = pGridOld->uv[1][m]; pGridNew->subGridTypes[m] = pGridOld->subGridTypes[m]; } pGridNew->vCenter.y = pGridOld->vCenter.y; pGridNew->vecCenterObjects = pGridOld->vecCenterObjects; pGridNew->bEffectByVertexColor = pGridOld->bEffectByVertexColor; this->mapRevertSplitMapGridIndex[dwGridIndexOld] = i; this->m_OldMapRegionIndexMap[nOldDivideRegionIndex] = pGridNew->m_nDivideRegionIndex; pGridNew->bSide = pGridOld->bSide; for ( vector< CTObjectPtr >::iterator iter = pGridNew->vecCenterObjects.begin(); iter != pGridNew->vecCenterObjects.end(); ++iter) { CTObjectPtr p = (*iter); CEditModelGroup *pModelGroup = p->GetModelGroup(); CMapEditObject *pMapEditObject = NULL; pMapEditObject = pModelGroup->GetSelfPresentation(0); int nOldModelCenterGridIndex = pMapEditObject->sModelSavePro.nCenterGridIndex; iiter = this->mapRevertSplitMapGridIndex.find(nOldModelCenterGridIndex); if( iiter != this->mapRevertSplitMapGridIndex.end() ) pMapEditObject->sModelSavePro.nCenterGridIndex = iiter->second; } } else { pGridNew->nodeInfo.strTextureNames[0] = m_strDefaultTerrainTexName; pGridNew->nodeInfo.strTextureNames[1] = m_strDefaultTerrainTexName; for (int m = 0; m < 4; ++m) { pGridNew->uv[0][m].x = U[nX][m]; pGridNew->uv[0][m].y = V[nZ][m]; } } } vector<int> vecGridIndicesRiver = this->CreateRiverInfo(pWaterNew); CMapEditApp::GetInst()->SetTerrainMesh(pTerrainNew); pTerrainNew->InitTerrain((CEditTerrainMgr*)CMapEditApp::GetInst()->GetDataScene()->GetTerrainMgr()); size_t size = vecGridIndicesRiver.size(); for (size_t i = 0; i < size; ++i ) { pWaterNew->AdjustWaterMeshVisibility(vecGridIndicesRiver[i],true); } this->ChangeRegionLightInfo(); }
CTerrainMesh* CEnlargetMapData::ResizeTerrainMesh(DWORD dwWidth, DWORD dwDepth,int offW,int offL) { //string strMapName(""); //size_t npos = strTitle.rfind("\\"); //if( npos != -1 ) // strMapName = strTitle.substr(npos+1, strTitle.length()); //npos = strMapName.rfind("."); //if( npos != -1 ) // strMapName = strMapName.substr(0, npos); //if( strMapName.empty() ) //{ // MessageBox(NULL,"需要切割的地图名为空,请重新选择","提示",MB_OK); // return; //} // //旧Mesh尺寸 DWORD oldTWidth = terrain->GetWidth(); DWORD oldTDepth = terrain->GetDepth(); //新Mesh尺寸 DWORD dwMapWidth = dwWidth * REGION_SPACE; DWORD dwMapDepth = dwDepth * REGION_SPACE; DWORD newGridCnt = dwMapWidth * dwMapDepth; DWORD newVertexCnt = (dwMapWidth + 1) * (dwMapDepth + 1); //创建新的Mesh CTerrainMesh *pTerrainNew = NULL; pTerrainNew = new CTerrainMesh; pTerrainNew->Create(dwWidth,dwDepth,m_strDefaultTerrainTexName,false,false); if( pTerrainNew == NULL ) return NULL; CTerrainMesh * pWaterNew = new CTerrainMesh; pWaterNew->Create(dwWidth,dwDepth,m_strDefaultWaterTexName,true,false); pTerrainNew->SetWater(pWaterNew); pTerrainNew->InitTerrain((CEditTerrainMgr*)CMapEditApp::GetInst()->GetDataScene()->GetTerrainMgr()); Ast(newVertexCnt == pTerrainNew->GetVertexCount()); int nNewVertexIndex = 0, nOldVertexIndex = 0; DWORD dwNewGridIndex = 0, dwOldGridIndex = 0; //旧Mesh在新Mesh下影射的区域 int oldMinX=offW*REGION_SPACE; int oldMaxX=offW*REGION_SPACE+oldTWidth; int oldMinZ=offL*REGION_SPACE; int oldMaxZ=offL*REGION_SPACE+oldTDepth; //替换顶点信息 for ( DWORD n = 0; n < newVertexCnt; ++n ) { DWORD dwVertexIndexOld = 0, oColor = VERTEX_COLOR, sColor = VERTEX_COLOR; float fPositionY = 0.0f; CVector3f vNormal(0.0, 1.0f, 0.0f); short sLogicHeight = 0; int VertexX=n%(dwMapWidth + 1); int VertexZ=n/(dwMapWidth + 1); if(VertexX>=oldMinX && oldMinX<=oldMaxX && VertexZ>=oldMinZ && VertexZ<=oldMaxZ) { dwVertexIndexOld=(VertexX-offW*REGION_SPACE)+(VertexZ-offL*REGION_SPACE)*oldTWidth; SVertex &VertexOld = terrain->GetVertex(dwVertexIndexOld); SVertex &VertexNew = pTerrainNew->GetVertex(n); VertexNew.oColor = VertexOld.oColor; VertexNew.sColor = VertexOld.sColor; VertexNew.vPosition.y = VertexOld.vPosition.y; VertexNew.vNormal = VertexOld.vNormal; VertexNew.fLogicHeight = short(VertexOld.fLogicHeight); pWaterNew->GetVertex(n).vPosition.y = VertexNew.vPosition.y + WATER_LAYER_BASE; } } //替换表格信息 //纹理坐标 float delta = 0.001f; float U[2][4] = { {delta, 0.5f, 0.5f, delta}, {0.5f, 1.0f - delta, 1.0f - delta, 0.5f} }; float V[2][4] = { {1.0f - delta, 1.0f - delta, 0.5f, 0.5f}, {0.5f, 0.5f, delta, delta} }; //map<int, int>::iterator iiter; for (DWORD i = 0; i < newGridCnt; ++i ) { int x = i % dwMapWidth; int z = i / dwMapWidth; int nX = x % 2; int nZ = z % 2; DWORD dwGridIndexOld = 0; int nOldDivideRegionIndex = 0, nNewDivideRegionIndex = 0; SGrid * pGridNew = &pTerrainNew->GetGrid(i); pGridNew->dwGridIndex = i; int tmpGirdX=x-offW*REGION_SPACE; int tmpGridZ=z-offL*REGION_SPACE; if(tmpGirdX<(int)oldTWidth && tmpGirdX>=0 && tmpGridZ>=0 && tmpGridZ<(int)oldTDepth) { dwGridIndexOld=tmpGirdX+tmpGridZ*oldTWidth; SGrid* pGridOld = &terrain->GetGrid(dwGridIndexOld); nOldDivideRegionIndex = pGridOld->m_nDivideRegionIndex; pGridNew->bGridHide = pGridOld->bGridHide; pGridNew->nBlockType = pGridOld->nBlockType; pGridNew->nodeInfo.strTextureNames[0] = pGridOld->nodeInfo.strTextureNames[0]; pGridNew->nodeInfo.strTextureNames[1] = pGridOld->nodeInfo.strTextureNames[1]; pGridNew->bCliffLayerOne = pGridOld->bCliffLayerOne; pGridNew->nMaterialIndex = pGridOld->nMaterialIndex; pGridNew->bMatNotEffectByTileSets = pGridOld->bMatNotEffectByTileSets;///强行设置该格子不受图素包设置影响,默认为受影响 for (int m = 0; m < 4; ++m) { pGridNew->uv[0][m] = pGridOld->uv[0][m]; pGridNew->uv[1][m] = pGridOld->uv[1][m]; pGridNew->subGridTypes[m] = pGridOld->subGridTypes[m]; } pGridNew->vCenter.y = pGridOld->vCenter.y; pGridNew->vecCenterObjects = pGridOld->vecCenterObjects; pGridNew->bEffectByVertexColor = pGridOld->bEffectByVertexColor; this->mapRevertSplitMapGridIndex[dwGridIndexOld] = i; this->m_OldMapRegionIndexMap[nOldDivideRegionIndex] = pGridNew->m_nDivideRegionIndex; pGridNew->bSide = pGridOld->bSide; //模型信息 //for ( vector< CTObjectPtr >::iterator iter = pGridNew->vecCenterObjects.begin(); iter != pGridNew->vecCenterObjects.end(); ++iter) //{ // CTObjectPtr p = (*iter); // CEditModelGroup *pModelGroup = p->GetModelGroup(); // CMapEditObject *pMapEditObject = NULL; // pMapEditObject = pModelGroup->GetSelfPresentation(0); // int nOldModelCenterGridIndex = pMapEditObject->sModelSavePro.nCenterGridIndex; // iiter = this->mapRevertSplitMapGridIndex.find(nOldModelCenterGridIndex); // if( iiter != this->mapRevertSplitMapGridIndex.end() ) // pMapEditObject->sModelSavePro.nCenterGridIndex = iiter->second; //} } else { pGridNew->nodeInfo.strTextureNames[0] = m_strDefaultTerrainTexName; pGridNew->nodeInfo.strTextureNames[1] = m_strDefaultTerrainTexName; for (int m = 0; m < 4; ++m) { pGridNew->uv[0][m].x = U[nX][m]; pGridNew->uv[0][m].y = V[nZ][m]; } } } //水面信息 //vector<int> vecGridIndicesRiver = this->CreateRiverInfo(pWaterNew); //pTerrainNew->InitTerrain((CEditTerrainMgr*)CMapEditApp::GetInst()->GetDataScene()->GetTerrainMgr()); //size_t size = vecGridIndicesRiver.size(); //for (size_t i = 0; i < size; ++i ) //{ // pWaterNew->AdjustWaterMeshVisibility(vecGridIndicesRiver[i],true); //} //区域光 //this->ChangeRegionLightInfo(); return pTerrainNew; }