Scale box control points
I'm sure this is simple, but I can't seem to get my head around how to do it. Basically, I want to scale a 3d mesh in code, but I want to scale it like this:
You enter 8 3d points (like a box), and if the box is defined, given the 8 points, at (-1, -1, -1) - (1, 1, 1) appropriately, then the mesh's verts will be at a 1:1 ratio. However, if you tweak any of the 8 control points on this "scale box", the mesh's verts will also scale accordingly. This way I can bend and warp meshes in all sorts of nifty ways. Am I looking at the problem wrong??? I can't, for whatever brain dead reason, figure out how to decide how much to weight each control point to determine the correct scaling of each vert.
I basically am getting the AABB of the mesh, and figuring out its center and the scale from the center needed to match that perfect 1:1 ratio scale box from above... but I'm stuck now at what to do next?? Any help would be appreciated. I think it is just a matter of interpolation and figuring out the weights of each control point (some how) - just don't know how I should go about that for each vert in the mesh.
Thanks to anyone that can help!!!
Cheers
-Scott
Although I've never tried what you're describing, it seems like you should be able to do it using trilinear interpolation. First, you would assign each vertex a set of weights (u, v, w) based on the 'default' size of the enclosing box. Then, whenever a control point changes, you would recompute each vertex from its weights and the control point locations using a 'trilerp' function.
I'm sure this sort of thing is a 'solved problem' as far as modeling applications go, but I'm not sure how it's usually implemented.
I'm sure this sort of thing is a 'solved problem' as far as modeling applications go, but I'm not sure how it's usually implemented.
Yep - just had to look up how to do trilinear interpolation. Just in case anyone happens to need such a thing and run across this thread, here is the code I ended up with.
And by the way, at least for the project I'm working on, this turned out to be a great way to dynamically animate eye shape when conveying various emotions.
And by the way, at least for the project I'm working on, this turned out to be a great way to dynamically animate eye shape when conveying various emotions.
void ModifyBasic::ScaleBox(const Vector3 &TLF, const Vector3 &TLB, const Vector3 &TRB, const Vector3 &TRF, const Vector3 &BLF, const Vector3 &BLB, const Vector3 &BRB, const Vector3 &BRF) { // Get the current defined AABB Vector3 Min = Obj_->Verts(StartVert_), Max = Obj_->Verts(StartVert_); for (UInt Index = StartVert_ + 1; Index < EndVert_; Index ++) { MinMaxAssign(Min.X, Max.X, Obj_->Verts(Index).X); MinMaxAssign(Min.Y, Max.Y, Obj_->Verts(Index).Y); MinMaxAssign(Min.Z, Max.Z, Obj_->Verts(Index).Z); } // Get the current scale by which all points will scale back to (0, 0, 0) - (1, 1, 1) Vector3 Scale = (Max - Min); // Avoid divide by 0, in these cases the 1 won't matter anyway if (Scale.X == 0) Scale.X = 1; if (Scale.Y == 0) Scale.Y = 1; if (Scale.Z == 0) Scale.Z = 1; // This function takes a box from (-1, -1, -1) to (1, 1, 1) as being the normal size. // So we scale it down to a unit box (0, 0, 0) - (1, 1, 1) for easier trilinear interp. Vector3 TLFS = TLF / 2 + Vector3(.5, .5, .5); Vector3 TLBS = TLB / 2 + Vector3(.5, .5, .5); Vector3 TRBS = TRB / 2 + Vector3(.5, .5, .5); Vector3 TRFS = TRF / 2 + Vector3(.5, .5, .5); Vector3 BLFS = BLF / 2 + Vector3(.5, .5, .5); Vector3 BLBS = BLB / 2 + Vector3(.5, .5, .5); Vector3 BRBS = BRB / 2 + Vector3(.5, .5, .5); Vector3 BRFS = BRF / 2 + Vector3(.5, .5, .5); // Now scale all points with trilinear interp. // Y is up, and -Z goes into the screen for (UInt Index = StartVert_; Index < EndVert_; Index ++) { // Get the "unit" vert at 0, 0, 0 - 1, 1, 1 Vector3 UnitVert = (Obj_->Verts(Index) - Min); UnitVert.X /= Scale.X; UnitVert.Y /= Scale.Y; UnitVert.Z /= Scale.Z; // Now shift it based on all 8 scales // TLF = 0, 1, 1 - the weight is our center to the vert as the CenterScaleBox float TLFWeight = (1 - UnitVert.X) * ( UnitVert.Y) * ( UnitVert.Z); // TLB = 0, 1, 0 float TLBWeight = (1 - UnitVert.X) * ( UnitVert.Y) * (1 - UnitVert.Z); // TRB = 1, 1, 0 float TRBWeight = ( UnitVert.X) * ( UnitVert.Y) * (1 - UnitVert.Z); // TRF = 1, 1, 1 - the weight is our center to the vert as the CenterScaleBox float TRFWeight = ( UnitVert.X) * ( UnitVert.Y) * ( UnitVert.Z); // BLF = 0, 0, 1 - the weight is our center to the vert as the CenterScaleBox float BLFWeight = (1 - UnitVert.X) * (1 - UnitVert.Y) * ( UnitVert.Z); // BLB = 0, 0, 0 float BLBWeight = (1 - UnitVert.X) * (1 - UnitVert.Y) * (1 - UnitVert.Z); // BRB = 1, 0, 0 float BRBWeight = ( UnitVert.X) * (1 - UnitVert.Y) * (1 - UnitVert.Z); // BRF = 1, 0, 1 - the weight is our center to the vert as the CenterScaleBox float BRFWeight = ( UnitVert.X) * (1 - UnitVert.Y) * ( UnitVert.Z); Obj_->Verts[Index] = TLFWeight * TLFS + TLBWeight * TLBS + TRBWeight * TRBS + TRFWeight * TRFS + BLFWeight * BLFS + BLBWeight * BLBS + BRBWeight * BRBS + BRFWeight * BRFS; Obj_->Verts[Index].X *= Scale.X; Obj_->Verts[Index].Y *= Scale.Y; Obj_->Verts[Index].Z *= Scale.Z; Obj_->Verts[Index] += Min; }}
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement