コード例 #1
0
ファイル: M2ImportGeom.cpp プロジェクト: helloqinglan/qinglan
// 1. 加载模型顶点数据
void M2Importer::importGeomObject()
{
	// Group Header Node
	INode* groupHeadNode = createGroupHeaderNode();
	groupHeadNode->SetGroupHead(TRUE);
	groupHeadNode->SetGroupMember(FALSE);

	if (m_modelHeader->nameLength > 1)
	{
		TCHAR* modelName = (TCHAR*)(m_m2FileData + m_modelHeader->nameOfs);
		groupHeadNode->SetName(modelName);
		m_logStream << "ModelName: " << modelName << endl;
	}
	else
		groupHeadNode->SetName("GeomGroup");


	// Geoset
	// 一个Geoset构造一个Node, 并且加入到组中

	unsigned short* verDataIndex = (unsigned short*)(m_m2FileData + m_modelView->ofsIndex);
	unsigned short* triData = (unsigned short*)(m_m2FileData + m_modelView->ofsTris);

	m_geosetNodeList.reserve(m_modelView->nSub);
	m_materialList.reserve(m_modelView->nSub);
	for (unsigned int i = 0; i < m_modelView->nSub; ++i)
		m_materialList.push_back(0);

	for (unsigned int i = 0; i < m_modelView->nSub; ++i)
	{
		ModelGeoset& geosetData = m_modelGeoset[i];

		// Triangle Mesh Object
		// 基本的三角形模型对象
		TriObject* triObject = CreateNewTriObject();

		// 创建Node, 并且设为Group Header Node的子节点
		ImpNode* tmpImpNode = m_impInterface->CreateNode();
		tmpImpNode->Reference(triObject);
		//tmpImpNode->SetPivot(*(Point3*)&(geosetData.v));

		m_impInterface->AddNodeToScene(tmpImpNode);
		INode* realINode = tmpImpNode->GetINode();
		realINode->SetGroupHead(FALSE);
		realINode->SetGroupMember(TRUE);
		groupHeadNode->AttachChild(realINode);

		m_geosetNodeList.push_back(realINode);

		TCHAR nodeName[256];
		sprintf(nodeName, "GeosetPart_%d", i);
		realINode->SetName(nodeName);

		// mesh
		Mesh& mesh = triObject->GetMesh();
		mesh.setNumVerts(geosetData.vcount);
		mesh.setNumTVerts(geosetData.vcount, TRUE);

		unsigned int triangeCount = geosetData.icount / 3;
		mesh.setNumFaces(triangeCount);
		mesh.setNumTVFaces(triangeCount);

		m_logStream << "Model Geoset " << i << " Vertex Count: " << geosetData.vcount << endl;
		m_logStream << "Model Geoset " << i << " Index Count: " << triangeCount << endl;

		// 顶点坐标和UV
		for (unsigned int i = 0; i < geosetData.vcount; ++i)
		{
			ModelVertex& vertexData = m_globalVertices[ verDataIndex[geosetData.vstart + i] ];

			mesh.verts[i] = *(Point3*)(&vertexData.pos);

			// UV坐标反转
			mesh.tVerts[i].x = vertexData.texcoords.x;
			mesh.tVerts[i].y = 1.0f - vertexData.texcoords.y;
		}

		// 三角形
		for (unsigned int i = 0; i < triangeCount; ++i)
		{
			Face& face = mesh.faces[i];
			face.setVerts(triData[geosetData.istart + i*3] - m_indexCount, 
						  triData[geosetData.istart + i*3+1] - m_indexCount, 
						  triData[geosetData.istart + i*3+2] - m_indexCount);
			face.Show();
			face.setEdgeVisFlags(EDGE_VIS, EDGE_VIS, EDGE_VIS);

			TVFace& tface = mesh.tvFace[i];
			tface.setTVerts(triData[geosetData.istart + i*3] - m_indexCount, 
							triData[geosetData.istart + i*3+1] - m_indexCount, 
							triData[geosetData.istart + i*3+2] - m_indexCount);
		}

		// 法线
		mesh.SpecifyNormals();
		MeshNormalSpec *specNorms = mesh.GetSpecifiedNormals();
		if (specNorms)
		{
			specNorms->ClearAndFree();
			specNorms->SetNumFaces(triangeCount);
			specNorms->SetNumNormals(geosetData.vcount);

			Point3* norms = specNorms->GetNormalArray();
			for (unsigned int i = 0; i < geosetData.vcount; ++i)
			{
				ModelVertex& vertexData = m_globalVertices[ verDataIndex[geosetData.vstart + i] ];
				norms[i] = *(Point3*)(&vertexData.normal);
			}

			MeshNormalFace* pFaces = specNorms->GetFaceArray();
			for (unsigned int i = 0; i < triangeCount; ++i)
			{
				pFaces[i].SpecifyNormalID(0, triData[geosetData.istart + i*3] - m_indexCount);
				pFaces[i].SpecifyNormalID(1, triData[geosetData.istart + i*3+1] - m_indexCount);
				pFaces[i].SpecifyNormalID(2, triData[geosetData.istart + i*3+2] - m_indexCount);
			}

			specNorms->SetAllExplicit(true);
			specNorms->CheckNormals();
		}

		// 删除重复的和无效的面
		mesh.RemoveDegenerateFaces();
		mesh.RemoveIllegalFaces();

		//realINode->BackCull(FALSE);			// 取消背面裁减 双面绘制与取消背面裁减一起设置
		realINode->EvalWorldState(0);

		// 索引值修正
		m_indexCount += geosetData.vcount;
	}

	// 加载材质
	unsigned short* texLookupData = (unsigned short*)(m_m2FileData + m_modelHeader->ofsTexLookup);
	ModelTextureDef* texUnitDefData = (ModelTextureDef*)(m_m2FileData + m_modelHeader->ofsTextures);
	ModelTexUnit* texUnitData = (ModelTexUnit*)(m_m2FileData + m_modelView->ofsTex);

	for (unsigned int i = 0; i < m_modelView->nTex; ++i)
	{
		ModelTexUnit& texUnit = texUnitData[i];
		unsigned short textureID = texLookupData[texUnit.textureid];
		ModelTextureDef& texDef = texUnitDefData[textureID];

		string textureName;

		if (texDef.type == 0)
			textureName = (LPCSTR)(m_m2FileData + texDef.nameOfs);
		else
			textureName = getReplacableTexture(texDef.type);

		StdMat2* material = m_materialList[texUnit.op];
		if (!material)
			material = createMaterial();

		// 根据混合属性决定加在第几层
		material->SetSubTexmap(ID_DI, createTexture(textureName.c_str()));
		material->EnableMap(ID_DI, TRUE);
		//material->SetTwoSided(TRUE);		// 双面 设置了此标志的才打开

		m_maxInterface->GetMaterialLibrary().Add(material);
		m_geosetNodeList[texUnit.op]->SetMtl(material);
	}

	m_maxInterface->RedrawViews(m_maxInterface->GetTime());
}
コード例 #2
0
StdMat2 *NifImporter::ImportMaterialAndTextures(ImpNode *node, NiAVObjectRef avObject)
{
   // Texture
   NiMaterialPropertyRef matRef = avObject->GetPropertyByType(NiMaterialProperty::TYPE);
   if (matRef != NULL){

		StdMat2 *m = NewDefaultStdMat();
		m->SetName(matRef->GetName().c_str());
		if (showTextures) {
			m->SetMtlFlag(MTL_DISPLAY_ENABLE_FLAGS, TRUE);
		}

		// try the civ4 shader first then default back to normal shaders
		if (ImportNiftoolsShader(node, avObject, m)) {
			return m;
		}

		NiTexturingPropertyRef texRef = avObject->GetPropertyByType(NiTexturingProperty::TYPE);
		NiWireframePropertyRef wireRef = avObject->GetPropertyByType(NiWireframeProperty::TYPE);
		NiAlphaPropertyRef alphaRef = avObject->GetPropertyByType(NiAlphaProperty::TYPE);
		NiStencilPropertyRef stencilRef = avObject->GetPropertyByType(NiStencilProperty::TYPE);
		NiShadePropertyRef shadeRef = avObject->GetPropertyByType(NiShadeProperty::TYPE);
		vector<NiPropertyRef> props = avObject->GetProperties();

		if (IsFallout3()) {
			m->SetAmbient(Color(0.588f, 0.588f, 0.588f),0);
			m->SetDiffuse(Color(0.588f, 0.588f, 0.588f),0);
			m->SetSpecular(Color(0.902f, 0.902f, 0.902f),0);
		} else {
			m->SetAmbient(TOCOLOR(matRef->GetAmbientColor()),0);
			m->SetDiffuse(TOCOLOR(matRef->GetDiffuseColor()),0);
			m->SetSpecular(TOCOLOR(matRef->GetSpecularColor()),0);
		}
      Color c = TOCOLOR(matRef->GetEmissiveColor());
      if (c.r != 0 || c.b != 0 || c.g != 0) {
         m->SetSelfIllumColorOn(TRUE);
         m->SetSelfIllumColor(c,0);
      }
      m->SetShinStr(0.0,0);
      m->SetShininess(matRef->GetGlossiness()/100.0,0);
      m->SetOpacity(matRef->GetTransparency(),0);

      bool hasShaderAttributes = (wireRef != NULL) || (stencilRef != NULL) || (shadeRef != NULL);
      if (m->SupportsShaders() && hasShaderAttributes) {
         if (Shader *s = m->GetShader()) {
            if (wireRef != NULL && (wireRef->GetFlags() & 1)) {
               BOOL value = TRUE;
               m->SetWire(value);
            }
            if (stencilRef != NULL) {
				if (stencilRef->GetFaceDrawMode() == DRAW_BOTH) {
                  BOOL value = TRUE;
                  m->SetTwoSided(value);
               }
            }
            if (shadeRef != NULL && shadeRef->GetFlags() & 1) {
               m->SetFaceted(TRUE);
            }
         }
      }

      if (NULL != texRef)
      {
         // Handle Base/Detail ???
         if (texRef->HasTexture(DECAL_0_MAP)){
            if (Texmap* tex = CreateTexture(texRef->GetTexture(DECAL_0_MAP)))
               m->SetSubTexmap(ID_DI, tex);
            if (texRef->HasTexture(BASE_MAP)){
               m->LockAmbDiffTex(FALSE);
               if (Texmap* tex = CreateTexture(texRef->GetTexture(BASE_MAP)))
                  m->SetSubTexmap(ID_AM, tex);
            }
         } else if (texRef->HasTexture(BASE_MAP)) {
			 if (Texmap* tex = CreateTexture(texRef->GetTexture(BASE_MAP))) {
               m->SetSubTexmap(ID_DI, tex);
			   if (showTextures) gi->ActivateTexture(tex,m);
			 }
         } 
         // Handle Bump map
         if (texRef->HasTexture(BUMP_MAP)) {
            if (Texmap* tex = CreateTexture(texRef->GetTexture(BUMP_MAP)))
               m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex));
         }
         // Shiny map
         if (texRef->HasTexture(GLOSS_MAP)) {
            if (Texmap* tex = CreateTexture(texRef->GetTexture(GLOSS_MAP)))
               m->SetSubTexmap(ID_SS, tex);
         }
         // Self illumination
         if (texRef->HasTexture(GLOW_MAP)) {
            if (Texmap* tex = CreateTexture(texRef->GetTexture(GLOW_MAP)))
               m->SetSubTexmap(ID_SI, tex);
         }

         // Custom Shader Handling
         int nTex = texRef->GetShaderTextureCount();
         if (nTex > 0) {
            list<NiExtraDataRef> data = avObject->GetExtraData();
            NiGeometryRef trigeom = DynamicCast<NiGeometry>(avObject);
            if (trigeom->HasShader()) {
               for (list<NiExtraDataRef>::iterator itr = data.begin(); itr != data.end(); ++itr) {
                  if ( NiIntegerExtraDataRef idx = DynamicCast<NiIntegerExtraData>(*itr) ) {
                     string name = idx->GetName();
                     if ( wildmatch("*Index", name) ) {
                        int shader = idx->GetData();
                        if (shader < nTex) {
                           if ( name == "NormalMapIndex" ) {
                              if (Texmap* tex = CreateTexture(texRef->GetShaderTexture(shader)))
                                 m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex));
                           } else if ( name == "SpecularIntensity" ) {
                              if (Texmap* tex = CreateTexture(texRef->GetShaderTexture(shader)))
                                 m->SetSubTexmap(ID_SP, CreateNormalBump(NULL, tex));
                           }
                        }
                     }
                  }
               }
            }
         }
      }
		if (NiTexturePropertyRef tex2Ref = avObject->GetPropertyByType(NiTextureProperty::TYPE)){
			// Handle Base/Detail ???
			if (Texmap* tex = CreateTexture(tex2Ref)) {
				m->SetSubTexmap(ID_DI, tex);
			} 
		}
		if (BSShaderNoLightingPropertyRef noLightShadeRef = SelectFirstObjectOfType<BSShaderNoLightingProperty>(props)) {
			if ( Texmap* tex = CreateTexture( noLightShadeRef->GetFileName() ) ) {
				m->SetSubTexmap(ID_DI, tex);
			}
		}
		if (BSShaderPPLightingPropertyRef ppLightShadeRef = SelectFirstObjectOfType<BSShaderPPLightingProperty>(props)) {
			if ( BSShaderTextureSetRef textures = ppLightShadeRef->GetTextureSet() ) {
				if ( Texmap* tex = CreateTexture( textures->GetTexture(0) ) )
					m->SetSubTexmap(ID_DI, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(1) ) )
               m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex));
            if ( Texmap* tex = CreateTexture( textures->GetTexture(3) ) )
               m->SetSubTexmap(ID_SI, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(4) ) )
               m->SetSubTexmap(ID_RL, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(5) ) ) {
               if ( Texmap* mask = CreateTexture( textures->GetTexture(2) ) )
                  tex = CreateMask(NULL, tex, mask);
               m->SetSubTexmap(ID_SP, tex);
            }
			}
		}
		if (SkyShaderPropertyRef skyShadeRef = SelectFirstObjectOfType<SkyShaderProperty>(props)) {
			if ( Texmap* tex = CreateTexture( skyShadeRef->GetFileName() ) ) {
				m->SetSubTexmap(ID_DI, tex);
			}
		}
		if (TileShaderPropertyRef tileShadeRef = SelectFirstObjectOfType<TileShaderProperty>(props)) {
			if ( Texmap* tex = CreateTexture( tileShadeRef->GetFileName() ) ) {
				m->SetSubTexmap(ID_DI, tex);
			}
		}
		if (TallGrassShaderPropertyRef grassShadeRef = SelectFirstObjectOfType<TallGrassShaderProperty>(props)) {
			if ( Texmap* tex = CreateTexture( grassShadeRef->GetFileName() ) ) {
				m->SetSubTexmap(ID_DI, tex);
			}
		}
		if (Lighting30ShaderPropertyRef lighting30ShadeRef = SelectFirstObjectOfType<Lighting30ShaderProperty>(props)) {
         if ( BSShaderTextureSetRef textures = lighting30ShadeRef->GetTextureSet() ) {
            if ( Texmap* tex = CreateTexture( textures->GetTexture(0) ) )
               m->SetSubTexmap(ID_DI, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(1) ) )
               m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex));
            if ( Texmap* tex = CreateTexture( textures->GetTexture(3) ) )
               m->SetSubTexmap(ID_SI, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(4) ) )
               m->SetSubTexmap(ID_RL, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(5) ) ) {
               if ( Texmap* mask = CreateTexture( textures->GetTexture(2) ) )
                  tex = CreateMask(NULL, tex, mask);
               m->SetSubTexmap(ID_SP, tex);
            }
         }
		}
		return m;
   }
   return NULL;
}