Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions packages/model-viewer/src/test/features/extra-model-spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,32 @@ suite('ExtraModel', () => {
expect(scene._models[1].position.x).to.equal(5);
});

test('applies orientation as rotation on the model quaternion', async () => {
element.loading = 'eager';
element.src = CUBE_GLB_PATH;

const extra = document.createElement('extra-model');
extra.setAttribute('src', CUBE_GLB_PATH);
// yaw = 90deg (third term in roll/pitch/yaw) → Euler(0, π/2, 0, 'YXZ')
// → quaternion.y ≈ 0.707, quaternion.w ≈ 0.707
extra.setAttribute('orientation', '0deg 0deg 90deg');
element.appendChild(extra);

await waitForEvent(element, 'load');

const scene = (element as any)[$scene];
const q = scene._models[1].quaternion;
expect(q.y).to.be.closeTo(Math.sin(Math.PI / 4), 0.001);
expect(q.w).to.be.closeTo(Math.cos(Math.PI / 4), 0.001);

// Update dynamically
extra.setAttribute('orientation', '0deg 0deg 0deg');
await timePasses();

expect(scene._models[1].quaternion.y).to.be.closeTo(0, 0.001);
expect(scene._models[1].quaternion.w).to.be.closeTo(1, 0.001);
});

test(
'does not calculate bounding box synchronously when offset changes',
async () => {
Expand Down
13 changes: 12 additions & 1 deletion packages/model-viewer/src/three-components/ModelScene.ts
Original file line number Diff line number Diff line change
Expand Up @@ -323,7 +323,7 @@ export class ModelScene extends Scene {
}

updateModelTransforms(
index: number, offset?: string|null, _orientation?: string|null,
index: number, offset?: string|null, orientation?: string|null,
scale?: string|null) {
const model = this._models[index];
if (!model)
Expand All @@ -339,6 +339,17 @@ export class ModelScene extends Scene {
}
}

if (orientation) {
const terms = parseExpressions(orientation)[0]
.terms as [NumberNode, NumberNode, NumberNode];
if (terms.length >= 3) {
const roll = normalizeUnit(terms[0]).number;
const pitch = normalizeUnit(terms[1]).number;
const yaw = normalizeUnit(terms[2]).number;
model.quaternion.setFromEuler(new Euler(pitch, yaw, roll, 'YXZ'));
}
}

if (scale) {
const parts = scale.split(' ')
.map(s => s.trim())
Expand Down
6 changes: 3 additions & 3 deletions packages/modelviewer.dev/examples/multimodel/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ <h2 class="demo-title">Interact with Multiple Models</h2>

<extra-model id="robot"
src="../../shared-assets/models/RobotExpressive.glb"
offset="-2.0 0 0" scale="0.2 0.2 0.2" orientation="0 30 0">
offset="-2.0 0 0" scale="0.2 0.2 0.2" orientation="0deg 0deg 30deg">
</extra-model>

<extra-model id="astronaut"
src="../../shared-assets/models/Astronaut.glb"
offset="2.0 0 0" scale="0.3 0.3 0.3" orientation="0 -30 0">
offset="2.0 0 0" scale="0.3 0.3 0.3" orientation="0deg 0deg -30deg">
</extra-model>

<div class="controls glass">
Expand Down
Loading