void BombObject::UpdateUI(TimeValue t) { if (hParam && !waitPostLoad) { if (this == DLGetWindowLongPtr<BombObject *>(hParam)) { strengthSpin->SetValue(GetStrength(t),FALSE); gravSpin->SetValue(GetGravity(t),FALSE); chaosSpin->SetValue(GetChaos(t),FALSE); falloffSpin->SetValue(GetFalloff(t),FALSE); spinSpin->SetValue(GetSpin(t),FALSE); if (pblock->KeyFrameAtTime(PB_STRENGTH,t)) strengthSpin->SetKeyBrackets(TRUE); else strengthSpin->SetKeyBrackets(FALSE); if (pblock->KeyFrameAtTime(PB_GRAVITY,t)) gravSpin->SetKeyBrackets(TRUE); else gravSpin->SetKeyBrackets(FALSE); if (pblock->KeyFrameAtTime(PB_CHAOS,t)) chaosSpin->SetKeyBrackets(TRUE); else chaosSpin->SetKeyBrackets(FALSE); if (pblock->KeyFrameAtTime(PB_SPIN,t)) spinSpin->SetKeyBrackets(TRUE); else spinSpin->SetKeyBrackets(FALSE); if (pblock->KeyFrameAtTime(PB_FALLOFF,t)) falloffSpin->SetKeyBrackets(TRUE); else falloffSpin->SetKeyBrackets(FALSE); } } }
int BombObject::Display(TimeValue t, INode* inode, ViewExp *vpt, int flags) { if ( ! vpt || ! vpt->IsAlive() ) { // why are we here DbgAssert(!_T("Invalid viewport!")); return FALSE; } GraphicsWindow *gw = vpt->getGW(); Material *mtl = &swMtl; Matrix3 mat = inode->GetObjectTM(t); DWORD rlim = gw->getRndLimits(); gw->setRndLimits(GW_WIREFRAME|GW_EDGES_ONLY|/*GW_BACKCULL|*/ (rlim&GW_Z_BUFFER?GW_Z_BUFFER:0) );//removed BC 2/16/99 DB gw->setTransform(mat); if (inode->Selected()) gw->setColor( LINE_COLOR, GetSelColor()); else if(!inode->IsFrozen()) //gw->setColor( LINE_COLOR, swMtl.Kd[0], swMtl.Kd[1], swMtl.Kd[2]); gw->setColor(LINE_COLOR,GetUIColor(COLOR_SPACE_WARPS)); mesh.render(gw, mtl, NULL, COMP_ALL); if (hParam && GetWindowLongPtr(hParam,GWLP_USERDATA)==(LONG_PTR)this && GetFalloffOn(t)) { DrawLineProc lp(gw); DrawFalloffSphere(GetFalloff(t),lp); } gw->setRndLimits(rlim); return(0); }
Interval BombObject::ObjectValidity(TimeValue time) { Interval ivalid = FOREVER; if (!waitPostLoad) { GetStrength(time,ivalid); GetGravity(time,ivalid); GetFalloff(time,ivalid); GetChaos(time,ivalid); GetSpin(time,ivalid); UpdateUI(time); } return ivalid; }
void BombObject::GetWorldBoundBox(TimeValue t, INode* inode, ViewExp* vpt, Box3& box ) { if ( ! vpt || ! vpt->IsAlive() ) { box.Init(); return; } Box3 meshBox; Matrix3 mat = inode->GetObjectTM(t); box.Init(); if (hParam && GetWindowLongPtr(hParam,GWLP_USERDATA)==(LONG_PTR)this && GetFalloffOn(t)) { BoxLineProc bproc(&mat); DrawFalloffSphere(GetFalloff(t),bproc); box = bproc.Box(); } GetLocalBoundBox(t,inode,vpt,meshBox); for(int i = 0; i < 8; i++) box += mat * meshBox[i]; }
void BombObject::BeginEditParams(IObjParam *ip,ULONG flags,Animatable *prev) { this->ip = ip; if (!hParam) { hSot = ip->AddRollupPage( hInstance, MAKEINTRESOURCE(IDD_BOMB_SOT), DefaultSOTProc, GetString(IDS_RB_SOT), (LPARAM)ip,APPENDROLL_CLOSED); hParam = ip->AddRollupPage( hInstance, MAKEINTRESOURCE(IDD_BOMBPARAMS), BombParamProc, GetString(IDS_RB_BOMBPARAMS), (LPARAM)this ); } else { DLSetWindowLongPtr(hParam, this); // Init the dialog to our values. strengthSpin->SetValue(GetStrength(ip->GetTime()),FALSE); gravSpin->SetValue(GetGravity(ip->GetTime()),FALSE ); chaosSpin->SetValue(GetChaos(ip->GetTime()),FALSE ); detSpin->SetValue(GetDetonation(ip->GetTime()),FALSE ); spinSpin->SetValue(GetSpin(ip->GetTime()),FALSE); falloffSpin->SetValue(GetFalloff(ip->GetTime()),FALSE); minFragSpin->SetValue(GetMinFrag(ip->GetTime()),FALSE); maxFragSpin->SetValue(GetMaxFrag(ip->GetTime()),FALSE); seedSpin->SetValue(GetSeed(ip->GetTime()),FALSE); CheckDlgButton(hParam,IDC_FALLOFF_ON,GetFalloffOn(ip->GetTime())); } if (GetFalloffOn(ip->GetTime())) { NotifyDependents(FOREVER,0,REFMSG_CHANGE); ip->RedrawViews(ip->GetTime()); } }
float Light::GetMaxRange() const { return GetRange() + GetFalloff() / 2; }
float Light::GetMinRange() const { return std::max(GetRange() - GetFalloff() / 2, 0.f); }
void MorphByBone::MirrorMorph(int sourceIndex, int targetIndex, BOOL mirrorData) { //validate the indices if ((sourceIndex < 0) || (sourceIndex >= boneData.Count())) return; if ((targetIndex < 0) || (targetIndex >= boneData.Count())) return; float threshold = 0.0f; pblock->GetValue(pb_mirrorthreshold,0,threshold,FOREVER); //get our mirror tm theHold.Begin(); theHold.Put(new MorphUIRestore(this)); //stupid Hack to handle UI update after redo for (int i = 0; i < localDataList.Count(); i++) { MorphByBoneLocalData *ld = localDataList[i]; if (ld) { //build our vertex look up index ld->tempPoints = ld->preDeform; ld->tempMatchList.SetCount(ld->tempPoints.Count()); for (int j = 0; j < ld->preDeform.Count(); j++) { Matrix3 tm(1); //need to put our original points ld->tempPoints[j] = ld->tempPoints[j] * mirrorTM; ld->tempMatchList[j] = -1; } for (int j = 0; j < ld->tempPoints.Count(); j++) { Point3 sourcePoint = ld->preDeform[j]; float closest = 3.4e+38; int closestID = -1; for (int k = 0; k < ld->tempPoints.Count(); k++) { Point3 mirrorPoint = ld->tempPoints[k]; float dist = Length(sourcePoint-mirrorPoint); if ((dist < threshold) && (dist < closest)) { closest = dist; closestID = k; } } if (closestID != -1) ld->tempMatchList[closestID] = j; } //loop through our targets int numberOfNewMorphs = boneData[sourceIndex]->morphTargets.Count(); int currentSourceMorph = 0; Matrix3 initialDriverTargetTM = GetNode(targetIndex)->GetNodeTM(GetCOREInterface()->GetTime()); // Matrix3 initialDriverTargetTM = boneData[targetIndex]->intialBoneNodeTM; Matrix3 initialDriverSourceTM = GetNode(sourceIndex)->GetNodeTM(GetCOREInterface()->GetTime());// boneData[sourceIndex]->intialBoneNodeTM; Matrix3 tm(1); //from world to local tm = Inverse(ld->selfNodeCurrentTM); //morph tm in local object space and mirrored tm = tm * mirrorTM; //back to world space tm = tm * ld->selfNodeCurrentTM; //now in local space of the target bone // tm = tm * Inverse(boneData[targetIndex]->parentBoneNodeCurrentTM); //now intitial driver tm in world space initialDriverSourceTM *= tm; for (int j = 0; j < numberOfNewMorphs; j++) { //create a new morph MorphTargets *morphTarget = boneData[sourceIndex]->morphTargets[currentSourceMorph]->Clone(); //remap the indices morphTarget->d.ZeroCount(); for (int k = 0; k < boneData[sourceIndex]->morphTargets[currentSourceMorph]->d.Count(); k++) { int vertID = boneData[sourceIndex]->morphTargets[currentSourceMorph]->d[k].vertexID; int index = ld->tempMatchList[vertID]; if (index != -1) { morphTarget->d.Append(1,&boneData[sourceIndex]->morphTargets[currentSourceMorph]->d[k],500); morphTarget->d[morphTarget->d.Count()-1].vertexID = index; morphTarget->d[morphTarget->d.Count()-1].originalPt = morphTarget->d[morphTarget->d.Count()-1].originalPt * mirrorTM; } } if (mirrorData) { morphTarget->parentTM = boneData[targetIndex]->parentBoneNodeCurrentTM; //mirror the source tms Matrix3 morphTM = morphTarget->boneTMInParentSpace; //put in world space morphTM = morphTM * boneData[sourceIndex]->parentBoneNodeCurrentTM; //now in world space morphTM *= tm; //rebuild the tms //put the driver tm in the morph tm space Matrix3 newTM = initialDriverTargetTM; newTM = newTM * Inverse(initialDriverSourceTM); newTM = newTM * morphTM; newTM = newTM * Inverse(boneData[targetIndex]->parentBoneNodeCurrentTM); morphTarget->boneTMInParentSpace = newTM; //mirror the source deltas for (int k = 0; k < morphTarget->d.Count(); k++) { Point3 vec = morphTarget->d[k].vec; // current bone space vec = VectorTransform(vec,boneData[sourceIndex]->intialBoneNodeTM); //world space vec = VectorTransform(vec,tm); //world space after mirror vec = VectorTransform(vec,Inverse(boneData[targetIndex]->intialBoneNodeTM)); //bone space morphTarget->d[k].vec = vec; vec = morphTarget->d[k].vecParentSpace; //parent space vec = VectorTransform(vec,boneData[sourceIndex]->intialParentNodeTM); //world space vec = VectorTransform(vec,tm); //world space after mirror vec = VectorTransform(vec,Inverse(boneData[targetIndex]->intialParentNodeTM)); //bone space morphTarget->d[k].vecParentSpace = vec; } } float angle = 0.0f; Matrix3 currentBoneTM = boneData[targetIndex]->currentBoneNodeTM; Matrix3 currentParentBoneTM = boneData[targetIndex]->parentBoneNodeCurrentTM; currentBoneTM *= Inverse(currentParentBoneTM); angle = AngleBetweenTMs(currentBoneTM,morphTarget->boneTMInParentSpace); float per = 1.0f - angle/morphTarget->influenceAngle; per = GetFalloff(per, morphTarget->falloff,morphTarget->curve); if (per < 0.0f) per = 0.0f; morphTarget->weight = per; boneData[targetIndex]->morphTargets.Append(1,&morphTarget); theHold.Put(new CreateMorphRestore(this,morphTarget)); currentSourceMorph++; } } } theHold.Put(new MorphUIRestore(this)); //stupid Hack to handle UI update after redo theHold.Accept(GetString(IDS_MIRRORMORPHS)); BuildTreeList(); }
void DropEffector::ModifyPoints(BaseObject* op, BaseObject* gen, BaseDocument* doc, EffectorDataStruct* data, MoData* md, BaseThread* thread) { if (!ed.target || !rcol || data->strength == 0.0) return; C4D_Falloff* falloff = GetFalloff(); if (!falloff) return; Int32 i = 0; Float fall = 0.0; Vector off = Vector(0.0); Vector ray_p = Vector(0.0), ray_dir = Vector(0.0); Vector targ_off = Vector(0.0), targ_hpb = Vector(0.0); MDArray<Int32> flag_array = md->GetLongArray(MODATA_FLAGS); MDArray<Matrix> mat_array = md->GetMatrixArray(MODATA_MATRIX); MDArray<Float> weight_array = md->GetRealArray(MODATA_WEIGHT); if (!mat_array) return; Int32 mdcount = (Int32)md->GetCount(); for (i = 0; i < mdcount; i++) { //If the particle isn't visible, don't calculate if (!(flag_array[i] & MOGENFLAG_CLONE_ON) || (flag_array[i] & MOGENFLAG_DISABLE)) continue; //Multiply into global space off = mat_array[i].off; off = ed.genmg * off; //Sample the falloff falloff->Sample(off, &fall, true, weight_array[i]); if (fall == 0.0) continue; //Set up the ray for the collision ray_p = ed.itargmg * off; switch (ed.mode) { default: case DROPEFFECTOR_MODE_PNORMAL: ray_dir = ed.genmg.TransformVector(mat_array[i].v3); break; case DROPEFFECTOR_MODE_NNORMAL: ray_dir = ed.genmg.TransformVector(-mat_array[i].v3); break; case DROPEFFECTOR_MODE_AXIS: ray_dir = (ed.targmg.off - off); break; case DROPEFFECTOR_MODE_SELFAXIS: ray_dir = (ed.genmg.off - off); break; case DROPEFFECTOR_MODE_PX: ray_dir = Vector(1.0, 0.0, 0.0); break; case DROPEFFECTOR_MODE_PY: ray_dir = Vector(0.0, 1.0, 0.0); break; case DROPEFFECTOR_MODE_PZ: ray_dir = Vector(0.0, 0.0, 1.0); break; case DROPEFFECTOR_MODE_NX: ray_dir = Vector(-1.0, 0.0, 0.0); break; case DROPEFFECTOR_MODE_NY: ray_dir = Vector(0.0, -1.0, 0.0); break; case DROPEFFECTOR_MODE_NZ: ray_dir = Vector(0.0, 0.0, -1.0); break; } ray_dir = ed.itargmg.TransformVector(ray_dir); //Calculate an intersection if (rcol->Intersect(ray_p, !ray_dir, ed.maxdist, false)) { if (rcol->GetNearestIntersection(&rcolres)) { fall *= data->strength; targ_off = Blend(mat_array[i].off, ed.igenmg * (ed.targmg * rcolres.hitpos), fall); targ_hpb = VectorToHPB(ed.igenmg.TransformVector(ed.targmg.TransformVector(rcolres.s_normal))); mat_array[i] = HPBToMatrix(Blend(MatrixToHPB(mat_array[i], ROTATIONORDER_DEFAULT), targ_hpb, fall), ROTATIONORDER_DEFAULT); mat_array[i].off = targ_off; } } } }