Skip to content

Instantly share code, notes, and snippets.

@andreasplesch
Last active August 16, 2023 18:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save andreasplesch/bb3ee65b6748644f640cd5b73f30ed6e to your computer and use it in GitHub Desktop.
Save andreasplesch/bb3ee65b6748644f640cd5b73f30ed6e to your computer and use it in GitHub Desktop.
dynamic cycleInterval test
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "http://www.web3d.org/specifications/x3d-4.0.dtd">
<X3D profile='Interchange' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='http://www.web3d.org/specifications/x3d-4.0.xsd'>
<head>
<component name='PointingDeviceSensor' level='1'/>
<component name='Scripting' level='1'/>
<meta name='created' content='Tue, 15 Aug 2023 18:05:37 GMT'/>
<meta name='comment' content='Rise and Shine'/>
<meta name='creator' content='Holger Seelig'/>
<meta name='generator' content='Sunrize X3D Editor V1.0.91, https://create3000.github.io/sunrize/'/>
<meta name='identifier' content='file:///Volumes/Home/Projekte/Library/Tests/Components/Time/CycleInterval.x3d'/>
<meta name='modified' content='Tue, 15 Aug 2023 18:17:43 GMT'/>
<meta name='modified' content='Andreas Plesch, 16 Aug 2023'/>
</head>
<Scene>
<Viewpoint />
<Group DEF='Animation'>
<TimeSensor DEF='_1'
cycleInterval='10'
loop='true'/>
<PositionInterpolator DEF='_2'
key='0, 0.125, 0.25, 0.375, 0.5, 0.615, 0.75, 0.875, 1'
keyValue='-4 0 0, -2 1 0, 0 0 0, 2 -1 0, 4 0 0, 2 -1 0, 0 0 0, -2 1 0, -4 0 0'/>
<Transform DEF='Box_1'
translation='-2.5152 0.7424 0'>
<Shape>
<Appearance>
<Material/>
</Appearance>
<Box/>
</Shape>
</Transform>
</Group>
<Group DEF='Button1_1'>
<TouchSensor DEF='_3'
description='cycleInterval x1'
onoutputchange='set_cycleInterval1(event)'/>
<Transform DEF='Box_2'
translation='-1 -3 0'
scale='0.2 0.2 0.2'>
<Shape>
<Appearance>
<Material/>
</Appearance>
<Box/>
</Shape>
</Transform>
</Group>
<Group DEF='Button2'>
<TouchSensor DEF='_4'
description='cycleInterval x2'
onoutputchange='set_cycleInterval2(event)'/>
<Transform DEF='Box_3'
translation='0 -3 0'
scale='0.2 0.2 0.2'>
<Shape>
<Appearance>
<Material/>
</Appearance>
<Box/>
</Shape>
</Transform>
</Group>
<Group DEF='Button0'>
<TouchSensor DEF='_5'
description='cycleInterval x0.5'
onoutputchange='set_cycleInterval0_5(event)'/>
<Transform DEF='Box'
translation='1 -3 0'
scale='0.2 0.2 0.2'>
<Shape>
<Appearance>
<Material/>
</Appearance>
<Box/>
</Shape>
</Transform>
</Group>
<!-- <Script DEF='cycleIntervalScript'>
<field accessType='inputOnly' type='SFTime' name='set_cycleInterval1'/>
<field accessType='inputOnly' type='SFTime' name='set_cycleInterval2'/>
<field accessType='inputOnly' type='SFTime' name='set_cycleInterval0_5'/>
<field accessType='outputOnly' type='SFTime' name='cycleInterval'/>
<![CDATA[ecmascript:
function set_cycleInterval1 ()
{
cycleInterval = 10;
}
function set_cycleInterval2 ()
{
cycleInterval = 20;
}
function set_cycleInterval0_5 ()
{
cycleInterval = 5;
}
]]>
</Script> -->
<script type='text/javascript'>
function setCycleInterval (e, v) {
if (e.fieldName == 'touchTime') {
document.querySelector('[DEF=_1]').setAttribute('cycleInterval', v);
}
};
function set_cycleInterval0_5 (e) { setCycleInterval(e, 5) };
function set_cycleInterval1 (e) { setCycleInterval(e, 10) };
function set_cycleInterval2 (e) { setCycleInterval(e, 20) };
</script>
<ROUTE fromNode='_2' fromField='value_changed' toNode='Box_1' toField='set_translation'/>
<ROUTE fromNode='_1' fromField='fraction_changed' toNode='_2' toField='set_fraction'/>
<!-- <ROUTE fromNode='_3' fromField='touchTime' toNode='cycleIntervalScript' toField='set_cycleInterval1'/> -->
<!-- <ROUTE fromNode='_4' fromField='touchTime' toNode='cycleIntervalScript' toField='set_cycleInterval2'/> -->
<!-- <ROUTE fromNode='_5' fromField='touchTime' toNode='cycleIntervalScript' toField='set_cycleInterval0_5'/> -->
<!-- <ROUTE fromNode='cycleIntervalScript' fromField='cycleInterval' toNode='_1' toField='set_cycleInterval'/> -->
<!-- x3dom internals below -->
<script type='text/javascript'>
//<![CDATA[
// console.log('Script');
//redefine implemenation
x3dom.nodeTypes.TimeSensor.prototype.fieldChanged = function ( fieldName )
{
if ( fieldName == "enabled" )
{
// TODO; eval other relevant outputs
if ( !this._vf.enabled && this._vf.isActive )
{
this.postMessage( "isActive", false );
}
}
else if ( fieldName == "startTime" )
{
// Spec: Should be ignored when active. (Restore old value)
if ( this._vf.isActive )
{
this._vf.startTime = this._backupStartTime;
return;
}
this._backupStartTime = this._vf.startTime;
this._updateCycleStopTime();
}
else if ( fieldName == "stopTime" )
{
// Spec: Should be ignored when active and less than startTime. (Restore old value)
if ( this._vf.isActive && this._vf.stopTime <= this._vf.startTime )
{
this._vf.stopTime = this._backupStopTime;
return;
}
this._backupStopTime = this._vf.stopTime;
}
else if ( fieldName == "cycleInterval" )
{
// Spec: Should be ignored when active. (Restore old value)
//console.log(this);
if ( this._vf.isActive )
{
this._vf.startTime = this._lastTime - this._fraction * this._vf.cycleInterval;
//this._vf.cycleInterval = this._backupCycleInterval;//only change sofar
//return;
}
this._backupCycleInterval = this._vf.cycleInterval;
}
else if ( fieldName == "loop" )
{
this._updateCycleStopTime();
}
else if ( fieldName == "resumeTime" )
{
// Spec: Should be ignored when ..
// add condition, return;
if (
this._vf.resumeTime < this._vf.pauseTime ||
this._vf.resumeTime < this._vf.startTime ||
!this._vf.enabled
)
{
return;
}
this._vf.startTime = this._vf.resumeTime - this._fraction * this._vf.cycleInterval;
this._backupStartTime = this._vf.startTime;
this._updateCycleStopTime(); // not sure if needed
}
};
//]]>
</script>
</Scene>
</X3D>
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE X3D PUBLIC "ISO//Web3D//DTD X3D 4.0//EN" "https://www.web3d.org/specifications/x3d-4.0.dtd">
<X3D profile='Full' version='4.0' xmlns:xsd='http://www.w3.org/2001/XMLSchema-instance' xsd:noNamespaceSchemaLocation='https://www.web3d.org/specifications/x3d-4.0.xsd'>
<head>
<meta content='dynamic cycleInterval' name='title'/>
<meta content='Figure08_4OrientationInterpolator.x3d' name='source'/>
<meta content='Figure 8.4, The VRML 2.0 Sourcebook, Copyright [1997] By Andrea L. Ames, David R. Nadeau, and John L. Moreland' name='reference'/>
<meta content='http://www.wiley.com/legacy/compbooks/vrml2sbk/ch08/08fig04.htm' name='reference'/>
<meta content='Kevin S. Anderson' name='translator'/>
<meta content='Don Brutzman' name='translator'/>
<meta content='8 August 2000' name='created'/>
<meta content='1 July 2023' name='modified'/>
<meta content='15 Aug 2023' name='modified'/>
<meta content='Andreas Plesch' name='modifier'/>
<meta content='Animation that rotates the column and changes speed between a full 360 rotation every four (fast) and every nine seconds (slow). The speed change happens every five seconds and is out of sync with the animation cycles. Clicking on the column pauses and resumes the animation. The column should continue to rotate smoothly throughout without stuttering or resets during speed changes or after resuming from a pause.' name='description'/>
<meta content='https://www.web3d.org/x3d/content/examples/Vrml2Sourcebook/Chapter08AnimatingPositionOrientationScale/Figure08_4OrientationInterpolator.x3d' name='reference'/>
<meta content='X3D-Edit 3.3, https://savage.nps.edu/X3D-Edit' name='generator'/>
<meta content='../../license.html' name='license'/>
</head>
<Scene>
<WorldInfo title='dynamic_OrientationInterpolator.x3d'/>
<Viewpoint description='dynamic OrientationInterpolator' position='0 0 4'/>
<!-- Rotating Cylinder -->
<Group>
<TouchSensor DEF='Sensor'/>
<Transform DEF='Column'>
<Shape>
<Cylinder height='1.0' radius='0.2'/>
<Appearance>
<Material diffuseColor='1 0 0' shininess='0.3'/>
</Appearance>
</Shape>
</Transform>
<TimeSensor DEF='Clock' cycleInterval='4.0' loop='true'/>
<OrientationInterpolator DEF='ColumnPath' key='0.0 0.50 1.0' keyValue='0.0 0.0 1.0 0.0 0.0 0.0 1.0 3.14 0.0 0.0 1.0 6.28'/>
</Group>
<BooleanToggle DEF='Toggle'/>
<BooleanFilter DEF='Filter'/>
<TimeTrigger DEF='TriggerPause' />
<TimeTrigger DEF='TriggerResume' />
<ROUTE fromField='isActive' fromNode='Sensor' toField='set_boolean' toNode='Toggle'/>
<ROUTE fromField='toggle_changed' fromNode='Toggle' toField='set_boolean' toNode='Filter'/>
<ROUTE fromField='inputTrue' fromNode='Filter' toField='set_boolean' toNode='TriggerPause'/>
<ROUTE fromField='inputFalse' fromNode='Filter' toField='set_boolean' toNode='TriggerResume'/>
<ROUTE fromField='triggerTime' fromNode='TriggerPause' toField='pauseTime' toNode='Clock'/>
<ROUTE fromField='triggerTime' fromNode='TriggerResume' toField='resumeTime' toNode='Clock'/>
<ROUTE fromField='fraction_changed' fromNode='Clock' toField='set_fraction' toNode='ColumnPath'/>
<ROUTE fromField='value_changed' fromNode='ColumnPath' toField='set_rotation' toNode='Column'/>
<!-- <ScalarInterpolator DEF='ONEtoFOUR' key='0 0.5 1' keyValue='1 2.5 4'/> --><!-- stress test -->
<ScalarInterpolator DEF='FOURtoNINE' key='0 0.5 0.5 1' keyValue='4 4 9 9' onoutputchange='castToSFTime(event)'/>
<Script type='text/vrmlscript' DEF='castToSFTime' directOutput='true'>
<field accessType='inputOnly' type='SFFloat' name='set_float'/>
<field accessType='outputOnly' type='SFTime' name='cycleInterval'/>
<field accessType='initializeOnly' type='SFNode' name='toNode'>
<TimeSensor USE='Clock' />
</field>
<![CDATA[ecmascript:
function set_float (value)
{
//print (value);
cycleInterval = value;
toNode.cycleInterval = value;
}
]]>
</Script>
<script id='x3domScripts' type='text/javascript'>
var print = x3dom.debug.logInfo;
var castToSFTime = function () {
return function (event) {
if (event.fieldName == 'value_changed') {
var value = event.value;
//print(value);
var cast = value;
//direct output
var toNode = document.querySelector('[DEF=Clock]');
toNode.setAttribute('cycleInterval', cast);
}
}
}();
</script>
<ROUTE fromField='value_changed' fromNode='FOURtoNINE' toField='set_float' toNode='castToSFTime'/>
<TimeSensor DEF='IntervalClock' cycleInterval='5' loop='true' />
<ROUTE fromField='fraction_changed' fromNode='IntervalClock' toField='set_fraction' toNode='FOURtoNINE'/>
<!-- x3dom internals below -->
<script type='text/javascript'>
//<![CDATA[
// console.log('Script');
//redefine implemenation
x3dom.nodeTypes.TimeSensor.prototype.fieldChanged = function ( fieldName )
{
if ( fieldName == "enabled" )
{
// TODO; eval other relevant outputs
if ( !this._vf.enabled && this._vf.isActive )
{
this.postMessage( "isActive", false );
}
}
else if ( fieldName == "startTime" )
{
// Spec: Should be ignored when active. (Restore old value)
if ( this._vf.isActive )
{
this._vf.startTime = this._backupStartTime;
return;
}
this._backupStartTime = this._vf.startTime;
this._updateCycleStopTime();
}
else if ( fieldName == "stopTime" )
{
// Spec: Should be ignored when active and less than startTime. (Restore old value)
if ( this._vf.isActive && this._vf.stopTime <= this._vf.startTime )
{
this._vf.stopTime = this._backupStopTime;
return;
}
this._backupStopTime = this._vf.stopTime;
}
else if ( fieldName == "cycleInterval" )
{
// Spec: Should be ignored when active. (Restore old value)
//console.log(this);
if ( this._vf.isActive )
{
this._vf.startTime = this._lastTime - this._fraction * this._vf.cycleInterval;
//this._vf.cycleInterval = this._backupCycleInterval;//only change sofar
//return;
}
this._backupCycleInterval = this._vf.cycleInterval;
}
else if ( fieldName == "loop" )
{
this._updateCycleStopTime();
}
else if ( fieldName == "resumeTime" )
{
// Spec: Should be ignored when ..
// add condition, return;
if (
this._vf.resumeTime < this._vf.pauseTime ||
this._vf.resumeTime < this._vf.startTime ||
!this._vf.enabled
)
{
return;
}
this._vf.startTime = this._vf.resumeTime - this._fraction * this._vf.cycleInterval;
this._backupStartTime = this._vf.startTime;
this._updateCycleStopTime(); // not sure if needed
}
};
//]]>
</script>
</Scene>
</X3D>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment