Skip to content

Commit b7ec2db

Browse files
committed
Anchor and ArSmoothedControls classes
1 parent 08d86b5 commit b7ec2db

File tree

4 files changed

+234
-2
lines changed

4 files changed

+234
-2
lines changed

dist/ARjs-core.js

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/index.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import Source from "./arjs-source";
22
import Profile from "./arjs-profile";
3+
import Anchor from "./new-api/arjs-anchor";
34
import Session from "./new-api/arjs-session";
45
import { SessionDebugUI } from "./new-api/arjs-debugui";
56

6-
export { Source, Profile, Session, SessionDebugUI };
7+
export { Anchor, Source, Profile, Session, SessionDebugUI };

src/new-api/arjs-anchor.js

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
import ArMarkerControls from "../arjs-armarkercontrols"; // Alias for dynamic importing
2+
import ArSmoothedControls from "../threex-arsmoothedcontrols";
3+
4+
export default class Anchor {
5+
constructor(arSession, markerParameters) {
6+
7+
const smoothedControls = new ArSmoothedControls(smoothedRoot);
8+
9+
let parent3D;
10+
let controlledObject;
11+
const _this = this;
12+
let arContext = arSession.arContext;
13+
const scene = arSession.parameters.scene;
14+
const camera = arSession.parameters.camera;
15+
16+
this.arSession = arSession;
17+
this.parameters = markerParameters;
18+
19+
// log to debug
20+
console.log(
21+
"ARjs.Anchor -",
22+
"changeMatrixMode:",
23+
this.parameters.changeMatrixMode,
24+
"/ markersAreaEnabled:",
25+
markerParameters.markersAreaEnabled
26+
);
27+
28+
const markerRoot = new THREE.Group();
29+
scene.add(markerRoot);
30+
31+
// set controlledObject depending on changeMatrixMode
32+
if (markerParameters.changeMatrixMode === "modelViewMatrix") {
33+
controlledObject = markerRoot;
34+
} else if (markerParameters.changeMatrixMode === "cameraTransformMatrix") {
35+
controlledObject = camera;
36+
} else console.assert(false);
37+
38+
if (markerParameters.markersAreaEnabled === false) {
39+
const markerControls = new ArMarkerControls(
40+
arContext,
41+
controlledObject,
42+
markerParameters
43+
);
44+
this.controls = markerControls;
45+
} else {
46+
// sanity check - MUST be a trackingBackend with markers
47+
console.assert(arContext.parameters.trackingBackend === "artoolkit");
48+
49+
// honor markers-page-resolution for https://webxr.io/augmented-website
50+
if (
51+
location.hash.substring(1).startsWith("markers-page-resolution=") === true
52+
) {
53+
// get resolutionW/resolutionH from url
54+
const markerPageResolution = location.hash.substring(1);
55+
const matches = markerPageResolution.match(
56+
/markers-page-resolution=(\d+)x(\d+)/
57+
);
58+
console.assert(matches.length === 3);
59+
const resolutionW = parseInt(matches[1]);
60+
const resolutionH = parseInt(matches[2]);
61+
arContext = arSession.arContext;
62+
}
63+
64+
// set controlledObject depending on changeMatrixMode
65+
if (markerParameters.changeMatrixMode === "modelViewMatrix") {
66+
parent3D = scene;
67+
} else if (markerParameters.changeMatrixMode === "cameraTransformMatrix") {
68+
parent3D = camera;
69+
} else console.assert(false);
70+
this.controls = multiMarkerControls;
71+
72+
this.object3d = new THREE.Group();
73+
74+
//////////////////////////////////////////////////////////////////////////////
75+
// THREEx.ArSmoothedControls
76+
//////////////////////////////////////////////////////////////////////////////
77+
78+
const shouldBeSmoothed = true;
79+
80+
if (shouldBeSmoothed === true) {
81+
// build a smoothedControls
82+
const smoothedRoot = new THREE.Group();
83+
scene.add(smoothedRoot);
84+
smoothedRoot.add(this.object3d);
85+
} else {
86+
markerRoot.add(this.object3d);
87+
}
88+
89+
//////////////////////////////////////////////////////////////////////////////
90+
// Code Separator
91+
//////////////////////////////////////////////////////////////////////////////
92+
this.update = function () {
93+
// update _this.object3d.visible
94+
_this.object3d.visible = _this.object3d.parent.visible;
95+
96+
// console.log('controlledObject.visible', _this.object3d.parent.visible)
97+
if (smoothedControls !== undefined) {
98+
// update smoothedControls
99+
smoothedControls.update(markerRoot);
100+
}
101+
};
102+
}
103+
104+
};
105+
}

src/threex-arsmoothedcontrols.js

