VRML / X3D time origin considered uncomfortable
This is mostly a rant about why I (Michalis)
think that VRML/X3D idea of time origin ("January 1, 1970") is a bad idea.
Don't worry, Castle Game Engine complies with VRML/X3D standard in this regard
— I'm just quite unhappy about this. You can change the behavior
to more sane (in my opinion) by using our extension KambiNavigationInfo.timeOriginAtLoad, also precalculated animations from
Kanim and MD3 formats will always start playing
from their begin-time, usually 0.0.
VRML/X3D have an idea that time stored in SFTime
corresponds to a real-world time. More precisely, it's the number
of seconds since 00:00:00 GMT January 1, 1970.
This affects time-dependent
nodes behavior, like TimeSensor and MovieTexture,
and timestamps generated by events.
As far as I'm concerned, this is a broken idea,
but view3dscene honors it anyway. Any general-purpose VRML browser must
honor it in some way, not necessarily by using real-world
time, but at least by setting initial time to some very large value.
Reason: otherwise many animations in VRML files start playing
immediately after file is loaded, and VRML authors don't expect
this. Default field values are designed such that
a default time-dependent node (with default loop = FALSE)
should play one cycle from time 0 to the end of it's cycle.
If a browser starts with real-world time value, this is
a very large time value,
larger than usual cycle interval, so node will not play at all.
So VRML authors learned to expect that actually "default values
for time-dependent nodes mean that node doesn't play when file
is loaded".
Why this is broken idea in my opinion?
The main problem is that this prevents user from pausing
the animation if you continuously supply time values as
real-world time. There's no way to just "pause" the animation.
It may not be rendered for some time, but real-world time
is always ticking. Well that's why it's called "real" world time after all.
That's why view3dscene doesn't really supply real-world time.
Although initial VRML time is taken from real-world time,
it's not guaranteed to be synchronized with real-world time.
As soon as you pause the animation, or open some modal window,
time pass is paused, and VRML world time is no longer synchronized
with real-world time. This way you can "pause" the animation,
which is rather useful feature.
Another trouble is that VRML authors cannot easily synchronize
starting of the animation with loading of the file.
startTime = 0 is useless, as "0" means "January 1, 1970".
For constantly looping animations (loop = TRUE,
rest of the fields as default) this is also a problem,
as you have no idea in what stage of the animation you
are when loading the file. Making some "welcome" animation
requires you to use tricks to route some
sensor like ProximitySensor (positioned to
include default viewpoint) to time-dependent node.
Which isn't difficult, but I feel it's needlessly complicated.
That's why view3dscene allows VRML author to
change VRML time origin by KambiNavigationInfo.timeOriginAtLoad.
This allows you to use startTime = 0 predictably.
Also, user has menu item "Animation -> Rewind to the
Beginning", for testing.
When using my engine to develop your own games, you can
simply start VRML time from 0.0 (by TCastleSceneCore.ResetTime(0.0)),
or to any other value you want. For example, setting it to some
large but determined value, like exactly a million, allows
you to work correctly with standard animations and at the same
time you're able to express startTime relative to loading time.
Large time values are not nice to show to the user.
It's strange to average user to see time value like
1220626229.13 immediately after opening the file.
And manual input
of such time values is difficult. This is a pity,
as sometimes I really have to ask or show VRML time
for user: for example when recording the VRML animation
(view3dscene can record animation to the movie,
or as a precalculated animation), and for things
like Logger node output timestamps.
To remedy this at least a little, view3dscene displays time
as World time: load time + %f = %f for standard VRML files
(that do not use timeOriginAtLoad = TRUE).
This way user sees also the simpler time (since load).
A minor problem is also that user doesn't expect
different behavior of VRML/X3D world depending on the real-world
time at which it is loaded. True, it opens some interesting
possibilities (VRML/X3D world may adjust to real-world
day/night state for example), but also some nightmarish
scenarios ("VRML/X3D world crashes with segfault but only
when opened ~5 minutues after the midnight" — now imagine you have to
debug this :) ).
More sane definition of "time origin" would seem to be
"for single-user games, time origin 0.0 is equivalent to the time when
browser finished initialization
and presented VRML world to the user, starting VRML sensors listening
and events processing". (For multi-player games over the network,
real-world time or some other server time may be more appropriate indeed.)
Actually this is exactly done
when our extension KambiNavigationInfo.timeOriginAtLoad = TRUE.
This also means that time-dependent node with all fields set as default
plays exactly once when the model is loaded — which is actually quite
sensible default behavior for me. (You can always set for example
startTime = -1 and stopTime = -0.5 to prevent node from playing.)
|