hsBool plMaxNodeBase::Contains(const Point3& worldPt) { TimeValue currTime = 0;//hsConverterUtils::Instance().GetTime(GetInterface()); Object *obj = EvalWorldState(currTime).obj; if( !obj ) return false; Matrix3 l2w = GetObjectTM(currTime); Matrix3 w2l = Inverse(l2w); Point3 pt = w2l * worldPt; if( obj->ClassID() == Class_ID(DUMMY_CLASS_ID,0) ) { DummyObject* dummy = (DummyObject*)obj; Box3 bnd = dummy->GetBox(); return bnd.Contains(pt); } if( obj->CanConvertToType(triObjectClassID) ) { TriObject *meshObj = (TriObject *)obj->ConvertToType(currTime, triObjectClassID); if( !meshObj ) return false; Mesh& mesh = meshObj->mesh; Box3 bnd = mesh.getBoundingBox(); if( !bnd.Contains(pt) ) { if( meshObj != obj ) meshObj->DeleteThis(); return false; } hsBool retVal = true; int i; for( i = 0; i < mesh.getNumFaces(); i++ ) { Face& face = mesh.faces[i]; Point3 p0 = mesh.verts[face.v[0]]; Point3 p1 = mesh.verts[face.v[1]]; Point3 p2 = mesh.verts[face.v[2]]; Point3 n = CrossProd(p1 - p0, p2 - p0); if( DotProd(pt, n) > DotProd(p0, n) ) { retVal = false; break; } } if( meshObj != obj ) meshObj->DeleteThis(); return retVal; } // If we can't figure out what it is, the point isn't inside it. return false; }
int XTCSample::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags, Object *pObj) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Doing Display() on invalid viewport!")); return FALSE; } if(pObj->ClassID() == XGSPHERE_CLASS_ID || pObj->IsSubClassOf(triObjectClassID)) { return DisplayMesh(t, inode, vpt, flags, GetMesh(pObj)); } #ifndef NO_PATCHES else if( pObj->IsSubClassOf(patchObjectClassID) ) { return DisplayPatch(t, inode, vpt, flags, (PatchObject *) pObj); } #endif else if(pObj->CanConvertToType(triObjectClassID)) { TriObject *pTri = (TriObject *) pObj->ConvertToType(t,triObjectClassID); DisplayMesh(t, inode, vpt, flags, &pTri->mesh); if(pTri != pObj) pTri->DeleteThis(); } return 0; }
BOOL plDistributor::IReadyRepNodes(plMeshCacheTab& cache) const { int i; for( i = 0; i < fRepNodes.Count(); i++ ) { Mesh* mesh = nil; TriObject* obj = nil; if( IGetMesh(fRepNodes[i], obj, mesh) ) { plMaxNode* repNode = (plMaxNode*)fRepNodes[i]; int iCache = cache.Count(); cache.SetCount(iCache + 1); cache[iCache].fMesh = new Mesh(*mesh); cache[iCache].fFlex = repNode->GetFlexibility(); if( obj ) obj->DeleteThis(); BOOL hasXImp = nil != repNode->GetXImposterComp(); ISetupNormals(repNode, cache[iCache].fMesh, hasXImp); ISetupSkinWeights(repNode, cache[iCache].fMesh, cache[iCache].fFlex); } else { fRepNodes.Delete(i, 1); i--; } } return fRepNodes.Count() > 0; }
float plMaxNodeBase::RegionPriority() { TimeValue currTime = 0;//hsConverterUtils::Instance().GetTime(GetInterface()); Object *obj = EvalWorldState(currTime).obj; if( !obj ) return 0; Matrix3 l2w = GetObjectTM(currTime); if( obj->ClassID() == Class_ID(DUMMY_CLASS_ID,0) ) { DummyObject* dummy = (DummyObject*)obj; Box3 bnd = dummy->GetBox(); return BoxVolume(bnd, l2w); } if( obj->CanConvertToType(triObjectClassID) ) { TriObject *meshObj = (TriObject *)obj->ConvertToType(currTime, triObjectClassID); if( !meshObj ) return 0; Mesh& mesh = meshObj->mesh; Box3 bnd = mesh.getBoundingBox(); if( meshObj != obj ) meshObj->DeleteThis(); return BoxVolume(bnd, l2w); } // Don't know how to interpret other, it's not contained. return 0; }
Object* SimpleObject::ConvertToType(TimeValue t, Class_ID obtype) { if (obtype==defObjectClassID||obtype==triObjectClassID||obtype==mapObjectClassID) { TriObject *triob; UpdateMesh(t); triob = CreateNewTriObject(); triob->GetMesh() = mesh; triob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); triob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); return triob; } #ifndef NO_PATCHES if (obtype == patchObjectClassID) { UpdateMesh(t); PatchObject *patchob = new PatchObject(); patchob->patch = mesh; // Handy Mesh->PatchMesh conversion patchob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); patchob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); return patchob; } #endif if (Object::CanConvertToType (obtype)) { UpdateMesh (t); return Object::ConvertToType(t,obtype); } if (CanConvertTriObject(obtype)) { UpdateMesh (t); TriObject *triob = CreateNewTriObject (); triob->GetMesh() = mesh; triob->SetChannelValidity(TOPO_CHAN_NUM,ObjectValidity(t)); triob->SetChannelValidity(GEOM_CHAN_NUM,ObjectValidity(t)); Object *ob = triob->ConvertToType (t, obtype); if (ob != triob) triob->DeleteThis (); // (ob should never = tob.) return ob; } return NULL; }
void BlobMesh::BuildMesh(TimeValue t) { //TODO: Implement the code to build the mesh representation of the object // using its parameter settings at the time passed. The plug-in should // use the data member mesh to store the built mesh. int numberOfNodes = pblock2->Count(pb_nodelist); float size, tension, renderCoarseness, viewCoarseness,coarseness; // Interval valid; pblock2->GetValue(pb_size,t,size,ivalid); pblock2->GetValue(pb_tension,t,tension,ivalid); if (tension < 0.011f) tension = 0.011f; if (tension > 1.0f) tension = 1.0f; pblock2->GetValue(pb_render,t,renderCoarseness,ivalid); pblock2->GetValue(pb_viewport,t,viewCoarseness,ivalid); BOOL autoCoarseness; pblock2->GetValue(pb_relativecoarseness,t,autoCoarseness,ivalid); BOOL largeDataSetOpt; pblock2->GetValue(pb_oldmetaballmethod,t,largeDataSetOpt,ivalid); BOOL useSoftSel; float minSize; pblock2->GetValue(pb_usesoftsel,t,useSoftSel,ivalid); pblock2->GetValue(pb_minsize,t,minSize,ivalid); if (inRender) coarseness = renderCoarseness; else coarseness = viewCoarseness; if (autoCoarseness) coarseness = size/coarseness; Tab<INode *> pfList; BOOL useAllPFEvents; pblock2->GetValue(pb_useallpf,0,useAllPFEvents,FOREVER); int pfCt = pblock2->Count(pb_pfeventlist); BOOL offInView; pblock2->GetValue(pb_offinview,0,offInView,FOREVER); for (int i = 0; i < pfCt; i++) { INode* node = NULL; pblock2->GetValue(pb_pfeventlist,0,node,FOREVER,i); if (node) pfList.Append(1,&node); } float thres = 0.6f; //need to get our tm if (selfNode == NULL) { MyEnumProc dep(true); DoEnumDependents(&dep); if (dep.Nodes.Count() > 0) selfNode = dep.Nodes[0]; } Matrix3 baseTM(1); if (selfNode != NULL) baseTM = Inverse(selfNode->GetObjectTM(t)); //loop throght the nodes if (!inRender) { if (offInView) numberOfNodes = 0; } std::vector<SphereData> data; data.reserve(500); for (int i = 0; i < numberOfNodes; i++) { INode* node = NULL; pblock2->GetValue(pb_nodelist,t,node,ivalid,i); if (node) { //get the nodes tm Matrix3 objectTM = node->GetObjectTM(t); Matrix3 toLocalSpace = objectTM*baseTM; ObjectState tos = node->EvalWorldState(t,TRUE); if (tos.obj->IsParticleSystem()) { SimpleParticle* pobj = NULL; IParticleObjectExt* epobj = NULL; pobj = static_cast<SimpleParticle*>( tos.obj->GetInterface(I_SIMPLEPARTICLEOBJ) ); if (pobj) { pobj->UpdateParticles(t, node); int count = pobj->parts.Count(); data.reserve(data.size() + count); float closest = 999999999.9f; SphereData d; for (int pid = 0; pid < count; pid++) { TimeValue age = pobj->ParticleAge(t,pid); TimeValue life = pobj->ParticleLife(t,pid); if (age != -1) { float psize = pobj->ParticleSize(t,pid); Point3 curval = pobj->parts.points[pid]; d.center = curval * baseTM; d.radius = psize; d.oradius = psize; d.rsquare = psize * psize; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } else { epobj = (IParticleObjectExt*) tos.obj->GetInterface(PARTICLEOBJECTEXT_INTERFACE); if (epobj) { epobj->UpdateParticles(node, t); int count = epobj->NumParticles(); data.reserve(data.size() + count); for (int pid = 0; pid < count; pid++) { TimeValue age = epobj->GetParticleAgeByIndex(pid); if (age!=-1) { INode *node = epobj->GetParticleGroup(pid); Point3 *curval = epobj->GetParticlePositionByIndex(pid); BOOL useParticle = TRUE; if (!useAllPFEvents) { useParticle = FALSE; for (int k = 0; k < pfList.Count(); k++) { if (node == pfList[k]) { useParticle = TRUE; k = pfList.Count(); } } } if ((curval) && (useParticle)) { float scale = epobj->GetParticleScaleByIndex(pid) ; float psize = scale; SphereData d; d.center = *curval*baseTM; d.radius = psize; d.oradius = psize; d.rsquare = psize * psize; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } } } } else if (tos.obj->IsShapeObject()) { PolyShape shape; ShapeObject *pathOb = (ShapeObject*)tos.obj; pathOb->MakePolyShape(t, shape); // first find out how many points there are: size_t num_points = 0; for (int i = 0; i < shape.numLines; i++) { PolyLine& line = shape.lines[i]; num_points += line.numPts; } data.reserve(data.size() + num_points); for (int i = 0; i < shape.numLines; i++) { PolyLine line = shape.lines[i]; for (int j = 0; j < line.numPts; j++) { SphereData d; float tsize = size; d.center = line.pts[j].p*toLocalSpace; d.radius = tsize; d.oradius = tsize; d.rsquare = tsize * tsize; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } else if (tos.obj->SuperClassID()==GEOMOBJECT_CLASS_ID) { SphereData d; BOOL converted = FALSE; TriObject *triObj = NULL; if(tos.obj->IsSubClassOf(triObjectClassID)) { triObj = (TriObject *)tos.obj; } // If it can convert to a TriObject, do it else if(tos.obj->CanConvertToType(triObjectClassID)) { triObj = (TriObject *)tos.obj->ConvertToType(t, triObjectClassID); converted = TRUE; } if (triObj != NULL) { Mesh* mesh = &triObj->GetMesh(); if (mesh) { int vcount = mesh->getNumVerts(); float *vsw = mesh->getVSelectionWeights (); BitArray vsel = mesh->VertSel(); data.reserve(data.size() + vcount); for (int j = 0; j < vcount; j++) { float tsize = size; if (useSoftSel) { tsize = 0.0f; if (vsw) { float v = 0.0f; if (vsel[j]) v = 1.0f; else { if (vsw) v = vsw[j]; } if (v == 0.0f) tsize = 0.0f; else { tsize = minSize + (size -minSize)*v; } } else { float v = 0.0f; if (vsel[j]) v = 1.0f; tsize = minSize + (size -minSize)*v; } } if (tsize != 0.0f) { d.center = mesh->getVert(j)*toLocalSpace; d.radius = tsize; d.oradius = tsize; d.rsquare = tsize * tsize; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } if (converted) triObj->DeleteThis(); } } else { SphereData d; d.center = Point3(0.0f,0.0f,0.0f)*toLocalSpace; d.radius = size; d.oradius = size; d.rsquare = size * size; d.tover4 = tension * d.rsquare *d.rsquare ; data.push_back(d); } } } if ((data.size() == 0) && (numberOfNodes==0)) { data.resize(1); data[0].center = Point3(0.0f,0.0f,0.0f); data[0].radius = size; data[0].oradius = size; data[0].rsquare = size * size; data[0].tover4 = tension * data[0].rsquare *data[0].rsquare ; } if (data.size() > 0) { int iRes = 1; if (!largeDataSetOpt) { MetaParticle oldBlob; iRes = oldBlob.CreatePodMetas(&data[0],(int)data.size(),&mesh,thres,coarseness); } else { MetaParticleFast blob; iRes = blob.CreatePodMetas(&data[0],(int)data.size(),&mesh,thres,coarseness); } // An out of memory error is the only reason iRes would be zero in either case if( (iRes == 0) && GetCOREInterface() ) GetCOREInterface()->DisplayTempPrompt(GetString(IDS_NOT_ENOUGH_MEM), 5000 ); } else { mesh.setNumFaces(0); mesh.setNumVerts(0); } mesh.InvalidateTopologyCache(); ivalid.Set(t,t); }
//Some helper functions to handle painter UI void PainterTextureSample::Paint() { node = NULL; // pblock->GetValue(pb_node,0,node,FOREVER); int nodeCount = GetCOREInterface()->GetSelNodeCount(); if (nodeCount > 0) node = GetCOREInterface()->GetSelNode(0); if ((pPainter) && (node))//need to check this since some one could have taken the painterinterface plugin out { if (!pPainter->InPaintMode()) { pPainter->InitializeCallback(this); //initialize the callback //we dont use the point gather or normal data pPainter->SetEnablePointGather(TRUE); pPainter->SetBuildNormalData(FALSE); //this sends all our dependant nodes to the painter Tab<INode*> nodes; nodes.Append(1,&node); pPainter->InitializeNodes(0, nodes); //since we are painting on the final mesh we dont need to do any special handling of nodes pPainter->StartPaintSession(); //start the paint session iPaintButton->SetCheck(TRUE); //need to build mesh and uvw data ObjectState sos; TimeValue t = GetCOREInterface()->GetTime(); if (node) { sos = node->EvalWorldState(t); Mesh *msh = NULL; TriObject *collapsedtobj = NULL; if (sos.obj) { if (sos.obj->IsSubClassOf(triObjectClassID)) { TriObject *tobj = (TriObject*)sos.obj; msh = &tobj->GetMesh(); } //collapse it to a mesh else if (sos.obj->CanConvertToType(triObjectClassID)) { collapsedtobj = (TriObject*) sos.obj->ConvertToType(t,triObjectClassID); msh = &collapsedtobj->GetMesh(); } if (msh != NULL) { int uvCount = msh->getNumMapVerts(1); int numFaces = msh->numFaces; uvwPoints.SetCount(uvCount); uvwFaces.SetCount(numFaces); memcpy(uvwPoints.Addr(0), msh->mapVerts(1),uvCount*sizeof(Point3)); memcpy(uvwFaces.Addr(0), msh->mapFaces(1),numFaces*sizeof(TVFace)); Matrix3 tm = node->GetObjectTM(t); BuildWorldSpaceData(msh,tm); int ct = worldSpaceList.Count(); pPainter->LoadCustomPointGather(ct, worldSpaceList.Addr(0), node); pPainter->UpdateMeshes(TRUE); } if ((collapsedtobj) && (collapsedtobj != sos.obj)) collapsedtobj->DeleteThis(); } } } else //we are currently in a paint mode so turn it off { pPainter->EndPaintSession(); //end the paint session iPaintButton->SetCheck(FALSE); } } }