Exemple #1
0
		PlaneIntergrationMaker()
		{
			D3DXVECTOR3 vNormal(1,1,1);
			D3DXVec3Normalize(&vNormal, &vNormal);
			FLOAT fNear = (FLOAT)em_mesh_range / 4;
			D3DXPlaneFromPointNormal(&plane, &D3DXVECTOR3(fNear, 0,0), &vNormal);
		}
Exemple #2
0
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;
}
Exemple #4
0
//*****************************************************************************
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;
}
Exemple #6
0
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;
}
Exemple #7
0
//---フィールド頂点を初期化
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();
}
Exemple #9
0
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);
		}
	}
Exemple #13
0
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;
	}