Class_ID ClassID ( ) { return Class_ID(YUVCLASSID,0); }
void AWDExporter::ExportMaterial( AWD *awd, awd_ncache *ncache, Mtl* mtl, int mtlID, int subNo) { TimeValue t = GetStaticFrame(); int i; BOOL usediffusemap = FALSE; const char *name = mtl->GetName(); int namelen = strlen( name ); AWDMaterial *material = new AWDMaterial( AWD_MATTYPE_COLOR, name, namelen ); AWDTexture *tex; for (i=0; i<mtl->NumSubTexmaps(); i++) { Texmap* subTex = mtl->GetSubTexmap(i); float amt = 1.0f; if (subTex) { // If it is a standard material we can see if the map is enabled. if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { if (!((StdMat*)mtl)->MapEnabled(i)) continue; amt = ((StdMat*)mtl)->GetTexmapAmt(i, 0); } tex = ExportTexture(awd, ncache, subTex, mtl->ClassID(), i, material ); if( tex && i == ID_DI ) { usediffusemap = true; } } } if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { StdMat* std = (StdMat*)mtl; material->color = get_awd_color( std->GetDiffuse(t), 1.0f ); } else { material->color = get_awd_color( mtl->GetDiffuse(), 1.0f ); } AWD_mat_type mattype; if( usediffusemap ) mattype = AWD_MATTYPE_BITMAP; else mattype = AWD_MATTYPE_COLOR; material->set_type( mattype ); awd_ncache_add(ncache, (InterfaceServer*)mtl, material); awd->add_material( material ); if (mtl->NumSubMtls() > 0) { for (i=0; i<mtl->NumSubMtls(); i++) { Mtl* subMtl = mtl->GetSubMtl(i); if (subMtl && mtlList.GetMtlID( subMtl ) == -1 ) { ExportMaterial(awd, ncache, subMtl, 0, i); } } } }
void XsiExp::DumpTexture(Texmap* tex, Class_ID cid, int subNo, float amt, int indentLevel) { if (!tex) return; TSTR indent = GetIndent(indentLevel+1); TSTR className; tex->GetClassName(className); if (tex->ClassID() == Class_ID(BMTEX_CLASS_ID, 0x00)) { fprintf(pStream, "%sSI_Texture2D {\n", indent.data() ); TSTR mapName = ((BitmapTex *)tex)->GetMapName(); fprintf(pStream, "%s\t\"%s\";\n", indent.data(), FixupName(mapName)); fprintf(pStream, "%s\t3;\n", indent.data()); fprintf(pStream, "%s\t0;0;\n", indent.data()); fprintf(pStream, "%s\t0;12594;0;543;\n", indent.data()); fprintf(pStream, "%s\t0;\n", indent.data()); fprintf(pStream, "%s\t1;1;\n", indent.data()); fprintf(pStream, "%s\t0;0;\n", indent.data()); fprintf(pStream, "%s\t1.000000;1.000000;\n", indent.data()); fprintf(pStream, "%s\t0.000000;0.000000;\n", indent.data()); fprintf(pStream, "%s\t1.000000,0.000000,0.000000,0.000000,\n", indent.data()); fprintf(pStream, "%s\t0.000000,1.000000,0.000000,0.000000,\n", indent.data()); fprintf(pStream, "%s\t0.000000,0.000000,1.000000,0.000000,\n", indent.data()); fprintf(pStream, "%s\t0.000000,0.000000,0.000000,1.000000;;\n", indent.data()); fprintf(pStream, "%s\t3;\n", indent.data()); fprintf(pStream, "%s\t1.000000;\n", indent.data()); fprintf(pStream, "%s\t0.750000;\n", indent.data()); fprintf(pStream, "%s\t1.000000;\n", indent.data()); fprintf(pStream, "%s\t0.000000;\n", indent.data()); fprintf(pStream, "%s\t0.000000;\n", indent.data()); fprintf(pStream, "%s\t0.000000;\n", indent.data()); fprintf(pStream, "%s\t0.000000;\n", indent.data()); fprintf(pStream, "%s}\n", indent.data()); } /* // If we include the subtexture ID, a parser could be smart enough to get // the class name of the parent texture/material and make it mean something. fprintf(pStream,"%s\t%s %d\n", indent.data(), ID_TEXSUBNO, subNo); fprintf(pStream,"%s\t%s %s\n", indent.data(), ID_TEXAMOUNT, Format(amt)); // Is this a bitmap texture? // We know some extra bits 'n pieces about the bitmap texture if (tex->ClassID() == Class_ID(BMTEX_CLASS_ID, 0x00)) { TSTR mapName = ((BitmapTex *)tex)->GetMapName(); fprintf(pStream,"%s\t%s \"%s\"\n", indent.data(), ID_BITMAP, FixupName(mapName)); StdUVGen* uvGen = ((BitmapTex *)tex)->GetUVGen(); if (uvGen) { DumpUVGen(uvGen, indentLevel+1); } TextureOutput* texout = ((BitmapTex*)tex)->GetTexout(); if (texout->GetInvert()) { fprintf(pStream,"%s\t%s\n", indent.data(), ID_TEX_INVERT); } fprintf(pStream,"%s\t%s ", indent.data(), ID_BMP_FILTER); switch(((BitmapTex*)tex)->GetFilterType()) { case FILTER_PYR: fprintf(pStream,"%s\n", ID_BMP_FILT_PYR); break; case FILTER_SAT: fprintf(pStream,"%s\n", ID_BMP_FILT_SAT); break; default: fprintf(pStream,"%s\n", ID_BMP_FILT_NONE); break; } } for (int i = 0; i < tex->NumSubTexmaps(); i++) { DumpTexture(tex->GetSubTexmap(i), tex->ClassID(), i, 1.0f, indentLevel+1); } fprintf(pStream, "%s}\n", indent.data()); */ }
//---------------------------------------------------------------------------- void SceneBuilder::ConvertMaterial (Mtl &mtl, MtlTree &mtlTree) { // 光照属性 PX2::Shine *shine = new0 PX2::Shine; Color color = mtl.GetAmbient(); float alpha = 1.0f - mtl.GetXParency(); shine->Ambient = PX2::Float4(color.r, color.g, color.b, 1.0f); color = mtl.GetDiffuse(); shine->Diffuse = PX2::Float4(color.r, color.g, color.b, alpha); color = mtl.GetSpecular(); float shininess = mtl.GetShininess()*2.0f; shine->Specular = PX2::Float4(color.r, color.g, color.b, shininess); const char *name = (const char*)mtl.GetName(); shine->SetName(name); mtlTree.SetShine(shine); bool IsDirect9Shader = false; if (mtl.ClassID() == Class_ID(CMTL_CLASS_ID, 0) || mtl.ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { StdMat2 *stdMat2 = (StdMat2*)(&mtl); Interval valid = FOREVER; stdMat2->Update(mTimeStart, valid); std::string strName(stdMat2->GetName()); bool doubleSide = (stdMat2->GetTwoSided()==1); char strBitMapName[256]; memset(strBitMapName, 0, 256*sizeof(char)); std::string resourcePath; PX2::Shader::SamplerFilter filter = PX2::Shader::SF_LINEAR_LINEAR; PX2::Shader::SamplerCoordinate uvCoord = PX2::Shader::SC_REPEAT; PX2_UNUSED(uvCoord); if (stdMat2->MapEnabled(ID_DI)) { BitmapTex *tex = (BitmapTex*)stdMat2->GetSubTexmap(ID_DI); BitmapInfo bI; const char *mapName = tex->GetMapName(); TheManager->GetImageInfo(&bI, mapName); strcpy(strBitMapName, bI.Name()); std::string fullName = std::string(strBitMapName); std::string::size_type sizeT = fullName.find_first_not_of(mSettings->SrcRootDir); resourcePath = std::string(strBitMapName).substr(sizeT); StdUVGen* uvGen = tex->GetUVGen(); PX2_UNUSED(uvGen); int filType = tex->GetFilterType(); switch (filType) { case FILTER_PYR: filter = PX2::Shader::SF_LINEAR_LINEAR; break; case FILTER_SAT: filter = PX2::Shader::SF_NEAREST; break; default: break; } } else { sprintf(strBitMapName, "%s/%s", mSettings->SrcRootDir, PX2_DEFAULT_TEXTURE); resourcePath = PX2_DEFAULT_TEXTURE; } PX2::Texture2D *tex2d = PX2::DynamicCast<PX2::Texture2D>( PX2::ResourceManager::GetSingleton().BlockLoad(strBitMapName)); tex2d->SetResourcePath(resourcePath); if (tex2d) { PX2::Texture2DMaterial *tex2dMtl = new0 PX2::Texture2DMaterial(filter, uvCoord, uvCoord); if (doubleSide) { tex2dMtl->GetCullProperty(0, 0)->Enabled = false; } PX2::MaterialInstance *instance = tex2dMtl->CreateInstance(tex2d); mtlTree.SetMaterialInstance(instance); } else { PX2::VertexColor4Material *vcMtl = new0 PX2::VertexColor4Material(); PX2::MaterialInstance *instance = vcMtl->CreateInstance(); mtlTree.SetMaterialInstance(instance); } } else if (mtl.ClassID() == Class_ID(MULTI_CLASS_ID, 0)) { } else if (mtl.ClassID() == DIRECTX_9_SHADER_CLASS_ID) { IsDirect9Shader = true; IDxMaterial* dxMtl = (IDxMaterial*)mtl.GetInterface(IDXMATERIAL_INTERFACE); char *effectName = dxMtl->GetEffectFilename(); IParamBlock2 *paramBlock = mtl.GetParamBlock(0); std::string outPath; std::string outBaseName; std::string outExtention; PX2::StringHelp::SplitFullFilename(effectName, outPath, outBaseName, outExtention); PX2::ShinePtr shineStandard = new0 PX2::Shine(); bool alphaVertex = false; PX2::Texture2DPtr diffTex; bool normalEnable = false; PX2::Texture2DPtr normalTex; float normalScale = 0.0f; bool specEnable = false; PX2::Texture2DPtr specTex; float specPower = 0.0f; bool reflectEnable = false; PX2::TextureCubePtr reflectTex; float reflectPower = 0.0f; bool doubleSide = false; int blendMode = 2; ParamBlockDesc2 *paramDesc = 0; int numParam = 0; if (paramBlock) { paramDesc = paramBlock->GetDesc(); numParam = paramBlock->NumParams(); ParamType2 paramType; for (int i=0; i<numParam; i++) { std::string parmName; PX2::Float4 color4 = PX2::Float4(0.0f, 0.0f, 0.0f, 0.0f); PX2::Float3 color3 = PX2::Float3(0.0f, 0.0f, 0.0f); float floatValue = 0.0f; bool boolValue = false; float *floatTable = 0; int intValue = 0; std::string str; PX2::Texture2D *tex2d = 0; paramType = paramBlock->GetParameterType((ParamID)i); if (TYPE_STRING == paramType) ConvertStringAttrib(paramBlock, i, parmName, str); else if (TYPE_FLOAT == paramType) ConvertFloatAttrib(paramBlock, i, parmName, floatValue); else if (TYPE_INT == paramType) ConvertIntAttrib(paramBlock, i, parmName, intValue); else if (TYPE_RGBA == paramType) ConvertColorAttrib(paramBlock, i, parmName, color4, i); else if (TYPE_POINT3 == paramType) ConvertPoint3Attrib(paramBlock, i, parmName, color3); else if (TYPE_POINT4 == paramType) ConvertPoint4Attrib(paramBlock, i, parmName, color4); else if (TYPE_BOOL == paramType) ConvertBoolAttrib(paramBlock, i, parmName, boolValue); else if (TYPE_FLOAT_TAB == paramType) ConvertFloatTabAttrib(paramBlock, i, parmName, floatTable); else if (TYPE_BITMAP == paramType) ConvertBitMapAttrib(paramBlock, i, parmName, tex2d); else if (TYPE_FRGBA ==paramType) ConvertFRGBAAttrib(paramBlock, i, parmName, color4); // shine if (parmName == "gBlendMode") { blendMode = intValue; } else if (parmName == "gShineEmissive") { shineStandard->Emissive = color4; } else if (parmName == "gShineAmbient") { shineStandard->Ambient = color4; } else if (parmName == "gShineDiffuse") { shineStandard->Diffuse = color4; } // alpha vertex else if (parmName == "gAlphaVertex") { alphaVertex = boolValue; } // diffuse else if (parmName == "gDiffuseTexture") { diffTex = tex2d; } // normal else if (parmName == "gNormalEnable") { normalEnable = boolValue; } else if (parmName == "gNormalTexture") { normalTex = tex2d; } else if (parmName == "gNormalScale") { normalScale = floatValue; } // specular else if (parmName == "gSpecularEnable") { specEnable = boolValue; } else if (parmName == "gSpecularTexture") { specTex = tex2d; } else if (parmName == "gSpecularPower") { specPower = floatValue; } // reflect else if (parmName == "gReflectionEnable") { reflectEnable = boolValue; } else if (parmName == "gReflectTexture") { //reflectTex = tex2d; } else if (parmName == "gReflectPower") { reflectPower = floatValue; } // other else if (parmName == "gDoubleSide") { doubleSide = boolValue; } } } PX2::MaterialInstance *inst = 0; PX2::StandardMaterial *standardMtl = 0; PX2::StandardESMaterial_Default *standardESMtl_D = 0; PX2::StandardESMaterial_Specular *standardESMtl_S = 0; if (outBaseName == "Standard") { char mtlName[256]; memset(mtlName, 0, 256*sizeof(char)); sprintf(mtlName, "%s/%s", mSettings->DstRootDir, "Data/mtls/Standard.pxfx"); standardMtl = new0 PX2::StandardMaterial(mtlName); } else if (outBaseName == "StandardES") { if (false == specEnable) { standardESMtl_D = new0 PX2::StandardESMaterial_Default(); if (0 == blendMode) { standardESMtl_D->GetAlphaProperty(0, 0)->BlendEnabled = false; standardESMtl_D->GetAlphaProperty(0, 0)->CompareEnabled = false; } else if (1 == blendMode) { standardESMtl_D->GetAlphaProperty(0, 0)->BlendEnabled = true; } else if (2 == blendMode) { standardESMtl_D->GetAlphaProperty(0, 0)->BlendEnabled = false; standardESMtl_D->GetAlphaProperty(0, 0)->CompareEnabled = true; standardESMtl_D->GetAlphaProperty(0, 0)->Compare = PX2::AlphaProperty::CM_GEQUAL; standardESMtl_D->GetAlphaProperty(0, 0)->Reference = 0.2f; } } else { char mtlName[256]; memset(mtlName, 0, 256*sizeof(char)); sprintf(mtlName, "%s/%s", mSettings->DstRootDir, "Data/mtls/StandardES_Specular.pxfx"); standardESMtl_S = new0 PX2::StandardESMaterial_Specular(mtlName); } } if (standardMtl && diffTex) { if (doubleSide) { standardMtl->GetCullProperty(0, 0)->Enabled = false; } inst = standardMtl->CreateInstance(diffTex, alphaVertex, normalEnable, normalTex, normalScale, specEnable, specTex, specPower, 0, shineStandard); } else if (standardESMtl_D && diffTex) { if (doubleSide) { standardESMtl_D->GetCullProperty(0, 0)->Enabled = false; } inst = standardESMtl_D->CreateInstance(diffTex, 0, shineStandard); } else if (standardESMtl_S && diffTex && specTex) { if (doubleSide) { standardESMtl_S->GetCullProperty(0, 0)->Enabled = false; } inst = standardESMtl_S->CreateInstance(diffTex, specTex, specPower, 0, shineStandard); } if (inst) { mtlTree.SetMaterialInstance(inst); } else { PX2::MaterialInstance *instance = PX2::VertexColor4Material::CreateUniqueInstance(); mtlTree.SetMaterialInstance(instance); } } else { PX2::VertexColor4Material *vcMtl = new0 PX2::VertexColor4Material(); PX2::MaterialInstance *instance = vcMtl->CreateInstance(); mtlTree.SetMaterialInstance(instance); } // 对子材质进行处理 if (IsDirect9Shader) return; int mQuantity = mtl.NumSubMtls(); // Class_ID(MULTI_CLASS_ID, 0) if (mQuantity > 0) { mtlTree.SetMChildQuantity(mQuantity); for (int i=0; i<mQuantity; i++) { Mtl *subMtl = 0; subMtl = mtl.GetSubMtl(i); if (subMtl) { ConvertMaterial(*subMtl, mtlTree.GetMChild(i)); } } } }
Class_ID ClassID() { return Class_ID(Billboard_CLASS_ID1, Billboard_CLASS_ID2); }
Class_ID ClassID() {return Class_ID(WINDOBJECT_CLASS_ID,0);}
Class_ID ClassID() { return Class_ID(CAL3D_CLASS_ID1, CAL3D_CLASS_ID2); }
Class_ID ClassID ( ) { return Class_ID(PDALPHACLASSID,0); }
// Here we process mesh geometry for given node. // Vertices for the geometry from the all meshes of the scene are allocated in // one big vertex pool. One vertex can occur several times in this pool, because // we add 3 new vertices for every face. // After all meshes in the scene are processed, this pool is collapsed to remove // duplicate vertices. void RBExport::ProcessMesh( INode* node ) { if (!node->Renderable() || node->IsNodeHidden()) { return; } ObjectState os = node->EvalWorldState( m_CurTime ); Object* pObject = os.obj; if (!pObject) { Warn( "Could not evaluate object state in node <%s>. Mesh was skipped.", node->GetName() ); return; } Matrix3 nodeTM = node->GetNodeTM( m_CurTime ); Matrix3 nodeTMAfterWSM = node->GetObjTMAfterWSM( m_CurTime ); Matrix3 mOffs = nodeTMAfterWSM*Inverse( nodeTM ); // triangulate TriObject* pTriObj = 0; if (pObject->CanConvertToType( Class_ID( TRIOBJ_CLASS_ID, 0 ) )) { pTriObj = (TriObject*)pObject->ConvertToType( m_CurTime, Class_ID( TRIOBJ_CLASS_ID, 0 ) ); } bool bReleaseTriObj = (pTriObj != pObject); if (!pTriObj) { Warn( "Could not triangulate mesh in node <%s>. Node was skipped", node->GetName() ); return; } if (!MeshModStackIsValid( node )) { Warn( "Modifier stack for node %s should be collapsed or contain only Skin modifier.", node->GetName() ); } // ensure, that vertex winding direction in polygon is CCW Matrix3 objTM = node->GetObjTMAfterWSM( m_CurTime ); bool bNegScale = (DotProd( CrossProd( objTM.GetRow(0), objTM.GetRow(1) ), objTM.GetRow(2) ) >= 0.0); int vx[3]; if (bNegScale) { vx[0] = 0; vx[1] = 1; vx[2] = 2; } else { vx[0] = 2; vx[1] = 1; vx[2] = 0; } Mesh& mesh = pTriObj->GetMesh(); bool bHasTexCoord = (mesh.numTVerts != 0); bool bHasVertexColor = (mesh.numCVerts != 0) && m_pConfig->m_bExportVertexColors; bool bHasNormal = m_pConfig->m_bExportNormals; bool bHasSkin = ProcessSkin( node ); // some cosmetics BOOL res = mesh.RemoveDegenerateFaces(); if (res) { Spam( "Degenerate faces were fixed." ); } res = mesh.RemoveIllegalFaces(); if (res) { Spam( "Degenerate indices were fixed." ); } ExpNode* pExpNode = GetExportedNode( node ); if (!pExpNode) { return; } int numPri = mesh.getNumFaces(); int numVert = mesh.numVerts; // initialize helper array for building vertices' 0-circles VertexPtrArray vertexEntry; vertexEntry.resize( numVert ); memset( &vertexEntry[0], 0, sizeof( ExpVertex* )*numVert ); Spam( "Original mesh has %d vertices and %d faces.", numVert, numPri ); bool bHasVoidFaces = false; // loop on mesh faces for (int i = 0; i < numPri; i++) { Face& face = mesh.faces[i]; // calculate face normal const Point3& v0 = mesh.verts[face.v[vx[0]]]; const Point3& v1 = mesh.verts[face.v[vx[1]]]; const Point3& v2 = mesh.verts[face.v[vx[2]]]; Point3 normal = -Normalize( (v1 - v0)^(v2 - v1) ); normal = mOffs.VectorTransform( normal ); normal = c_FlipTM.VectorTransform( normal ); // loop on face vertices ExpVertex* pFaceVertex[3]; for (int j = 0; j < 3; j++) { ExpVertex v; v.mtlID = pExpNode->GetMaterialIdx( face.getMatID() ); v.nodeID = pExpNode->m_Index; if (v.mtlID < 0) { bHasVoidFaces = true; } // extract vertex position and apply world-space modifier to it int vIdx = face.v[vx[j]]; Point3 pt = mesh.verts[vIdx]; pt = mOffs.PointTransform( pt ); pt = c_FlipTM.PointTransform( pt ); v.index = vIdx; v.pos = Vec3( pt.x, pt.y, pt.z ); //v.pos *= m_WorldScale; // extract skinning info if (bHasSkin) { GetSkinInfo( v ); } // assign normal if (bHasNormal) { v.normal = Vec3( normal.x, normal.y, normal.z ); v.smGroup = face.smGroup; } // extract vertex colors if (bHasVertexColor) { const VertColor& vcol = mesh.vertCol[mesh.vcFace[i].t[vx[j]]]; v.color = ColorToDWORD( Color( vcol.x, vcol.y, vcol.z ) ); } // extract texture coordinates if (bHasTexCoord) { const Point3& texCoord = mesh.tVerts[mesh.tvFace[i].t[vx[j]]]; v.uv.x = texCoord.x; v.uv.y = 1.0f - texCoord.y; // second texture coordinate channel if (mesh.getNumMaps() > 1 && mesh.mapSupport( 2 )) { UVVert* pUVVert = mesh.mapVerts( 2 ); TVFace* pTVFace = mesh.mapFaces( 2 ); if (pUVVert && pTVFace) { const Point3& tc2 = pUVVert[pTVFace[i].t[vx[j]]]; v.uv2.x = tc2.x; v.uv2.y = 1.0f - tc2.y; } } } // allocate new vertex pFaceVertex[j] = AddVertex( v ); // we want vertices in the 0-ring neighborhood to be linked into closed linked list if (vertexEntry[vIdx] == NULL) { vertexEntry[vIdx] = pFaceVertex[j]; pFaceVertex[j]->pNext = pFaceVertex[j]; } else { vertexEntry[vIdx]->AddToZeroRing( pFaceVertex[j] ); } } AddPolygon( pFaceVertex[0], pFaceVertex[1], pFaceVertex[2] ); if (IsCanceled()) { return; } } // correct normals at vertices corresponding to smoothing groups SmoothNormals( vertexEntry ); // put vertices into set (this removes duplicate vertices) for (int i = 0; i < numVert; i++) { ExpVertex::ZeroRingIterator it( vertexEntry[i] ); while (it) { VertexSet::iterator sIt = m_VertexSet.find( it ); if (sIt == m_VertexSet.end()) { m_VertexSet.insert( it ); } else { it->pBase = (*sIt); } ++it; } } if (bReleaseTriObj) { delete pTriObj; } if (bHasVoidFaces) { Warn( "Mesh %s has faces with no material assigned.", node->GetName() ); } } // RBExport::ProcessMesh
Class_ID ClassID() { return Class_ID(TEST_SOUNDOBJ_CLASS_ID,0); }
Class_ID ClassID() {return Class_ID(UTILTEST_CLASS_ID,0);}
void UtilTest::MakeObject() { // Create a new object through the CreateInstance() API Object *obj = (Object*)ip->CreateInstance( GEOMOBJECT_CLASS_ID, Class_ID(CYLINDER_CLASS_ID,0)); assert(obj); // Get a hold of the parameter block IParamArray *iCylParams = obj->GetParamBlock(); assert(iCylParams); // Set the value of radius, height and segs. int rad = obj->GetParamBlockIndex(CYLINDER_RADIUS); assert(rad>=0); iCylParams->SetValue(rad,TimeValue(0),30.0f); int height = obj->GetParamBlockIndex(CYLINDER_HEIGHT); assert(height>=0); iCylParams->SetValue(height,TimeValue(0),100.0f); int segs = obj->GetParamBlockIndex(CYLINDER_SEGMENTS); assert(segs>=0); iCylParams->SetValue(segs,TimeValue(0),10); // Create a derived object that references the cylinder IDerivedObject *dobj = CreateDerivedObject(obj); // Create a bend modifier Modifier *bend = (Modifier*)ip->CreateInstance( OSM_CLASS_ID, Class_ID(BENDOSM_CLASS_ID,0)); // Set the bend angle - ParamBlock2 IParamBlock2* iBendBlock = ((Animatable*)bend)->GetParamBlock(0); //only one pblock2 assert(iBendBlock); iBendBlock->SetValue(BEND_ANGLE,TimeValue(0),90.0f); // Add the bend modifier to the derived object. dobj->AddModifier(bend); // Create a node in the scene that references the derived object INode *node = ip->CreateObjectNode(dobj); // Name the node and make the name unique. TSTR name(_T("MyNode")); ip->MakeNameUnique(name); node->SetName(name); // Get ready to add WSMs to this node node->CreateWSMDerivedObject(); IDerivedObject *wsdobj = node->GetWSMDerivedObject(); if (wsdobj) { WSMObject *swobj = (WSMObject*)ip->CreateInstance( WSM_OBJECT_CLASS_ID, Class_ID(SINEWAVE_OBJECT_CLASS_ID,0)); int ix; IParamArray *iRipParams = swobj->GetParamBlock(); ix = swobj->GetParamBlockIndex(RWAVE_AMPLITUDE); iRipParams->SetValue(ix,TimeValue(0),10.0f); ix = swobj->GetParamBlockIndex(RWAVE_AMPLITUDE2); iRipParams->SetValue(ix,TimeValue(0),10.0f); ix = swobj->GetParamBlockIndex(RWAVE_WAVELEN); iRipParams->SetValue(ix,TimeValue(0),40.0f); ix = swobj->GetParamBlockIndex(RWAVE_CIRCLES); iRipParams->SetValue(ix,TimeValue(0),10); ix = swobj->GetParamBlockIndex(RWAVE_DIVISIONS); iRipParams->SetValue(ix,TimeValue(0),4); ix = swobj->GetParamBlockIndex(RWAVE_SEGMENTS); iRipParams->SetValue(ix,TimeValue(0),16); INode *swnode = ip->CreateObjectNode(swobj); TSTR swname(_T("RippleNode")); ip->MakeNameUnique(swname); node->SetName(swname); // Create a Space Warp Modifier Modifier *swmod = swobj->CreateWSMMod(swnode); if (swmod) { wsdobj->AddModifier(swmod); } } // Redraw the views ip->RedrawViews(ip->GetTime()); }
int AlembicImport_Camera(const std::string& path, AbcG::IObject& iObj, alembic_importoptions& options, INode** pMaxNode) { const std::string& identifier = iObj.getFullName(); if (!AbcG::ICamera::matches(iObj.getMetaData())) { return alembic_failure; } AbcG::ICamera objCamera = AbcG::ICamera(iObj, Abc::kWrapExisting); if (!objCamera.valid()) { return alembic_failure; } bool isConstant = objCamera.getSchema().isConstant(); TimeValue zero(0); INode* pNode = *pMaxNode; CameraObject* pCameraObj = NULL; if (!pNode) { // Create the camera object and place it in the scene GenCamera* pGenCameraObj = GET_MAX_INTERFACE()->CreateCameraObject(FREE_CAMERA); if (pGenCameraObj == NULL) { return alembic_failure; } pGenCameraObj->Enable(TRUE); pGenCameraObj->SetConeState(TRUE); pGenCameraObj->SetManualClip(TRUE); IMultiPassCameraEffect* pCameraEffect = pGenCameraObj->GetIMultiPassCameraEffect(); const int TARGET_DISTANCE = 0; pCameraEffect->GetParamBlockByID(0)->SetValue(TARGET_DISTANCE, zero, FALSE); pCameraObj = pGenCameraObj; Abc::IObject parent = iObj.getParent(); std::string name = removeXfoSuffix(parent.getName().c_str()); pNode = GET_MAX_INTERFACE()->CreateObjectNode( pGenCameraObj, EC_UTF8_to_TCHAR(name.c_str())); if (pNode == NULL) { return alembic_failure; } *pMaxNode = pNode; } else { Object* obj = pNode->EvalWorldState(zero).obj; if (obj->CanConvertToType(Class_ID(SIMPLE_CAM_CLASS_ID, 0))) { pCameraObj = reinterpret_cast<CameraObject*>( obj->ConvertToType(zero, Class_ID(SIMPLE_CAM_CLASS_ID, 0))); } else if (obj->CanConvertToType(Class_ID(LOOKAT_CAM_CLASS_ID, 0))) { pCameraObj = reinterpret_cast<CameraObject*>( obj->ConvertToType(zero, Class_ID(LOOKAT_CAM_CLASS_ID, 0))); } else { return alembic_failure; } } // Fill in the mesh // alembic_fillcamera_options dataFillOptions; // dataFillOptions.pIObj = &iObj; // dataFillOptions.pCameraObj = pCameraObj; // dataFillOptions.dTicks = GET_MAX_INTERFACE()->GetTime(); // AlembicImport_FillInCamera(dataFillOptions); // printAnimatables(pCameraObj); Interval interval = FOREVER; AlembicFloatController* pControl = NULL; { std::string prop("horizontalFOV"); if (options.attachToExisting) { pControl = getController(pCameraObj, identifier, prop, 0, 0); } if (pControl) { pControl->GetParamBlockByID(0)->SetValue( GetParamIdByName(pControl, 0, "path"), zero, EC_UTF8_to_TCHAR(path.c_str())); } else if (assignController(createFloatController(path, identifier, prop), pCameraObj, 0, 0) && !isConstant) { std::stringstream controllerName; controllerName << GET_MAXSCRIPT_NODE(pNode); controllerName << "mynode2113.FOV.controller.time"; AlembicImport_ConnectTimeControl(controllerName.str().c_str(), options); } } { std::string prop("FocusDistance"); if (options.attachToExisting) { pControl = getController(pCameraObj, identifier, prop, 1, 0, 1); } if (pControl) { pControl->GetParamBlockByID(0)->SetValue( GetParamIdByName(pControl, 0, "path"), zero, EC_UTF8_to_TCHAR(path.c_str())); } else if (assignController(createFloatController(path, identifier, prop), pCameraObj, 1, 0, 1) && !isConstant) { std::stringstream controllerName; controllerName << GET_MAXSCRIPT_NODE(pNode); controllerName << "mynode2113.MultiPass_Effect.focalDepth.controller.time"; AlembicImport_ConnectTimeControl(controllerName.str().c_str(), options); } } { std::string prop("NearClippingPlane"); if (options.attachToExisting) { pControl = getController(pCameraObj, identifier, prop, 0, 2); } if (pControl) { pControl->GetParamBlockByID(0)->SetValue( GetParamIdByName(pControl, 0, "path"), zero, EC_UTF8_to_TCHAR(path.c_str())); } else if (assignController(createFloatController(path, identifier, prop), pCameraObj, 0, 2) && !isConstant) { std::stringstream controllerName; controllerName << GET_MAXSCRIPT_NODE(pNode); controllerName << "mynode2113.nearclip.controller.time"; AlembicImport_ConnectTimeControl(controllerName.str().c_str(), options); } } { std::string prop("FarClippingPlane"); if (options.attachToExisting) { pControl = getController(pCameraObj, identifier, prop, 0, 3); } if (pControl) { pControl->GetParamBlockByID(0)->SetValue( GetParamIdByName(pControl, 0, "path"), zero, EC_UTF8_to_TCHAR(path.c_str())); } else if (assignController(createFloatController(path, identifier, prop), pCameraObj, 0, 3) && !isConstant) { std::stringstream controllerName; controllerName << GET_MAXSCRIPT_NODE(pNode); controllerName << "mynode2113.farclip.controller.time"; AlembicImport_ConnectTimeControl(controllerName.str().c_str(), options); } } // if(assignControllerToLevel1SubAnim(createFloatController(path, identifier, // std::string("FocusDistance")), pCameraObj, 0, 1) && !isConstant){ // AlembicImport_ConnectTimeControl( "$.targetDistance.controller.time", // options ); //} createCameraModifier(path, identifier, pNode); // Add the new inode to our current scene list SceneEntry* pEntry = options.sceneEnumProc.Append( pNode, pCameraObj, OBTYPE_CAMERA, &std::string(iObj.getFullName())); options.currentSceneList.Append(pEntry); // Set the visibility controller AlembicImport_SetupVisControl(path, identifier, iObj, pNode, options); importMetadata(pNode, iObj); return 0; }
bool AlembicCamera::Save(double time, bool bLastFrame) { TimeValue ticks = GetTimeValueFromFrame(time); Object *obj = mMaxNode->EvalWorldState(ticks).obj; if (mNumSamples == 0) { bForever = CheckIfObjIsValidForever(obj, ticks); } else { bool bNewForever = CheckIfObjIsValidForever(obj, ticks); if (bForever && bNewForever != bForever) { ESS_LOG_INFO("bForever has changed"); } } bForever = false; SaveMetaData(mMaxNode, this); // Set the xform sample Matrix3 wm = mMaxNode->GetObjTMAfterWSM(ticks); if (mJob) { Point3 worldMaxPoint = wm.GetTrans(); Abc::V3f alembicWorldPoint = ConvertMaxPointToAlembicPoint(worldMaxPoint); mJob->GetArchiveBBox().extendBy(alembicWorldPoint); } // check if the camera is animated if (mNumSamples > 0) { if (bForever) { return true; } } // Return a pointer to a Camera given an INode or return false if the node // cannot be converted to a Camera CameraObject *cam = NULL; if (obj->CanConvertToType(Class_ID(SIMPLE_CAM_CLASS_ID, 0))) { cam = reinterpret_cast<CameraObject *>( obj->ConvertToType(ticks, Class_ID(SIMPLE_CAM_CLASS_ID, 0))); } else if (obj->CanConvertToType(Class_ID(LOOKAT_CAM_CLASS_ID, 0))) { cam = reinterpret_cast<CameraObject *>( obj->ConvertToType(ticks, Class_ID(LOOKAT_CAM_CLASS_ID, 0))); } else { return false; } CameraState cs; Interval valid = FOREVER; cam->EvalCameraState(ticks, valid, &cs); float tDist = cam->GetTDist(ticks); float ratio = GetCOREInterface()->GetRendImageAspect(); float aperatureWidth = GetCOREInterface()->GetRendApertureWidth(); // this may differ from the // imported value // unfortunately float focalLength = (float)((aperatureWidth / 2.0) / tan(cs.fov / 2.0)); // alembic wants this one in millimeters aperatureWidth /= 10.0f; // convert to centimeters IMultiPassCameraEffect *pCameraEffect = cam->GetIMultiPassCameraEffect(); Interval interval = FOREVER; BOOL bUseTargetDistance = FALSE; const int TARGET_DISTANCE = 0; pCameraEffect->GetParamBlockByID(0)->GetValue(TARGET_DISTANCE, ticks, bUseTargetDistance, interval); float fFocalDepth = 0.0f; const int FOCAL_DEPTH = 1; pCameraEffect->GetParamBlockByID(0)->GetValue(FOCAL_DEPTH, ticks, fFocalDepth, interval); // store the camera data mCameraSample.setNearClippingPlane(cs.hither); mCameraSample.setFarClippingPlane(cs.yon); // mCameraSample.setLensSqueezeRatio(ratio); // should set to 1.0 according the article "Maya to Softimage: Camera // Interoperability" mCameraSample.setLensSqueezeRatio(1.0); mCameraSample.setFocalLength(focalLength); mCameraSample.setHorizontalAperture(aperatureWidth); mCameraSample.setVerticalAperture(aperatureWidth / ratio); if (bUseTargetDistance) { mCameraSample.setFocusDistance(tDist); } else { mCameraSample.setFocusDistance(fFocalDepth); } // save the samples mCameraSchema.set(mCameraSample); mNumSamples++; // Note that the CamObject should only be deleted if the pointer to it is not // equal to the object pointer that called ConvertToType() if (cam != NULL && obj != cam) { delete cam; cam = NULL; return false; } return true; }
/* ==================== GatherSkin ==================== */ void G3DSExport::GatherSkin(INode* i_node) { SKIN skin; // get the name of the node skin.name = i_node->GetName(); // get the skin interface Modifier *modifier = GetModifier(i_node,SKIN_CLASSID); ISkin* i_skin = (ISkin*)modifier->GetInterface(I_SKIN); MAX_CHECK(i_skin); // convert to the triangle type Mesh* i_mesh = NULL; Object* obj = i_node->EvalWorldState(mTime).obj; if(obj && ( obj->SuperClassID() == GEOMOBJECT_CLASS_ID )) { if(obj->CanConvertToType(Class_ID(TRIOBJ_CLASS_ID, 0))) { TriObject *tri_obj = (TriObject*)obj->ConvertToType(mTime, Class_ID(TRIOBJ_CLASS_ID, 0)); MAX_CHECK(tri_obj); i_mesh = &tri_obj->mesh; } } MAX_CHECK(i_mesh&&i_mesh->getNumFaces()&&i_mesh->getNumVerts()); // get the material skin.texture = "textures/default.tga"; Mtl* mtl = i_node->GetMtl(); if(mtl && (mtl->ClassID()==Class_ID(DMTL_CLASS_ID, 0)) && ((StdMat*)mtl)->MapEnabled(ID_DI)) { Texmap *texmap = mtl->GetSubTexmap(ID_DI); if(texmap && texmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0x00)) { skin.texture = UnifySlashes(((BitmapTex *)texmap)->GetMapName()); if( !strstr( skin.texture.c_str(), mPath.c_str() ) ) { G3DAssert("The material(%s) is error : the texture path(%s) is illegal!",mtl->GetName(), skin.texture.c_str()); } else { skin.texture = strstr(skin.texture.c_str(),mPath.c_str()) + strlen(mPath.c_str()); } } } // if it has uvs int map_count = i_mesh->getNumMaps(); bool has_uvs = i_mesh->getNumTVerts() && i_mesh->tvFace; if(!(has_uvs&&map_count)) { G3DAssert("The skin(%s) has not the uv coordinates.",skin.name.c_str()); return; } // get the transform Matrix3 mesh_matrix = i_node->GetObjectTM(mTime); Matrix3 node_matrix = i_node->GetNodeTM(mTime); Matrix3 transform = mesh_matrix * Inverse(node_matrix); // get the points skin.points.assign(i_mesh->verts, i_mesh->verts+i_mesh->getNumVerts()); // get the triangles for(int i = 0; i < i_mesh->getNumFaces(); i++) { Face& face = i_mesh->faces[i]; TRIANGLE tri; tri.smoothing = face.smGroup; for(int j = 0; j < 3; j++) { VPTNIS v; v.pos = transform * i_mesh->verts[face.v[j]]; // get the uv UVVert * map_verts = i_mesh->mapVerts(1); TVFace * map_faces = i_mesh->mapFaces(1); v.uv = reinterpret_cast<Point2&>(map_verts[map_faces[i].t[j]]); v.uv.y = 1 - v.uv.y; // initialize the normal v.normal = Point3::Origin; // get the vertex index v.index = face.v[j]; // get the smoothing group v.smoothing = face.smGroup; // set the index for the triangle tri.index0[j] = v.index; // reassemble the vertex list tri.index1[j] = AddVertex(skin, v); } // add the triangle to the table skin.triangles.push_back(tri); } // build the index map for( int i = 0; i < skin.vertexes.size(); i++ ) { skin.vertex_index_map[skin.vertexes[i].index].push_back(i); } // get the skin context data ISkinContextData* i_skin_context_data = i_skin->GetContextInterface(i_node); if(i_skin_context_data == NULL) { G3DAssert("The skin(%s) has not the weight.",skin.name.c_str()); return; } // gets the initial matrix of the skinned object Matrix3 initial_object_transform; i_skin->GetSkinInitTM(i_node, initial_object_transform, true); // process the points int num_points = i_skin_context_data->GetNumPoints(); for(int i = 0; i < num_points; i++) { MAX_CHECK(i < skin.points.size()); VPIW viw; // get the initial point viw.pos = initial_object_transform * skin.points[i]; // process the weights std::multimap< float, int > weights; // get the number of bones that control this vertex int num_bones = i_skin_context_data->GetNumAssignedBones(i); if(num_bones>0) { for (int j = 0; j < num_bones; j++) { Matrix3 transform; // get the assigned bone of the point INode* i_bone_node = i_skin->GetBone(i_skin_context_data->GetAssignedBone(i, j)); MAX_CHECK(i_bone_node != NULL); // get the weight of the bone float weight = i_skin_context_data->GetBoneWeight(i, j); // add the weight to the table weights.insert(std::make_pair(weight, AddBone(skin,i_bone_node))); } } else { // add the weight to the table weights.insert(std::make_pair(1.f, AddBone(skin,i_node))); } // recalculate the weights float weight0 = 0.f, weight1 = 0.f, weight2 = 0.f; int index0 = 0, index1 = 0, index2 = 0; std::multimap< float, int >::iterator it = weights.end(); it--; weight0 = it->first; index0 = it->second; if(it != weights.begin()) { it--; weight1 = it->first; index1 = it->second; if(it != weights.begin()) { it--; weight2 = it->first; index2 = it->second; } } float sum_weights = weight0 + weight1 + weight2; // store the skin weights viw.weight[0] = weight0/sum_weights; viw.index[0] = index0; viw.weight[1] = weight1/sum_weights; viw.index[1] = index1; viw.weight[2] = weight2/sum_weights; viw.index[2] = index2; skin.weights.push_back(viw); } // get the initial transforms skin.transforms.resize(skin.bones.size()); for(int i = 0; i < skin.bones.size(); i++) { INode* node = skin.bones[i]; Matrix3 mat; if (SKIN_INVALID_NODE_PTR == i_skin->GetBoneInitTM( node, mat )) { if (SKIN_INVALID_NODE_PTR == i_skin->GetSkinInitTM( node, mat )) { mat.IdentityMatrix(); } } skin.transforms[i] = Inverse(mat); } // there is a 75 bone limit for each skinned object. if(skin.bones.size()>75) { G3DAssert("There are more %d bones in the skin(%s).",skin.bones.size(), i_node->GetName()); return; } // reset the skin vertex position for(int i = 0; i < skin.vertexes.size(); i++) { VPTNIS& v0 = skin.vertexes[i]; VPIW& v1 = skin.weights[v0.index]; v0.pos = v1.pos; } // build the normal space BuildNormal(skin); // calculate the bounding box skin.box.Init(); for(int i = 0; i < skin.vertexes.size(); i++) { Point3 pt = node_matrix * skin.vertexes[i].pos; skin.box += pt; } // add the skin to the table mSkins.push_back(skin); }
Class_ID ClassID() { return Class_ID(2,2); }
Class_ID ClassID() {return Class_ID(WINDMOD_CLASS_ID,0);}
virtual bool Convert(plMaxNode* node, plErrorMsg *pErrMsg); virtual plATCAnim * NewAnimation(const plString &name, double begin, double end); bool ConvertNode(plMaxNode *node, plErrorMsg *pErrMsg); bool ConvertNodeSegmentBranch(plMaxNode *node, plAGAnim *mod, plErrorMsg *pErrMsg); bool MakePersistent(plMaxNode *node, plAGAnim *anim, const plString &animName, plErrorMsg *pErrMsg); virtual void CollectNonDrawables(INodeTab& nonDrawables) { AddTargetsToList(nonDrawables); } void DeleteThis() { delete this; } }; //plAGAnimMgr * plAnimAvatarComponent::fManager = nil; CLASS_DESC(plAnimAvatarComponent, gAnimAvatarDesc, "Compound Animation", "Compound Animation", COMP_TYPE_AVATAR, Class_ID(0x3192253d, 0x60c4178c)) // // Anim Avatar ParamBlock2 // // ParamBlockDesc2 gAnimAvatarBk ( plComponent::kBlkComp, _T("CompoundAnim"), 0, &gAnimAvatarDesc, P_AUTO_CONSTRUCT + P_AUTO_UI, plComponent::kRefComp, //Roll out IDD_COMP_ANIM_AVATAR, IDS_COMP_ANIM_AVATARS, 0, 0, NULL, // params kShareableBool, _T("ShareableBool"), TYPE_BOOL, 0, 0, p_default, FALSE,
Class_ID ClassID() {return Class_ID(COLOR_CLIP_CLASS_ID,0);}
ColMesh* RBExport::GetColMesh( INode* node ) { ObjectState os = node->EvalWorldState( m_CurTime ); Object* pObject = os.obj; if (!pObject) { Warn( "Could not evaluate object state. Collision mesh %s was skipped.", node->GetName() ); return NULL; } Matrix3 nodeTM = node->GetNodeTM( m_CurTime ); Matrix3 nodeTMAfterWSM = node->GetObjTMAfterWSM( m_CurTime ); Matrix3 mOffs = nodeTMAfterWSM*Inverse( nodeTM ); // triangulate TriObject* pTriObj = NULL; if (pObject->CanConvertToType( Class_ID( TRIOBJ_CLASS_ID, 0 ) )) { pTriObj = (TriObject*)pObject->ConvertToType( m_CurTime, Class_ID( TRIOBJ_CLASS_ID, 0 ) ); } bool bReleaseTriObj = (pTriObj != pObject); if (!pTriObj) { Warn( "Could not triangulate mesh in node. Collision mesh %s was skipped.", node->GetName() ); return NULL; } // ensure, that vertex winding direction in polygon is CCW Matrix3 objTM = node->GetObjTMAfterWSM( m_CurTime ); bool bNegScale = (DotProd( CrossProd( objTM.GetRow(0), objTM.GetRow(1) ), objTM.GetRow(2) ) >= 0.0); int vx[3]; vx[0] = bNegScale ? 2 : 0; vx[1] = bNegScale ? 1 : 1; vx[2] = bNegScale ? 0 : 2; Mesh& mesh = pTriObj->GetMesh(); // some cosmetics mesh.RemoveDegenerateFaces(); mesh.RemoveIllegalFaces(); // create collision mesh ColMesh* pMesh = new ColMesh(); int numPri = mesh.getNumFaces(); int numVert = mesh.numVerts; // copy vertices for (int i = 0; i < numVert; i++) { Point3 pt = mesh.verts[i]; pt = mOffs.PointTransform( pt ); pt = c_FlipTM.PointTransform( pt ); pMesh->AddVertex( Vec3( pt.x, pt.y, pt.z ) ); } // loop on mesh faces for (int i = 0; i < numPri; i++) { Face& face = mesh.faces[i]; pMesh->AddPoly( face.v[vx[0]], face.v[vx[1]], face.v[vx[2]] ); } Msg( LogType_Stats, "Physics collision trimesh has %d vertices and %d faces.", numVert, numPri ); return pMesh; } // RBExport::GetColMesh
static INT_PTR CALLBACK UVStripDlgProc( HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam) { switch (msg) { case WM_INITDIALOG: theUVStrip.Init(hWnd); TCHAR s[50]; _stprintf(s,GetString(IDS_OBJ_SELECTED),theUVStrip.ip->GetSelNodeCount()); SetWindowText(GetDlgItem(hWnd,IDC_SEL),s); break; case WM_DESTROY: theUVStrip.Destroy(hWnd); break; case WM_COMMAND: switch (LOWORD(wParam)) { case IDC_R1: { int cn = theUVStrip.ip->GetSelNodeCount(); Interval valid=FOREVER; if(cn>0) { for(int x=0;x<cn;x++) { // then osm stack Object* obj = theUVStrip.ip->GetSelNode(x)->GetObjectRef(); //check to make sure no modifiers on the object int ct = 0; SClass_ID sc; IDerivedObject* dobj; if ((sc = obj->SuperClassID()) == GEN_DERIVOB_CLASS_ID) { dobj = (IDerivedObject*)obj; while (sc == GEN_DERIVOB_CLASS_ID) { ct += dobj->NumModifiers(); dobj = (IDerivedObject*)dobj->GetObjRef(); sc = dobj->SuperClassID(); } } if ((dobj = theUVStrip.ip->GetSelNode(x)->GetWSMDerivedObject()) != NULL) { ct += dobj->NumModifiers(); } if (ct != 0) { //error message here TSTR buf2 = GetString(IDS_ERROR); TSTR buf1 = GetString(IDS_ERROR_MESH); MessageBox(hWnd,buf1,buf2,MB_ICONEXCLAMATION); } else { ObjectState os = theUVStrip.ip->GetSelNode(x)->EvalWorldState(theUVStrip.ip->GetTime()); if (os.obj && os.obj->SuperClassID() == GEOMOBJECT_CLASS_ID && os.obj->IsSubClassOf(triObjectClassID)) { Object *bobj = os.obj->FindBaseObject(); if (bobj->ClassID() ==Class_ID(EDITTRIOBJ_CLASS_ID,0)) { TriObject *T1 = (TriObject *)os.obj; T1->GetMesh().setNumTVerts(0); T1->GetMesh().setNumTVFaces(0); } else { //error message here TSTR buf2 = GetString(IDS_ERROR); TSTR buf1 = GetString(IDS_ERROR_MESH); MessageBox(hWnd,buf1,buf2,MB_ICONEXCLAMATION); } } else { //error message here TSTR buf2 = GetString(IDS_ERROR); TSTR buf1 = GetString(IDS_ERROR_MESH); MessageBox(hWnd,buf1,buf2,MB_ICONEXCLAMATION); } } theUVStrip.ip->ForceCompleteRedraw(); } } break; } case IDC_R2:{ int cn = theUVStrip.ip->GetSelNodeCount(); if(cn>0){ for(int x=0;x<cn;x++){ INode *tmp=theUVStrip.ip->GetSelNode(x); tmp->SetMtl(NULL); if(GetCheckBox(hWnd, IDC_BLANK)) tmp->SetWireColor(RGB(160,160,160)); } theUVStrip.ip->ForceCompleteRedraw(); } break;} } break; default: return FALSE; } return TRUE; }
void BombMod::ModifyObject( TimeValue t, ModContext &mc, ObjectState *os, INode *node) { BombObject *bobj = GetWSMObject(t); if (bobj && nodeRef && (bobj->ClassID() == Class_ID(BOMB_OBJECT_CLASS_ID,0))) { assert(os->obj->IsSubClassOf(triObjectClassID)); TriObject *triOb = (TriObject *)os->obj; Interval valid = FOREVER; if (os->GetTM()) { Matrix3 tm = *(os->GetTM()); for (int i=0; i<triOb->GetMesh().getNumVerts(); i++) { triOb->GetMesh().verts[i] = triOb->GetMesh().verts[i] * tm; } os->obj->UpdateValidity(GEOM_CHAN_NUM,os->tmValid()); os->SetTM(NULL,FOREVER); } if (waitPostLoad) { valid.SetInstant(t); triOb->UpdateValidity(GEOM_CHAN_NUM,valid); triOb->UpdateValidity(TOPO_CHAN_NUM,valid); return; } Matrix3 tm; TimeValue det = bobj->GetDetonation(t,valid); float strength = bobj->GetStrength(t,valid) * STRENGTH_CONSTANT; float grav = bobj->GetGravity(t,valid); float chaos = bobj->GetChaos(t,valid); float chaosBase = (float(1)-chaos/2); float rotSpeed = bobj->GetSpin(t,valid) * TWOPI/float(TIME_TICKSPERSEC); int minClust = bobj->GetMinFrag(t,valid), maxClust = bobj->GetMaxFrag(t,valid); if (minClust<1) minClust = 1; if (maxClust<1) maxClust = 1; int clustVar = maxClust-minClust+1; float falloff = bobj->GetFalloff(t,valid); int useFalloff = bobj->GetFalloffOn(t,valid); int seed = bobj->GetSeed(t,valid); //tm = nodeRef->GetNodeTM(t,&valid); tm = nodeRef->GetObjectTM(t,&valid); if (t<det) { valid.Set(TIME_NegInfinity,det-1); triOb->UpdateValidity(GEOM_CHAN_NUM,valid); triOb->UpdateValidity(TOPO_CHAN_NUM,valid); triOb->PointsWereChanged(); return; } float dt = float(t-det); valid.SetInstant(t); int n0=0,n1=1,n2=2,nv; Point3 v, p0, p1, g(0.0f,0.0f,grav*GRAVITY_CONSTANT); Tab<Point3> l_newVerts ; Face *f = triOb->GetMesh().faces; float dot; Mesh &mesh = triOb->GetMesh(); // First, segment the faces. srand((unsigned int)seed); Tab<DWORD> vclust; Tab<DWORD> vmap; Tab<Point3> nverts; vclust.SetCount(mesh.getNumVerts()); vmap.SetCount(mesh.getNumVerts()); int numClust = 0; if (minClust==1 && maxClust==1) { // Simple case... 1 face per cluster nv = triOb->GetMesh().getNumFaces() * 3; l_newVerts.SetCount(nv); vclust.SetCount(nv); for (int i=0; i<nv; i++) { vclust[i] = i/3; } for (int i=0,j=0; i<mesh.getNumFaces(); i++) { l_newVerts[j] = mesh.verts[mesh.faces[i].v[0]]; l_newVerts[j+1] = mesh.verts[mesh.faces[i].v[1]]; l_newVerts[j+2] = mesh.verts[mesh.faces[i].v[2]]; mesh.faces[i].v[0] = j; mesh.faces[i].v[1] = j+1; mesh.faces[i].v[2] = j+2; j += 3; } numClust = triOb->GetMesh().getNumFaces(); } else { // More complex case... clusters are randomely sized for (int i=0; i<mesh.getNumVerts(); i++) { vclust[i] = UNDEFINED; vmap[i] = i; } int cnum = 0; for (int i=0; i<mesh.getNumFaces(); ) { int csize = int(Rand1()*float(clustVar)+float(minClust)); if (i+csize>mesh.getNumFaces()) { csize = mesh.getNumFaces()-i; } // Make sure each face in the cluster has at least 2 verts in common with another face. BOOL verified = FALSE; while (!verified) { verified = TRUE; if (csize<2) break; for (int j=0; j<csize; j++) { BOOL match = FALSE; for (int k=0; k<csize; k++) { if (k==j) continue; int common = 0; for (int i1=0; i1<3; i1++) { for (int i2=0; i2<3; i2++) { if (mesh.faces[i+j].v[i1]== mesh.faces[i+k].v[i2]) common++; } } if (common>=2) { match = TRUE; break; } } if (!match) { csize = j; verified = FALSE; // Have to check again break; } } } if (csize==0) csize = 1; // Clear the vert map for (int j=0; j<mesh.getNumVerts(); j++) vmap[j] = UNDEFINED; // Go through the cluster and remap verts. for (int j=0;j<csize; j++) { for (int k=0; k<3; k++) { if (vclust[mesh.faces[i+j].v[k]]==UNDEFINED) { vclust[mesh.faces[i+j].v[k]] = cnum; } else if (vclust[mesh.faces[i+j].v[k]]!=(DWORD)cnum) { if (vmap[mesh.faces[i+j].v[k]]==UNDEFINED) { vclust.Append(1,(DWORD*)&cnum,50); nverts.Append(1,&mesh.verts[mesh.faces[i+j].v[k]],50); mesh.faces[i+j].v[k] = vmap[mesh.faces[i+j].v[k]] = mesh.getNumVerts()+nverts.Count()-1; } else { mesh.faces[i+j].v[k] = vmap[mesh.faces[i+j].v[k]]; } } } } cnum++; numClust++; i += csize; } nv = mesh.getNumVerts() + nverts.Count(); l_newVerts.SetCount(nv); int i; for (i=0; i<mesh.getNumVerts(); i++) l_newVerts[i] = mesh.verts[i]; for ( ; i<mesh.getNumVerts()+nverts.Count(); i++) l_newVerts[i] = nverts[i-mesh.getNumVerts()]; } // Find the center of all clusters Tab<Point3> clustCent; Tab<DWORD> clustCounts; clustCent.SetCount(numClust); clustCounts.SetCount(numClust); for (int i=0; i<numClust; i++) { clustCent[i] = Point3(0,0,0); clustCounts[i] = 0; } for (int i=0; i<nv; i++) { if (vclust[i]==UNDEFINED) continue; clustCent[vclust[i]] += l_newVerts[i]; clustCounts[vclust[i]]++; } // Build transformations for all clusters Tab<Matrix3> mats; mats.SetCount(numClust); srand((unsigned int)seed); for (int i=0; i<numClust; i++) { if (clustCounts[i]) clustCent[i] /= float(clustCounts[i]); v = clustCent[i] - tm.GetTrans(); float u = 1.0f; if (useFalloff) { u = 1.0f - Length(v)/falloff; if (u<0.0f) u = 0.0f; } dot = DotProd(v,v); if (dot==0.0f) dot = 0.000001f; v = v / dot * strength * u; v.x *= chaosBase + chaos * Rand1(); v.y *= chaosBase + chaos * Rand1(); v.z *= chaosBase + chaos * Rand1(); p1 = v*dt + 0.5f*g*dt*dt; // projectile motion // Set rotation Point3 axis; axis.x = -1.0f + 2.0f*Rand1(); axis.y = -1.0f + 2.0f*Rand1(); axis.z = -1.0f + 2.0f*Rand1(); axis = Normalize(axis); float angle = dt*rotSpeed*(chaosBase + chaos * Rand1())*u; Quat q = QFromAngAxis(angle, axis); q.MakeMatrix(mats[i]); mats[i].PreTranslate(-clustCent[i]); mats[i].Translate(clustCent[i]+p1); } // Now transform the clusters for (int i=0; i<nv; i++) { if (vclust[i]==UNDEFINED) continue; l_newVerts[i] = l_newVerts[i] * mats[vclust[i]]; } triOb->UpdateValidity(GEOM_CHAN_NUM,valid); triOb->UpdateValidity(TOPO_CHAN_NUM,valid); triOb->PointsWereChanged(); triOb->GetMesh().setNumVerts(nv,FALSE,TRUE); //assign the new vertices to the mesh for ( int i=0; i < nv; i++) triOb->GetMesh().setVert( i,l_newVerts[i]); } }
{ return new TemplateObjectSnap(); } const MCHAR* TemplateObjectSnapClassDesc::ClassName() { TODO("Replace with your own localized plug-in name"); return _M("Template Object Snap"); } SClass_ID TemplateObjectSnapClassDesc::SuperClassID() { return OSNAP_CLASS_ID; } Class_ID TemplateObjectSnapClassDesc::ClassID() { TODO("Replace the Class_ID with a new unique one") static const Class_ID cid = Class_ID(0x6E06AEC6, 0x7C91FF41); return cid; } const MCHAR* TemplateObjectSnapClassDesc::Category() { TODO("Replace with an appropriate category") return SDK_TUTORIALS_CATEGORY; } const MCHAR* TemplateObjectSnapClassDesc::GetInternalName() { TODO("Replace with your own internal (non-localized) plug-in name"); return _M("TemplateObjectSnap"); } HINSTANCE TemplateObjectSnapClassDesc::HInstance() { return hDllInstance;
Class_ID InputType() { return Class_ID(TRIOBJ_CLASS_ID,0); }
AWDTexture * AWDExporter::ExportTexture(AWD *awd, awd_ncache *ncache,Texmap* tex, Class_ID cid, int subNo, AWDMaterial * mat ) { AWDTexture *awd_tex; const char* name; int name_len; bool hasAlpha = false; MSTR path; awd_uint8 * buf; int buf_len; if (!tex) return NULL; if (tex->ClassID() != Class_ID(BMTEX_CLASS_ID, 0x00) ) return NULL; // texture already exist in cache awd_tex = (AWDTexture *)awd_ncache_get( ncache, tex ); if( awd_tex ) return awd_tex; BitmapTex *bmptex = (BitmapTex*)tex; MaxSDK::AssetManagement::AssetUser asset = bmptex->GetMap(); hasAlpha = bmptex->GetBitmap( GetStaticFrame() )->HasAlpha(); if( !asset.GetFullFilePath(path) ) { fprintf( logfile, " export !asset.GetFullFilePath(path) : %i \n", asset.GetType() ); fflush( logfile ); //return NULL; } fprintf( logfile, " export : %s \n", path ); fflush( logfile ); AWD_tex_type textype = EXTERNAL; if( GetIncludeMaps() && asset.GetType() == MaxSDK::AssetManagement::kBitmapAsset ) { const char * dot; dot = strrchr(path,'.'); if( !strcmp(dot, ".jpg")|| !strcmp(dot, ".JPG")|| !strcmp(dot, ".jpeg")|| !strcmp(dot, ".JPEG") ) { textype = EMBEDDED_JPEG; } else if ( !strcmp(dot, ".png")|| !strcmp(dot, ".PNG") ) { textype = EMBEDDED_PNG; } if( textype == 0 ) { fprintf( logfile, " export texture : %s \n", path ); fflush( logfile ); // try to extract data Bitmap *bmp = bmptex->GetBitmap( GetStaticFrame() ); BitmapInfo bi; MaxSDK::Util::Path *temppath; bi.SetWidth( bmp->Width() ); bi.SetHeight( bmp->Height() ); if( hasAlpha ) { bi.SetType( BMM_TRUE_32 ); bi.SetFlags( MAP_HAS_ALPHA ); path = "C:\\Users\\lepersp\\Desktop\\temp\\awdexporttempjpg.png"; textype = EMBEDDED_PNG; } else { bi.SetType( BMM_TRUE_24 ); path = "C:\\Users\\lepersp\\Desktop\\temp\\awdexporttempjpg.jpg"; textype = EMBEDDED_JPEG; } temppath = new MaxSDK::Util::Path( path ); bi.SetPath( *temppath ); bmp->OpenOutput( & bi ); bmp->Write( & bi ); bmp->Close(& bi); } if( path != NULL ) { size_t result; int fd; errno_t err = _sopen_s( &fd, path, _O_RDONLY|_O_BINARY, _SH_DENYNO, _S_IREAD ); if( err == 0 ) { struct stat *s; s = (struct stat *)malloc(sizeof(struct stat)); fstat(fd, s); buf_len = s->st_size; buf = (awd_uint8 *) malloc (buf_len * sizeof( awd_uint8 ) ); lseek(fd, 0, SEEK_SET); result = read(fd, buf, buf_len); if (result != buf_len) { textype = EXTERNAL; } _close( fd ); } else { textype = EXTERNAL; } } } name = tex->GetName(); name_len = strlen( name ); char* namecpy = (char*) malloc( name_len*sizeof( char ) ) ; strcpy( namecpy, name ); awd_tex = new AWDTexture( textype, namecpy, name_len ); if( textype != 0 ) { awd_tex->set_embed_data(buf, buf_len); } char * pathcpy = (char *) malloc( (path.length()+1) * sizeof( char ) ); strcpy( pathcpy, path.data() ); awd_tex->set_url( pathcpy, strlen( pathcpy ) ); awd->add_texture( awd_tex ); awd_ncache_add( ncache, tex, awd_tex ); if( subNo == ID_DI ) { mat->set_texture( awd_tex ); mat->alpha_blending = hasAlpha; } return awd_tex; }
Class_ID ClassID() { return Class_ID(BOMB_OBJECT_CLASS_ID,0); }
void XsiExp::DumpMaterial(Mtl * mtl, int mtlID, int subNo, int indentLevel) { if (!mtl) { return; } TSTR indent = GetIndent(indentLevel+1); if (mtl->NumSubMtls() > 0) { for (int i = 0; i < mtl->NumSubMtls(); i++) { Mtl* subMtl = mtl->GetSubMtl(i); if (subMtl) { DumpMaterial( subMtl, 0, i, indentLevel); } } } else { TimeValue t = GetStaticFrame(); // Note about material colors: // This is only the color used by the interactive renderer in MAX. // To get the color used by the scanline renderer, we need to evaluate // the material using the mtl->Shade() method. // Since the materials are procedural there is no real "diffuse" color for a MAX material // but we can at least take the interactive color. fprintf(pStream,"%sSI_Material {\n", indent.data()); fprintf(pStream,"%s\t%.6f;%.6f;%.6f;%.6f;;\n", indent.data(), mtl->GetDiffuse(t).r, mtl->GetDiffuse(t).g, mtl->GetDiffuse(t).b, 1.0 - mtl->GetXParency(t) ); fprintf(pStream,"%s\t%.6f;\n", indent.data(), mtl->GetShinStr(t) ); fprintf(pStream,"%s\t%.6f;%.6f;%.6f;;\n", indent.data(), mtl->GetSpecular(t).r, mtl->GetSpecular(t).g, mtl->GetSpecular(t).b ); fprintf(pStream,"%s\t%.6f;%.6f;%.6f;;\n", indent.data(), 0.0f, 0.0f, 0.0f); // emissive fprintf(pStream,"%s\t%.6f;\n", indent.data(), 0.0f); // ? fprintf(pStream,"%s\t%.6f;%.6f;%.6f;;\n\n", indent.data(), mtl->GetAmbient(t).r, mtl->GetAmbient(t).g, mtl->GetAmbient(t).b ); for (int i = 0; i < mtl->NumSubTexmaps(); i++) { Texmap * subTex = mtl->GetSubTexmap(i); float amt = 1.0f; if (subTex) { // If it is a standard material we can see if the map is enabled. if (mtl->ClassID() == Class_ID(DMTL_CLASS_ID, 0)) { if (!((StdMat*)mtl)->MapEnabled(i)) { continue; } amt = ((StdMat*)mtl)->GetTexmapAmt(i, 0); } DumpTexture(subTex, mtl->ClassID(), i, amt, indentLevel+1); } } fprintf(pStream,"%s}\n", indent.data()); } }
//---------------------------------------------------------------------------- bool SceneBuilder::Traverse(INode *maxNode, PX2::Node *relatParent) { // movbale对应maxNode的父节点 bool isHasSkin = false; // Modifier if (mSettings->IncludeModifiers) { ModifierInfo *modInfo = new0 ModifierInfo; CollectModifiers(maxNode, modInfo->Modifiers); if (modInfo->Modifiers.empty()) { delete0(modInfo); } else { modInfo->Node = maxNode; mModifierList.push_back(modInfo); for (int i=0; i<(int)modInfo->Modifiers.size(); i++) { Modifier *modifier = modInfo->Modifiers[i]; Class_ID id = modifier->ClassID(); if (id == SKIN_CLASSID || id == Class_ID(PHYSIQUE_CLASS_ID_A, PHYSIQUE_CLASS_ID_B)) { isHasSkin = true; } } } } // Node const char *nodeName = maxNode->GetName(); if(stricmp(nodeName, "PHYSICSDATA") == 0) { } else if(stricmp(nodeName, "PORTALDATA") == 0) { } PX2::Movable *child = 0; ObjectState objectState = maxNode->EvalWorldState(mTimeStart); bool supported = true; // Object if (objectState.obj) { switch (objectState.obj->SuperClassID()) { case GEOMOBJECT_CLASS_ID: if (IsNodeRenderable(maxNode, objectState.obj)) child = BuildGeometry(maxNode, relatParent, isHasSkin); else child = BuildNode(maxNode, relatParent); break; case CAMERA_CLASS_ID: // ToDo break; case LIGHT_CLASS_ID: if (mSettings->IncludeLights && !maxNode->IsHidden()) { BuildLight(maxNode, relatParent); } break; case HELPER_CLASS_ID: //supported = false; child = BuildNode(maxNode, relatParent); break; default: assertion(false, "Some object type not supportted."); supported = false; break; } } // Keyframe if (child) { if (mSettings->IncludeKeyFrames) BuildKeyFrameController(maxNode, child); else BuildFrameController(maxNode, child); } // Child int numChildren = maxNode->NumberOfChildren(); if (numChildren == 0) return true; PX2::Node *childNode = 0; childNode = PX2::DynamicCast<PX2::Node>(child); if (childNode == 0) return true; for (int i=0; i<numChildren; i++) { if (!Traverse(maxNode->GetChildNode(i), childNode) || mMax->GetCancel()) return false; } return true; }
Class_ID ClassID() { return Class_ID(TRUETYPE_LOADER_CLASS_ID,0); }
Class_ID ClassID() { return Class_ID(0x1a5d641c, 0x77092034); }