Unfortunately, resetting the THREE.Clock
to zero time is not feasible after the r73 release in October 2015. The explanation is provided below, with potential workarounds outlined towards the end of this response.
An In-Depth Analysis of the Flawed Design of Three.Clock
The design of Clock is problematic...
-- Mrdoob, GitHub issue comment
To comprehend the issues with THREE.Clock
, a thorough examination of the source code is necessary. Upon inspecting the constructor of a Clock, it becomes apparent that certain variables are initialized, leading to the misconception that these can be overwritten on individual Clock
instances to reset the timer to zero:
this.startTime = 0;
this.oldTime = 0;
this.elapsedTime = 0;
However, a deeper analysis reveals the implications of calling getElapsedTime()
. This method internally invokes getDelta()
, which alters the this.elapsedTime
property. Essentially, getDelta
and getElapsedTime
are conflicting and risky functions, necessitating a closer examination of getDelta
:
var newTime = self.performance.now();
diff = 0.001 * ( newTime - this.oldTime );
this.oldTime = newTime;
this.elapsedTime += diff;
This function notably refers to an implicit global variable, self
, and invokes an unusual function, self.performance.now()
. This raises concerns, prompting a more detailed investigation...
It emerges that Three.js defines the global variable self
with the property performance
containing the method now()
as defined in the main Three.js file.
In revisiting THREE.Clock
, the dependence of this.elapsedTime
on the return value of self.performance.now()
becomes evident. Although this might seem harmless initially, the underlying issue becomes apparent. The function self.performance.now()
establishes a true "private" variable within a closure, rendering it inaccessible from external sources:
( function () {
var start = Date.now();
self.performance.now = function () {
return Date.now() - start;
}
} )();
The variable start
denotes the application's start time in milliseconds, as obtained from Date.now()
.
Essentially, upon loading the Three.js library, start
is set to the value of Date.now()
. Consequently, simply including the Three.js
script leads to global and irreversible impacts on the timer. The recalculated elapsed time in Clock
is tied to this private "start time" linked to Three.js' inclusion, inherently relative to that moment.
Potential Solutions
Workaround #1
To address this issue, store
startTime = clock.getElapsedTime()
at the launch of your game or level, basing all subsequent calculations on this initial point. For instance, calculate the current time as
var currentTime = clock.getElapsedTime() - startTime
to accurately track the absolute time from scene load/start.
Workaround #2
Recognizing that Three.Clock
essentially mirrors Date.now()
in its core functionality, consider establishing a custom abstraction around this method for a more manageable clock implementation, supplemented with an easy-to-implement reset()
feature. Keep an eye out for any relevant npm
packages or consider creating your own solution.
Workaround #3
Stay informed about updates to the Three.js Three.Clock
source code, potentially by monitoring the ongoing ticket. A future pull request aimed at resolving this issue may be considered for integration.