Jump to content
  • Advertisement
Sign in to follow this  
popsoftheyear

Scale box control points

This topic is 3706 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement
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.

Share this post


Link to post
Share on other sites
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.


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;
}
}

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!