Lines changed: 126 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
import ArBaseControls from "./threex-arbasecontrols";
2+
import { setParameters } from "./functions/utils";
3+
4+
export default class ArSmoothedControls extends ArBaseControls {
5+
constructor(object3d, parameters) {
6+
super(object3d);
7+
8+
this._lastLerpStepAt = null;
9+
this._visibleStartedAt = null;
10+
this._unvisibleStartedAt = null;
11+
12+
// handle default parameters
13+
parameters = parameters || {};
14+
this.parameters = {
15+
// lerp coeficient for the position - between [0,1] - default to 1
16+
lerpPosition: 0.8,
17+
// lerp coeficient for the quaternion - between [0,1] - default to 1
18+
lerpQuaternion: 0.2,
19+
// lerp coeficient for the scale - between [0,1] - default to 1
20+
lerpScale: 0.7,
21+
// delay for lerp fixed steps - in seconds - default to 1/120
22+
lerpStepDelay: 1 / 60,
23+
// minimum delay the sub-control must be visible before this controls become visible - default to 0 seconds
24+
minVisibleDelay: 0.0,
25+
// minimum delay the sub-control must be unvisible before this controls become unvisible - default to 0 seconds
26+
minUnvisibleDelay: 0.2,
27+
};
28+
29+
//////////////////////////////////////////////////////////////////////////////
30+
// setParameters
31+
//////////////////////////////////////////////////////////////////////////////
32+
setParameters(parameters, this);
33+
}
34+
35+
update (targetObject3d) {
36+
const object3d = this.object3d;
37+
const parameters = this.parameters;
38+
const wasVisible = object3d.visible;
39+
const present = performance.now() / 1000;
40+
41+
//////////////////////////////////////////////////////////////////////////////
42+
// handle object3d.visible with minVisibleDelay/minUnvisibleDelay
43+
//////////////////////////////////////////////////////////////////////////////
44+
if (targetObject3d.visible === false) this._visibleStartedAt = null;
45+
if (targetObject3d.visible === true) this._unvisibleStartedAt = null;
46+
47+
if (targetObject3d.visible === true && this._visibleStartedAt === null)
48+
this._visibleStartedAt = present;
49+
if (targetObject3d.visible === false && this._unvisibleStartedAt === null)
50+
this._unvisibleStartedAt = present;
51+
52+
if (wasVisible === false && targetObject3d.visible === true) {
53+
const visibleFor = present - this._visibleStartedAt;
54+
if (visibleFor >= this.parameters.minVisibleDelay) {
55+
object3d.visible = true;
56+
snapDirectlyToTarget();
57+
}
58+
// console.log('visibleFor', visibleFor)
59+
}
60+
61+
if (wasVisible === true && targetObject3d.visible === false) {
62+
const unvisibleFor = present - this._unvisibleStartedAt;
63+
if (unvisibleFor >= this.parameters.minUnvisibleDelay) {
64+
object3d.visible = false;
65+
}
66+
}
67+
68+
//////////////////////////////////////////////////////////////////////////////
69+
// apply lerp on positon/quaternion/scale
70+
//////////////////////////////////////////////////////////////////////////////
71+
72+
// apply lerp steps - require fix time steps to behave the same no matter the fps
73+
if (this._lastLerpStepAt === null) {
74+
applyOneSlerpStep();
75+
this._lastLerpStepAt = present;
76+
} else {
77+
var nStepsToDo = Math.floor(
78+
(present - this._lastLerpStepAt) / this.parameters.lerpStepDelay
79+
);
80+
for (var i = 0; i < nStepsToDo; i++) {
81+
applyOneSlerpStep();
82+
this._lastLerpStepAt += this.parameters.lerpStepDelay;
83+
}
84+
}
85+
86+
// disable the lerp by directly copying targetObject3d position/quaternion/scale
87+
if (false) {
88+
snapDirectlyToTarget();
89+
}
90+
91+
// update the matrix
92+
this.object3d.updateMatrix();
93+
94+
//////////////////////////////////////////////////////////////////////////////
95+
// honor becameVisible/becameUnVisible event
96+
//////////////////////////////////////////////////////////////////////////////
97+
// honor becameVisible event
98+
if (wasVisible === false && object3d.visible === true) {
99+
this.dispatchEvent({ type: "becameVisible" });
100+
}
101+
// honor becameUnVisible event
102+
if (wasVisible === true && object3d.visible === false) {
103+
this.dispatchEvent({ type: "becameUnVisible" });
104+
}
105+
return;
106+
107+
function snapDirectlyToTarget() {
108+
object3d.position.copy(targetObject3d.position);
109+
object3d.quaternion.copy(targetObject3d.quaternion);
110+
object3d.scale.copy(targetObject3d.scale);
111+
}
112+
113+
function applyOneSlerpStep() {
114+
object3d.position.lerp(targetObject3d.position, parameters.lerpPosition);
115+
object3d.quaternion.slerp(
116+
targetObject3d.quaternion,
117+
parameters.lerpQuaternion
118+
);
119+
object3d.scale.lerp(targetObject3d.scale, parameters.lerpScale);
120+
}
121+
};
122+
123+
name() {
124+
return "ArSmoothedControls";
125+
}
126+
}

0 commit comments

Comments
 (0)