Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Switch node and lights #838

Closed
gkovacsds opened this issue May 10, 2018 · 8 comments
Closed

Switch node and lights #838

gkovacsds opened this issue May 10, 2018 · 8 comments

Comments

@gkovacsds
Copy link

gkovacsds commented May 10, 2018

I experience that setting whichChoice for Switch nodes does not handle the contained lights properly - ie. they are always on, even if they should be off by the switch state. So they have to be turned off by explicitly setting the "on" attribute.
I guess lights should behave as other nodes, shouldn't they?
I only tested it with external inline nodes, no idea if it works for explicit x3d switch definitions.

Tester html and x3d file below:

<!DOCTYPE>
<html>
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge"/>
    <script type='text/javascript' src='x3dom.js'> </script>
    <link rel='stylesheet' type='text/css' href='x3dom.css'/>
    <script type="text/javascript" src="jquery.min.js" ></script>
    <script type="text/javascript">
		var oid = "xobj";
		var lid = "thelight";
		var swid= "state";
		
		function setlight( state ) {
			var id1 = '#'+oid;
			if ( $( id1 ).length == 0 )
				alert( 'no obj? ' + id1 );
			else
			if ( $(id1+"__"+lid ).length == 0 )
				alert( 'no light?' );
			else
				$(id1+"__"+lid).attr("on",state );
		}
		function setswitch( state ) {
			var id1 = '#'+oid;
			if ( $( id1 ).length == 0 )
				alert( 'no obj? ' + id1 );
			else
			if ( $(id1+"__"+swid ).length == 0 )
				alert( 'no switch?' );
			else
				$(id1+"__"+swid).attr("whichChoice",state );
		}
	 </script>
</head>
<body>
Light <a href="#" onclick='setlight("true");'>ON</a> <a href="#" onclick='setlight("false");'>OFF</a>  <br/>
Switch <a href="#" onclick='setswitch("0");'>0</a> <a href="#" onclick='setswitch("1");'>1</a> <a href="#" onclick='setswitch("-1");'>None</a> <br/>
<X3D id="element3d" showStat="false" showLog="false" x="0px" y="0px" width="500px" height="500px">
    <Scene id="x3dscene">
	<navigationInfo headlight='false' type='"TURNTABLE"'></navigationInfo> 
	<Background	skyColor="0.6 0.6 1"></Background>
	<DirectionalLight
		ambientIntensity="0.34999999403953552"
		intensity="0.64999997615814209"
		direction="0.18299999833106995 0.7070000171661377 0.68300002813339233"></DirectionalLight>
	<DirectionalLight
		ambientIntensity="0.17000000178813934"
		intensity="0.33000001311302185"
		direction="0.18299999833106995 0.7070000171661377 -0.68300002813339233"></DirectionalLight>
		<Inline nameSpaceName="xobj" mapDEFToID="true" id="xobj" url="simplelight.x3d"/>
    </Scene>
</X3D>
</body>
</html>

<?xml version="1.0" encoding="utf-8"?>
<X3D profile="Interchange" version="3.0"
xmlns:xsd="http://www.w3.org/2001/XMLSchema-instance"
xsd:noNamespaceSchemaLocation="http://www.web3d.org/specifications/x3d-3.0.xsd">
	<Scene>
		<Switch DEF="state" whichChoice="1">
			<Transform translation="0 0 0">
				<Pointlight def='thelight' intensity='1.0' color='1 0 0' location='0 0 2' radius='1000' global='true'/>
				<Shape>
					<Appearance>
						<Material diffuseColor="1 1 1"/>
					</Appearance>
					<Sphere radius='1'/>
				</Shape>
			</Transform>
			<Transform translation="0 0 0">
				<Shape>
					<Appearance>
						<Material diffuseColor="0.5 0.5 0.5"/>
					</Appearance>
					<Sphere radius='1'/>
				</Shape>
			</Transform>
		</Switch>
	</Scene>
</X3D>

@andreasplesch
Copy link
Contributor

andreasplesch commented May 11, 2018

I put the example on glitch to experiment with:

https://x3dom-light-switch.glitch.me/

https://glitch.com/edit/#!/x3dom-light-switch

@andreasplesch
Copy link
Contributor

andreasplesch commented May 11, 2018

Ok, I modified x3dom a bit in the example by introducing a ._traversed property for lights:

https://glitch.com/edit/#!/x3dom-light-switch?path=traverseLights.js:19:3

Enabled lights are collected each frame by viewarea.getLights(). By also checking if they were traversed as children of grouping nodes, one can exclude lights not in the active switch child.

This also requires resetting to being non-traversed before each traversal which seem to work well by doing that in the getViewMatrix method. This is not ideal since it has nothing to do with the view matrix. getViewMatrix probably happens right after CollectDrawables is done going through the scene which would be correct but maybe there is a better place. See below.

Also, collectDrawableObjects is meant for Shapes, not Lights, but really is called for all child nodes of grouping nodes, including scene.

Perhaps there is a better solution but seems worth testing more thoroughly before submitting a PR.

Hm. it looks like this would not work for rendered texture since

var lightMatrix = viewarea.getLightMatrix()[0];

would reset all ._traversed to false before .getLights is called a little later. Actually in the main renderScene, getViewMatrix gets called a couple of times before the RTRenderPass is done.

runtime.exitFrame may be the only other place without having to dive into gfx_webgl.

So introducing an internal doc.exitFrame method after the render call may be best and I modified the example accordingly.

@andreasplesch
Copy link
Contributor

andreasplesch commented May 11, 2018

You may be able to use

https://x3dom-light-switch.glitch.me/traverseLights.js

as a temporary fix for your scene.

@andreasplesch
Copy link
Contributor

Does using the switch node instead of the 'on' attribute provide substantial benefits ? Can you outline your use case ?

@gkovacsds
Copy link
Author

gkovacsds commented May 12, 2018

Hello Andreas,
thanks for all this work,
we have some electric component models like a lightbulb or a led. It would be easy to just change switch state, but it won't be a problem to use 'on' too. So I guess you should just do what fits best for the code structure, or leave it as it is. Anyway now you know about this - I don't know if the x3d specification has anything to say about how this should work.

@andreasplesch
Copy link
Contributor

Actually, this was a good opportunity to get background on what X3D specifies. I modified your example to work with any X3D viewer: https://glitch.com/edit/#!/x3d-switch-global-light?path=simpleLight.x3d

Most do what you would expect, eg. switching the light on and off.

Still a little unsure to introduce this change since it affects performance a little bit, checking all lights at each frame.

@gkovacsds
Copy link
Author

gkovacsds commented May 15, 2018

Thanks, then it really may be unnnecessary, as I can really easily switch the lights when needed.
Something like this with jquery:

			$(this).attr( 'whichChoice', value );
			$(this).find( 'PointLight,SpotLight' ).each( function(index) {
						$(this).attr('on',lightstate);
					} );
				  

@andreasplesch
Copy link
Contributor

Closing for now, please reopen as necessary.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants