Scale box control points

Started by
1 comment, last by popsoftheyear 15 years, 9 months ago
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
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.
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;	}}

This topic is closed to new replies.

Advertisement