int FExtrudeMod::Display( TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } GraphicsWindow *gw = vpt->getGW(); Point3 pt; Matrix3 tm = CompMatrix(t,inode,mc); int savedLimits; gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM); gw->setTransform(tm); // Draw start point if (ip && ip->GetSubObjectLevel() == 1) { //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); gw->marker(&pt,HOLLOW_BOX_MRKR); gw->setRndLimits(savedLimits); return 0; }
int FExtrudeMod::HitTest( TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } GraphicsWindow *gw = vpt->getGW(); Point3 pt; HitRegion hr; int savedLimits, res = 0; Matrix3 tm = CompMatrix(t,inode,mc); MakeHitRegion(hr,type, crossing,4,p); gw->setHitRegion(&hr); gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM); gw->setTransform(tm); gw->clearHitCode(); base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); gw->marker(&pt,HOLLOW_BOX_MRKR); if (gw->checkHitCode()) { vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL); res = 1; } gw->setRndLimits(savedLimits); return res; }
int AFRMod::HitTest( TimeValue t, INode* inode, int type, int crossing, int flags, IPoint2 *p, ViewExp *vpt, ModContext* mc) { GraphicsWindow *gw = vpt->getGW(); Point3 pt; HitRegion hr; int savedLimits, res = 0; Matrix3 tm = CompMatrix(t,inode,mc); MakeHitRegion(hr,type, crossing,4,p); gw->setHitRegion(&hr); gw->setRndLimits(((savedLimits = gw->getRndLimits()) | GW_PICK) & ~GW_ILLUM); gw->setTransform(tm); // Hit test start point if ((flags&HIT_SELONLY && sel[0]) || (flags&HIT_UNSELONLY && !sel[0]) || !(flags&(HIT_UNSELONLY|HIT_SELONLY)) ) { gw->clearHitCode(); p1->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); gw->marker(&pt,HOLLOW_BOX_MRKR); if (gw->checkHitCode()) { vpt->LogHit(inode, mc, gw->getHitDistance(), 0, NULL); res = 1; } } // Hit test end point if ((flags&HIT_SELONLY && sel[1]) || (flags&HIT_UNSELONLY && !sel[1]) || !(flags&(HIT_UNSELONLY|HIT_SELONLY)) ) { gw->clearHitCode(); p2->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); gw->marker(&pt,HOLLOW_BOX_MRKR); if (gw->checkHitCode()) { vpt->LogHit(inode, mc, gw->getHitDistance(), 1, NULL); res = 1; } } gw->setRndLimits(savedLimits); return res; }
void FExtrudeMod::GetSubObjectCenters (SubObjAxisCallback *cb, TimeValue t, INode *node,ModContext *mc) { Matrix3 tm = CompMatrix(t,node,mc); Point3 p; mp_base->GetValue(t,&p,FOREVER,CTRL_ABSOLUTE); tm.PreTranslate(p); cb->Center(tm.GetTrans(),0); }
Interval AFRMod::LocalValidity(TimeValue t) { // aszabo|feb.05.02 If we are being edited, return NEVER // to forces a cache to be built after previous modifier. if (TestAFlag(A_MOD_BEING_EDITED)) return NEVER; Interval iv = FOREVER; float v; Point3 pt; pblock->GetValue(PB_FALLOFF,t,v,iv); pblock->GetValue(PB_PINCH,t,v,iv); pblock->GetValue(PB_BUBBLE,t,v,iv); p1->GetValue(t,&pt,iv,CTRL_ABSOLUTE); p2->GetValue(t,&pt,iv,CTRL_ABSOLUTE); return iv; }
void FExtrudeMod::GetWorldBoundBox (TimeValue t, INode* inode, ViewExp * /*vpt*/, Box3& box, ModContext *mc) { Matrix3 tm = CompMatrix(t,inode,mc); Point3 pt; box.Init(); mp_base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); box += pt * tm; }
Matrix3 SymmetryMod::CompMatrix (TimeValue t, INode *inode, ModContext *mc, Interval *validity) { Interval localInterval(FOREVER); if (!validity) validity = &localInterval; Matrix3 tm(1); mp_mirror->GetValue(t,&tm,*validity,CTRL_RELATIVE); if (mc && mc->tm) tm = tm * Inverse(*(mc->tm)); if (inode) tm = tm * inode->GetObjTMBeforeWSM(t,validity); return tm; }
//aszabo|feb.06.02 - When LocalValidity is called by ModifyObject, // it returns NEVER and thus the object channels are marked non valid // As a result, the mod stack enters and infinite evaluation of the modifier // ModifyObject now calls GetValidity and CORE calls LocalValidity to // allow for building a cache on the input of this modifier when it's // being edited Interval MirrorMod::GetValidity(TimeValue t) { Interval iv = FOREVER; Matrix3 mat(1); tmControl->GetValue(t,&mat,iv,CTRL_RELATIVE); float o; pblock->GetValue(PB_OFFSET,t,o,iv); return iv; }
void AFRMod::GetSubObjectCenters( SubObjAxisCallback *cb,TimeValue t, INode *node,ModContext *mc) { Matrix3 tm = CompMatrix(t,node,mc); Point3 pt(0,0,0), p; int c=0; if (sel[0]) { p1->GetValue(t,&p,FOREVER,CTRL_ABSOLUTE); pt += p; c++; } if (sel[1]) { p2->GetValue(t,&p,FOREVER,CTRL_ABSOLUTE); pt += p; c++; } if (c) pt /= float(c); tm.PreTranslate(pt); cb->Center(tm.GetTrans(),0); }
void AFRMod::GetWorldBoundBox( TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc) { Matrix3 tm = CompMatrix(t,inode,mc); Point3 pt1, pt2; box.Init(); p1->GetValue(t,&pt1,FOREVER,CTRL_ABSOLUTE); box += pt1 * tm; p2->GetValue(t,&pt2,FOREVER,CTRL_ABSOLUTE); box += pt2 * tm; Matrix3 vtm; vpt->GetAffineTM(vtm); Point3 vz = vtm.GetRow(2) * Inverse(tm); Point3 dp = (pt2-pt1); Point3 v = Normalize(vz^dp) * Length(dp) * 0.2f; box += (pt2 - (0.2f*dp) + v) * tm; box += (pt2 - (0.2f*dp) - v) * tm; v = Normalize(v^dp) * Length(dp) * 0.2f; box += (pt2 - (0.2f*dp) + v) * tm; box += (pt2 - (0.2f*dp) - v) * tm; }
Interval FExtrudeMod::LocalValidity(TimeValue t) { // aszabo|feb.05.02 If we are being edited, // return NEVER to forces a cache to be built after previous modifier. if (TestAFlag(A_MOD_BEING_EDITED)) return NEVER; Interval iv = FOREVER; float v; Point3 pt; int type; mp_pblock->GetValue(kFexAmount,t,v,iv); mp_pblock->GetValue(kFexScale,t,v,iv); mp_pblock->GetValue (kFexType, t, type, iv); if (type==2) mp_base->GetValue(t,&pt,iv,CTRL_ABSOLUTE); return iv; }
Interval FExtrudeMod::LocalValidity(TimeValue t) { // aszabo|feb.05.02 If we are being edited, return NEVER // to forces a cache to be built after previous modifier. if (TestAFlag(A_MOD_BEING_EDITED)) return NEVER; Interval iv = FOREVER; float v; Point3 pt; pblock->GetValue(PB_AMOUNT,t,v,iv); pblock->GetValue(PB_SCALE,t,v,iv); base->GetValue(t,&pt,iv,CTRL_ABSOLUTE); return iv; }
Matrix3 MirrorMod::CompMatrix( TimeValue t,INode *inode,ModContext *mc) { Interval iv; Matrix3 tm(1); tmControl->GetValue(t,&tm,iv,CTRL_RELATIVE); if (mc && mc->tm) tm = tm * Inverse(*(mc->tm)); if (inode) { #ifdef DESIGN_VER tm = tm * inode->GetObjTMBeforeWSM(GetCOREInterface()->GetTime(),&iv); #else tm = tm * inode->GetObjTMBeforeWSM(t,&iv); #endif // DESIGN_VER } return tm; }
void FExtrudeMod::GetWorldBoundBox( TimeValue t,INode* inode, ViewExp *vpt, Box3& box, ModContext *mc) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return; } Matrix3 tm = CompMatrix(t,inode,mc); Point3 pt; box.Init(); base->GetValue(t,&pt,FOREVER,CTRL_ABSOLUTE); box += pt * tm; }
Interval SymmetryMod::LocalValidity(TimeValue t) { // aszabo|feb.05.02 If we are being edited, // return NEVER to forces a cache to be built after previous modifier. if (TestAFlag(A_MOD_BEING_EDITED)) return NEVER; Interval iv = FOREVER; int foo; mp_pblock->GetValue(kSymAxis, t, foo, iv); mp_pblock->GetValue (kSymFlip, t, foo, iv); mp_pblock->GetValue(kSymWeld, t, foo, iv); mp_pblock->GetValue(kSymSlice, t, foo, iv); float thresh; mp_pblock->GetValue (kSymThreshold, t, thresh, iv); Matrix3 mat(1); mp_mirror->GetValue(t,&mat,iv,CTRL_RELATIVE); return iv; }
void BaseLimitCtrl::GetUnlimitedValue ( const TimeValue& in_t, void* in_val, Interval& out_valid, GetSetMethod in_method // = CTRL_ABSOLUTE ) const { // Check if we have a controller assigned. If so, GetValue on it Control *limitedCtrl = GetLimitedControl(); if (limitedCtrl) { limitedCtrl->GetValue(in_t, in_val, out_valid, in_method); } else { // Get the limit controller static value out_valid = FOREVER; GetStaticValue(in_val, in_method); } }
void RandKeysUtil::Apply() { BOOL timeMode = iu->GetMajorMode()==TVMODE_EDITTIME; BOOL fcurveMode = iu->GetMajorMode()==TVMODE_EDITFCURVE; Interval iv = iu->GetTimeSelection(); if (!doTime && !doVal) return; theHold.Begin(); // Turn animation on SuspendAnimate(); AnimateOn(); for (int i=0; i<iu->GetNumTracks(); i++) { if ((timeMode||fcurveMode) && !iu->IsSelected(i)) continue; // Get Interfaces Animatable *anim = iu->GetAnim(i); Animatable *client = iu->GetClient(i); int subNum = iu->GetSubNum(i); Control *cont = GetControlInterface(anim); IKeyControl *ikc = GetKeyControlInterface(anim); IKey *key = GetKeyPointer(anim->SuperClassID(),anim->ClassID()); if (!ikc || !cont || !key) continue; if (fcurveMode && !anim->IsCurveSelected()) continue; // Get the param dim float min = negVal, max = posVal; ParamDimension *dim = client->GetParamDimension(subNum); if (dim) { min = dim->UnConvert(min); max = dim->UnConvert(max); } for (int j=0; j<ikc->GetNumKeys(); j++) { // Get the key data ikc->GetKey(j,key); // Check if it's selected if (timeMode && !iv.InInterval(key->time)) continue; if (!timeMode && !(key->flags&IKEY_SELECTED)) continue; // Randomize time if (doTime) { key->time = (int)CompRand( float(key->time-negTime), float(key->time+posTime)); ikc->SetKey(j,key); } } if (doTime) ikc->SortKeys(); for (j=0; j<ikc->GetNumKeys(); j++) { // Get the key data ikc->GetKey(j,key); // Check if it's selected if (timeMode && !iv.InInterval(key->time)) continue; if (!timeMode && !(key->flags&IKEY_SELECTED)) continue; // Randomize value if (doVal) { Point3 pt, ang; Point4 p4; float f; Quat q; ScaleValue s; BOOL doX, doY, doZ, doW; doX = doY = doZ = doW = TRUE; if (!fcurveMode) { if (!(key->flags&IKEY_XSEL)) doX = FALSE; if (!(key->flags&IKEY_YSEL)) doY = FALSE; if (!(key->flags&IKEY_ZSEL)) doZ = FALSE; if (!(key->flags&IKEY_WSEL)) doW = FALSE; } switch (anim->SuperClassID()) { case CTRL_FLOAT_CLASS_ID: cont->GetValue(key->time,&f,FOREVER); f = CompRand(f-min,f+max); cont->SetValue(key->time,&f); break; case CTRL_POSITION_CLASS_ID: case CTRL_POINT3_CLASS_ID: cont->GetValue(key->time,&pt,FOREVER); if (doX) pt.x = CompRand(pt.x-min,pt.x+max); if (doY) pt.y = CompRand(pt.y-min,pt.y+max); if (doZ) pt.z = CompRand(pt.z-min,pt.z+max); cont->SetValue(key->time,&pt); break; case CTRL_POINT4_CLASS_ID: cont->GetValue(key->time,&p4,FOREVER); if (doX) p4.x = CompRand(p4.x-min,p4.x+max); if (doY) p4.y = CompRand(p4.y-min,p4.y+max); if (doZ) p4.z = CompRand(p4.z-min,p4.z+max); if (doW) p4.w = CompRand(p4.w-min,p4.w+max); cont->SetValue(key->time,&p4); break; case CTRL_ROTATION_CLASS_ID: cont->GetValue(key->time,&q,FOREVER); QuatToEuler(q, ang); ang.x = CompRand(ang.x-min,ang.x+max); ang.y = CompRand(ang.y-min,ang.y+max); ang.z = CompRand(ang.z-min,ang.z+max); EulerToQuat(ang,q); cont->SetValue(key->time,&q); break; case CTRL_SCALE_CLASS_ID: cont->GetValue(key->time,&s,FOREVER); if (doX) s.s.x = CompRand(s.s.x-min,s.s.x+max); if (doY) s.s.y = CompRand(s.s.y-min,s.s.y+max); if (doZ) s.s.z = CompRand(s.s.z-min,s.s.z+max); cont->SetValue(key->time,&s); break; } } } } ResumeAnimate(); theHold.Accept(GetString(IDS_RB_RANDOMIZEKEYS)); ip->RedrawViews(ip->GetTime()); }
void SkeletonExporter::export_camera(INode *node) { Control *c; int size_key; float camera_znear, camera_zfar; CameraState cs; // Interval valid = FOREVER; ObjectState os; CameraObject *cam; GenCamera *gencam; float roll0; Matrix3 mat; Point3 row; os = node->EvalWorldState(0); cam = (CameraObject *)os.obj; gencam = (GenCamera *)os.obj; if (gencam->Type() != TARGETED_CAMERA) { fprintf(fTXT, "Only targeted camera are supported!\n\n"); return; } fprintf(fTXT, "Targeted camera found\n"); write_chunk_header(fA3D, TARGETED_CAMERA_ID, node->GetName(), 40); if (makeRAY) write_chunk_header(fRAY, TARGETED_CAMERA_ID, node->GetName(), 40); INode* target = node->GetTarget(); fprintf(fTXT, "Name : %s\n", node->GetName()); cam->EvalCameraState(0, FOREVER, &cs); // ------------------ salviamo znear e zfar ---------------------- camera_znear=2; camera_zfar=2000; if (cs.manualClip) { camera_znear=cs.hither; camera_zfar=cs.yon; } fprintf(fTXT, "Znear = %f \n", camera_znear); fwrite(&camera_znear, sizeof(float), 1, fA3D); if (makeRAY) fwrite(&camera_znear, sizeof(float), 1, fRAY); fprintf(fTXT, "Zfar = %f \n", camera_zfar); fwrite(&camera_zfar, sizeof(float), 1, fA3D); if (makeRAY) fwrite(&camera_zfar, sizeof(float), 1, fRAY); // ----------------- salviamo l'angolo di FOV -------------------- fprintf(fTXT, "FOV (rad) = %f \n", cs.fov); fwrite(&cs.fov, sizeof(float), 1, fA3D); if (makeRAY) fwrite(&cs.fov, sizeof(float), 1, fRAY); // ------------------ salviamo l'angolo di roll ------------------ c=node->GetTMController()->GetRollController(); c->GetValue(0, &roll0, FOREVER); fprintf(fTXT, "Roll (rad) = %f \n", roll0); fwrite(&roll0, sizeof(float), 1, fA3D); if (makeRAY) fwrite(&roll0, sizeof(float), 1, fRAY); // salviamo la posizione nel mondo mat = node->GetNodeTM(0); row = mat.GetRow(3); fprintf(fTXT, "Camera world position : x=%f, y=%f, z=%f\n", row.x, row.y, row.z); write_point3(&row, fA3D); if (makeRAY) write_point3(&row, fRAY); // --------- salviamo la posizione del target nel mondo ---------- if (target) { mat = target->GetNodeTM(0); row = mat.GetRow(3); fprintf(fTXT, "Target world position : x=%f, y=%f, z=%f\n", row.x, row.y, row.z); write_point3(&row, fA3D); if (makeRAY) write_point3(&row, fRAY); } // esportiamo l'animazione della posizione della camera // se ci sono un numero di key > 0 c=node->GetTMController()->GetPositionController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=36; else if (IsBezierControl(c)) size_key=40; else size_key=16; fprintf(fTXT, "Camera position track present."); write_chunk_header(fA3D, POSITION_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_point3_track(c, 1, fA3D); if (makeRAY) write_chunk_header(fRAY, POSITION_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); if (makeRAY) export_point3_track(c, 1, fRAY); } // ----- esportiamo l'animazione della posizione del target ------ if (target) { c=target->GetTMController()->GetPositionController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=36; else if (IsBezierControl(c)) size_key=40; else size_key=16; fprintf(fTXT, "Target position track present."); write_chunk_header(fA3D, CAMERA_TARGET_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_point3_track(c, 1, fA3D); if (makeRAY) write_chunk_header(fRAY, CAMERA_TARGET_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); if (makeRAY) export_point3_track(c, 1, fRAY); } } // --------------- esportiamo le tracce di FOV ------------------- c=gencam->GetFOVControl(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Camera FOV track present."); write_chunk_header(fA3D, CAMERA_FOV_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); // radianti if (makeRAY) write_chunk_header(fRAY, CAMERA_FOV_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); if (makeRAY) export_float_track(c, 1, fRAY); // radianti } // --------------- esportiamo le tracce di roll ------------------ c=node->GetTMController()->GetRollController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Camera roll track present."); write_chunk_header(fA3D, CAMERA_ROLL_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); // radianti if (makeRAY) write_chunk_header(fRAY, CAMERA_ROLL_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); if (makeRAY) export_float_track(c, 1, fRAY); // radianti } fprintf(fTXT, "\n\n--------------------------------------------------\n"); }
void FExtrudeMod::ModifyObject( TimeValue t, ModContext &mc, ObjectState *os, INode *node) { if (os->obj->IsSubClassOf(triObjectClassID)) { TriObject *tobj = (TriObject*)os->obj; Mesh &mesh = tobj->GetMesh(); Interval iv = FOREVER; float a, s; Point3 pt, center; int c; pblock->GetValue(PB_AMOUNT,t,a,iv); pblock->GetValue(PB_SCALE,t,s,iv); pblock->GetValue(PB_CENTER,t,c,iv); base->GetValue(t,&pt,iv,CTRL_ABSOLUTE); // Extrude the faces -- this just creates the new faces mesh.ExtrudeFaces(); // Build normals of selected faces only Tab<Point3> normals; if (!c) { normals.SetCount(mesh.getNumVerts()); for (int i=0; i<mesh.getNumVerts(); i++) { normals[i] = Point3(0,0,0); } for (int i=0; i<mesh.getNumFaces(); i++) { if (mesh.faceSel[i]) { Point3 norm = (mesh.verts[mesh.faces[i].v[1]]-mesh.verts[mesh.faces[i].v[0]]) ^ (mesh.verts[mesh.faces[i].v[2]]-mesh.verts[mesh.faces[i].v[1]]); for (int j=0; j<3; j++) { normals[mesh.faces[i].v[j]] += norm; } } } for (int i=0; i<mesh.getNumVerts(); i++) { normals[i] = Normalize(normals[i]); } } else { // Compute the center point base->GetValue(t,¢er,iv,CTRL_ABSOLUTE); } // Mark vertices used by selected faces BitArray sel; sel.SetSize(mesh.getNumVerts()); for (int i=0; i<mesh.getNumFaces(); i++) { if (mesh.faceSel[i]) { for (int j=0; j<3; j++) sel.Set(mesh.faces[i].v[j],TRUE); } } // Move selected verts for (int i=0; i<mesh.getNumVerts(); i++) { if (sel[i]) { if (!c) { mesh.verts[i] += normals[i]*a; } else { Point3 vect = Normalize((mesh.verts[i] * (*mc.tm)) - center); mesh.verts[i] += vect*a; } } } // Scale verts if (s!=100.0f) { s /= 100.0f; AdjEdgeList ae(mesh); AdjFaceList af(mesh,ae); FaceClusterList clust(mesh.faceSel,af); // Make sure each vertex is only scaled once. BitArray done; done.SetSize(mesh.getNumVerts()); // scale each cluster independently for (int i=0; (DWORD)i<clust.count; i++) { // First determine cluster center Point3 cent(0,0,0); int ct=0; for (int j=0; j<mesh.getNumFaces(); j++) { if (clust[j]==(DWORD)i) { for (int k=0; k<3; k++) { cent += mesh.verts[mesh.faces[j].v[k]]; ct++; } } } if (ct) cent /= float(ct); // Now scale the cluster about its center for (int j=0; j<mesh.getNumFaces(); j++) { if (clust[j]==(DWORD)i) { for (int k=0; k<3; k++) { int index = mesh.faces[j].v[k]; if (done[index]) continue; done.Set(index); mesh.verts[index] = (mesh.verts[index]-cent)*s + cent; } } } } } mesh.InvalidateTopologyCache (); os->obj->UpdateValidity(GEOM_CHAN_NUM,iv); } }
void FExtrudeMod::ModifyPolyObject (TimeValue t, ModContext &mc, PolyObject *pobj) { MNMesh &mesh = pobj->GetMesh(); // Luna task 747 // We cannot support specified normals in Face Extrude at this time. mesh.ClearSpecifiedNormals(); Interval iv = FOREVER; float amount, scale; Point3 center; int type, i, j; mp_pblock->GetValue (kFexAmount, t, amount, iv); mp_pblock->GetValue (kFexScale, t, scale, iv); mp_pblock->GetValue (kFexType, t, type, iv); MNTempData temp(&mesh); bool abort=false; DWORD flag=MN_SEL; // Later can be used to "inherit" selection from other SO levels. switch (type) { case 0: // Group normals abort = !mesh.ExtrudeFaceClusters (*(temp.FaceClusters(flag))); if (!abort) { temp.Invalidate (TOPO_CHANNEL); // Forces reevaluation of face clusters. mesh.GetExtrudeDirection (temp.ChamferData(), temp.FaceClusters(flag), temp.ClusterNormals (MNM_SL_FACE, flag)->Addr(0)); } break; case 1: // Local normals abort = !mesh.ExtrudeFaceClusters (*(temp.FaceClusters(flag))); if (!abort) { temp.Invalidate (TOPO_CHANNEL); // Forces reevaluation of face clusters. mesh.GetExtrudeDirection (temp.ChamferData(), flag); } break; case 2: // from center: mp_base->GetValue(t,¢er,iv,CTRL_ABSOLUTE); abort = !mesh.ExtrudeFaceClusters (*(temp.FaceClusters(flag))); if (!abort) { temp.Invalidate (GEOM_CHANNEL); MNChamferData *mcd = temp.ChamferData(); mcd->InitToMesh (mesh); mcd->ClearLimits (); int j, mp; // Make clear that there are no map values: for (mp=-NUM_HIDDENMAPS; mp<mesh.numm; mp++) mcd->MDir(mp).SetCount(0); // Each vertex on flagged faces moves according to the direction from the center: for (i=0; i<mesh.numv; i++) { mcd->vdir[i] = Point3(0,0,0); if (mesh.v[i].GetFlag (MN_DEAD)) continue; if (!mesh.vfac[i].Count()) continue; bool hasflagged = false; for (j=0; j<mesh.vfac[i].Count(); j++) { MNFace & mf = mesh.f[mesh.vfac[i][j]]; if (!mf.GetFlag (MN_SEL)) continue; hasflagged = true; } if (!hasflagged) continue; mcd->vdir[i] = Normalize((mesh.P(i)*(*mc.tm))-center); } } break; } if (abort) return; // Move verts for (i=0; i<mesh.numv; i++) { if (mesh.v[i].GetFlag (MN_DEAD)) continue; mesh.v[i].p += temp.ChamferData()->vdir[i]*amount; } // Scale verts if (scale!=1.0f) { temp.freeAll (); temp.SetMesh (&mesh); MNFaceClusters *fc = temp.FaceClusters(); Tab<Point3> *centers = temp.ClusterCenters (MNM_SL_FACE); // Make sure each vertex is only scaled once. BitArray done; done.SetSize(mesh.numv); // scale each cluster independently for (i=0; i<fc->count; i++) { Point3 cent = (centers->Addr(0))[i]; // Scale the cluster about its center for (j=0; j<mesh.numf; j++) { if (fc->clust[j]==i) { for (int k=0; k<mesh.f[j].deg; k++) { int index = mesh.f[j].vtx[k]; if (done[index]) continue; done.Set(index); mesh.v[index].p = (mesh.v[index].p-cent)*scale + cent; } } } } } mesh.InvalidateTopoCache (); mesh.FillInMesh (); pobj->UpdateValidity(GEOM_CHAN_NUM,iv); }
void FExtrudeMod::ModifyTriObject (TimeValue t, ModContext &mc, TriObject *tobj) { Mesh &mesh = tobj->GetMesh(); Interval iv = FOREVER; float amount, scale; Point3 center; int i, j, type; mp_pblock->GetValue (kFexAmount, t, amount, iv); mp_pblock->GetValue (kFexScale, t, scale, iv); mp_pblock->GetValue (kFexType, t, type, iv); // Extrude the faces -- this just does the topological operation. MeshDelta tmd(mesh); tmd.ExtrudeFaces (mesh, mesh.faceSel); tmd.Apply(mesh); // Mark vertices used by selected faces BitArray sel; sel.SetSize(mesh.getNumVerts()); for (i=0; i<mesh.getNumFaces(); i++) { if (mesh.faceSel[i]) { for (int j=0; j<3; j++) sel.Set(mesh.faces[i].v[j],TRUE); } } MeshTempData temp(&mesh); Point3 *vertexDir; Tab<Point3> centerBasedBuffer; if (type<2) { int extrusionType = type ? MESH_EXTRUDE_LOCAL : MESH_EXTRUDE_CLUSTER; vertexDir = temp.FaceExtDir(extrusionType)->Addr(0); } else { // We need to move all vertices away from the "center". // Compute the center point Point3 center; mp_base->GetValue(t,¢er,iv,CTRL_ABSOLUTE); // Create array of vertex directions centerBasedBuffer.SetCount (mesh.numVerts); vertexDir = centerBasedBuffer.Addr(0); for (i=0; i<mesh.numVerts; i++) { if (!sel[i]) continue; vertexDir[i] = Normalize((mesh.verts[i] * (*mc.tm)) - center); } } // Actually do the move: for (i=0; i<mesh.numVerts; i++) { if (!sel[i]) continue; mesh.verts[i] += amount * vertexDir[i]; } // Scale verts if (scale!=1.0f) { temp.freeAll (); temp.SetMesh (&mesh); FaceClusterList *fc = temp.FaceClusters(); Tab<Point3> *centers = temp.ClusterCenters (MESH_FACE); // Make sure each vertex is only scaled once. BitArray done; done.SetSize(mesh.getNumVerts()); // scale each cluster independently for (i=0; (DWORD)i<fc->count; i++) { Point3 cent = (centers->Addr(0))[i]; // Scale the cluster about its center for (j=0; j<mesh.getNumFaces(); j++) { if (fc->clust[j]==(DWORD)i) { for (int k=0; k<3; k++) { int index = mesh.faces[j].v[k]; if (done[index]) continue; done.Set(index); mesh.verts[index] = (mesh.verts[index]-cent)*scale + cent; } } } } } mesh.InvalidateTopologyCache (); tobj->UpdateValidity(GEOM_CHAN_NUM,iv); }
int AFRMod::Display( TimeValue t, INode* inode, ViewExp *vpt, int flagst, ModContext *mc) { GraphicsWindow *gw = vpt->getGW(); Point3 pt[4]; Matrix3 tm = CompMatrix(t,inode,mc); int savedLimits; gw->setRndLimits((savedLimits = gw->getRndLimits()) & ~GW_ILLUM); gw->setTransform(tm); // Draw start point if (ip && ip->GetSubObjectLevel() == 1) { if (sel[0]) gw->setColor(LINE_COLOR, (float)1.0, (float)0.0, (float)0.0); else //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } p1->GetValue(t,&pt[0],FOREVER,CTRL_ABSOLUTE); gw->marker(&pt[0],HOLLOW_BOX_MRKR); // Draw end point if (ip && ip->GetSubObjectLevel() == 1) { if (sel[1]) gw->setColor(LINE_COLOR, (float)1.0, (float)0.0, (float)0.0); else //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } p2->GetValue(t,&pt[1],FOREVER,CTRL_ABSOLUTE); gw->marker(&pt[1],HOLLOW_BOX_MRKR); // Draw a line inbetween if (ip && ip->GetSubObjectLevel() == 1) { //gw->setColor(LINE_COLOR, (float)1.0, (float)1.0, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SEL_GIZMOS)); } else { //gw->setColor(LINE_COLOR, (float).85, (float).5, (float)0.0); gw->setColor(LINE_COLOR,GetUIColor(COLOR_GIZMOS)); } gw->polyline(2, pt, NULL, NULL, 0, NULL); // Draw arrowhead Matrix3 vtm; vpt->GetAffineTM(vtm); Point3 vz = vtm.GetRow(2) * Inverse(tm); Point3 dp = (pt[1]-pt[0]); Point3 v = Normalize(vz^dp) * Length(dp) * 0.2f; pt[0] = pt[1] - (0.2f*dp) + v; pt[2] = pt[1] - (0.2f*dp) - v; gw->polyline(3, pt, NULL, NULL, 0, NULL); v = Normalize(v^dp) * Length(dp) * 0.2f; pt[0] = pt[1] - (0.2f*dp) + v; pt[2] = pt[1] - (0.2f*dp) - v; gw->polyline(3, pt, NULL, NULL, 0, NULL); gw->setRndLimits(savedLimits); return 0; }
// *********************************************************** // ****************** VENTO *********************** // *********************************************************** void SkeletonExporter::export_WSM_wind(INode *node) { Point3 row; Matrix3 mat; Control *c; int size_key; char sval[50]; ObjectState os = node->EvalWorldState(0); if (!os.obj) return; INode *padre=node->GetParentNode(); int sf; if ((padre) && (strcmp(padre->GetName(), "Scene Root")!=0)) sf=strlen(padre->GetName())+1; else sf=0; fprintf(fTXT, "Wind space modifier found\n"); fprintf(fTXT, "Name : %s\n", node->GetName()); // flag padre + nome padre + pivot + matrice(t=0) + // strenght + decay + mapping + turbolence + frequency + scale write_chunk_header(fA3D, WIND_MODIFIER_ID, node->GetName(), 4+sf+12+48+4*6); fwrite(&sf, sizeof(int), 1, fA3D); if (sf>0) write_string0(fA3D, padre->GetName()); // --------------- scrittura del punto di pivot ---------------- GetPivotOffset(node, &row); fprintf(fTXT, "Pivot point : %f, %f, %f\n", row.x, row.y, row.z); write_point3(&row, fA3D); // ------------------- scrittura matrice ----------------------- mat = node->GetNodeTM(0); write_matrix(&mat, fA3D); float turb, decay, stren, freq, scale; int type=0; SimpleWSMObject2 *obj=(SimpleWSMObject2 *)os.obj; fflush(fTXT); export_animatable(obj->pblock2, 5); // ----------------------- strenght ----------------------- c=obj->pblock2->GetController(WPB_STRENGTH); if (c) c->GetValue(0, &stren, FOREVER); else obj->pblock2->GetValue(WPB_STRENGTH, 0, stren, FOREVER); fprintf(fTXT, "Strenght: %f\n", stren); fflush(fTXT); // ----------------------- decay ----------------------- c=obj->pblock2->GetController(WPB_DECAY); if (c) c->GetValue(0, &decay, FOREVER); else obj->pblock2->GetValue(WPB_DECAY, 0, decay, FOREVER); fprintf(fTXT, "Decay: %f\n", decay); fflush(fTXT); // ----------------------- type ----------------------- //obj->pblock2->GetValue(WPB_TYPE, 0, type, FOREVER); //obj->pblock2->GetController(WPB_TYPE)->GetValue(0, &type, FOREVER); type=0; fprintf(fTXT, "Type: %d\n", type); fflush(fTXT); // ----------------------- turbulence ----------------------- c=obj->pblock2->GetController(WPB_TURBULENCE); if (c) c->GetValue(0, &turb, FOREVER); else obj->pblock2->GetValue(WPB_TURBULENCE, 0, turb, FOREVER); fprintf(fTXT, "Turbulence: %f\n", turb); fflush(fTXT); // ----------------------- frequency ----------------------- c=obj->pblock2->GetController(WPB_FREQUENCY); if (c) c->GetValue(0, &freq, FOREVER); else obj->pblock2->GetValue(WPB_FREQUENCY, 0, freq, FOREVER); fprintf(fTXT, "Frequency: %f\n", freq); fflush(fTXT); // ----------------------- scale ----------------------- c=obj->pblock2->GetController(WPB_SCALE); if (c) c->GetValue(0, &scale, FOREVER); else obj->pblock2->GetValue(WPB_SCALE, 0, scale, FOREVER); fprintf(fTXT, "Scale: %f\n", scale); fflush(fTXT); fwrite(&stren, sizeof(float), 1, fA3D); fwrite(&decay, sizeof(float), 1, fA3D); fwrite(&type, sizeof(int), 1, fA3D); fwrite(&turb, sizeof(float), 1, fA3D); fwrite(&freq, sizeof(float), 1, fA3D); fwrite(&scale, sizeof(float), 1, fA3D); //------------------------ // ESPORTAZIONE KEYFRAMER //------------------------ // POSITION CONTROLLER c=node->GetTMController()->GetPositionController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=36; else if (IsBezierControl(c)) size_key=40; else size_key=16; fprintf(fTXT, "Object position track present.\n"); write_chunk_header(fA3D, POSITION_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_point3_track(c, 1, fA3D); } else { fprintf(fTXT, "Object position track present. (1 key case)\n"); size_key=36; write_chunk_header(fA3D, POSITION_TRACK_ID, node->GetName(), 1+2+4+1*size_key); export_1key_point3_track(c, 1, fA3D); } // ROTATION CONTROLLER c=node->GetTMController()->GetRotationController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=40; else size_key=20; fprintf(fTXT, "Object rotation track present.\n"); write_chunk_header(fA3D, ROTATION_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_rot_track(c, fA3D); } else { fprintf(fTXT, "Object rotation track present. (1 key case)\n"); size_key=40; write_chunk_header(fA3D, ROTATION_TRACK_ID, node->GetName(), 1+2+4+1*size_key); export_1key_rot_track(c, fA3D); } // SCALE CONTROLLER c=node->GetTMController()->GetScaleController(); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=36; else if (IsBezierControl(c)) size_key=40; else size_key=16; fprintf(fTXT, "Wind scaling track present.\n"); write_chunk_header(fA3D, SCALE_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_scale_track(c, fA3D); } else { fprintf(fTXT, "Wind scaling track present. (1 key case)\n"); size_key=36; write_chunk_header(fA3D, SCALE_TRACK_ID, node->GetName(), 1+2+4+1*size_key); export_1key_scale_track(c, fA3D); } // wind strength keyframer c=obj->pblock2->GetController(WPB_STRENGTH); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Wind strength track present.\n"); write_chunk_header(fA3D, WIND_STRENGTH_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); } // wind decay keyframer c=obj->pblock2->GetController(WPB_DECAY); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Wind decay track present.\n"); write_chunk_header(fA3D, WIND_DECAY_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); } // wind turbolence keyframer c=obj->pblock2->GetController(WPB_TURBULENCE); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Wind turbolence track present.\n"); write_chunk_header(fA3D, WIND_TURBOLENCE_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); } // wind frequency keyframer c=obj->pblock2->GetController(WPB_FREQUENCY); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Wind frequency track present.\n"); write_chunk_header(fA3D, WIND_FREQUENCY_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); } // wind scale keyframer c=obj->pblock2->GetController(WPB_SCALE); if ((c) && (c->NumKeys()>0)) { if (IsTCBControl(c)) size_key=28; else if (IsBezierControl(c)) size_key=16; else size_key=8; fprintf(fTXT, "Wind scale(parameter) track present.\n"); write_chunk_header(fA3D, WIND_SCALE_TRACK_ID, node->GetName(), 1+2+4+c->NumKeys()*size_key); export_float_track(c, 1, fA3D); } if (makeADP) { fprintf(fADP, " windWSM %c%s%c\n {\n", '"', node->GetName(), '"'); if (type==0) fprintf(fADP, " type=%c%PLANAR%c;\n", '"', '"'); else fprintf(fADP, " type=%c%SPHERICAL%c;\n", '"', '"'); my_ftoa(stren, sval); fprintf(fADP, " strength=%c%s%c;\n", '"', sval, '"'); my_ftoa(decay, sval); fprintf(fADP, " decay=%c%s%c;\n", '"', sval, '"'); my_ftoa(turb, sval); fprintf(fADP, " turbolence=%c%s%c;\n", '"', sval, '"'); my_ftoa(freq, sval); fprintf(fADP, " frequency=%c%s%c;\n", '"', sval, '"'); my_ftoa(scale, sval); fprintf(fADP, " scale=%c%s%c;\n", '"', sval, '"'); fprintf(fADP, " }\n\n"); } fprintf(fTXT, "\n\n"); fflush(fTXT); if (makeADP) fflush(fADP); }