void FBXParser::ProcessFBXMaterial(const aiScene* pFbxScene, unsigned int iIndex, CParaXModel *pMesh) { aiMaterial* pfbxMaterial = pFbxScene->mMaterials[iIndex]; unsigned int iUV; float fBlend; aiTextureOp eOp; aiString szPath; char* content_begin = NULL; int content_len = -1; std::string sMatName; { aiString sMaterialName; if (AI_SUCCESS == aiGetMaterialString(pfbxMaterial, AI_MATKEY_NAME, &sMaterialName)) sMatName = sMaterialName.C_Str(); } aiGetMaterialTexture(pfbxMaterial, (aiTextureType)aiTextureType_DIFFUSE, 0, &szPath, NULL, &iUV, &fBlend, &eOp, NULL, NULL, &content_begin, &content_len); std::string diffuseTexName(szPath.C_Str()); if (diffuseTexName != "") { diffuseTexName = GetTexturePath(diffuseTexName); if (content_begin) { std::string sFileName = CParaFile::GetFileName(m_sFilename); diffuseTexName = CParaFile::GetParentDirectoryFromPath(diffuseTexName) + sFileName + "/" + CParaFile::GetFileName(diffuseTexName); m_textureContentMapping[diffuseTexName] = ""; m_textureContentMapping[diffuseTexName].append(content_begin, content_len); // OUTPUT_LOG("embedded FBX texture %s used. size %d bytes\n", texname.c_str(), (int)m_textureContentMapping[texname].size()); } else if (!CParaFile::DoesFileExist(diffuseTexName.c_str(), true)) { OUTPUT_LOG("warn: FBX texture %s not exist\n", diffuseTexName.c_str()); diffuseTexName = ""; } } m_beUsedVertexColor = diffuseTexName.empty() && m_beUsedVertexColor; // parse material name FBXMaterial fbxMat; ParseMaterialByName(sMatName, &fbxMat); int16 blendmode = BM_OPAQUE; if (!diffuseTexName.empty()) { if (AI_SUCCESS == aiGetMaterialTexture(pfbxMaterial, (aiTextureType)aiTextureType_OPACITY, 0, &szPath, NULL, &iUV, &fBlend, &eOp, NULL, NULL, &content_begin, &content_len)) { if (fbxMat.isAlphaBlended()) blendmode = BM_ALPHA_BLEND; else blendmode = BM_TRANSPARENT; } } if (fbxMat.bAddictive) blendmode = BM_ADDITIVE; if (m_beUsedVertexColor) { diffuseTexName = std::string(g_sDefaultTexture); } fbxMat.m_filename = diffuseTexName; m_textures.push_back(fbxMat); int texture_index = m_textures.size() - 1; ModelRenderPass pass; pass.tex = texture_index; pass.SetCategoryId(fbxMat.GetCategoryID()); pass.texanim = -1; pass.color = -1; pass.opacity = -1; pass.unlit = fbxMat.bUnlit; pass.nozwrite = fbxMat.bDisableZWrite; pass.disable_physics = fbxMat.bDisablePhysics; pass.force_physics = fbxMat.bForcePhysics; pass.blendmode = blendmode; pass.cull = blendmode == BM_OPAQUE ? true : false; pass.order = fbxMat.m_nOrder; pass.geoset = 0; //*(((DWORD*)&(pass.geoset)) + 1) = parser.ReadInt(); pMesh->passes.push_back(pass); }
// MilkShape 3D void ExportMS3D_M2(Attachment *att, Model *m, const char *fn, bool init) { wxFFileOutputStream f(wxString(fn, wxConvUTF8), wxT("w+b")); if (!f.IsOk()) { wxLogMessage(wxT("Error: Unable to open file '%s'. Could not export model."), fn); return; } LogExportData(wxT("MS3D"),m->modelname,wxString(fn, wxConvUTF8)); unsigned short numVerts = 0; unsigned short numFaces = 0; unsigned short numGroups = 0; ModelData *verts = NULL; GroupData *groups = NULL; //we need the initial position anyway InitCommon(att, true, verts, groups, numVerts, numGroups, numFaces); //wxLogMessage(wxT("Num Verts: %i, Num Faces: %i, Num Groups: %i"), numVerts, numFaces, numGroups); //wxLogMessage(wxT("Vert[0] BoneID: %i, Group[0].m.name = %s"),verts[0].boneid, groups[0].m->name); wxLogMessage(wxT("Init Common Complete.")); // Write the header ms3d_header_t header; strncpy(header.id, "MS3D000000", sizeof(header.id)); header.version = 4; // Header f.Write(reinterpret_cast<char *>(&header), sizeof(ms3d_header_t)); wxLogMessage(wxT("Header Data Written.")); // Vertex Count f.Write(reinterpret_cast<char *>(&numVerts), sizeof(numVerts)); //wxLogMessage(wxT("NumVerts: %i"),numVerts); // Write Vertex data? for (size_t i=0; i<numVerts; i++) { ms3d_vertex_t vert; vert.boneId = verts[i].boneid; vert.flags = 0; //SELECTED; vert.referenceCount = 0; // what the? vert.vertex[0] = verts[i].vertex.x; vert.vertex[1] = verts[i].vertex.y; vert.vertex[2] = verts[i].vertex.z; f.Write(reinterpret_cast<char *>(&vert), sizeof(ms3d_vertex_t)); } wxLogMessage(wxT("Vertex Data Written.")); // --------------------------- // Triangle Count f.Write(reinterpret_cast<char *>(&numFaces), sizeof(numFaces)); //wxLogMessage(wxT("NumFaces: %i"),numFaces); // Write Triangle Data? for (size_t i=0; i<(unsigned int)numVerts; i+=3) { ms3d_triangle_t tri; tri.flags = 0; //SELECTED; tri.groupIndex = (unsigned char)verts[i].groupIndex; tri.smoothingGroup = 1; // 1 - 32 for (ssize_t j=0; j<3; j++) { tri.vertexIndices[j] = (word)i+j; tri.s[j] = verts[i+j].tu; tri.t[j] = verts[i+j].tv; tri.vertexNormals[j][0] = verts[i+j].normal.x; tri.vertexNormals[j][1] = verts[i+j].normal.y; tri.vertexNormals[j][2] = verts[i+j].normal.z; } f.Write(reinterpret_cast<char *>(&tri), sizeof(ms3d_triangle_t)); } wxLogMessage(wxT("Triangle Data Written.")); // --------------------------- // Number of groups f.Write(reinterpret_cast<char *>(&numGroups), sizeof(numGroups)); //wxLogMessage(wxT("NumGroups: %i"),numGroups); unsigned short indiceCount = 0; for (unsigned short i=0; i<(unsigned int)numGroups; i++) { wxString groupName(wxString::Format(wxT("Geoset_%i"), i)); const char flags = 0; // SELECTED f.Write(&flags, sizeof(flags)); char name[32]; strncpy(name, groupName.mb_str(), sizeof(name)); f.Write(name, sizeof(name)); unsigned short faceCount = groups[i].p.indexCount / 3; f.Write(reinterpret_cast<char *>(&faceCount), sizeof(faceCount)); for (ssize_t k=0; k<faceCount; k++) { //triIndices[k] = indiceCount; f.Write(reinterpret_cast<char *>(&indiceCount), sizeof(indiceCount)); indiceCount++; } unsigned char gIndex = (char)i; f.Write(reinterpret_cast<char *>(&gIndex), sizeof(gIndex)); } wxLogMessage(wxT("Group Data Written.")); // Number of materials (pretty much identical to groups, each group has its own material) f.Write(reinterpret_cast<char *>(&numGroups), sizeof(numGroups)); for (unsigned short i=0; i<(unsigned int)numGroups; i++) { wxString matName(wxString::Format(wxT("Material_%i"), i)); ModelRenderPass p = groups[i].p; if (p.init(groups[i].m)) { ms3d_material_t mat; memset(mat.alphamap, '\0', sizeof(mat.alphamap)); strncpy(mat.name, matName.mb_str(), sizeof(mat.name)); mat.ambient[0] = 0.7f; mat.ambient[1] = 0.7f; mat.ambient[2] = 0.7f; mat.ambient[3] = 1.0f; mat.diffuse[0] = p.ocol.x; mat.diffuse[1] = p.ocol.y; mat.diffuse[2] = p.ocol.z; mat.diffuse[3] = p.ocol.w; mat.specular[0] = 0.0f; mat.specular[1] = 0.0f; mat.specular[2] = 0.0f; mat.specular[3] = 1.0f; mat.emissive[0] = p.ecol.x; mat.emissive[1] = p.ecol.y; mat.emissive[2] = p.ecol.z; mat.emissive[3] = p.ecol.w; mat.transparency = p.ocol.w; if (p.useEnvMap) { mat.shininess = 30.0f; mat.mode = 1; } else { mat.shininess = 0.0f; mat.mode = 0; } /* unsigned int bindtex = 0; if (groups[i].m->specialTextures[p.tex]==-1) bindtex = groups[i].m->textures[p.tex]; else bindtex = groups[i].m->replaceTextures[groups[i].m->specialTextures[p.tex]]; */ wxString texName = GetM2TextureName(m,p,i); texName << wxT(".tga"); strncpy(mat.texture, texName.mb_str(), sizeof(mat.texture)); f.Write(reinterpret_cast<char *>(&mat), sizeof(ms3d_material_t)); wxString texFilename(fn, wxConvUTF8); texFilename = texFilename.BeforeLast(SLASH); texFilename += SLASH; texFilename += texName; wxLogMessage(wxT("Exporting Image: %s"),texFilename.c_str()); SaveTexture(texFilename); } } wxLogMessage(wxT("Material Data Written.")); if (init) { float fps = 1.0f; float fCurTime = 0.0f; int totalFrames = 0; f.Write(reinterpret_cast<char *>(&fps), sizeof(fps)); f.Write(reinterpret_cast<char *>(&fCurTime), sizeof(fCurTime)); f.Write(reinterpret_cast<char *>(&totalFrames), sizeof(totalFrames)); // number of joints unsigned short numJoints = 0; f.Write(reinterpret_cast<char *>(&numJoints), sizeof(numJoints)); } else { float fps = 25.0f; float fCurTime = 0.0f; int totalFrames = ceil((m->anims[m->anim].timeEnd - m->anims[m->anim].timeStart) / 1000.0f * fps); f.Write(reinterpret_cast<char *>(&fps), sizeof(fps)); f.Write(reinterpret_cast<char *>(&fCurTime), sizeof(fCurTime)); f.Write(reinterpret_cast<char *>(&totalFrames), sizeof(totalFrames)); // number of joints unsigned short numJoints = (unsigned short)m->header.nBones; f.Write(reinterpret_cast<char *>(&numJoints), sizeof(numJoints)); for (size_t i=0; i<numJoints; i++) { ms3d_joint_t joint; int parent = m->bones[i].parent; joint.flags = 0; // SELECTED memset(joint.name, '\0', sizeof(joint.name)); snprintf(joint.name, sizeof(joint.name), "Bone_%i", i); memset(joint.parentName, '\0', sizeof(joint.parentName)); if (parent != -1) snprintf(joint.parentName, sizeof(joint.parentName), "Bone_%i", parent); joint.rotation[0] = 0; joint.rotation[1] = 0; joint.rotation[2] = 0; Vec3D p = FixPivot(m, (int)i, m->bones[i].pivot); joint.position[0] = p.x; joint.position[1] = p.y; joint.position[2] = p.z; joint.numKeyFramesRot = (unsigned short)m->bones[i].rot.data[m->anim].size(); joint.numKeyFramesTrans = (unsigned short)m->bones[i].trans.data[m->anim].size(); f.Write(reinterpret_cast<char *>(&joint), sizeof(ms3d_joint_t)); if (joint.numKeyFramesRot > 0) { ms3d_keyframe_rot_t *keyFramesRot = new ms3d_keyframe_rot_t[joint.numKeyFramesRot]; for (size_t j=0; j<joint.numKeyFramesRot; j++) { keyFramesRot[j].time = m->bones[i].rot.times[m->anim][j] / 1000.0f; Vec3D euler = QuatToEuler(m->bones[i].rot.data[m->anim][j]); keyFramesRot[j].rotation[0] = euler.x; keyFramesRot[j].rotation[1] = euler.y; keyFramesRot[j].rotation[2] = euler.z; } f.Write(reinterpret_cast<char *>(keyFramesRot), sizeof(ms3d_keyframe_rot_t) * joint.numKeyFramesRot); wxDELETEA(keyFramesRot); } if (joint.numKeyFramesTrans > 0) { ms3d_keyframe_pos_t *keyFramesTrans = new ms3d_keyframe_pos_t[joint.numKeyFramesTrans]; for (size_t j=0; j<joint.numKeyFramesTrans; j++) { keyFramesTrans[j].time = m->bones[i].trans.times[m->anim][j] / 1000.0f; keyFramesTrans[j].position[0] = m->bones[i].trans.data[m->anim][j].x; keyFramesTrans[j].position[1] = m->bones[i].trans.data[m->anim][j].y; keyFramesTrans[j].position[2] = m->bones[i].trans.data[m->anim][j].z; } f.Write(reinterpret_cast<char *>(keyFramesTrans), sizeof(ms3d_keyframe_pos_t) * joint.numKeyFramesTrans); wxDELETEA(keyFramesTrans); } } } f.Close(); wxLogMessage(wxT("Finished Milkshape Export.")); if (verts){ //wxLogMessage("verts found. Deleting..."); wxDELETEA(verts); } if (groups){ //wxLogMessage("groups found. Deleting..."); wxDELETEA(groups); } //wxLogMessage(wxT("Finished Milkshape Cleanup.\n")); }
void M2Object::CreateRenderPass() { //LoadModelData(); if (header.nVertices == 0) return; LoadModelData2(); size_t count = renderPasses.size(); int currPass = 0; for (size_t i=0; i < count; ++i) { ModelRenderPass pass = renderPasses.at(i); if (pass.init(this)) { RenderData& data = render_data[currPass++]; GetRenderData(data); data.colorIndex = pass.color; data.opacity = pass.opacity; data.startIndex = pass.indexStart; data.endIndex = pass.indexCount; data.vertexStart = pass.vertexStart; data.vertexEnd = pass.vertexEnd; uint32 bindtex = 0; if (specialTextures[pass.tex]==-1) bindtex = textureIds[pass.tex]; else bindtex = replaceTextures[specialTextures[pass.tex]]; data.baseTex = bindtex; if (replaceTextures[TEXTURE_BUMP] > 0) { data.bumpTex = replaceTextures[TEXTURE_BUMP]; //data.normalSampler = } // Texture // ALPHA BLENDING // blend mode BlendStateID blend = -1; switch (pass.blendmode) { case BM_OPAQUE: // 0 break; case BM_TRANSPARENT: // 1 //glEnable(GL_ALPHA_TEST); //glAlphaFunc(GL_GEQUAL,0.7f); // Dx10 ÀÌÈÄ Alpha Test ¾ø¾îÁü. break; case BM_ALPHA_BLEND: blend = GetApp()->GetBlendMode(0); break; case BM_ADDITIVE: // 3 blend = GetApp()->GetBlendMode(1); break; case BM_ADDITIVE_ALPHA: blend = GetApp()->GetBlendMode(2); break; case BM_MODULATE: blend = GetApp()->GetBlendMode(3); break; case BM_MODULATEX2: // 6, not sure if this is right blend = GetApp()->GetBlendMode(4); break; default: blend = GetApp()->GetBlendMode(5); break; } data.blendMode = blend; if (pass.cull) data.cull = renderer->addRasterizerState(D3D11_CULL_FRONT); else data.cull = renderer->addRasterizerState(D3D11_CULL_NONE); DepthStateID depthid = -1; if (pass.noZWrite) // depth write == false depthid = renderer->addDepthState(true, false); else depthid = renderer->addDepthState(true, true); data.depthMode = depthid; data.unlit = pass.unlit; } } numPass = currPass; }