-
-
Notifications
You must be signed in to change notification settings - Fork 150
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transform entire scene #1530
Comments
Here's a cleaned up and parameterized implementation: import { Document, Transform, vec3, vec4 } from "@gltf-transform/core";
import { assignDefaults, createTransform } from "@gltf-transform/functions";
const NAME = "transformWorld";
type TransformWorldOptions = {
translation?: vec3;
rotation?: vec4;
scale?: number | vec3;
};
const TRANSFORM_WORLD_DEFAULTS: Required<TransformWorldOptions> = {
translation: [0, 0, 0] as vec3,
rotation: [0, 0, 0, 1] as vec4,
scale: 1,
};
function normalize(v: vec4): vec4;
function normalize(v: number[]) {
const n = 1 / Math.hypot(...v);
return Array.from(v, (x) => x * n);
}
function uniform(s): vec3 {
return [s, s, s];
}
function transformWorld(
_options: TransformWorldOptions = TRANSFORM_WORLD_DEFAULTS,
): Transform {
const options = assignDefaults(TRANSFORM_WORLD_DEFAULTS, _options);
return createTransform(NAME, (doc: Document): void => {
const logger = doc.getLogger();
doc
.getRoot()
.listScenes()
.forEach((s) => {
// let vScale:vec3 =
const newRoot = doc
.createNode()
.setRotation(normalize(options.rotation))
.setTranslation(options.translation)
.setScale(
typeof options.scale === "number"
? uniform(options.scale)
: options.scale,
);
s.listChildren().forEach((c) => {
newRoot.addChild(c);
});
s.addChild(newRoot);
});
logger.debug(`${NAME}: Complete.`);
});
}
await document.transform(transformWorld({ rotation: [1, 0, 0, 1] })); |
What about animations? Skip, remove, or keep |
I don’t see animations would need to change anything here. Keep animations and they should still work. Did I miss something? |
Hi @rotu, thanks for the suggestion! Animations should still work, if we're adding a new parent to the scene and not changing the local transform of any existing animated nodes. The new root will cause some validation warnings (skinned meshes are not supposed to be transformed, only the joint hierarchy) but that's already true for I think my preferred starting point would be a One more consideration – KHRMaterialsVolume is affected by scale. If we're changing the scene's scale, then the thickness of volumetric materials will need to be updated too, as we do in quantization: glTF-Transform/packages/functions/src/quantize.ts Lines 358 to 372 in 7aa92be
|
s.listChildren().forEach((c) => {if (c.skin!==null){newRoot.addChild(c)}}); Not sure how to handle
I definitely think it belongs as a CLI command or document-level transform for use in a transform pipeline on I don't like taking a matrix as an argument - especially since (1) the matrix may or may not be a legal transform (2) I'm usually only rotating the scene or scaling it.
I don't think it's appropriate to update the thickness factor, since, "Thickness is given in the coordinate space of the mesh. Any transformations applied to the mesh's node will also be applied to the thickness."1. Also, I think that, when you flatten a node graph, thickness should scale with the transformed length of the normal vector, not uniformly like Footnotes |
The inverse bind matrices shouldn't need to change, though I suppose we should test it. Taking separate TRS arguments as import { transformScene } from '@gltf-transform/functions';
for (const scene of document.getRoot().listScenes()) {
transformScene(scene, [0, 5, 0]);
} And I see you're correct about keeping the thickness factor, yes! We'd need to update that only if the vertex data had changed, no need here. But I don't think I follow about "thickness should scale with the transformed length of the normal vector". In that case we're uniformly scaling a node, potentially by a very large or very small factor. |
That's fair. Would you want to expose a limited subset like permuting the basis vectors?
I wasn't even sure how to get started with this. The gltf.report example script uses I do think it's kinda awkward for a
Ah you're right. I missed the fact that |
Is your feature request related to a problem? Please describe.
I have a bunch of models which may be rotated and scaled incorrectly, and gltf-transform does not provide an easy way to fix this.
Describe the solution you'd like
I would like a new file function that inserts a new root node in all scenes with a given transform.
e.g.
gltf-transform reroot --translate [0,0,1] --rotate [1,0,0,1] --scale 0.4
(where the argument to rotate is a non-normalized quaternion)
Describe alternatives you've considered
I currently do this with a script like following:
The
translate
feature has much in common with thecenter
function, so it may make sense to unify these.The text was updated successfully, but these errors were encountered: