I have code to rotate and scale my model below.
My problem is after I rotate the model if I go to change the width height or depth depending on how my model was rotated it does not work as expected. For example if model was laying back and flipped upright then the height and depth know work as the other essnetially. This becomes a problem for me because I intend on letting the user edit the scale and rotation after I or an admin user does the initial proccessing. So my question is is there any way to keep it intuitive or create a copy that acts like it was never rotated or something of that order? Any pointers would be much appreciated.
My Current Code
private void ApplyScalingAndRotation(Model3D model, double width, double height, double depth, double xRot, double yRot, double zRot)
{
// Retrieve the bounds of the model
var bounds = model.Bounds;
// Calculate the center point of the model
var modelCenter = new Point3D(
bounds.X + bounds.SizeX / 2,
bounds.Y + bounds.SizeY / 2,
bounds.Z + bounds.SizeZ / 2
);
// Original dimensions of the model
double originalWidth = bounds.SizeX;
double originalHeight = bounds.SizeY;
double originalDepth = bounds.SizeZ;
// Calculate scaling factors for each dimension
double widthScaleFactor = width / originalWidth;
double heightScaleFactor = height / originalHeight;
double depthScaleFactor = depth / originalDepth;
// Create a scale transformation without any rotation
ScaleTransform3D scaleTransform = new ScaleTransform3D(
widthScaleFactor, heightScaleFactor, depthScaleFactor,
modelCenter.X, modelCenter.Y, modelCenter.Z
);
// Convert degrees to radians for rotation
double rotationXDegrees = xRot;
double rotationYDegrees = yRot;
double rotationZDegrees = zRot;
// Create rotation transformations
RotateTransform3D rotateXTransform = new RotateTransform3D(new AxisAngleRotation3D(new System.Windows.Media.Media3D.Vector3D(1, 0, 0), rotationXDegrees));
RotateTransform3D rotateYTransform = new RotateTransform3D(new AxisAngleRotation3D(new System.Windows.Media.Media3D.Vector3D(0, 1, 0), rotationYDegrees));
RotateTransform3D rotateZTransform = new RotateTransform3D(new AxisAngleRotation3D(new System.Windows.Media.Media3D.Vector3D(0, 0, 1), rotationZDegrees));
// Combine the rotation transformations into one Transform3DGroup
Transform3DGroup rotationGroup = new Transform3DGroup();
rotationGroup.Children.Add(rotateXTransform);
rotationGroup.Children.Add(rotateYTransform);
rotationGroup.Children.Add(rotateZTransform);
// Combine the scale and rotation transformations into one Transform3DGroup
Transform3DGroup combinedTransform = new Transform3DGroup();
combinedTransform.Children.Add(scaleTransform);
combinedTransform.Children.Add(rotationGroup);
// Apply the combined transformation to the model
model.Transform = combinedTransform;
}
I ended up wrapping each one with model I want to rotate with another Model3DGroup and rotating that. That solves my problem.
private void ApplyScalingAndRotation(Model3D model, double width, double height, double depth, double xRot, double yRot, double zRot)
{
var model3DGroup = new Model3DGroup();
//This should hopefully make it start in the back left corner
TranslateTransform3D translation = new TranslateTransform3D(-0.5, -0.5, -0.5);
// Apply the new translation transformation to the model
model3DGroup.Transform = translation;
model3DGroup.Children.Add(model);
// Retrieve the bounds of the model
var bounds = model3DGroup.Bounds;
//Calculate the center point of the model
var modelCenter = new Point3D(
bounds.X + bounds.SizeX / 2,
bounds.Y + bounds.SizeY / 2,
bounds.Z + bounds.SizeZ / 2
);
// Original dimensions of the model
double originalWidth = bounds.SizeX;
double originalHeight = bounds.SizeY;
double originalDepth = bounds.SizeZ;
// Calculate scaling factors for each dimension
double widthScaleFactor = width / originalWidth;
double heightScaleFactor = height / originalHeight;
double depthScaleFactor = depth / originalDepth;
// Create a scale transformation without any rotation
ScaleTransform3D scaleTransform = new ScaleTransform3D(
widthScaleFactor, heightScaleFactor, depthScaleFactor,
modelCenter.X, modelCenter.Y, modelCenter.Z
);
// Create rotation transformations
RotateTransform3D rotateXTransform = new RotateTransform3D(new AxisAngleRotation3D(new System.Windows.Media.Media3D.Vector3D(1, 0, 0), xRot));
RotateTransform3D rotateYTransform = new RotateTransform3D(new AxisAngleRotation3D(new System.Windows.Media.Media3D.Vector3D(0, 1, 0), yRot));
RotateTransform3D rotateZTransform = new RotateTransform3D(new AxisAngleRotation3D(new System.Windows.Media.Media3D.Vector3D(0, 0, 1), zRot));
// Combine the rotation transformations into one Transform3DGroup
Transform3DGroup rotationGroup = new Transform3DGroup();
rotationGroup.Children.Add(rotateXTransform);
rotationGroup.Children.Add(rotateYTransform);
rotationGroup.Children.Add(rotateZTransform);
// Combine the scale and rotation transformations into one Transform3DGroup
Transform3DGroup combinedTransform = new Transform3DGroup();
combinedTransform.Children.Add(scaleTransform);
combinedTransform.Children.Add(rotationGroup);
// Apply the combined transformation to the model
model3DGroup.Transform = combinedTransform;
ContentVisual.Content = model3DGroup;
//So it is a model 3d group
//Change camera not sure we need this.
bounds = model.Bounds;
modelCenter = new Point3D(bounds.X + bounds.SizeX / 2,
bounds.Y + bounds.SizeY / 2,
bounds.Z + bounds.SizeZ / 2);
var modelSize = Math.Sqrt(bounds.SizeX * bounds.SizeX +
bounds.SizeY * bounds.SizeY +
bounds.SizeZ * bounds.SizeZ);
Camera1.TargetPosition = modelCenter;
Camera1.Distance = modelSize * 2;
}