From eca528a26540388609f9234e5c28ed6c70984085 Mon Sep 17 00:00:00 2001 From: xeolabs Date: Tue, 16 Sep 2014 23:47:59 +0200 Subject: [PATCH] More rendering effects and examples --- about.html | 6 +- api/latest/firstExample.html | 4 +- api/latest/plugins/node/cameras/orbit.js | 34 +- .../plugins/node/cameras/pickFlyOrbit.js | 105 +- api/latest/plugins/node/canvas/capture.js | 2 +- api/latest/plugins/node/effects/crt.js | 36 - api/latest/plugins/node/effects/fog.js | 298 +- api/latest/plugins/node/effects/snowyPeaks.js | 50 - api/latest/plugins/node/effects/wobble.js | 42 - api/latest/plugins/node/frustum/body.js | 112 - api/latest/plugins/node/frustum/lod.js | 125 - api/latest/plugins/node/heightmaps/custom.js | 164 - api/latest/plugins/node/import/md2.js | 1 + .../node/objects/buildings/building.js | 297 +- .../plugins/node/objects/buildings/city.js | 4 +- .../plugins/node/objects/plants/ghostTree.js | 4 +- .../node/objects/space/planets/earth.js | 4 +- .../plugins/node/objects/toys/drinkingBird.js | 32 +- api/latest/plugins/node/physics/box.js | 2 +- api/latest/plugins/node/physics/plane.js | 2 +- api/latest/plugins/node/physics/sphere.js | 2 +- api/latest/plugins/node/physics/teapot.js | 2 +- api/latest/plugins/node/prims/quad.js | 43 - api/latest/plugins/node/reflections/london.js | 33 - api/latest/plugins/node/skyboxes/clouds.js | 19 - api/latest/plugins/node/skyboxes/cloudySea.js | 19 - api/latest/plugins/node/skyboxes/custom.js | 163 - .../plugins/node/skyboxes/grimmNight.js | 19 - .../plugins/node/skyboxes/violentDays.js | 19 - api/latest/plugins/node/textures/video.js | 102 - api/latest/scenejs.js | 2083 +++--- build.js | 15 +- css/styles.css | 24 + demos/cameras-pickFlyOrbit-city.html | 188 - demos/cameras-pickFlyOrbit-terrain.html | 140 - demos/heightmaps-custom.html | 108 - demos/heightmaps-snowypeaks.html | 143 - demos/nodes-custom-tank.html | 109 - demos/physics-spheres.html | 224 - demos/textures-bumpMap-add.html | 93 - demos/textures-bumpMap-colorMap.html | 105 - demos/textures-bumpMap-multiply.html | 93 - demos/textures-glowMap-vertexDisplace.html | 179 - demos/textures-rtt.html | 175 - docs/files.html | 1116 ---- docs/index.html | 402 -- docs/symbols/SceneJS.Camera.html | 498 -- docs/symbols/SceneJS.Clips.html | 430 -- docs/symbols/SceneJS.Flags.html | 1220 ---- docs/symbols/SceneJS.Framebuf.html | 368 -- docs/symbols/SceneJS.Geometry.html | 951 --- docs/symbols/SceneJS.Layer.html | 543 -- docs/symbols/SceneJS.Library.html | 367 -- docs/symbols/SceneJS.Lights.html | 430 -- docs/symbols/SceneJS.Lookat.html | 1642 ----- docs/symbols/SceneJS.Material.html | 859 --- docs/symbols/SceneJS.Matrix.html | 563 -- docs/symbols/SceneJS.MorphGeometry.html | 543 -- docs/symbols/SceneJS.Name.html | 464 -- docs/symbols/SceneJS.Node#constructor.html | 347 - docs/symbols/SceneJS.Node.html | 2757 -------- docs/symbols/SceneJS.RenderContext.html | 729 -- docs/symbols/SceneJS.Rotate.html | 955 --- docs/symbols/SceneJS.Scale.html | 1000 --- docs/symbols/SceneJS.Scene.html | 1287 ---- docs/symbols/SceneJS.Tag.html | 465 -- docs/symbols/SceneJS.Texture.html | 475 -- docs/symbols/SceneJS.Translate.html | 966 --- docs/symbols/SceneJS.XForm.html | 513 -- docs/symbols/SceneJS_webgl_Program.html | 846 --- docs/symbols/_global_.html | 4539 ------------- .../src/licenses_license-header.js.html | 24 - docs/symbols/src/src_core_canvas.js.html | 114 - docs/symbols/src/src_core_config.js.html | 71 - ...rc_core_display_chunks_cameraChunk.js.html | 54 - .../src/src_core_display_chunks_chunk.js.html | 74 - ...c_core_display_chunks_chunkFactory.js.html | 148 - ...src_core_display_chunks_clipsChunk.js.html | 80 - .../src_core_display_chunks_drawChunk.js.html | 32 - ...src_core_display_chunks_flagsChunk.js.html | 67 - ..._core_display_chunks_framebufChunk.js.html | 36 - ..._core_display_chunks_geometryChunk.js.html | 106 - ...rc_core_display_chunks_lightsChunk.js.html | 85 - ...core_display_chunks_listenersChunk.js.html | 29 - ...rc_core_display_chunks_lookAtChunk.js.html | 57 - ..._core_display_chunks_materialChunk.js.html | 55 - ..._display_chunks_morphGeometryChunk.js.html | 174 - .../src_core_display_chunks_nameChunk.js.html | 32 - ...c_core_display_chunks_programChunk.js.html | 81 - ..._core_display_chunks_rendererChunk.js.html | 33 - ...rc_core_display_chunks_shaderChunk.js.html | 38 - ...e_display_chunks_shaderParamsChunk.js.html | 38 - ...c_core_display_chunks_textureChunk.js.html | 71 - ...src_core_display_chunks_xformChunk.js.html | 67 - .../src/src_core_display_display.js.html | 917 --- .../src/src_core_display_object.js.html | 69 - .../src_core_display_objectFactory.js.html | 54 - .../src/src_core_display_program.js.html | 72 - .../src_core_display_programFactory.js.html | 77 - .../src_core_display_programSource.js.html | 57 - ..._core_display_programSourceFactory.js.html | 957 --- .../src_core_display_renderContext.js.html | 95 - docs/symbols/src/src_core_engine.js.html | 567 -- docs/symbols/src/src_core_errors.js.html | 92 - .../symbols/src/src_core_eventManager.js.html | 103 - docs/symbols/src/src_core_events.js.html | 194 - docs/symbols/src/src_core_log.js.html | 109 - docs/symbols/src/src_core_map.js.html | 72 - docs/symbols/src/src_core_math.js.html | 2117 ------ docs/symbols/src/src_core_plugins.js.html | 74 - .../symbols/src/src_core_scene_camera.js.html | 170 - docs/symbols/src/src_core_scene_clips.js.html | 105 - docs/symbols/src/src_core_scene_core.js.html | 50 - .../src/src_core_scene_coreFactory.js.html | 162 - docs/symbols/src/src_core_scene_flags.js.html | 287 - .../src/src_core_scene_framebuf.js.html | 208 - .../src/src_core_scene_geometry.js.html | 695 -- docs/symbols/src/src_core_scene_layer.js.html | 75 - .../src/src_core_scene_library.js.html | 16 - .../symbols/src/src_core_scene_lights.js.html | 181 - .../symbols/src/src_core_scene_lookAt.js.html | 394 -- .../src/src_core_scene_material.js.html | 149 - .../symbols/src/src_core_scene_matrix.js.html | 93 - .../src_core_scene_modelXFormStack.js.html | 223 - .../src/src_core_scene_morphGeometry.js.html | 390 -- docs/symbols/src/src_core_scene_name.js.html | 55 - docs/symbols/src/src_core_scene_node.js.html | 1161 ---- .../src/src_core_scene_nodeEvents.js.html | 87 - .../src/src_core_scene_nodeFactory.js.html | 91 - .../src/src_core_scene_renderer.js.html | 787 --- .../symbols/src/src_core_scene_rotate.js.html | 156 - docs/symbols/src/src_core_scene_scale.js.html | 160 - docs/symbols/src/src_core_scene_scene.js.html | 228 - .../symbols/src/src_core_scene_shader.js.html | 201 - .../src/src_core_scene_shaderParams.js.html | 104 - docs/symbols/src/src_core_scene_tag.js.html | 67 - .../src/src_core_scene_texture.js.html | 507 -- .../src/src_core_scene_translate.js.html | 166 - docs/symbols/src/src_core_scene_xform.js.html | 88 - docs/symbols/src/src_core_scenejs.js.html | 194 - docs/symbols/src/src_core_status.js.html | 58 - .../src/src_core_webgl-debug-utils.js.html | 847 --- docs/symbols/src/src_core_webgl.js.html | 844 --- examples.html | 201 +- examples/_index.html | 624 ++ .../background_gradient.html | 8 +- examples/background_water.html | 71 + examples/benchmarks_10000boxes.html | 81 + examples/benchmarks_40000boxes.html | 81 + examples/benchmarks_5000boxes.html | 81 + .../cameras_orbit.html | 8 +- examples/cameras_path.html | 253 + examples/cameras_pickFlyOrbit_city.html | 103 + examples/cameras_pickFlyOrbit_terrain.html | 127 + .../canvas_capture.html | 4 +- examples/canvas_capture_customSize.html | 117 + .../canvas_external.html | 15 +- .../canvas_external_transparent.html | 16 +- .../canvas_transparent.html | 4 +- examples/colorBuffer_blendEnabled.html | 118 + examples/colorBuffer_colorMask.html | 124 + .../configs_disableStatusPopups.html | 4 +- examples/configs_optimizations.html | 73 + .../configs_pluginPath.html | 4 +- {demos => examples}/css/prettify.css | 0 {demos => examples}/css/styles.css | 2 +- .../depthBuffer_clearDepth.html | 10 +- .../depthBuffer_depthFunc.html | 12 +- .../depthBuffer_enableDisable.html | 12 +- examples/effects_anaglyph.html | 125 + examples/effects_anaglyph_pickFlyOrbit.html | 141 + examples/effects_oculusRift.html | 90 + .../effects_oculusRift_externalCanvas.html | 93 + examples/effects_oculusRift_pickFlyOrbit.html | 85 + examples/effects_stereo.html | 127 + examples/effects_stereo_pickFlyOrbit.html | 122 + examples/environments_gridRoom_teapot.html | 63 + examples/environments_holoDeck.html | 63 + examples/environments_lawn_city.html | 99 + examples/environments_lawn_teapots.html | 82 + examples/environments_modelView_teapot.html | 46 + examples/exampleLinks.json | 281 + .../extending_nodes_custom.html | 4 +- .../extending_nodes_custom_animation.html | 4 +- .../extending_nodes_custom_pubSub.html | 4 +- .../extending_nodes_custom_tasks.html | 4 +- examples/features.json | 472 ++ .../geometry_autoNormals.html | 0 .../geometry_box.html | 10 +- .../geometry_cylinder.html | 4 +- examples/geometry_heightmap.html | 88 + examples/geometry_heightmap_fogAndGrid.html | 127 + .../geometry_heightmap_texture.html | 17 +- .../geometry_heightmap_texture_video.html | 14 +- .../geometry_heightmap_transparent.html | 24 +- .../geometry_lines.html | 0 .../geometry_morphTargets.html | 0 .../geometry_morphTargets_typedArrays.html | 0 .../geometry_plane.html | 4 +- .../geometry_points.html | 0 .../geometry_sphere.html | 8 +- .../geometry_teapot.html | 4 +- .../geometry_torus.html | 4 +- .../geometry_torus_wireframe.html | 4 +- .../geometry_triangles.html | 0 .../geometry_typedArrays.html | 0 examples/geometry_vectorText.html | 72 + .../geometry_vertexColors.html | 0 .../images/chrome-experiment.png | Bin .../importing_3ds_lexus.html | 0 .../importing_md2_lion.html | 0 .../importing_obj_duck.html | 0 .../importing_obj_raptor.html | 0 .../layers_enableDisable.html | 12 +- .../layers_transparencySort.html | 12 +- {demos => examples}/libs/cityBuilder.js | 0 {demos => examples}/libs/dat.gui.min.js | 0 {demos => examples}/libs/gl-matrix-min.js | 0 {demos => examples}/libs/gl-matrix.js | 0 {demos => examples}/libs/jquery-1.8.3.min.js | 0 {demos => examples}/libs/stats.min.js | 0 {demos => examples}/libs/sylvester.js | 0 .../lighting_ambient.html | 4 +- .../lighting_default.html | 4 +- .../lighting_directional_view.html | 4 +- .../lighting_directional_world.html | 4 +- .../lighting_directional_world_texture.html | 4 +- examples/lighting_material_custom.html | 109 + .../lighting_material_defaults.html | 6 +- .../lighting_point_view.html | 4 +- .../lighting_point_world.html | 4 +- {demos => examples}/models/3ds/lexus.3ds | Bin {demos => examples}/models/3ds/lexus.jpg | Bin {demos => examples}/models/3ds/teapot.3ds | Bin {demos => examples}/models/md2/lion.jpg | Bin {demos => examples}/models/md2/lion.md2 | Bin {demos => examples}/models/obj/cube.obj | 0 {demos => examples}/models/obj/duck.obj | 0 {demos => examples}/models/obj/ladybird.obj | 0 {demos => examples}/models/obj/raptor.jpg | Bin {demos => examples}/models/obj/raptor.obj | 0 {demos => examples}/models/obj/teapot.obj | 0 {demos => examples}/models/sky.js | 0 {demos => examples}/models/solidGrid.js | 0 {demos => examples}/models/tank.js | 0 {demos => examples}/models/test.js | 0 {demos => examples}/models/wireGrid.js | 2 +- examples/models_buildings_city.html | 54 + examples/models_space_earth.html | 53 + examples/models_vehicles_tank.html | 54 + {demos => examples}/movies/bumpMap.ogg | Bin {demos => examples}/movies/bunny.ogg | Bin {demos => examples}/movies/testVideo.ogv | Bin examples/multipass_threePasses.html | 121 + examples/multipass_twoPasses.html | 116 + .../optimization_discreteLOD.html | 21 +- .../optimization_frustumClipping.html | 10 +- ...tion_frustumClipping_withDepthOfField.html | 166 + .../optimization_instancing.html | 0 examples/optimization_textureAtlas.html | 117 + .../optimization_vertexSharing.html | 0 examples/physics_balls.html | 236 + .../physics_boxes.html | 10 +- .../physics_materials.html | 17 +- .../physics_multithreaded.html | 10 +- .../picking_basic.html | 14 +- .../picking_disabling.html | 8 +- .../picking_names.html | 44 +- .../picking_rayPicking.html | 16 +- .../picking_rayPicking_performance.html | 8 +- .../picking_spheres.html | 4 +- .../picking_throughTransparency.html | 8 +- examples/postprocessing_blur.html | 124 + examples/postprocessing_crt.html | 73 + ...rocessing_custom_twoStagesWithPicking.html | 268 + examples/postprocessing_depthOfField.html | 171 + ...postprocessing_depthOfField_autofocus.html | 128 + examples/postprocessing_filmGrain.html | 75 + .../postprocessing_fog.html | 26 +- examples/postprocessing_lens.html | 80 + examples/postprocessing_pipeline.html | 187 + examples/postprocessing_scanlines.html | 73 + .../postprocessing_scanlinesAndSepia.html | 90 + examples/postprocessing_sepia.html | 79 + .../postprocessing_technicolor.html | 41 +- examples/reflections_clouds.html | 102 + .../reflections_custom.html | 6 +- .../reflections_intensity.html | 26 +- .../reflections_manyObjects.html | 36 +- .../reflections_multipleCombined.html | 6 +- examples/reflections_multipleSeparate.html | 137 + .../reflections_shinyRaptor.html | 4 +- examples/reflections_withNormalMap.html | 173 + .../reflections_withSpecularMap.html | 12 +- .../reflections_withSpecularMaterial.html | 14 +- .../reflections_withTransparency.html | 10 +- .../scenegraph_enable.html | 4 +- .../scenegraph_events_misc.html | 15 +- .../scenegraph_events_status.html | 46 +- .../scenegraph_events_status2.html | 8 +- .../scenegraph_firstExample.html | 50 +- .../scenegraph_flags.html | 4 +- .../scenegraph_flags_ambient.html | 4 +- .../scenegraph_flags_backfaceLighting.html | 4 +- .../scenegraph_flags_backfaceTexturing.html | 4 +- .../scenegraph_flags_backfaces.html | 4 +- .../scenegraph_flags_diffuse.html | 4 +- .../scenegraph_flags_enabled.html | 4 +- .../scenegraph_flags_frontface.html | 4 +- .../scenegraph_flags_picking.html | 4 +- .../scenegraph_flags_reflection.html | 4 +- .../scenegraph_flags_specular.html | 4 +- .../scenegraph_flags_transparent.html | 8 +- .../scenegraph_multipleScenes.html | 8 +- .../scenegraph_nodes_adding.html | 66 +- .../scenegraph_nodes_events_rendered.html | 14 +- examples/scenegraph_nodes_instancing.html | 183 + .../scenegraph_nodes_moving.html | 8 +- .../scenegraph_tags.html | 16 +- examples/scenegraph_webglContextRecovery.html | 425 ++ examples/setups_lawn.html | 49 + examples/setups_workshop.html | 45 + examples/shaders_custom_material_color.html | 87 + examples/shaders_custom_skybox.html | 201 + examples/shaders_custom_water.html | 105 + examples/shaders_custom_withTexture.html | 83 + .../shaders_custom_withThreeTextures.html | 107 + examples/shaders_custom_withTransforms.html | 89 + examples/shaders_custom_withTwoTextures.html | 96 + .../shaders_scanline.html | 10 +- .../shaders_vertexDisplacement.html | 14 +- .../shaders_xray.html | 16 +- examples/showcase_BioDigitalHuman.html | 24 + examples/showcase_BioDigitalHuman_eye.html | 24 + .../showcase_earth.html | 6 +- examples/showcase_tank.html | 318 + .../skyboxes_clouds.html | 10 +- .../skyboxes_cloudySea.html | 10 +- .../skyboxes_custom.html | 10 +- examples/skyboxes_custom_sixImages.html | 79 + .../skyboxes_grimmNight.html | 10 +- .../skyboxes_interstellarClouds.html | 10 +- .../skyboxes_miramarClouds.html | 10 +- .../skyboxes_stormyDays.html | 10 +- .../skyboxes_violentDays.html | 10 +- examples/stages_fog.html | 218 + examples/stages_scanlines.html | 184 + examples/stages_threeStages.html | 229 + examples/stages_twoStages.html | 185 + examples/stages_withPicking.html | 245 + examples/stages_withReflection.html | 185 + examples/stages_withSharedShader.html | 220 + examples/stages_withTransparencySort.html | 256 + .../tests_drinkingBird.html | 12 +- .../texture_alpha.html | 10 +- .../texture_alpha_add.html | 8 +- examples/texture_alpha_mix.html | 111 + .../texture_alpha_multiply.html | 10 +- .../texture_animation.html | 4 +- .../texture_bump.html | 8 +- .../texture_color.html | 4 +- .../texture_color_add.html | 4 +- .../texture_color_multiply.html | 4 +- .../texture_emit.html | 4 +- .../texture_emit_add.html | 4 +- .../texture_emit_multiply.html | 4 +- examples/texture_legacy_color.html | 68 + examples/texture_lib_oil.html | 63 + examples/texture_lib_slime.html | 63 + examples/texture_lib_tunnel.html | 63 + examples/texture_lib_water.html | 63 + .../texture_multiTexture.html | 204 +- examples/texture_procedural.html | 82 + examples/texture_procedural_alpha.html | 130 + examples/texture_procedural_color.html | 93 + examples/texture_procedural_color_mold.html | 93 + examples/texture_procedural_color_water.html | 83 + examples/texture_procedural_emit.html | 116 + examples/texture_procedural_specular.html | 118 + examples/texture_rtt.html | 168 + examples/texture_rtt_color.html | 167 + examples/texture_rtt_depth.html | 169 + examples/texture_rtt_depthAndColor.html | 232 + examples/texture_rtt_depthAndColor2.html | 242 + .../texture_rtt_heightmap.html | 71 +- .../texture_rtt_manyTextures.html | 88 +- examples/texture_rtt_shader.html | 194 + .../texture_rtt_sharedTexture.html | 59 +- examples/texture_rtt_withVideo.html | 176 + .../texture_specular.html | 4 +- .../texture_specular_add.html | 4 +- .../texture_specular_multiply.html | 4 +- examples/texture_uvLayers.html | 115 + .../texture_video_alpha.html | 12 +- .../texture_video_bump.html | 8 +- .../texture_video_color.html | 8 +- .../texture_video_emit.html | 8 +- .../texture_video_specular.html | 8 +- {demos => examples}/textures/BrickWall.jpg | Bin {demos => examples}/textures/MediumCloud.png | Bin {demos => examples}/textures/alphaMap.jpg | Bin {demos => examples}/textures/asteroidBump.jpg | Bin .../textures/asteroidColor.jpg | Bin .../textures/asteroidNormal.jpg | Bin .../textures/chainLinkAlphaMap.jpg | Bin .../textures/city/HighRiseGlass.jpg | Bin .../textures/city/HighRiseGlassSpecular.jpg | Bin .../textures/city/highrise-windows.jpg | Bin .../textures/city/pixelcity_windows7.jpg | Bin {demos => examples}/textures/cloud.jpg | Bin {demos => examples}/textures/cloud.png | Bin {demos => examples}/textures/clouds-box.jpg | Bin {demos => examples}/textures/clouds.jpg | Bin .../textures/cloudsBackground.jpg | Bin .../textures/compressed/test-dxt1.crn | Bin .../textures/compressed/test-dxt1.dds | Bin .../textures/compressed/test-dxt5.crn | Bin .../textures/compressed/test-dxt5.dds | Bin .../textures/compressed/test.bmp | Bin .../textures/compressed/test.gif | Bin .../textures/compressed/test.jpg | Bin .../textures/compressed/test.png | Bin .../textures/compressed/test.tga | Bin .../textures/crossGridSpecularMap.jpg | Bin {demos => examples}/textures/earth-lights.gif | Bin .../textures/earth-specular.gif | Bin .../textures/earth-specular.jpg | Bin .../textures/earth-specular.png | Bin {demos => examples}/textures/earth.jpg | Bin {demos => examples}/textures/earthBump.jpg | Bin {demos => examples}/textures/earthclouds.jpg | Bin {demos => examples}/textures/general-zod.jpg | Bin {demos => examples}/textures/grid.jpg | Bin {demos => examples}/textures/heightMap.jpg | Bin {demos => examples}/textures/heightmap.jpg | Bin {demos => examples}/textures/heightmap.png | Bin examples/textures/holodeck/bottom.jpg | Bin 0 -> 58464 bytes examples/textures/holodeck/east.jpg | Bin 0 -> 142573 bytes examples/textures/holodeck/north.jpg | Bin 0 -> 142800 bytes examples/textures/holodeck/south.jpg | Bin 0 -> 143894 bytes examples/textures/holodeck/top.jpg | Bin 0 -> 188470 bytes examples/textures/holodeck/west.jpg | Bin 0 -> 143809 bytes .../textures/leavesAlphaMap.jpg | Bin .../textures/leavesSpecularMap.jpg | Bin {demos => examples}/textures/milky-way.gif | Bin examples/textures/normalMap.png | Bin 0 -> 118538 bytes {demos => examples}/textures/normal_map.jpg | Bin {demos => examples}/textures/oilySheen.jpg | Bin {demos => examples}/textures/pattern.jpg | Bin .../textures/reflection}/clouds/a.png | Bin .../textures/reflection}/clouds/b.png | Bin .../textures/reflection}/clouds/bottom.png | Bin .../textures/reflection}/clouds/c.png | Bin .../textures/reflection}/clouds/d.png | Bin .../textures/reflection}/clouds/top.png | Bin .../textures/reflection}/london/neg-x.png | Bin .../textures/reflection}/london/neg-y.png | Bin .../textures/reflection}/london/neg-z.png | Bin .../textures/reflection}/london/pos-x.png | Bin .../textures/reflection}/london/pos-y.png | Bin .../textures/reflection}/london/pos-z.png | Bin .../textures/reflectionSpecularMap1.jpg | Bin .../textures/reflectionSpecularMap2.jpg | Bin .../textures/reflectionSpecularMap3.jpg | Bin {demos => examples}/textures/sand.jpg | Bin {demos => examples}/textures/superman.jpg | Bin .../textures/texture-atlas.jpg | Bin .../textures/weirdAlphaMap.gif | Bin {demos => examples}/textures/weirdGlowMap.jpg | Bin .../transforms_modelling_hierarchy.html | 36 +- .../transforms_modelling_matrix.html | 4 +- examples/transforms_modelling_quaternion.html | 138 + .../transforms_modelling_rotate.html | 4 +- .../transforms_modelling_scale.html | 4 +- .../transforms_modelling_translate.html | 4 +- .../transforms_projection_default.html | 4 +- .../transforms_projection_frustum.html | 4 +- .../transforms_projection_ortho.html | 4 +- .../transforms_projection_perspective.html | 4 +- .../transforms_viewing.html | 4 +- examplesold/features.json | 427 -- examplesold/index.json | 2 +- .../pages/configuration/pluginPath.html | 4 +- .../pages/configuration/statusPopups.html | 4 +- examplesold/pages/demos/bubbles.html | 12 +- examplesold/pages/demos/city.html | 16 +- examplesold/pages/demos/clouds.html | 4 +- examplesold/pages/demos/earth.html | 4 +- examplesold/pages/demos/firstExample.html | 4 +- examplesold/pages/demos/ghostTrees.html | 12 +- examplesold/pages/demos/orbitPicked.html | 52 +- examplesold/pages/demos/physics.html | 2 +- examplesold/pages/demos/pickFlyOrbitCity.html | 20 +- .../pages/demos/pickFlyOrbitTerrain.html | 14 +- examplesold/pages/demos/secondExample.html | 6 +- examplesold/pages/demos/tanks.html | 10 +- examplesold/pages/demos/tronTank.html | 6 +- .../pages/demos/webglContextRestore.html | 12 +- examplesold/pages/depthbuf/clearDepth.html | 10 +- examplesold/pages/depthbuf/depthFunc.html | 12 +- examplesold/pages/depthbuf/enableDisable.html | 12 +- .../pages/events/blockUntilLoaded.html | 4 +- examplesold/pages/events/connectingLines.html | 8 +- .../pages/events/nodeRenderedEvent.html | 12 +- examplesold/pages/events/sceneStatus.html | 4 +- examplesold/pages/flags/allflags.html | 4 +- examplesold/pages/flags/ambient.html | 4 +- examplesold/pages/flags/backfaceLighting.html | 4 +- .../pages/flags/backfaceTexturing.html | 4 +- examplesold/pages/flags/backfaces.html | 4 +- examplesold/pages/flags/diffuse.html | 4 +- examplesold/pages/flags/enabled.html | 4 +- examplesold/pages/flags/frontface.html | 4 +- examplesold/pages/flags/picking.html | 4 +- examplesold/pages/flags/reflection.html | 4 +- examplesold/pages/flags/specular.html | 4 +- examplesold/pages/flags/transparent.html | 8 +- examplesold/pages/layers/alphaSort.html | 12 +- examplesold/pages/layers/toggleEnabled.html | 12 +- examplesold/pages/lights/ambient.html | 4 +- examplesold/pages/lights/default.html | 4 +- examplesold/pages/lights/directionalView.html | 4 +- .../pages/lights/directionalWorld.html | 4 +- .../lights/directionalWorldWithColorMap.html | 4 +- examplesold/pages/lights/pointView.html | 4 +- examplesold/pages/lights/pointWorld.html | 4 +- examplesold/pages/material/default.html | 4 +- examplesold/pages/picking/basicPicking.html | 8 +- examplesold/pages/picking/disablePicking.html | 8 +- .../pages/picking/firstRayPickExample.html | 16 +- .../pages/picking/pickNameHierarchy.html | 44 +- .../picking/pickThroughTransparentObject.html | 8 +- examplesold/pages/picking/picking.html | 4 +- examplesold/pages/picking/rayPicking.html | 8 +- .../pages/plugins/backgrounds/gradient.html | 8 +- examplesold/pages/plugins/bundled/city.html | 14 +- examplesold/pages/plugins/bundled/color.html | 4 +- .../plugins/bundled/skyGridAndTeapot.html | 10 +- examplesold/pages/plugins/camera/orbit.html | 4 +- .../plugins/camera/pickFlyOrbitCity.html | 20 +- .../plugins/camera/pickFlyOrbitTerrain.html | 14 +- examplesold/pages/plugins/canvas/capture.html | 4 +- .../pages/plugins/culling/detailCulling.html | 20 +- .../pages/plugins/culling/enableNode.html | 4 +- .../pages/plugins/culling/tagNode.html | 16 +- .../plugins/culling/visibilityCulling.html | 10 +- .../animatedInlineCustomNodeTypeDef.html | 4 +- .../defining/basicCustomNodeTypeDef.html | 4 +- .../customNodeDefWithPublications.html | 4 +- .../defining/customNodeDefWithTasks.html | 4 +- .../defining/inlineCustomNodeTypeDef.html | 4 +- examplesold/pages/plugins/fx/crt.html | 6 +- examplesold/pages/plugins/fx/fog.html | 26 +- examplesold/pages/plugins/fx/wobble.html | 14 +- examplesold/pages/plugins/fx/xray.html | 16 +- .../pages/plugins/heightmaps/custom.html | 14 +- .../pages/plugins/heightmaps/olympusMons.html | 14 +- .../pages/plugins/heightmaps/snowyPeaks.html | 16 +- .../pages/plugins/heightmaps/textured.html | 6 +- .../pages/plugins/objects/drinkingBird.html | 12 +- examplesold/pages/plugins/objects/earth.html | 6 +- .../pages/plugins/physics/bouncingBoxes.html | 10 +- .../plugins/physics/bouncingSpheres.html | 10 +- .../bouncingSpheresMultipleSystems.html | 10 +- .../pages/plugins/physics/materials.html | 10 +- examplesold/pages/plugins/prims/box.html | 4 +- examplesold/pages/plugins/prims/cylinder.html | 4 +- examplesold/pages/plugins/prims/plane.html | 4 +- examplesold/pages/plugins/prims/sphere.html | 4 +- examplesold/pages/plugins/prims/teapot.html | 4 +- examplesold/pages/plugins/prims/torus.html | 4 +- .../pages/plugins/prims/vectorText.html | 4 +- .../pages/plugins/prims/wireframeTorus.html | 4 +- .../pages/plugins/skyboxes/clouds.html | 10 +- .../pages/plugins/skyboxes/cloudySea.html | 10 +- .../pages/plugins/skyboxes/custom.html | 10 +- .../pages/plugins/skyboxes/grimmNight.html | 10 +- .../plugins/skyboxes/interstellarClouds.html | 10 +- .../pages/plugins/skyboxes/miramarClouds.html | 10 +- .../plugins/skyboxes/stormyDaysClouds.html | 10 +- .../plugins/skyboxes/violentDaysClouds.html | 10 +- examplesold/pages/plugins/vehicles/tank.html | 14 +- examplesold/pages/scene/addingNodes.html | 4 +- examplesold/pages/scene/linkToCanvas.html | 4 +- examplesold/pages/scene/movingNodes.html | 8 +- examplesold/pages/scene/multipleScenes.html | 8 +- .../pages/scene/transparentAutoCanvas.html | 4 +- .../pages/scene/transparentCanvas.html | 4 +- .../pages/shaders/fragment/pixelColor.html | 4 +- .../pages/shaders/fragment/pixels.html | 4 +- .../pages/shaders/fragment/scanline.html | 4 +- examplesold/pages/shaders/fragment/xray.html | 8 +- .../pages/shaders/params/shaderParams.html | 20 +- .../shaders/vertex/modelVertexDisplace.html | 4 +- examplesold/pages/shaders/vertex/skybox.html | 8 +- .../shaders/vertex/viewVertexDisplace.html | 4 +- .../shaders/vertex/worldVertexDisplace.html | 4 +- examplesold/pages/style/lineWidth.html | 4 +- .../tests/heightmaps/colorMapHeightMap.html | 6 +- .../tests/nodes/createAndDestroySameNode.html | 2 +- .../pages/tests/nodes/slaveGeometryPos.html | 8 +- examplesold/pages/texture/alpha/alphaMap.html | 10 +- .../pages/texture/alpha/alphaMapAdd.html | 10 +- .../pages/texture/alpha/alphaMapMultiply.html | 10 +- .../pages/texture/bump/bumpAndColorMaps.html | 4 +- examplesold/pages/texture/bump/bumpMap.html | 4 +- .../pages/texture/bump/bumpMapAdd.html | 4 +- .../pages/texture/bump/bumpMapMultiply.html | 4 +- examplesold/pages/texture/color/colorMap.html | 4 +- .../pages/texture/color/colorMapAdd.html | 4 +- .../texture/color/colorMapAnimation.html | 4 +- .../pages/texture/color/colorMapMultiply.html | 4 +- examplesold/pages/texture/glow/glowMap.html | 4 +- .../pages/texture/glow/glowMapAdd.html | 4 +- .../pages/texture/glow/glowMapMultiply.html | 6 +- .../glow/glowMapWithVertexDisplace.html | 6 +- .../pages/texture/multi/multitexture.html | 8 +- .../pages/texture/reflection/reflection.html | 6 +- .../reflection/reflectionIntensity.html | 26 +- .../reflection/reflectionMultipleObjects.html | 36 +- .../reflection/reflectionWithControlMap.html | 12 +- .../reflection/reflectionWithLayers.html | 4 +- .../reflectionWithVaryingSpecularity.html | 14 +- .../pages/texture/render/renderToTexture.html | 12 +- .../pages/texture/specular/specularMap.html | 4 +- .../texture/specular/specularMapAdd.html | 4 +- .../texture/specular/specularMapMultiply.html | 4 +- .../pages/texture/video/videoAlphaMap.html | 10 +- .../pages/texture/video/videoBumpMap.html | 6 +- .../pages/texture/video/videoColorMap.html | 4 +- .../pages/texture/video/videoGlowMap.html | 6 +- .../pages/texture/video/videoSpecularMap.html | 6 +- .../transformation/modelling/matrix.html | 4 +- .../transformation/modelling/rotate.html | 4 +- .../pages/transformation/modelling/scale.html | 4 +- .../modelling/transformHierarchy.html | 36 +- .../transformation/modelling/translate.html | 4 +- .../projection/cameraDefaults.html | 4 +- .../projection/cameraFrustum.html | 4 +- .../projection/cameraOrtho.html | 4 +- .../projection/cameraPerspective.html | 4 +- .../pages/transformation/viewing/lookat.html | 4 +- .../pages/transparency/transparency.html | 8 +- files/inconsolata.woff | Bin 0 -> 28040 bytes index.html | 60 +- src/core/canvas.js | 14 +- src/core/display/chunks/chunkFactory.js | 2 + .../{colorbufChunk.js => colorBufferChunk.js} | 8 +- .../{depthbufChunk.js => depthBufferChunk.js} | 6 +- src/core/display/chunks/depthTargetChunk.js | 35 - src/core/display/chunks/drawChunk.js | 9 +- src/core/display/chunks/programChunk.js | 22 +- src/core/display/chunks/renderTargetChunk.js | 53 +- src/core/display/chunks/rendererChunk.js | 9 +- src/core/display/chunks/textureChunk.js | 4 +- src/core/display/display.js | 262 +- src/core/display/programSourceFactory.js | 17 +- src/core/engine.js | 247 +- src/core/scene/camera.js | 16 +- src/core/scene/colorBuffer.js | 87 + src/core/scene/colorTarget.js | 4 - src/core/scene/colorbuf.js | 64 - .../scene/{depthbuf.js => depthBuffer.js} | 41 +- src/core/scene/depthTarget.js | 4 - src/core/scene/geometry.js | 4 +- src/core/scene/layer.js | 28 +- src/core/scene/name.js | 2 +- src/core/scene/node.js | 17 +- src/core/scene/projection.js | 185 + src/core/scene/reflect.js | 2 - src/core/scene/renderer.js | 357 +- src/core/scene/scene.js | 32 +- src/core/scene/{pass.js => stage.js} | 40 +- src/core/scene/textureMap.js | 3 +- src/core/status.js | 4 +- src/core/webgl/renderBuffer.js | 19 +- src/plugins/lib/path.js | 286 + .../plugins/node/background}/gradient.js | 3 +- src/plugins/node/background/water.js | 106 + src/plugins/node/backgrounds/gradient.js | 148 - src/plugins/node/cameras/orbit.js | 34 +- src/plugins/node/cameras/path.js | 168 + src/plugins/node/cameras/path/lerplookat.js | 261 + src/plugins/node/cameras/pickFlyOrbit.js | 105 +- src/plugins/node/cameras/temp.js | 141 + src/plugins/node/canvas/capture.js | 2 +- src/plugins/node/colorTarget/render.js | 49 + src/plugins/node/{frustum => cull}/body.js | 4 +- .../node/{frustum/lod.js => cull/detail.js} | 4 +- .../plugins/node/cull/visibility.js | 4 +- src/plugins/node/demos/models/city.js | 109 + src/plugins/node/depthTarget/render.js | 56 + src/plugins/node/effects/anaglyph.js | 290 + src/plugins/node/effects/crt.js | 36 - src/plugins/node/effects/oculusRift.js | 329 + src/plugins/node/effects/snowyPeaks.js | 50 - src/plugins/node/effects/stereo.js | 279 + src/plugins/node/effects/xray.js | 126 - src/plugins/node/environments/gameGrid.js | 96 + src/plugins/node/environments/gridRoom.js | 91 + src/plugins/node/environments/holodeck.js | 94 + src/plugins/node/environments/lawn.js | 123 + src/plugins/node/environments/modelView.js | 130 + src/plugins/node/environments/newton.js | 140 + .../node/environments/pickFlyOrbitDOF.js | 52 + src/plugins/node/frustum/cull.js | 42 - .../plugins/node/geometry}/boundary.js | 6 +- src/plugins/node/{prims => geometry}/box.js | 6 +- .../plugins/node/geometry}/cylinder.js | 4 +- .../plugins/node/geometry}/grid.js | 4 +- .../custom.js => geometry/heightmap.js} | 2 +- .../plugins/node/geometry/path.js | 6 +- .../plugins/node/geometry}/plane.js | 6 +- src/plugins/node/{prims => geometry}/quad.js | 6 +- src/plugins/node/geometry/randomObjects.js | 62 + .../plugins/node/geometry}/sphere.js | 6 +- .../plugins/node/geometry}/teapot.js | 6 +- .../plugins/node/geometry}/torus.js | 6 +- .../plugins/node/geometry}/vectorText.js | 4 +- src/plugins/node/import/md2.js | 1 + src/plugins/node/lights/randomPointLights.js | 66 + src/plugins/node/models/buildings/building.js | 345 + .../buildings/building/HighRiseGlass.jpg | Bin .../building/HighRiseGlassSpecular.jpg | Bin .../buildings/building/highrise-windows.jpg | Bin .../buildings/building/pixelcity_windows7.jpg | Bin .../{objects => models}/buildings/city.js | 4 +- src/plugins/node/models/ground/grid.js | 63 + src/plugins/node/models/ground/grid2.js | 56 + src/plugins/node/models/ground/slime.js | 43 + src/plugins/node/models/ground/water.js | 43 + .../{objects => models}/plants/ghostTree.js | 4 +- .../node/models/space/planets/earth.js | 173 + .../space/planets/earth/earth-lights.gif | Bin .../space/planets/earth/earth-specular.png | Bin 0 -> 430093 bytes .../node/models/space/planets/earth/earth.jpg | Bin 0 -> 245064 bytes .../models/space/planets/earth/earthBump.jpg | Bin 0 -> 90293 bytes .../space/planets/earth/earthbump.jpg | Bin .../space/planets/earth/earthclouds.jpg | Bin 0 -> 409537 bytes .../{objects => models}/toys/drinkingBird.js | 32 +- .../node/{objects => models}/vehicles/tank.js | 2 +- .../node/objects/buildings/building.js | 352 - .../node/objects/space/planets/earth.js | 168 - .../space/planets/earth/earth-specular.gif | Bin 38092 -> 0 bytes .../space/planets/earth/earth-specular.jpg | Bin 60349 -> 0 bytes .../objects/space/planets/earth/earth.jpg | Bin 156018 -> 0 bytes .../space/planets/earth/earthclouds.jpg | Bin 161207 -> 0 bytes src/plugins/node/physics/box.js | 2 +- src/plugins/node/physics/plane.js | 2 +- src/plugins/node/physics/sphere.js | 2 +- src/plugins/node/physics/teapot.js | 2 +- src/plugins/node/postprocess/blur.js | 269 + src/plugins/node/postprocess/boilerplate.js | 85 + src/plugins/node/postprocess/crt.js | 103 + src/plugins/node/postprocess/dof.js | 534 ++ src/plugins/node/postprocess/filmGrain.js | 162 + src/plugins/node/postprocess/fog.js | 147 + src/plugins/node/postprocess/lens.js | 131 + src/plugins/node/postprocess/pipeline.js | 234 + src/plugins/node/postprocess/pipeline/std.js | 84 + src/plugins/node/postprocess/scanlines.js | 103 + src/plugins/node/postprocess/sepia.js | 106 + src/plugins/node/postprocess/technicolor.js | 111 + src/plugins/node/postprocess/template1.js | 95 + src/plugins/node/prims/boundary.js | 73 - src/plugins/node/prims/cylinder.js | 186 - src/plugins/node/prims/grid.js | 47 - src/plugins/node/prims/plane.js | 116 - src/plugins/node/prims/sphere.js | 107 - src/plugins/node/prims/teapot.js | 5846 ----------------- src/plugins/node/prims/torus.js | 149 - src/plugins/node/prims/vectorText.js | 1508 ----- .../node/{reflections => reflect}/clouds.js | 6 +- src/plugins/node/reflect/grid.js | 25 + .../plugins/node/reflect/holodeck.js | 20 +- .../node/{reflections => reflect}/london.js | 6 +- src/plugins/node/reflect/numberedGrid.js | 25 + .../node/reflect/textures}/clouds/a.png | Bin .../node/reflect/textures}/clouds/b.png | Bin .../node/reflect/textures}/clouds/bottom.png | Bin .../node/reflect/textures}/clouds/c.png | Bin .../node/reflect/textures}/clouds/d.png | Bin .../node/reflect/textures}/clouds/top.png | Bin src/plugins/node/reflect/textures/grid.jpg | Bin 0 -> 148933 bytes .../node/reflect/textures/holodeck/bottom.jpg | Bin 0 -> 58464 bytes .../node/reflect/textures/holodeck/east.jpg | Bin 0 -> 142573 bytes .../node/reflect/textures/holodeck/north.jpg | Bin 0 -> 142800 bytes .../node/reflect/textures/holodeck/south.jpg | Bin 0 -> 143894 bytes .../node/reflect/textures/holodeck/top.jpg | Bin 0 -> 188470 bytes .../node/reflect/textures/holodeck/west.jpg | Bin 0 -> 143809 bytes .../node/reflect/textures}/london/neg-x.png | Bin .../node/reflect/textures}/london/neg-y.png | Bin .../node/reflect/textures}/london/neg-z.png | Bin .../node/reflect/textures}/london/pos-x.png | Bin .../node/reflect/textures}/london/pos-y.png | Bin .../node/reflect/textures}/london/pos-z.png | Bin .../node/reflect/textures/numberedGrid.jpg | Bin 0 -> 45946 bytes src/plugins/node/scene/object.js | 17 + src/plugins/node/{effects => shader}/fog.js | 12 +- src/plugins/node/shader/scanline.js | 31 + .../node/{effects => shader}/wobble.js | 2 +- .../plugins/node/shader}/xray.js | 6 +- src/plugins/node/skybox.js | 261 + .../node/{skyboxes => skybox}/clouds.js | 8 +- .../node/{skyboxes => skybox}/cloudySea.js | 8 +- src/plugins/node/skybox/gameGrid.js | 24 + src/plugins/node/skybox/grid.js | 24 + src/plugins/node/skybox/grid2.js | 24 + src/plugins/node/skybox/grid3.js | 24 + .../node/{skyboxes => skybox}/grimmNight.js | 8 +- src/plugins/node/skybox/holodeck.js | 32 + .../node/skybox}/interstellarClouds.js | 8 +- .../plugins/node/skybox}/miramarClouds.js | 8 +- src/plugins/node/skybox/numberedGrid.js | 24 + .../plugins/node/skybox}/stormyDays.js | 8 +- .../plugins/node/skybox}/textures/clouds.jpg | Bin .../textures/clouds/a.png | Bin .../textures/clouds/b.png | Bin .../textures/clouds/bottom.png | Bin .../textures/clouds/c.png | Bin .../textures/clouds/d.png | Bin .../textures/clouds/top.png | Bin .../node/skybox}/textures/cloudySea.jpg | Bin src/plugins/node/skybox/textures/gameGrid.jpg | Bin 0 -> 79747 bytes src/plugins/node/skybox/textures/grid.jpg | Bin 0 -> 122398 bytes src/plugins/node/skybox/textures/grid2.jpg | Bin 0 -> 90667 bytes .../node/skybox}/textures/grimmNight.jpg | Bin .../node/skybox/textures/holodeck/bottom.jpg | Bin 0 -> 58464 bytes .../node/skybox/textures/holodeck/east.jpg | Bin 0 -> 142573 bytes .../node/skybox/textures/holodeck/north.jpg | Bin 0 -> 142800 bytes .../node/skybox/textures/holodeck/south.jpg | Bin 0 -> 143894 bytes .../node/skybox/textures/holodeck/top.jpg | Bin 0 -> 188470 bytes .../node/skybox/textures/holodeck/west.jpg | Bin 0 -> 143809 bytes .../skybox}/textures/interstellarClouds.jpg | Bin .../textures/london/neg-x.png | Bin .../textures/london/neg-y.png | Bin .../textures/london/neg-z.png | Bin .../textures/london/pos-x.png | Bin .../textures/london/pos-y.png | Bin .../textures/london/pos-z.png | Bin .../node/skybox}/textures/miramarClouds.jpg | Bin .../node/skybox/textures/numberedGrid.jpg | Bin 0 -> 45946 bytes .../node/skybox}/textures/stormyDays.jpg | Bin .../node/skybox}/textures/violentDays.jpg | Bin .../node/{skyboxes => skybox}/violentDays.js | 8 +- src/plugins/node/skyboxes/custom.js | 163 - .../node/skyboxes/interstellarClouds.js | 19 - src/plugins/node/skyboxes/miramarClouds.js | 19 - src/plugins/node/skyboxes/stormyDays.js | 19 - src/plugins/node/skyboxes/textures/clouds.jpg | Bin 409524 -> 0 bytes .../node/skyboxes/textures/cloudySea.jpg | Bin 886392 -> 0 bytes .../node/skyboxes/textures/grimmNight.jpg | Bin 507624 -> 0 bytes .../skyboxes/textures/interstellarClouds.jpg | Bin 753776 -> 0 bytes .../node/skyboxes/textures/miramarClouds.jpg | Bin 583585 -> 0 bytes .../node/skyboxes/textures/stormyDays.jpg | Bin 628565 -> 0 bytes .../node/skyboxes/textures/violentDays.jpg | Bin 684530 -> 0 bytes src/plugins/node/texture/procedural.js | 121 + src/plugins/node/texture/procedural/fungus.js | 57 + src/plugins/node/texture/procedural/grid.js | 40 + src/plugins/node/texture/procedural/hex.js | 64 + src/plugins/node/texture/procedural/oil.js | 45 + src/plugins/node/texture/procedural/water.js | 45 + .../node/{textures => texture}/video.js | 2 +- src/plugins/node/xform/quaternion.js | 99 + 864 files changed, 24570 insertions(+), 57142 deletions(-) delete mode 100644 api/latest/plugins/node/effects/crt.js delete mode 100644 api/latest/plugins/node/effects/snowyPeaks.js delete mode 100644 api/latest/plugins/node/effects/wobble.js delete mode 100644 api/latest/plugins/node/frustum/body.js delete mode 100644 api/latest/plugins/node/frustum/lod.js delete mode 100644 api/latest/plugins/node/heightmaps/custom.js delete mode 100644 api/latest/plugins/node/prims/quad.js delete mode 100644 api/latest/plugins/node/reflections/london.js delete mode 100644 api/latest/plugins/node/skyboxes/clouds.js delete mode 100644 api/latest/plugins/node/skyboxes/cloudySea.js delete mode 100644 api/latest/plugins/node/skyboxes/custom.js delete mode 100644 api/latest/plugins/node/skyboxes/grimmNight.js delete mode 100644 api/latest/plugins/node/skyboxes/violentDays.js delete mode 100644 api/latest/plugins/node/textures/video.js delete mode 100644 demos/cameras-pickFlyOrbit-city.html delete mode 100644 demos/cameras-pickFlyOrbit-terrain.html delete mode 100644 demos/heightmaps-custom.html delete mode 100644 demos/heightmaps-snowypeaks.html delete mode 100644 demos/nodes-custom-tank.html delete mode 100644 demos/physics-spheres.html delete mode 100644 demos/textures-bumpMap-add.html delete mode 100644 demos/textures-bumpMap-colorMap.html delete mode 100644 demos/textures-bumpMap-multiply.html delete mode 100644 demos/textures-glowMap-vertexDisplace.html delete mode 100644 demos/textures-rtt.html delete mode 100644 docs/files.html delete mode 100644 docs/index.html delete mode 100644 docs/symbols/SceneJS.Camera.html delete mode 100644 docs/symbols/SceneJS.Clips.html delete mode 100644 docs/symbols/SceneJS.Flags.html delete mode 100644 docs/symbols/SceneJS.Framebuf.html delete mode 100644 docs/symbols/SceneJS.Geometry.html delete mode 100644 docs/symbols/SceneJS.Layer.html delete mode 100644 docs/symbols/SceneJS.Library.html delete mode 100644 docs/symbols/SceneJS.Lights.html delete mode 100644 docs/symbols/SceneJS.Lookat.html delete mode 100644 docs/symbols/SceneJS.Material.html delete mode 100644 docs/symbols/SceneJS.Matrix.html delete mode 100644 docs/symbols/SceneJS.MorphGeometry.html delete mode 100644 docs/symbols/SceneJS.Name.html delete mode 100644 docs/symbols/SceneJS.Node#constructor.html delete mode 100644 docs/symbols/SceneJS.Node.html delete mode 100644 docs/symbols/SceneJS.RenderContext.html delete mode 100644 docs/symbols/SceneJS.Rotate.html delete mode 100644 docs/symbols/SceneJS.Scale.html delete mode 100644 docs/symbols/SceneJS.Scene.html delete mode 100644 docs/symbols/SceneJS.Tag.html delete mode 100644 docs/symbols/SceneJS.Texture.html delete mode 100644 docs/symbols/SceneJS.Translate.html delete mode 100644 docs/symbols/SceneJS.XForm.html delete mode 100644 docs/symbols/SceneJS_webgl_Program.html delete mode 100644 docs/symbols/_global_.html delete mode 100644 docs/symbols/src/licenses_license-header.js.html delete mode 100644 docs/symbols/src/src_core_canvas.js.html delete mode 100644 docs/symbols/src/src_core_config.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_cameraChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_chunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_chunkFactory.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_clipsChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_drawChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_flagsChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_framebufChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_geometryChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_lightsChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_listenersChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_lookAtChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_materialChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_morphGeometryChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_nameChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_programChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_rendererChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_shaderChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_shaderParamsChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_textureChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_chunks_xformChunk.js.html delete mode 100644 docs/symbols/src/src_core_display_display.js.html delete mode 100644 docs/symbols/src/src_core_display_object.js.html delete mode 100644 docs/symbols/src/src_core_display_objectFactory.js.html delete mode 100644 docs/symbols/src/src_core_display_program.js.html delete mode 100644 docs/symbols/src/src_core_display_programFactory.js.html delete mode 100644 docs/symbols/src/src_core_display_programSource.js.html delete mode 100644 docs/symbols/src/src_core_display_programSourceFactory.js.html delete mode 100644 docs/symbols/src/src_core_display_renderContext.js.html delete mode 100644 docs/symbols/src/src_core_engine.js.html delete mode 100644 docs/symbols/src/src_core_errors.js.html delete mode 100644 docs/symbols/src/src_core_eventManager.js.html delete mode 100644 docs/symbols/src/src_core_events.js.html delete mode 100644 docs/symbols/src/src_core_log.js.html delete mode 100644 docs/symbols/src/src_core_map.js.html delete mode 100644 docs/symbols/src/src_core_math.js.html delete mode 100644 docs/symbols/src/src_core_plugins.js.html delete mode 100644 docs/symbols/src/src_core_scene_camera.js.html delete mode 100644 docs/symbols/src/src_core_scene_clips.js.html delete mode 100644 docs/symbols/src/src_core_scene_core.js.html delete mode 100644 docs/symbols/src/src_core_scene_coreFactory.js.html delete mode 100644 docs/symbols/src/src_core_scene_flags.js.html delete mode 100644 docs/symbols/src/src_core_scene_framebuf.js.html delete mode 100644 docs/symbols/src/src_core_scene_geometry.js.html delete mode 100644 docs/symbols/src/src_core_scene_layer.js.html delete mode 100644 docs/symbols/src/src_core_scene_library.js.html delete mode 100644 docs/symbols/src/src_core_scene_lights.js.html delete mode 100644 docs/symbols/src/src_core_scene_lookAt.js.html delete mode 100644 docs/symbols/src/src_core_scene_material.js.html delete mode 100644 docs/symbols/src/src_core_scene_matrix.js.html delete mode 100644 docs/symbols/src/src_core_scene_modelXFormStack.js.html delete mode 100644 docs/symbols/src/src_core_scene_morphGeometry.js.html delete mode 100644 docs/symbols/src/src_core_scene_name.js.html delete mode 100644 docs/symbols/src/src_core_scene_node.js.html delete mode 100644 docs/symbols/src/src_core_scene_nodeEvents.js.html delete mode 100644 docs/symbols/src/src_core_scene_nodeFactory.js.html delete mode 100644 docs/symbols/src/src_core_scene_renderer.js.html delete mode 100644 docs/symbols/src/src_core_scene_rotate.js.html delete mode 100644 docs/symbols/src/src_core_scene_scale.js.html delete mode 100644 docs/symbols/src/src_core_scene_scene.js.html delete mode 100644 docs/symbols/src/src_core_scene_shader.js.html delete mode 100644 docs/symbols/src/src_core_scene_shaderParams.js.html delete mode 100644 docs/symbols/src/src_core_scene_tag.js.html delete mode 100644 docs/symbols/src/src_core_scene_texture.js.html delete mode 100644 docs/symbols/src/src_core_scene_translate.js.html delete mode 100644 docs/symbols/src/src_core_scene_xform.js.html delete mode 100644 docs/symbols/src/src_core_scenejs.js.html delete mode 100644 docs/symbols/src/src_core_status.js.html delete mode 100644 docs/symbols/src/src_core_webgl-debug-utils.js.html delete mode 100644 docs/symbols/src/src_core_webgl.js.html create mode 100644 examples/_index.html rename demos/plugins-backgrounds-gradient.html => examples/background_gradient.html (95%) create mode 100644 examples/background_water.html create mode 100644 examples/benchmarks_10000boxes.html create mode 100644 examples/benchmarks_40000boxes.html create mode 100644 examples/benchmarks_5000boxes.html rename demos/cameras-orbit.html => examples/cameras_orbit.html (80%) create mode 100644 examples/cameras_path.html create mode 100644 examples/cameras_pickFlyOrbit_city.html create mode 100644 examples/cameras_pickFlyOrbit_terrain.html rename demos/canvas-capture.html => examples/canvas_capture.html (97%) create mode 100644 examples/canvas_capture_customSize.html rename demos/canvas-external.html => examples/canvas_external.html (84%) rename demos/canvas-transparent-external.html => examples/canvas_external_transparent.html (85%) rename demos/canvas-transparent.html => examples/canvas_transparent.html (95%) create mode 100644 examples/colorBuffer_blendEnabled.html create mode 100644 examples/colorBuffer_colorMask.html rename demos/configs-statusPopups.html => examples/configs_disableStatusPopups.html (94%) create mode 100644 examples/configs_optimizations.html rename demos/configs-pluginPath.html => examples/configs_pluginPath.html (95%) rename {demos => examples}/css/prettify.css (100%) rename {demos => examples}/css/styles.css (98%) rename demos/depthBuf-clearDepth.html => examples/depthBuffer_clearDepth.html (91%) rename demos/depthBuf-depthFunc.html => examples/depthBuffer_depthFunc.html (91%) rename demos/depthBuf-enableDisable.html => examples/depthBuffer_enableDisable.html (88%) create mode 100644 examples/effects_anaglyph.html create mode 100644 examples/effects_anaglyph_pickFlyOrbit.html create mode 100644 examples/effects_oculusRift.html create mode 100644 examples/effects_oculusRift_externalCanvas.html create mode 100644 examples/effects_oculusRift_pickFlyOrbit.html create mode 100644 examples/effects_stereo.html create mode 100644 examples/effects_stereo_pickFlyOrbit.html create mode 100644 examples/environments_gridRoom_teapot.html create mode 100644 examples/environments_holoDeck.html create mode 100644 examples/environments_lawn_city.html create mode 100644 examples/environments_lawn_teapots.html create mode 100644 examples/environments_modelView_teapot.html create mode 100644 examples/exampleLinks.json rename demos/nodes-custom-basic.html => examples/extending_nodes_custom.html (97%) rename demos/nodes-custom-animated.html => examples/extending_nodes_custom_animation.html (97%) rename demos/nodes-custom-pubsub.html => examples/extending_nodes_custom_pubSub.html (97%) rename demos/nodes-custom-tasks.html => examples/extending_nodes_custom_tasks.html (97%) create mode 100644 examples/features.json rename demos/geometry-autoNormals.html => examples/geometry_autoNormals.html (100%) rename demos/geometry-box.html => examples/geometry_box.html (83%) rename demos/geometry-cylinder.html => examples/geometry_cylinder.html (95%) create mode 100644 examples/geometry_heightmap.html create mode 100644 examples/geometry_heightmap_fogAndGrid.html rename demos/heightmaps-textured.html => examples/geometry_heightmap_texture.html (82%) rename demos/heightmaps-videoTexture.html => examples/geometry_heightmap_texture_video.html (88%) rename demos/heightmaps-transparent.html => examples/geometry_heightmap_transparent.html (92%) rename demos/geometry-lines.html => examples/geometry_lines.html (100%) rename demos/geometry-morphing.html => examples/geometry_morphTargets.html (100%) rename demos/geometry-morphing-typedArrays.html => examples/geometry_morphTargets_typedArrays.html (100%) rename demos/geometry-plane.html => examples/geometry_plane.html (95%) rename demos/geometry-points.html => examples/geometry_points.html (100%) rename demos/geometry-sphere.html => examples/geometry_sphere.html (82%) rename demos/geometry-teapot.html => examples/geometry_teapot.html (91%) rename demos/geometry-torus.html => examples/geometry_torus.html (92%) rename demos/geometry-torus-wireframe.html => examples/geometry_torus_wireframe.html (93%) rename demos/geometry-triangles.html => examples/geometry_triangles.html (100%) rename demos/geometry-typedArrays.html => examples/geometry_typedArrays.html (100%) create mode 100644 examples/geometry_vectorText.html rename demos/geometry-vertexColors.html => examples/geometry_vertexColors.html (100%) rename {demos => examples}/images/chrome-experiment.png (100%) rename demos/import-3ds-lexus.html => examples/importing_3ds_lexus.html (100%) rename demos/import-md2-lion.html => examples/importing_md2_lion.html (100%) rename demos/import-obj-duck.html => examples/importing_obj_duck.html (100%) rename demos/import-obj-raptor.html => examples/importing_obj_raptor.html (100%) rename demos/layers-enableDisable.html => examples/layers_enableDisable.html (95%) rename demos/layers-transparencySort.html => examples/layers_transparencySort.html (94%) rename {demos => examples}/libs/cityBuilder.js (100%) rename {demos => examples}/libs/dat.gui.min.js (100%) rename {demos => examples}/libs/gl-matrix-min.js (100%) rename {demos => examples}/libs/gl-matrix.js (100%) rename {demos => examples}/libs/jquery-1.8.3.min.js (100%) rename {demos => examples}/libs/stats.min.js (100%) rename {demos => examples}/libs/sylvester.js (100%) rename demos/lights-ambient.html => examples/lighting_ambient.html (95%) rename demos/lights-default.html => examples/lighting_default.html (97%) rename demos/lights-directional-view.html => examples/lighting_directional_view.html (98%) rename demos/lights-directional-world.html => examples/lighting_directional_world.html (95%) rename demos/lights-directional-world-texture.html => examples/lighting_directional_world_texture.html (96%) create mode 100644 examples/lighting_material_custom.html rename demos/materials-default.html => examples/lighting_material_defaults.html (96%) rename demos/lights-point-view.html => examples/lighting_point_view.html (97%) rename demos/lights-point-world.html => examples/lighting_point_world.html (96%) rename {demos => examples}/models/3ds/lexus.3ds (100%) rename {demos => examples}/models/3ds/lexus.jpg (100%) rename {demos => examples}/models/3ds/teapot.3ds (100%) rename {demos => examples}/models/md2/lion.jpg (100%) rename {demos => examples}/models/md2/lion.md2 (100%) rename {demos => examples}/models/obj/cube.obj (100%) rename {demos => examples}/models/obj/duck.obj (100%) rename {demos => examples}/models/obj/ladybird.obj (100%) rename {demos => examples}/models/obj/raptor.jpg (100%) rename {demos => examples}/models/obj/raptor.obj (100%) rename {demos => examples}/models/obj/teapot.obj (100%) rename {demos => examples}/models/sky.js (100%) rename {demos => examples}/models/solidGrid.js (100%) rename {demos => examples}/models/tank.js (100%) rename {demos => examples}/models/test.js (100%) rename {demos => examples}/models/wireGrid.js (96%) create mode 100644 examples/models_buildings_city.html create mode 100644 examples/models_space_earth.html create mode 100644 examples/models_vehicles_tank.html rename {demos => examples}/movies/bumpMap.ogg (100%) rename {demos => examples}/movies/bunny.ogg (100%) rename {demos => examples}/movies/testVideo.ogv (100%) create mode 100644 examples/multipass_threePasses.html create mode 100644 examples/multipass_twoPasses.html rename demos/culling-frustum-detail.html => examples/optimization_discreteLOD.html (92%) rename demos/culling-frustum.html => examples/optimization_frustumClipping.html (95%) create mode 100644 examples/optimization_frustumClipping_withDepthOfField.html rename demos/nodes-cores-sharing.html => examples/optimization_instancing.html (100%) create mode 100644 examples/optimization_textureAtlas.html rename demos/geometry-vertexSharing.html => examples/optimization_vertexSharing.html (100%) create mode 100644 examples/physics_balls.html rename demos/physics-boxes.html => examples/physics_boxes.html (96%) rename demos/physics-materials.html => examples/physics_materials.html (92%) rename demos/physics-multithreaded.html => examples/physics_multithreaded.html (96%) rename demos/picking.html => examples/picking_basic.html (93%) rename demos/picking-disabling.html => examples/picking_disabling.html (95%) rename demos/picking-names.html => examples/picking_names.html (96%) rename demos/picking-ray.html => examples/picking_rayPicking.html (94%) rename demos/picking-ray-spheres.html => examples/picking_rayPicking_performance.html (97%) rename demos/picking-spheres.html => examples/picking_spheres.html (98%) rename demos/picking-throughTransparency.html => examples/picking_throughTransparency.html (95%) create mode 100644 examples/postprocessing_blur.html create mode 100644 examples/postprocessing_crt.html create mode 100644 examples/postprocessing_custom_twoStagesWithPicking.html create mode 100644 examples/postprocessing_depthOfField.html create mode 100644 examples/postprocessing_depthOfField_autofocus.html create mode 100644 examples/postprocessing_filmGrain.html rename demos/effects-fog.html => examples/postprocessing_fog.html (89%) create mode 100644 examples/postprocessing_lens.html create mode 100644 examples/postprocessing_pipeline.html create mode 100644 examples/postprocessing_scanlines.html create mode 100644 examples/postprocessing_scanlinesAndSepia.html create mode 100644 examples/postprocessing_sepia.html rename demos/import-3ds-teapot.html => examples/postprocessing_technicolor.html (55%) create mode 100644 examples/reflections_clouds.html rename demos/reflection.html => examples/reflections_custom.html (94%) rename demos/reflection-intensity.html => examples/reflections_intensity.html (89%) rename demos/reflection-multipleObjects.html => examples/reflections_manyObjects.html (97%) rename demos/reflection-multiple.html => examples/reflections_multipleCombined.html (95%) create mode 100644 examples/reflections_multipleSeparate.html rename demos/reflection-obj.html => examples/reflections_shinyRaptor.html (95%) create mode 100644 examples/reflections_withNormalMap.html rename demos/reflection-specularMap.html => examples/reflections_withSpecularMap.html (94%) rename demos/reflection-specularity.html => examples/reflections_withSpecularMaterial.html (93%) rename demos/reflection-transparent.html => examples/reflections_withTransparency.html (96%) rename demos/culling-enable.html => examples/scenegraph_enable.html (96%) rename demos/scene-events-misc.html => examples/scenegraph_events_misc.html (89%) rename demos/scene-events-status.html => examples/scenegraph_events_status.html (65%) rename demos/scene-events-status2.html => examples/scenegraph_events_status2.html (93%) rename demos/geometry-text.html => examples/scenegraph_firstExample.html (53%) rename demos/flags.html => examples/scenegraph_flags.html (96%) rename demos/flags-ambient.html => examples/scenegraph_flags_ambient.html (97%) rename demos/flags-backfaceLighting.html => examples/scenegraph_flags_backfaceLighting.html (96%) rename demos/flags-backfaceTexturing.html => examples/scenegraph_flags_backfaceTexturing.html (96%) rename demos/flags-backfaces.html => examples/scenegraph_flags_backfaces.html (96%) rename demos/flags-diffuse.html => examples/scenegraph_flags_diffuse.html (97%) rename demos/flags-enabled.html => examples/scenegraph_flags_enabled.html (96%) rename demos/flags-frontface.html => examples/scenegraph_flags_frontface.html (96%) rename demos/flags-picking.html => examples/scenegraph_flags_picking.html (97%) rename demos/flags-reflection.html => examples/scenegraph_flags_reflection.html (97%) rename demos/flags-specular.html => examples/scenegraph_flags_specular.html (97%) rename demos/flags-transparent.html => examples/scenegraph_flags_transparent.html (94%) rename demos/scenes-multiple.html => examples/scenegraph_multipleScenes.html (84%) rename demos/nodes-adding.html => examples/scenegraph_nodes_adding.html (51%) rename demos/node-events-rendered.html => examples/scenegraph_nodes_events_rendered.html (95%) create mode 100644 examples/scenegraph_nodes_instancing.html rename demos/nodes-moving.html => examples/scenegraph_nodes_moving.html (94%) rename demos/culling-regex.html => examples/scenegraph_tags.html (93%) create mode 100644 examples/scenegraph_webglContextRecovery.html create mode 100644 examples/setups_lawn.html create mode 100644 examples/setups_workshop.html create mode 100644 examples/shaders_custom_material_color.html create mode 100644 examples/shaders_custom_skybox.html create mode 100644 examples/shaders_custom_water.html create mode 100644 examples/shaders_custom_withTexture.html create mode 100644 examples/shaders_custom_withThreeTextures.html create mode 100644 examples/shaders_custom_withTransforms.html create mode 100644 examples/shaders_custom_withTwoTextures.html rename demos/effects-crt.html => examples/shaders_scanline.html (86%) rename demos/effects-wobble.html => examples/shaders_vertexDisplacement.html (83%) rename demos/effects-xray.html => examples/shaders_xray.html (90%) create mode 100644 examples/showcase_BioDigitalHuman.html create mode 100644 examples/showcase_BioDigitalHuman_eye.html rename demos/nodes-custom-earth.html => examples/showcase_earth.html (89%) create mode 100644 examples/showcase_tank.html rename demos/skyboxes-clouds.html => examples/skyboxes_clouds.html (87%) rename demos/skyboxes-cloudySea.html => examples/skyboxes_cloudySea.html (84%) rename demos/skyboxes-custom.html => examples/skyboxes_custom.html (85%) create mode 100644 examples/skyboxes_custom_sixImages.html rename demos/skyboxes-grimmNight.html => examples/skyboxes_grimmNight.html (91%) rename demos/skyboxes-interstellarClouds.html => examples/skyboxes_interstellarClouds.html (91%) rename demos/skyboxes-miramarClouds.html => examples/skyboxes_miramarClouds.html (89%) rename demos/skyboxes-stormyDays.html => examples/skyboxes_stormyDays.html (89%) rename demos/skyboxes-violentDays.html => examples/skyboxes_violentDays.html (89%) create mode 100644 examples/stages_fog.html create mode 100644 examples/stages_scanlines.html create mode 100644 examples/stages_threeStages.html create mode 100644 examples/stages_twoStages.html create mode 100644 examples/stages_withPicking.html create mode 100644 examples/stages_withReflection.html create mode 100644 examples/stages_withSharedShader.html create mode 100644 examples/stages_withTransparencySort.html rename demos/nodes-custom-drinkingBird.html => examples/tests_drinkingBird.html (85%) rename demos/textures-alphaMap.html => examples/texture_alpha.html (93%) rename demos/textures-alphaMap-add.html => examples/texture_alpha_add.html (95%) create mode 100644 examples/texture_alpha_mix.html rename demos/textures-alphaMap-multiply.html => examples/texture_alpha_multiply.html (93%) rename demos/textures-colorMap-animated.html => examples/texture_animation.html (97%) rename demos/textures-bumpMap.html => examples/texture_bump.html (91%) rename demos/textures-colorMap.html => examples/texture_color.html (95%) rename demos/textures-colorMap-add.html => examples/texture_color_add.html (95%) rename demos/textures-colorMap-multiply.html => examples/texture_color_multiply.html (93%) rename demos/textures-glowMap.html => examples/texture_emit.html (97%) rename demos/textures-glowMap-add.html => examples/texture_emit_add.html (98%) rename demos/textures-glowMap-multiply.html => examples/texture_emit_multiply.html (98%) create mode 100644 examples/texture_legacy_color.html create mode 100644 examples/texture_lib_oil.html create mode 100644 examples/texture_lib_slime.html create mode 100644 examples/texture_lib_tunnel.html create mode 100644 examples/texture_lib_water.html rename demos/textures-multitexture.html => examples/texture_multiTexture.html (72%) create mode 100644 examples/texture_procedural.html create mode 100644 examples/texture_procedural_alpha.html create mode 100644 examples/texture_procedural_color.html create mode 100644 examples/texture_procedural_color_mold.html create mode 100644 examples/texture_procedural_color_water.html create mode 100644 examples/texture_procedural_emit.html create mode 100644 examples/texture_procedural_specular.html create mode 100644 examples/texture_rtt.html create mode 100644 examples/texture_rtt_color.html create mode 100644 examples/texture_rtt_depth.html create mode 100644 examples/texture_rtt_depthAndColor.html create mode 100644 examples/texture_rtt_depthAndColor2.html rename demos/textures-rtt-heightmap.html => examples/texture_rtt_heightmap.html (70%) rename demos/textures-rtt-multiple-textures.html => examples/texture_rtt_manyTextures.html (78%) create mode 100644 examples/texture_rtt_shader.html rename demos/textures-rtt-shared-texture.html => examples/texture_rtt_sharedTexture.html (84%) create mode 100644 examples/texture_rtt_withVideo.html rename demos/textures-specularMap.html => examples/texture_specular.html (96%) rename demos/textures-specularMap-add.html => examples/texture_specular_add.html (96%) rename demos/textures-specularMap-multiply.html => examples/texture_specular_multiply.html (96%) create mode 100644 examples/texture_uvLayers.html rename demos/textures-video-alphaMap.html => examples/texture_video_alpha.html (91%) rename demos/textures-video-bumpMap.html => examples/texture_video_bump.html (92%) rename demos/textures-video-colorMap.html => examples/texture_video_color.html (91%) rename demos/textures-video-glowMap.html => examples/texture_video_emit.html (93%) rename demos/textures-video-specularMap.html => examples/texture_video_specular.html (94%) rename {demos => examples}/textures/BrickWall.jpg (100%) rename {demos => examples}/textures/MediumCloud.png (100%) rename {demos => examples}/textures/alphaMap.jpg (100%) rename {demos => examples}/textures/asteroidBump.jpg (100%) rename {demos => examples}/textures/asteroidColor.jpg (100%) rename {demos => examples}/textures/asteroidNormal.jpg (100%) rename {demos => examples}/textures/chainLinkAlphaMap.jpg (100%) rename {demos => examples}/textures/city/HighRiseGlass.jpg (100%) rename {demos => examples}/textures/city/HighRiseGlassSpecular.jpg (100%) rename {demos => examples}/textures/city/highrise-windows.jpg (100%) rename {demos => examples}/textures/city/pixelcity_windows7.jpg (100%) rename {demos => examples}/textures/cloud.jpg (100%) rename {demos => examples}/textures/cloud.png (100%) rename {demos => examples}/textures/clouds-box.jpg (100%) rename {demos => examples}/textures/clouds.jpg (100%) rename {demos => examples}/textures/cloudsBackground.jpg (100%) rename {demos => examples}/textures/compressed/test-dxt1.crn (100%) rename {demos => examples}/textures/compressed/test-dxt1.dds (100%) rename {demos => examples}/textures/compressed/test-dxt5.crn (100%) rename {demos => examples}/textures/compressed/test-dxt5.dds (100%) rename {demos => examples}/textures/compressed/test.bmp (100%) rename {demos => examples}/textures/compressed/test.gif (100%) rename {demos => examples}/textures/compressed/test.jpg (100%) rename {demos => examples}/textures/compressed/test.png (100%) rename {demos => examples}/textures/compressed/test.tga (100%) rename {demos => examples}/textures/crossGridSpecularMap.jpg (100%) rename {demos => examples}/textures/earth-lights.gif (100%) rename {demos => examples}/textures/earth-specular.gif (100%) rename {demos => examples}/textures/earth-specular.jpg (100%) rename {demos => examples}/textures/earth-specular.png (100%) rename {demos => examples}/textures/earth.jpg (100%) rename {demos => examples}/textures/earthBump.jpg (100%) rename {demos => examples}/textures/earthclouds.jpg (100%) rename {demos => examples}/textures/general-zod.jpg (100%) rename {demos => examples}/textures/grid.jpg (100%) rename {demos => examples}/textures/heightMap.jpg (100%) rename {demos => examples}/textures/heightmap.jpg (100%) rename {demos => examples}/textures/heightmap.png (100%) create mode 100644 examples/textures/holodeck/bottom.jpg create mode 100644 examples/textures/holodeck/east.jpg create mode 100644 examples/textures/holodeck/north.jpg create mode 100644 examples/textures/holodeck/south.jpg create mode 100644 examples/textures/holodeck/top.jpg create mode 100644 examples/textures/holodeck/west.jpg rename {demos => examples}/textures/leavesAlphaMap.jpg (100%) rename {demos => examples}/textures/leavesSpecularMap.jpg (100%) rename {demos => examples}/textures/milky-way.gif (100%) create mode 100644 examples/textures/normalMap.png rename {demos => examples}/textures/normal_map.jpg (100%) rename {demos => examples}/textures/oilySheen.jpg (100%) rename {demos => examples}/textures/pattern.jpg (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/clouds/a.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/clouds/b.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/clouds/bottom.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/clouds/c.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/clouds/d.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/clouds/top.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/london/neg-x.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/london/neg-y.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/london/neg-z.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/london/pos-x.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/london/pos-y.png (100%) rename {api/latest/plugins/node/reflections/textures => examples/textures/reflection}/london/pos-z.png (100%) rename {demos => examples}/textures/reflectionSpecularMap1.jpg (100%) rename {demos => examples}/textures/reflectionSpecularMap2.jpg (100%) rename {demos => examples}/textures/reflectionSpecularMap3.jpg (100%) rename {demos => examples}/textures/sand.jpg (100%) rename {demos => examples}/textures/superman.jpg (100%) rename {demos => examples}/textures/texture-atlas.jpg (100%) rename {demos => examples}/textures/weirdAlphaMap.gif (100%) rename {demos => examples}/textures/weirdGlowMap.jpg (100%) rename demos/transforms-model-hierarchy.html => examples/transforms_modelling_hierarchy.html (95%) rename demos/transforms-model-matrix.html => examples/transforms_modelling_matrix.html (96%) create mode 100644 examples/transforms_modelling_quaternion.html rename demos/transforms-model-rotate.html => examples/transforms_modelling_rotate.html (93%) rename demos/transforms-model-scale.html => examples/transforms_modelling_scale.html (96%) rename demos/transforms-model-translate.html => examples/transforms_modelling_translate.html (94%) rename demos/transforms-projection-default.html => examples/transforms_projection_default.html (95%) rename demos/transforms-projection-frustum.html => examples/transforms_projection_frustum.html (98%) rename demos/transforms-projection-ortho.html => examples/transforms_projection_ortho.html (96%) rename demos/transforms-projection-perspective.html => examples/transforms_projection_perspective.html (96%) rename demos/transforms-view.html => examples/transforms_viewing.html (98%) delete mode 100644 examplesold/features.json create mode 100644 files/inconsolata.woff rename src/core/display/chunks/{colorbufChunk.js => colorBufferChunk.js} (77%) rename src/core/display/chunks/{depthbufChunk.js => depthBufferChunk.js} (89%) delete mode 100644 src/core/display/chunks/depthTargetChunk.js create mode 100644 src/core/scene/colorBuffer.js delete mode 100644 src/core/scene/colorbuf.js rename src/core/scene/{depthbuf.js => depthBuffer.js} (79%) create mode 100644 src/core/scene/projection.js rename src/core/scene/{pass.js => stage.js} (52%) create mode 100644 src/plugins/lib/path.js rename {api/latest/plugins/node/backgrounds => src/plugins/node/background}/gradient.js (97%) create mode 100644 src/plugins/node/background/water.js delete mode 100644 src/plugins/node/backgrounds/gradient.js create mode 100644 src/plugins/node/cameras/path.js create mode 100644 src/plugins/node/cameras/path/lerplookat.js create mode 100644 src/plugins/node/cameras/temp.js create mode 100644 src/plugins/node/colorTarget/render.js rename src/plugins/node/{frustum => cull}/body.js (97%) rename src/plugins/node/{frustum/lod.js => cull/detail.js} (98%) rename api/latest/plugins/node/frustum/cull.js => src/plugins/node/cull/visibility.js (95%) create mode 100644 src/plugins/node/demos/models/city.js create mode 100644 src/plugins/node/depthTarget/render.js create mode 100644 src/plugins/node/effects/anaglyph.js delete mode 100644 src/plugins/node/effects/crt.js create mode 100644 src/plugins/node/effects/oculusRift.js delete mode 100644 src/plugins/node/effects/snowyPeaks.js create mode 100644 src/plugins/node/effects/stereo.js delete mode 100644 src/plugins/node/effects/xray.js create mode 100644 src/plugins/node/environments/gameGrid.js create mode 100644 src/plugins/node/environments/gridRoom.js create mode 100644 src/plugins/node/environments/holodeck.js create mode 100644 src/plugins/node/environments/lawn.js create mode 100644 src/plugins/node/environments/modelView.js create mode 100644 src/plugins/node/environments/newton.js create mode 100644 src/plugins/node/environments/pickFlyOrbitDOF.js delete mode 100644 src/plugins/node/frustum/cull.js rename {api/latest/plugins/node/prims => src/plugins/node/geometry}/boundary.js (91%) rename src/plugins/node/{prims => geometry}/box.js (94%) rename {api/latest/plugins/node/prims => src/plugins/node/geometry}/cylinder.js (98%) rename {api/latest/plugins/node/prims => src/plugins/node/geometry}/grid.js (91%) rename src/plugins/node/{heightmaps/custom.js => geometry/heightmap.js} (98%) rename api/latest/plugins/node/prims/box.js => src/plugins/node/geometry/path.js (94%) rename {api/latest/plugins/node/prims => src/plugins/node/geometry}/plane.js (92%) rename src/plugins/node/{prims => geometry}/quad.js (87%) create mode 100644 src/plugins/node/geometry/randomObjects.js rename {api/latest/plugins/node/prims => src/plugins/node/geometry}/sphere.js (93%) rename {api/latest/plugins/node/prims => src/plugins/node/geometry}/teapot.js (99%) rename {api/latest/plugins/node/prims => src/plugins/node/geometry}/torus.js (94%) rename {api/latest/plugins/node/prims => src/plugins/node/geometry}/vectorText.js (99%) create mode 100644 src/plugins/node/lights/randomPointLights.js create mode 100644 src/plugins/node/models/buildings/building.js rename src/plugins/node/{objects => models}/buildings/building/HighRiseGlass.jpg (100%) rename src/plugins/node/{objects => models}/buildings/building/HighRiseGlassSpecular.jpg (100%) rename src/plugins/node/{objects => models}/buildings/building/highrise-windows.jpg (100%) rename src/plugins/node/{objects => models}/buildings/building/pixelcity_windows7.jpg (100%) rename src/plugins/node/{objects => models}/buildings/city.js (86%) create mode 100644 src/plugins/node/models/ground/grid.js create mode 100644 src/plugins/node/models/ground/grid2.js create mode 100644 src/plugins/node/models/ground/slime.js create mode 100644 src/plugins/node/models/ground/water.js rename src/plugins/node/{objects => models}/plants/ghostTree.js (99%) create mode 100644 src/plugins/node/models/space/planets/earth.js rename src/plugins/node/{objects => models}/space/planets/earth/earth-lights.gif (100%) create mode 100644 src/plugins/node/models/space/planets/earth/earth-specular.png create mode 100644 src/plugins/node/models/space/planets/earth/earth.jpg create mode 100644 src/plugins/node/models/space/planets/earth/earthBump.jpg rename src/plugins/node/{objects => models}/space/planets/earth/earthbump.jpg (100%) create mode 100644 src/plugins/node/models/space/planets/earth/earthclouds.jpg rename src/plugins/node/{objects => models}/toys/drinkingBird.js (95%) rename src/plugins/node/{objects => models}/vehicles/tank.js (99%) delete mode 100644 src/plugins/node/objects/buildings/building.js delete mode 100644 src/plugins/node/objects/space/planets/earth.js delete mode 100644 src/plugins/node/objects/space/planets/earth/earth-specular.gif delete mode 100644 src/plugins/node/objects/space/planets/earth/earth-specular.jpg delete mode 100644 src/plugins/node/objects/space/planets/earth/earth.jpg delete mode 100644 src/plugins/node/objects/space/planets/earth/earthclouds.jpg create mode 100644 src/plugins/node/postprocess/blur.js create mode 100644 src/plugins/node/postprocess/boilerplate.js create mode 100644 src/plugins/node/postprocess/crt.js create mode 100644 src/plugins/node/postprocess/dof.js create mode 100644 src/plugins/node/postprocess/filmGrain.js create mode 100644 src/plugins/node/postprocess/fog.js create mode 100644 src/plugins/node/postprocess/lens.js create mode 100644 src/plugins/node/postprocess/pipeline.js create mode 100644 src/plugins/node/postprocess/pipeline/std.js create mode 100644 src/plugins/node/postprocess/scanlines.js create mode 100644 src/plugins/node/postprocess/sepia.js create mode 100644 src/plugins/node/postprocess/technicolor.js create mode 100644 src/plugins/node/postprocess/template1.js delete mode 100644 src/plugins/node/prims/boundary.js delete mode 100644 src/plugins/node/prims/cylinder.js delete mode 100644 src/plugins/node/prims/grid.js delete mode 100644 src/plugins/node/prims/plane.js delete mode 100644 src/plugins/node/prims/sphere.js delete mode 100644 src/plugins/node/prims/teapot.js delete mode 100644 src/plugins/node/prims/torus.js delete mode 100644 src/plugins/node/prims/vectorText.js rename src/plugins/node/{reflections => reflect}/clouds.js (85%) create mode 100644 src/plugins/node/reflect/grid.js rename api/latest/plugins/node/reflections/clouds.js => src/plugins/node/reflect/holodeck.js (53%) rename src/plugins/node/{reflections => reflect}/london.js (85%) create mode 100644 src/plugins/node/reflect/numberedGrid.js rename {demos/textures/reflection => src/plugins/node/reflect/textures}/clouds/a.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/clouds/b.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/clouds/bottom.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/clouds/c.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/clouds/d.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/clouds/top.png (100%) create mode 100644 src/plugins/node/reflect/textures/grid.jpg create mode 100644 src/plugins/node/reflect/textures/holodeck/bottom.jpg create mode 100644 src/plugins/node/reflect/textures/holodeck/east.jpg create mode 100644 src/plugins/node/reflect/textures/holodeck/north.jpg create mode 100644 src/plugins/node/reflect/textures/holodeck/south.jpg create mode 100644 src/plugins/node/reflect/textures/holodeck/top.jpg create mode 100644 src/plugins/node/reflect/textures/holodeck/west.jpg rename {demos/textures/reflection => src/plugins/node/reflect/textures}/london/neg-x.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/london/neg-y.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/london/neg-z.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/london/pos-x.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/london/pos-y.png (100%) rename {demos/textures/reflection => src/plugins/node/reflect/textures}/london/pos-z.png (100%) create mode 100644 src/plugins/node/reflect/textures/numberedGrid.jpg create mode 100644 src/plugins/node/scene/object.js rename src/plugins/node/{effects => shader}/fog.js (95%) create mode 100644 src/plugins/node/shader/scanline.js rename src/plugins/node/{effects => shader}/wobble.js (96%) rename {api/latest/plugins/node/effects => src/plugins/node/shader}/xray.js (97%) create mode 100644 src/plugins/node/skybox.js rename src/plugins/node/{skyboxes => skybox}/clouds.js (70%) rename src/plugins/node/{skyboxes => skybox}/cloudySea.js (70%) create mode 100644 src/plugins/node/skybox/gameGrid.js create mode 100644 src/plugins/node/skybox/grid.js create mode 100644 src/plugins/node/skybox/grid2.js create mode 100644 src/plugins/node/skybox/grid3.js rename src/plugins/node/{skyboxes => skybox}/grimmNight.js (69%) create mode 100644 src/plugins/node/skybox/holodeck.js rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/interstellarClouds.js (67%) rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/miramarClouds.js (69%) create mode 100644 src/plugins/node/skybox/numberedGrid.js rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/stormyDays.js (68%) rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/textures/clouds.jpg (100%) rename src/plugins/node/{reflections => skybox}/textures/clouds/a.png (100%) rename src/plugins/node/{reflections => skybox}/textures/clouds/b.png (100%) rename src/plugins/node/{reflections => skybox}/textures/clouds/bottom.png (100%) rename src/plugins/node/{reflections => skybox}/textures/clouds/c.png (100%) rename src/plugins/node/{reflections => skybox}/textures/clouds/d.png (100%) rename src/plugins/node/{reflections => skybox}/textures/clouds/top.png (100%) rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/textures/cloudySea.jpg (100%) create mode 100644 src/plugins/node/skybox/textures/gameGrid.jpg create mode 100644 src/plugins/node/skybox/textures/grid.jpg create mode 100644 src/plugins/node/skybox/textures/grid2.jpg rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/textures/grimmNight.jpg (100%) create mode 100644 src/plugins/node/skybox/textures/holodeck/bottom.jpg create mode 100644 src/plugins/node/skybox/textures/holodeck/east.jpg create mode 100644 src/plugins/node/skybox/textures/holodeck/north.jpg create mode 100644 src/plugins/node/skybox/textures/holodeck/south.jpg create mode 100644 src/plugins/node/skybox/textures/holodeck/top.jpg create mode 100644 src/plugins/node/skybox/textures/holodeck/west.jpg rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/textures/interstellarClouds.jpg (100%) rename src/plugins/node/{reflections => skybox}/textures/london/neg-x.png (100%) rename src/plugins/node/{reflections => skybox}/textures/london/neg-y.png (100%) rename src/plugins/node/{reflections => skybox}/textures/london/neg-z.png (100%) rename src/plugins/node/{reflections => skybox}/textures/london/pos-x.png (100%) rename src/plugins/node/{reflections => skybox}/textures/london/pos-y.png (100%) rename src/plugins/node/{reflections => skybox}/textures/london/pos-z.png (100%) rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/textures/miramarClouds.jpg (100%) create mode 100644 src/plugins/node/skybox/textures/numberedGrid.jpg rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/textures/stormyDays.jpg (100%) rename {api/latest/plugins/node/skyboxes => src/plugins/node/skybox}/textures/violentDays.jpg (100%) rename src/plugins/node/{skyboxes => skybox}/violentDays.js (69%) delete mode 100644 src/plugins/node/skyboxes/custom.js delete mode 100644 src/plugins/node/skyboxes/interstellarClouds.js delete mode 100644 src/plugins/node/skyboxes/miramarClouds.js delete mode 100644 src/plugins/node/skyboxes/stormyDays.js delete mode 100644 src/plugins/node/skyboxes/textures/clouds.jpg delete mode 100644 src/plugins/node/skyboxes/textures/cloudySea.jpg delete mode 100644 src/plugins/node/skyboxes/textures/grimmNight.jpg delete mode 100644 src/plugins/node/skyboxes/textures/interstellarClouds.jpg delete mode 100644 src/plugins/node/skyboxes/textures/miramarClouds.jpg delete mode 100644 src/plugins/node/skyboxes/textures/stormyDays.jpg delete mode 100644 src/plugins/node/skyboxes/textures/violentDays.jpg create mode 100644 src/plugins/node/texture/procedural.js create mode 100644 src/plugins/node/texture/procedural/fungus.js create mode 100644 src/plugins/node/texture/procedural/grid.js create mode 100644 src/plugins/node/texture/procedural/hex.js create mode 100644 src/plugins/node/texture/procedural/oil.js create mode 100644 src/plugins/node/texture/procedural/water.js rename src/plugins/node/{textures => texture}/video.js (98%) create mode 100644 src/plugins/node/xform/quaternion.js diff --git a/about.html b/about.html index d371a93c..73fe039e 100644 --- a/about.html +++ b/about.html @@ -299,7 +299,7 @@

6. Custom Scene Node Types

z: 5.0, nodes: [{ - type: "prims/box" + type: "geometry/box" }] }, { type: "translate", @@ -307,11 +307,11 @@

6. Custom Scene Node Types

z: 5.0, nodes: [{ - type: "prims/box" + type: "geometry/box" }] }] }, { - type: "prims/teapot" + type: "geometry/teapot" }] }] }); diff --git a/api/latest/firstExample.html b/api/latest/firstExample.html index e53db56b..176850fe 100644 --- a/api/latest/firstExample.html +++ b/api/latest/firstExample.html @@ -63,9 +63,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/api/latest/plugins/node/cameras/orbit.js b/api/latest/plugins/node/cameras/orbit.js index 0c92a794..24d481b8 100644 --- a/api/latest/plugins/node/cameras/orbit.js +++ b/api/latest/plugins/node/cameras/orbit.js @@ -20,14 +20,14 @@ */ SceneJS.Types.addType("cameras/orbit", { - construct:function (params) { + construct: function (params) { var lookat = this.addNode({ - type:"lookAt", + type: "lookAt", // A plugin node type is responsible for attaching specified // child nodes within itself - nodes:params.nodes + nodes: params.nodes }); var yaw = params.yaw || 0; @@ -40,17 +40,24 @@ SceneJS.Types.addType("cameras/orbit", { var lastX; var lastY; var dragging = false; + var lookatDirty = false; - var eye = params.eye || { x:0, y:0, z:0 }; - var look = params.look || { x:0, y:0, z:0}; + var eye = params.eye || { x: 0, y: 0, z: 0 }; + var look = params.look || { x: 0, y: 0, z: 0}; lookat.set({ - eye:{ x:eye.x, y:eye.y, z:-zoom }, - look:{ x:look.x, y:look.y, z:look.z }, - up:{ x:0, y:1, z:0 } + eye: { x: eye.x, y: eye.y, z: -zoom }, + look: { x: look.x, y: look.y, z: look.z }, + up: { x: 0, y: 1, z: 0 } }); - update(); +// this._tick = this.getScene().on("tick", +// function () { +// if (lookatDirty) { +// update(); +// lookatDirty = false; +// } +// }); var canvas = this.getScene().getCanvas(); @@ -157,16 +164,19 @@ SceneJS.Types.addType("cameras/orbit", { var eye3 = SceneJS_math_transformPoint3(pitchMat, eye); eye3 = SceneJS_math_transformPoint3(yawMat, eye3); - lookat.setEye({x:eye3[0], y:eye3[1], z:eye3[2] }); + lookat.setEye({x: eye3[0], y: eye3[1], z: eye3[2] }); } + + update(); }, - setLook: function(l) { + setLook: function (l) { }, - destruct:function () { + destruct: function () { + this.getScene().off(this.tick); // TODO: remove mouse handlers } }); diff --git a/api/latest/plugins/node/cameras/pickFlyOrbit.js b/api/latest/plugins/node/cameras/pickFlyOrbit.js index f1d06f3d..95c90981 100644 --- a/api/latest/plugins/node/cameras/pickFlyOrbit.js +++ b/api/latest/plugins/node/cameras/pickFlyOrbit.js @@ -44,6 +44,7 @@ require([ style.background = "#AAFFAA"; style.opacity = "0.8"; style["border-radius"] = "3px"; + style["z-index"] = 100000; style["-moz-border-radius"] = "3px"; style["box-shadow"] = "3px 3px 3px #444444"; style.left = "0"; @@ -55,18 +56,18 @@ require([ return { // Shows label, but only if text has been set - setShown:function (shown) { + setShown: function (shown) { style.display = shown && text ? "" : "none"; }, // Sets canvas position of label - setPos:function (pos) { + setPos: function (pos) { style.left = "" + pos.x + "px"; style.top = "" + pos.y + "px"; }, // Sets text in label - setText:function (t) { + setText: function (t) { text = t; div.innerHTML = "" + text + ""; } @@ -75,19 +76,21 @@ require([ SceneJS.Types.addType("cameras/pickFlyOrbit", { - construct:function (params) { + construct: function (params) { + + var self = this; var lookat = this.addNode({ - type:"lookAt", + type: "lookAt", - nodes:[ + nodes: [ { - type:"name", - name:"noname", + type: "name", + name: "noname", // A plugin node type is responsible for attaching specified // child nodes within itself - nodes:params.nodes + nodes: params.nodes } ] }); @@ -104,44 +107,44 @@ require([ // Sphere position, with a ID so we can update this node: indicatorPos = lookat.addNode({ - type:"translate", - id:"__spherePOI" + type: "translate", + id: "__spherePOI" }); indicatorVis = indicatorPos.addNode({ - type:"flags", - flags:{ - enabled:false, - transparent:true, - specular:true, - diffuse:false + type: "flags", + flags: { + enabled: false, + transparent: true, + specular: true, + diffuse: false } }); var cursorSize = params.cursorSize || 1; indicatorSize = indicatorVis.addNode({ - type:"scale", - id:"__sphereSize", - x:cursorSize, - y:cursorSize, - z:cursorSize, - nodes:[ + type: "scale", + id: "__sphereSize", + x: cursorSize, + y: cursorSize, + z: cursorSize, + nodes: [ { - type:"material", - color:{ r:0.4, g:1.0, b:0.4 }, - specularColor:{ r:1.0, g:1.0, b:1.0 }, - emit:0.2, - nodes:[ + type: "material", + color: { r: 0.4, g: 1.0, b: 0.4 }, + specularColor: { r: 1.0, g: 1.0, b: 1.0 }, + emit: 0.2, + nodes: [ { - type:"style", - lineWidth:2, - nodes:[ + type: "style", + lineWidth: 2, + nodes: [ // Sphere primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type: "geometry/sphere" } ] } @@ -158,16 +161,18 @@ require([ }); } - var eye = params.eye || { x:0, y:0, z:0 }; - var look = params.look || { x:0, y:0, z:0}; + var eye = params.eye || { x: 0, y: 0, z: 0 }; + var look = params.look || { x: 0, y: 0, z: 0}; var zoom = params.zoom || 100; var zoomSensitivity = params.zoomSensitivity || 1.0; - lookat.set({ - eye:{ x:eye.x, y:eye.y, z:eye.z}, - look:{ x:look.x, y:look.y, z:look.z }, - up:{ x:0, y:1, z:0 } - }); + var lookatArgs = { + eye: { x: eye.x, y: eye.y, z: eye.z}, + look: { x: look.x, y: look.y, z: look.z }, + up: { x: 0, y: 1, z: 0 } + }; + lookat.set(lookatArgs); + this.publish("updated", lookatArgs); var canvas = this.getScene().getCanvas(); @@ -276,7 +281,7 @@ require([ } function pick(canvasX, canvasY) { - scene.pick(canvasX, canvasY, { rayPick:true }); + scene.pick(canvasX, canvasY, { rayPick: true }); } var scene = this.getScene(); @@ -295,7 +300,7 @@ require([ if (indicatorVis) { indicatorVis.setEnabled(true); - indicatorPos.setXYZ({x:endPivot[0], y:endPivot[1], z:endPivot[2] }); + indicatorPos.setXYZ({x: endPivot[0], y: endPivot[1], z: endPivot[2] }); label.setShown(true); } @@ -372,8 +377,18 @@ require([ glmat.vec3.transformMat4(eye3, eye, mat); // Update view transform - lookat.setLook({x:look[0], y:look[1], z:look[2] }); - lookat.setEye({x:look[0] - eye3[0], y:look[1] - eye3[1], z:look[2] - eye3[2] }); + lookat.setLook({x: look[0], y: look[1], z: look[2] }); + lookat.setEye({x: look[0] - eye3[0], y: look[1] - eye3[1], z: look[2] - eye3[2] }); + + var lookatArgs = { + eye: {x: look[0], y: look[1], z: look[2] }, + look: {x: look[0] - eye3[0], y: look[1] - eye3[1], z: look[2] - eye3[2] } + }; + +// lookat.setLook(lookatArgs.look); +// lookat.setEye(lookatArgs.eye); + + self.publish("updated", lookatArgs); // Rotate complete orbiting = false; @@ -388,7 +403,7 @@ require([ }); }, - destruct:function () { + destruct: function () { // TODO: remove mouse handlers } }); diff --git a/api/latest/plugins/node/canvas/capture.js b/api/latest/plugins/node/canvas/capture.js index a32c931d..0ba95b8c 100644 --- a/api/latest/plugins/node/canvas/capture.js +++ b/api/latest/plugins/node/canvas/capture.js @@ -48,7 +48,7 @@ require([ SceneJS.Types.addType("canvas/capture", { construct:function (params) { - this._format = params.format ? supportedFormat(params.format) : "jpeg"; + this._format = params.format ? this._supportedFormat(params.format) : "jpeg"; this._width = params.width; this._height = params.height; }, diff --git a/api/latest/plugins/node/effects/crt.js b/api/latest/plugins/node/effects/crt.js deleted file mode 100644 index d2f1c411..00000000 --- a/api/latest/plugins/node/effects/crt.js +++ /dev/null @@ -1,36 +0,0 @@ -SceneJS.Types.addType("shader/crt", { - - construct:function (params) { - - this._shader = this.addNode({ - type:"shader", - - shaders:[ - - { - stage:"fragment", - code:"vec4 myPixelColorFunc(vec4 color) {\n\ - float m = mod(gl_FragCoord.y, 4.0);\n\ - if (m < 1.5) {\n\ - color = vec4(0.0, 0.0, 0.0, 1.0);\n\ - } else if (m < 2.0) {\n\ - color = vec4(0.2, 0.2, 0.2, 1.0);\n\ - } else if (m < 2.5) {\n\ - color = vec4(0.2, 0.2, 0.2, 1.0);\n\ - }\n\ - return color;\n\ - }", - - hooks:{ - pixelColor:"myPixelColorFunc" - } - } - ], - nodes:params.nodes - }); - }, - - destruct:function () { - // Not used - } -}); diff --git a/api/latest/plugins/node/effects/fog.js b/api/latest/plugins/node/effects/fog.js index 68e2091d..fe9581d7 100644 --- a/api/latest/plugins/node/effects/fog.js +++ b/api/latest/plugins/node/effects/fog.js @@ -1,159 +1,145 @@ -SceneJS.Types.addType("effects/fog", { - - construct:function (params) { - - // Holds params for custom shader node - this._shaderParams = { - fogMode:1.0, // 0.0 disabled, 1.0 linear, 2.0 exponential, 3.0 quadratic, 4.0 constant - fogDensity:0.05, // Fog density in range of [0.0..1.0] - fogStart:0.0, // Nearest point of fog in view space (receeding Z-axis is positive) - fogEnd:10000.0, // Furthest point of fog in view space - fogColor:[0.6, 0.0, 0.0] // Colour of fog - the colour that objects blend into - }; - - // Custom shader node - this._shader = this.addNode({ - type:"shader", - coreId:"effects/fog", - - shaders:[ - - { - stage:"fragment", - code:[ - - /* Parameter uniforms - */ - "uniform float fogMode;", - "uniform float fogDensity;", - "uniform float fogStart;", - "uniform float fogEnd;", - "uniform vec3 fogColor;", - - /* Collected view-space fragment position - */ - "vec4 _viewPos;", - - /* Collects view-space fragment position - */ - "void fogViewPosFunc(vec4 viewPos) {", - " _viewPos = viewPos;", - "}", - - /* Modifies fragment colour - */ - "vec4 fogPixelColorFunc(vec4 color) {", - " if (fogMode != 0.0) {", // not "disabled" - " float fogFactor = (1.0 - fogDensity);", - " if (fogMode != 4.0) {", // not "constant" - " if (fogMode == 1.0) {", // "linear" - " fogFactor *= clamp(pow(max((fogEnd - length(- _viewPos.xyz)) / " + - " (fogStart - fogEnd), 0.0), 2.0), 0.0, 1.0);", - " } else {", // "exp" or "exp2" - " fogFactor *= clamp((fogStart - length(- _viewPos.xyz)) / (fogStart - fogEnd), 0.0, 1.0);", - " }", - " }", - " return color * (fogFactor + vec4(fogColor, 1.0)) * (1.0 - fogFactor);", - " }", - " return color;", - "}" - ], - - /* Bind our functions to hooks - */ - hooks:{ - viewPos:"fogViewPosFunc", - pixelColor:"fogPixelColorFunc" +/** + * Depth-of-Field postprocess effect + * + */ +SceneJS.Types.addType("postprocess/dof", { + + construct: function (params) { + + // Unique IDs for the render target nodes + var colorTarget = this.id + ".colorTarget"; + var colorTarget2 = this.id + ".colorTarget2"; + var depthTarget = this.id + ".depthTarget"; + + + this.addNodes([ + + // Pass 1 + // Render scene to color and depth targets + { + type: "pass", + priority: 1, + nodes: [ + + // Output color target + { + type: "colorTarget", + id: colorTarget, + + nodes: [ + + // Output depth target + { + type: "depthTarget", + id: depthTarget, + + // The scene nodes + nodes: params.nodes + } + ] } - } - ], - - // Declare parameters and set default values - params:this._shaderParams, - - nodes:params.nodes - }); - - if (params.mode != undefined) { - this.setMode(params.mode); - } - if (params.density != undefined) { - this.setDensity(params.density); - } - if (params.start != undefined) { - this.setStart(params.start); - } - if (params.end != undefined) { - this.setEnd(params.end); - } - if (params.color != undefined) { - this.setColor(params.color); - } - }, - - setMode:function (mode) { - switch (mode) { - case "disabled": - this._shaderParams.fogMode = 0; - break; - case "linear": - this._shaderParams.fogMode = 1; - break; - case "exp": - this._shaderParams.fogMode = 2; - break; - case "exp2": - this._shaderParams.fogMode = 3; - break; - case "constant": - this._shaderParams.fogMode = 4; - break; - } - this._shader.setParams(this._shaderParams); - }, - - getMode:function () { - return ["disabled", "linear", "exp", "exp2", "constant"][this._shaderParams.fogMode]; // TODO: optimize - }, - - setDensity:function (density) { - this._shaderParams.fogDensity = density; - this._shader.setParams(this._shaderParams); - }, - - getDensity:function () { - return this._shaderParams.fogDensity; - }, - - setStart:function (start) { - this._shaderParams.fogStart = start; - this._shader.setParams(this._shaderParams); - }, - - getStart:function () { - return this._shaderParams.fogStart; - }, - - setEnd:function (end) { - this._shaderParams.fogEnd = end; - this._shader.setParams(this._shaderParams); - }, - - getEnd:function () { - return this._shaderParams.fogEnd; - }, - - setColor:function (color) { - this._shaderParams.fogColor = [color.r || 0, color.g || 0, color.b || 0 ]; - this._shader.setParams(this._shaderParams); - }, - - getColor:function () { - var color = this._shaderParams.fogColor; - return { r:color[0], g:color[1], b:color[2] }; - }, - - destruct:function () { - // Not used + ] + }, + + // Debug pass - renders the depth buffer to the canvas + { + type: "pass", + priority: 1.2, + nodes: [ + { + // type: "depthTarget/render", + target: depthTarget + } + ] + }, + + // Pass 2 + // Render scene with custom shader using color and depth targets as textures + { + type: "pass", + priority: 2, + + nodes: [ + + // Input color target + { + type: "textureMap", + target: colorTarget, + + nodes: [ + + // Input depth target + { + type: "textureMap", + target: depthTarget, + + nodes: [ + + // Horizontal blur shader + { + type: "shader", + coreId: "xx", + shaders: [ + + // Vertex shader simply passes through vertex position and UV + { + stage: "vertex", + code: [ + "attribute vec3 SCENEJS_aVertex;", + "attribute vec2 SCENEJS_aUVCoord;", + "varying vec2 vUv;", + "void main () {", + " gl_Position = vec4(SCENEJS_aVertex, 1.0);", + " vUv = SCENEJS_aUVCoord;", + "}" + ] + }, + + // Fragment shader + { + stage: "fragment", + code: [ + "precision highp float;", + + "uniform sampler2D SCENEJS_uSampler0;", // Colour target's texture + "uniform sampler2D SCENEJS_uSampler1;", // Depth target's texture + + /// Unpack an RGBA pixel to floating point value. + "float unpack (vec4 colour) {", + " const vec4 bitShifts = vec4(1.0,", + " 1.0 / 255.0,", + " 1.0 / (255.0 * 255.0),", + " 1.0 / (255.0 * 255.0 * 255.0));", + " return dot(colour, bitShifts);", + "}", + + "void main () {", + " float depth = unpack(texture2D(SCENEJS_uSampler1, vUv));", + " gl_FragColor = depth * texture2D(SCENEJS_uSampler0, vUv);", + "}" + ] + } + ], + + params: { + }, + + nodes: [ + + // Quad primitive, implemented by plugin at + // http://scenejs.org/api/latest/plugins/node/geometry/quad.js + { + type: "geometry/quad" + } + ] + } + ] + } + ] + } + ] + } + ]); } }); + diff --git a/api/latest/plugins/node/effects/snowyPeaks.js b/api/latest/plugins/node/effects/snowyPeaks.js deleted file mode 100644 index a44c1d0d..00000000 --- a/api/latest/plugins/node/effects/snowyPeaks.js +++ /dev/null @@ -1,50 +0,0 @@ -SceneJS.Types.addType("effects/snowyPeaks", { - - construct:function (params) { - - var altitude = params.altitude || 0; - - this._shader = this.addNode({ - type:"shader", - shaders:[ - { - stage:"fragment", - code:[ - "float posY = 0.0;", - "vec4 myWorldPosFunc(vec4 pos){", - " posY=pos.y;", - " return pos;", - "}", - - "uniform float altitude;", - "vec3 myMaterialBaseColorFunc(vec3 color) {", - " if (posY > altitude) {", - " color = vec3(1.0, 1.0, 1.0);", - " }", - " return color;", - "}" - ], - hooks:{ - materialBaseColor:"myMaterialBaseColorFunc", - worldPos:"myWorldPosFunc" - } - } - ], - params:{ - altitude:altitude - }, - nodes:params.nodes - }); - }, - - setAltitude:function (altitude) { - this._shader.setParams({ - altitude:altitude - }); - }, - - destruct:function () { - // Not used - } -}) -; diff --git a/api/latest/plugins/node/effects/wobble.js b/api/latest/plugins/node/effects/wobble.js deleted file mode 100644 index 6b36447d..00000000 --- a/api/latest/plugins/node/effects/wobble.js +++ /dev/null @@ -1,42 +0,0 @@ -SceneJS.Types.addType("effects/wobble", { - - construct:function (params) { - - var shader = this.addNode({ - type:"shader", - shaders:[ - { - stage:"vertex", - code:"uniform float time;\n\ - vec4 myWorldPosFunc(vec4 pos){\n\ - pos.x=pos.x+sin(pos.x*5.0+time+10.0)*0.1;\n\ - pos.y=pos.y+sin(pos.y*5.0+time+10.0)*0.1;\n\ - pos.z=pos.z+sin(pos.z*5.0+time+10.0)*0.1;\n\ - return pos;\n\ - }\n", - hooks:{ - worldPos:"myWorldPosFunc" - } - } - ], - params:{ - time:0.5 - }, - nodes:params.nodes - }); - - var time = 0; - - this._tick = this.getScene().on("tick", - function () { - shader.setParams({ - time:time - }); - time += 0.1; - }); - }, - - destruct:function () { - this.getScene().off(this._tick); - } -}); diff --git a/api/latest/plugins/node/frustum/body.js b/api/latest/plugins/node/frustum/body.js deleted file mode 100644 index bccd850b..00000000 --- a/api/latest/plugins/node/frustum/body.js +++ /dev/null @@ -1,112 +0,0 @@ -require([ - // Prefix routes to plugin support libs - "scenejsPluginDeps/frustum/frustumCullSystemPool" -], - function (pool) { - - SceneJS.Types.addType("frustum/body", { - - construct:function (params) { - - // Frustum culling and projected canvas size enabled by default - this._frustumCull = params.frustumCull != undefined ? params.frustumCull : true; - this._detailCull = params.detailCull != undefined ? params.detailCull : true; - - var shape = params.shape || "box"; - - switch (shape) { - case "box": - this._bodyCfg = { - shape:shape, - min:params.min || [0, 0, 0], - max:params.max || [0, 0, 0], - frustumCull:this._frustumCull, - detailCull:this._detailCull - }; - if (params.showBoundary) { - this.addNode({ - type:"prims/boundary", - min:params.min || [0, 0, 0], - max:params.max || [0, 0, 0], - wire:true - }); - } - break; - -// case "sphere": -// this._bodyCfg = { -// shape:"sphere", -// center:params.center || [0, 0, 0], -// radius:params.radius || 1.0 -// }; -// break; - - default: - this.log("error", "Unsupported value for attribute 'shape'"); - } - - if (params.nodes) { - this.addNodes(params.nodes); - } - }, - - preCompile:function () { - - // This node might have been relocated in the scene graph - // and therefore inherits new view and projection transforms, - // so we'll release any existing system just in case. - - this._putBody(); - this._getBody(); - }, - - _putBody:function () { - if (this._bodyId) { - this._system.removeBody(this._bodyId); - this._bodyId = null; - } - if (this._system) { - pool.putSystem(this._system); - this._system = null; - } - }, - - _getBody:function () { - try { - this._system = pool.getSystem(this); - var self = this; - this._bodyId = this._system.createBody(this._bodyCfg, - function (intersect, canvasSize) { // Body update handler - - // Not that much overhead in relaying status - // updates via pub/sub because they only happen sparsely, - // ie. for bodies whose status actually changes - - if (self._frustumCull) { // Frustum culling switching enabled - self.publish("intersect", intersect); - } - - if (self._detailCull) { // LOD switching enabled - self.publish("canvasSize", canvasSize); - } - - // self.log(" intersect = " + intersect + ", canvasSize = " + canvasSize); - }); - } catch (e) { - this.log("Error : " + e); - if (this._system) { - pool.putSystem(this._system); - this._system = null; - } - } - }, - - postCompile:function () { - // Not used - }, - - destruct:function () { - this._putBody(); - } - }); - }); diff --git a/api/latest/plugins/node/frustum/lod.js b/api/latest/plugins/node/frustum/lod.js deleted file mode 100644 index 07bf092a..00000000 --- a/api/latest/plugins/node/frustum/lod.js +++ /dev/null @@ -1,125 +0,0 @@ -SceneJS.Types.addType("frustum/lod", { - - construct:function (params) { - - var self = this; - - var sizes = params.sizes; - if (!sizes) { - this.log("error", "mandatory attribute missing: 'sizes'"); - return; - } - - var nodes = params.nodes; - if (!nodes) { - this.log("error", "mandatory attribute missing: 'nodes'"); - return; - } - - if (sizes.length != nodes.length) { - this.log("error", "invalid attribute(s): 'sizes' and 'nodes' should be arrays of equal length"); - return; - } - - for (var i = 0, len = sizes.length; i < len; i++) { - if (sizes[i] <= 0) { - this.log("error", "invalid attribute: values in 'sizes' should be greater than zero"); - return; - } - if (i > 0) { - if (sizes[i] <= sizes[i - 1]) { - this.log("error", "invalid attribute: values in 'sizes' should be in ascending order"); - return; - } - } - } - - this.addNode({ - type:"frustum/body", - shape:params.shape, - min:params.min, - max:params.max, - showBoundary:params.showBoundary, - frustumCull: params.frustumCull ? params.frustumCull : true, // Enable frustum culling? - detailCull:true // Enable detail culling information (default) - }, - function (body) { - if (params.nodes) { - var childNodes = []; - for (var i = 0, len = params.nodes.length; i < len; i++) { - childNodes.push(self.addNode({ - type:"enable", - enabled:false, - nodes:[ - params.nodes[i] - ] - })); - } - - // The currently active child node - var currentNode; - - // If frustum culling is not disabled by - // params.frustumCull, then we'll get notification - // whenever the boundaries intersection status - // changes with respect to the view frustum. - - body.on("intersect", - function (intersect) { - if (currentNode) { - switch (intersect) { - case 0: // Completely outside frustum - currentNode.setEnabled(false); - break; - case 1: // Partially inside frustum - currentNode.setEnabled(true); - break; - case 2: // Completely inside frustum - currentNode.setEnabled(true); - break; - } - } - }); - - // If frustum culling is not disabled by params.frustumCull, - // then we'll get notifications of change in projected canvas - // size for the boundary as long as the "intersect" notification - // reported that the boundary is not outside the view frustum. - - // If frustum culling is disabled. then we'll get - // notification of canvas size changes regardless of - // whether the boundary is outside the frustum of not. - - body.on("canvasSize", - function (canvasSize) { - - if (currentNode) { - - // We only get a 2d size update when the size has changed, - // so its safe to say we'll not be immediately re-enabling - // the currently enabled child node. No need to avoid - // any redundant re-enabling or disabling here. - - currentNode.setEnabled(false); - } -// - if (canvasSize == -1) { - // All Culled - return; - } - - // Enable the appropriate child, if any, - // for the boundary's projected 2D size - - for (var i = sizes.length - 1; i >= 0; i--) { - if (canvasSize >= sizes[i]) { - currentNode = childNodes[i]; - currentNode.setEnabled(true); - return; - } - } - }); - } - }); - } -}); \ No newline at end of file diff --git a/api/latest/plugins/node/heightmaps/custom.js b/api/latest/plugins/node/heightmaps/custom.js deleted file mode 100644 index 1e666705..00000000 --- a/api/latest/plugins/node/heightmaps/custom.js +++ /dev/null @@ -1,164 +0,0 @@ -(function () { - - SceneJS.Types.addType("heightmaps/custom", { - - construct:function (params) { - - if (!params.src) { - throw "heightmap param expected: src"; - } - - params.xSize = params.xSize || 1.0; - params.ySize = params.ySize || 0.25; - params.zSize = params.zSize || 1.0; - - params.xSegments = params.xSegments || 100; - params.zSegments = params.zSegments || 100; - - var self = this; - - // Notify SceneJS so it can support loading/busy indicators etc - this._taskId = this.taskStarted("Loading heightmap"); - - var image = new Image(); - - image.onload = function (e) { - - var element = window.document.createElement('canvas'); - element.width = image.width; - element.height = image.height; - - var c = element.getContext("2d"); - - c.drawImage(image, 0, 0); - - var imageData = c.getImageData(0, 0, image.width, image.height).data; - - var mesh = createMeshData(params, image, imageData); - - var wire = params.wire; - - if (self._taskId) { - - self._taskId = self.taskFinished(self._taskId); - - // Create geometry node - self.addNode({ - type:"rotate", - x:1, - angle:90, - nodes:[ - { - type:"geometry", - primitive:wire ? "lines" : "triangles", - positions:mesh.positions, - normals:!wire ? "auto" : null, // Get SceneJS to compute the normals - uv:!wire ? mesh.uv : null, - indices:mesh.indices, - coreId:"heightmap_" + (wire == true ? "wire_" : "") + params.zSize + "_" + params.xSize + "_" + params.ySize + "_" + params.xSegments + "_" + params.zSegments - } - ] - }); - } - }; - - image.onerror = function () { - self._taskId = self.taskFailed(self._taskId); - }; - - image.src = params.src; - }, - - destruct:function () { - this._taskId = self.taskFinished(this._taskId); - } - }); - - function createMeshData(params, image, imageData) { - - var imageWidth = image.width; - var imageHeight = image.height; - - var positions = []; - var uvs = []; - var indices = []; - - var width = params.xSize; - var height = params.zSize; - - var xSegments = params.xSegments; - var zSegments = params.zSegments; - - var halfWidth = width / 2; - var halfHeight = height / 2; - - var gridX = xSegments; - var gridZ = zSegments; - - var gridX1 = gridX + 1; - var gridZ1 = gridZ + 1; - - var segWidth = width / gridX; - var segHeight = height / gridZ; - - var imgX; - var imgY; - - var x; - var y; - var z; - - for (var px = 0; px <= gridZ; px++) { - for (var py = 0; py <= gridX; py++) { - - x = px * segWidth; - y = py * segHeight; - - imgX = Math.round((x / width) * (imageWidth - 1)); - imgY = Math.round((y / height) * (imageHeight - 1)); - - z = (imageData[(imageWidth * imgY + imgX) * 4]) / 255 * params.ySize; - - if (z == undefined || isNaN(z)) { - z = 0; - } - - positions.push(x - halfWidth); - positions.push(-y + halfHeight); - positions.push(-z); - - uvs.push(py / gridX); - uvs.push(1 - px / gridZ); - } - } - - var a; - var b; - var c; - var d; - - for (var iz = 0; iz < gridZ; iz++) { - for (var ix = 0; ix < gridX; ix++) { - - a = ix + gridX1 * iz; - b = ix + gridX1 * ( iz + 1 ); - c = ( ix + 1 ) + gridX1 * ( iz + 1 ); - d = ( ix + 1 ) + gridX1 * iz; - - indices.push(a); - indices.push(b); - indices.push(c); - - indices.push(c); - indices.push(d); - indices.push(a); - } - } - - return { - positions:positions, - uv:uvs, - indices:indices - }; - } -})(); diff --git a/api/latest/plugins/node/import/md2.js b/api/latest/plugins/node/import/md2.js index 3a13fbd2..e9a2c47e 100644 --- a/api/latest/plugins/node/import/md2.js +++ b/api/latest/plugins/node/import/md2.js @@ -19,6 +19,7 @@ require([ if (!params.src) { this.log("error", "Attribute expected: src"); + return; } // Notify SceneJS so it can support loading/busy indicators etc diff --git a/api/latest/plugins/node/objects/buildings/building.js b/api/latest/plugins/node/objects/buildings/building.js index 47b8ba67..23fd78d9 100644 --- a/api/latest/plugins/node/objects/buildings/building.js +++ b/api/latest/plugins/node/objects/buildings/building.js @@ -2,9 +2,9 @@ var buildingTypes = initBuildingTypes(); - SceneJS.Types.addType("objects/buildings/building", { + SceneJS.Types.addType("models/buildings/building", { - construct:function (params) { + construct: function (params) { var type = params.buildingType || 0; var buildingType = buildingTypes[type]; if (!buildingType) { @@ -12,162 +12,164 @@ } var pos = params.pos || {}; createBuilding(buildingType, this, { - xmin:(pos.x || 0) - 10, - zmin:(pos.z || 0) - 10, - xmax:(pos.x || 0) + 10, - zmax:(pos.z || 0) + 10 + xmin: (pos.x || 0) - 10, + zmin: (pos.z || 0) - 10, + xmax: (pos.x || 0) + 10, + zmax: (pos.z || 0) + 10 }); } }); function initBuildingTypes() { - var texturePath = SceneJS.getConfigs("pluginPath") + "/node/objects/buildings/building/"; + var texturePath = SceneJS.getConfigs("pluginPath") + "/node/models/buildings/building/"; return [ // Building 1 { - freq:50, - material:{ - type:"material", - coreId:"building.1.material", - baseColor:{ - r:1.0, - g:1.0, - b:1.0 + freq: 50, + material: { + type: "material", + coreId: "building.1.material", + baseColor: { + r: 1.0, + g: 1.0, + b: 1.0 }, - specularColor:[ 1.0, 1.0, 1.0 ], - specular:0.4, - shine:20.0 + specularColor: [ 1.0, 1.0, 1.0 ], + specular: 0.4, + shine: 20.0 }, - texture:{ - type:"texture", - coreId:"building.1.texture", - layers:[ + texture: { + type: "texture", + coreId: "building.1.texture", + layers: [ { - src:texturePath + "highrise-windows.jpg", - applyTo:"baseColor", - blendMode:"multiply", - wrapS:"repeat", - wrapT:"repeat", - scale:{ - x:0.04, - y:0.05 + src: texturePath + "highrise-windows.jpg", + applyTo: "baseColor", + blendMode: "multiply", + wrapS: "repeat", + wrapT: "repeat", + scale: { + x: 0.04, + y: 0.05 } } ] }, - roof:{ - height:1, - material:{ - type:"material", - coreId:"building.1.roof", - baseColor:{ - r:1.0, - g:1.0, - b:1.0 + roof: { + height: 1, + material: { + type: "material", + coreId: "building.1.roof", + baseColor: { + r: 1.0, + g: 1.0, + b: 1.0 } } } }, // Building 2 { - freq:30, - material:{ - type:"material", - coreId:"building.2.material", - baseColor:{ - r:1.0, - g:1.0, - b:1.0 + freq: 30, + material: { + type: "material", + coreId: "building.2.material", + baseColor: { + r: 1.0, + g: 1.0, + b: 1.0 }, - specularColor:[ 1.0, 1.0, 1.0 ], - specular:1.0, - shine:5.0 + specularColor: [ 1.0, 1.0, 1.0 ], + specular: 1.0, + shine: 5.0 }, - texture:{ - type:"texture", - coreId:"building.2.texture", - layers:[ + texture: { + type: "texture", + coreId: "building.2.texture", + layers: [ { - src:texturePath + "HighRiseGlass.jpg", - applyTo:"baseColor", - blendMode:"multiply", - wrapS:"repeat", - wrapT:"repeat", - scale:{ - x:0.25, - y:0.2 + src: texturePath + "HighRiseGlass.jpg", + applyTo: "baseColor", + blendMode: "multiply", + wrapS: "repeat", + wrapT: "repeat", + scale: { + x: 0.25, + y: 0.2 } }, { - src:texturePath + "HighRiseGlassSpecular.jpg", - applyTo:"specular", - blendMode:"multiply", - wrapS:"repeat", - wrapT:"repeat", - scale:{ - x:0.25, - y:0.2 + src: texturePath + "HighRiseGlassSpecular.jpg", + applyTo: "specular", + blendMode: "multiply", + wrapS: "repeat", + wrapT: "repeat", + scale: { + x: 0.25, + y: 0.2 } } ] }, - roof:{ - height:1, - material:{ - type:"material", - coreId:"building.2.roof", - baseColor:{ - r:0.4, - g:0.4, - b:0.4 - } + roof: { + height: 1, + material: { + type: "material", + coreId: "building.2.roof", + baseColor: { + r: 0.4, + g: 0.4, + b: 0.4 + }, + specular: 0.2 } } }, // Building 3 { - freq:20, - material:{ - type:"material", - coreId:"building.3.material", - baseColor:{ - r:1.0, - g:1.0, - b:1.0 + freq: 20, + material: { + type: "material", + coreId: "building.3.material", + baseColor: { + r: 1.0, + g: 1.0, + b: 1.0 }, - specularColor:[ 1.0, 1.0, 1.0 ], - specular:0.4, - shine:20.0 + specularColor: [ 1.0, 1.0, 1.0 ], + specular: 0.4, + shine: 20.0 }, - texture:{ - type:"texture", - coreId:"building.3.texture", - layers:[ + texture: { + type: "texture", + coreId: "building.3.texture", + layers: [ { - src:texturePath + "pixelcity_windows7.jpg", - applyTo:"baseColor", - blendMode:"multiply", - wrapS:"repeat", - wrapT:"repeat", - scale:{ - x:0.015, - y:0.01 + src: texturePath + "pixelcity_windows7.jpg", + applyTo: "baseColor", + blendMode: "multiply", + wrapS: "repeat", + wrapT: "repeat", + scale: { + x: 0.015, + y: 0.01 } } ] }, - roof:{ - height:1, - material:{ - type:"material", - coreId:"building.3.roof", - baseColor:{ - r:0.0, - g:0.0, - b:0.0 - } + roof: { + height: 1, + material: { + type: "material", + coreId: "building.3.roof", + baseColor: { + r: 0.0, + g: 0.0, + b: 0.0 + }, + specular: 0.2 } } } @@ -281,26 +283,23 @@ function addBase(buildingType, node, xpos, zpos, xsize, ysize, zsize) { node.addNode({ - type:"translate", - x:xpos, - y:ysize, - z:zpos, - nodes:[ + type: "translate", + x: xpos, + y: ysize, + z: zpos, + nodes: [ { - type:"material", - baseColor:{ - r:0.6, g:.6, b:0.6 + type: "material", + baseColor: { + r: 0.6, g: .6, b: 0.6 }, - coreId:"building.base", - nodes:[ + coreId: "building.base", + nodes: [ { - type:"geometry", - source:{ - type:"box", - xSize:xsize, - ySize:ysize, - zSize:zsize - } + type: "geometry/box", + xSize: xsize, + ySize: ysize, + zSize: zsize } ] } @@ -314,19 +313,16 @@ */ node.addNode(buildingType.roof.material) .addNode({ - type:"translate", - x:xpos, - y:ypos + ysize + buildingType.roof.height, - z:zpos + type: "translate", + x: xpos, + y: ypos + ysize + buildingType.roof.height, + z: zpos }) .addNode({ - type:"geometry", - source:{ - type:"box", - xSize:xsize, - ySize:buildingType.roof.height, - zSize:zsize - } + type: "geometry/box", + xSize: xsize, + ySize: buildingType.roof.height, + zSize: zsize }); /* Body with texture @@ -334,19 +330,16 @@ node.addNode(buildingType.material)// Current material .addNode(buildingType.texture)// Current texture .addNode({ - type:"translate", - x:xpos, - y:ypos, - z:zpos + type: "translate", + x: xpos, + y: ypos, + z: zpos }) .addNode({ - type:"geometry", - source:{ - type:"box", - xSize:xsize, - ySize:ysize, - zSize:zsize - } + type: "geometry/box", + xSize: xsize, + ySize: ysize, + zSize: zsize }); } })(); \ No newline at end of file diff --git a/api/latest/plugins/node/objects/buildings/city.js b/api/latest/plugins/node/objects/buildings/city.js index 4ffc121e..7ffda93e 100644 --- a/api/latest/plugins/node/objects/buildings/city.js +++ b/api/latest/plugins/node/objects/buildings/city.js @@ -1,4 +1,4 @@ -SceneJS.Types.addType("objects/buildings/city", { +SceneJS.Types.addType("models/buildings/city", { construct:function (params) { @@ -12,7 +12,7 @@ SceneJS.Types.addType("objects/buildings/city", { for (var x = -halfWidth; x < halfWidth; x += 50) { for (var z = -halfWidth; z < halfWidth; z += 50) { this.addNode({ - type:"objects/buildings/building", + type:"models/buildings/building", buildingType:Math.floor(Math.random() * 3), // Three building types pos:{ x:x, diff --git a/api/latest/plugins/node/objects/plants/ghostTree.js b/api/latest/plugins/node/objects/plants/ghostTree.js index 161ace79..8983b1d7 100644 --- a/api/latest/plugins/node/objects/plants/ghostTree.js +++ b/api/latest/plugins/node/objects/plants/ghostTree.js @@ -7,7 +7,7 @@ * http://www.chromeexperiments.com/detail/ghost-trees/ * * Tree generation code is wrapped in a custom SceneJS node type defined in: - * http://scenejs.org/api/latest/plugins/node/objects/plants/ghostTree.js + * http://scenejs.org/api/latest/plugins/node/models/plants/ghostTree.js * * All the parameters for the tree generator are exposed as configurations * for the node type. @@ -21,7 +21,7 @@ ], function (glmat) { - SceneJS.Types.addType("objects/plants/ghostTree", { + SceneJS.Types.addType("models/plants/ghostTree", { construct:function (params) { diff --git a/api/latest/plugins/node/objects/space/planets/earth.js b/api/latest/plugins/node/objects/space/planets/earth.js index dbb403be..3db6bfe2 100644 --- a/api/latest/plugins/node/objects/space/planets/earth.js +++ b/api/latest/plugins/node/objects/space/planets/earth.js @@ -1,8 +1,8 @@ -SceneJS.Types.addType("objects/space/planets/earth", { +SceneJS.Types.addType("models/space/planets/earth", { construct:function (params) { - var texturePath = SceneJS.getConfigs("pluginPath") + "/node/objects/space/planets/earth/"; + var texturePath = SceneJS.getConfigs("pluginPath") + "/node/models/space/planets/earth/"; var node = this.addNode({ type:"rotate", diff --git a/api/latest/plugins/node/objects/toys/drinkingBird.js b/api/latest/plugins/node/objects/toys/drinkingBird.js index eb46c8da..28a985d7 100644 --- a/api/latest/plugins/node/objects/toys/drinkingBird.js +++ b/api/latest/plugins/node/objects/toys/drinkingBird.js @@ -6,12 +6,12 @@ * Usage example: * * someNode.addNode({ - * type: "objects/toys/drinkingBird", + * type: "models/toys/drinkingBird", * rotate: true // Default false - causes bird to drink when true * }); * */ -SceneJS.Types.addType("objects/toys/drinkingBird", { +SceneJS.Types.addType("models/toys/drinkingBird", { init:function (params) { @@ -110,7 +110,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { color:{ r:0.53, g:0.53, b:0.53 }, nodes:[ { - type:"prims/cylinder", + type:"geometry/cylinder", radiusTop:5, radiusBottom:5, height:300, @@ -137,7 +137,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"feetMaterial", nodes:[ { - type:"prims/box", + type:"geometry/box", xSize:83, ySize:2, zSize:(110 + 64 + 20) / 2 @@ -161,7 +161,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"feetMaterial", nodes:[ { - type:"prims/box", + type:"geometry/box", xSize:3, ySize:52 / 2, zSize:(110 + 64 + 20) / 2 @@ -179,7 +179,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"feetMaterial", nodes:[ { - type:"prims/box", + type:"geometry/box", xSize:3, ySize:15, zSize:64 / 2 @@ -197,7 +197,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"legMaterial", nodes:[ { - type:"prims/box", + type:"geometry/box", xSize:3, ySize:(334 - 30) / 2, zSize:64 / 2 @@ -221,7 +221,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"feetMaterial", nodes:[ { - type:"prims/box", + type:"geometry/box", xSize:3, ySize:52 / 2, zSize:(110 + 64 + 20) / 2 @@ -239,7 +239,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"feetMaterial", nodes:[ { - type:"prims/box", + type:"geometry/box", xSize:3, ySize:15, zSize:64 / 2 @@ -257,7 +257,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"legMaterial", nodes:[ { - type:"prims/box", + type:"geometry/box", xSize:3, ySize:(334 - 30) / 2, zSize:64 / 2 @@ -304,7 +304,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"waterMaterial", nodes:[ { - type:"prims/cylinder", + type:"geometry/cylinder", radiusTop:8, radiusBottom:8, height:300, @@ -345,7 +345,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"waterMaterial", nodes:[ { - type:"prims/cylinder", + type:"geometry/cylinder", radiusTop:52, radiusBottom:52, height:0, @@ -366,7 +366,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"glassMaterial", nodes:[ { - type:"prims/cylinder", + type:"geometry/cylinder", radiusTop:12, radiusBottom:12, height:435, @@ -434,7 +434,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"headMaterial", nodes:[ { - type:"prims/cylinder", + type:"geometry/cylinder", radiusTop:8, radiusBottom:15, height:70, @@ -573,7 +573,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"hatMaterial", nodes:[ { - type:"prims/cylinder", + type:"geometry/cylinder", radiusTop:71, radiusBottom:71, height:10, @@ -590,7 +590,7 @@ SceneJS.Types.addType("objects/toys/drinkingBird", { coreId:"hatMaterial", nodes:[ { - type:"prims/cylinder", + type:"geometry/cylinder", radiusTop:45, radiusBottom:45, height:66, diff --git a/api/latest/plugins/node/physics/box.js b/api/latest/plugins/node/physics/box.js index 230e27c1..26464e7c 100644 --- a/api/latest/plugins/node/physics/box.js +++ b/api/latest/plugins/node/physics/box.js @@ -20,7 +20,7 @@ SceneJS.Types.addType("physics/box", { nodes:[ { - type:"prims/box", + type:"geometry/box", size: params.size } ] diff --git a/api/latest/plugins/node/physics/plane.js b/api/latest/plugins/node/physics/plane.js index b81daefc..5daebf29 100644 --- a/api/latest/plugins/node/physics/plane.js +++ b/api/latest/plugins/node/physics/plane.js @@ -31,7 +31,7 @@ SceneJS.Types.addType("physics/plane", { angle:90, nodes:[ { - type:"prims/plane", + type:"geometry/plane", wire:params.wire, xSegments:params.xSegments || 100, zSegments:params.zSegments || 100 diff --git a/api/latest/plugins/node/physics/sphere.js b/api/latest/plugins/node/physics/sphere.js index be88e842..fe104dec 100644 --- a/api/latest/plugins/node/physics/sphere.js +++ b/api/latest/plugins/node/physics/sphere.js @@ -20,7 +20,7 @@ SceneJS.Types.addType("physics/sphere", { nodes:[ { - type:"prims/radius", + type:"geometry/radius", latitudeBands: params.latitudeBands, longitudeBands: params.longitudeBands, radius: params.radius diff --git a/api/latest/plugins/node/physics/teapot.js b/api/latest/plugins/node/physics/teapot.js index 0dee1a6e..7e0a5e79 100644 --- a/api/latest/plugins/node/physics/teapot.js +++ b/api/latest/plugins/node/physics/teapot.js @@ -20,7 +20,7 @@ SceneJS.Types.addType("physics/teapot", { nodes:[ { - type:"prims/teapot" + type:"geometry/teapot" } ] }); diff --git a/api/latest/plugins/node/prims/quad.js b/api/latest/plugins/node/prims/quad.js deleted file mode 100644 index 44f25d45..00000000 --- a/api/latest/plugins/node/prims/quad.js +++ /dev/null @@ -1,43 +0,0 @@ -/** - * Quad geometry node type - * - * Usage example: - * - * someNode.addNode({ - * type: "prims/quad", - * wire: false // Default - * }); - */ -(function () { - - SceneJS.Types.addType("prims/quad", { - construct:function (params) { - this.addNode(build.call(this, params)); - } - }); - - function build(params) { - - var coreId = "prims/quad" + (params.wire ? "wire" : "_solid"); - - // If a node core already exists for a prim with the given properties, - // then for efficiency we'll share that core rather than create another geometry - if (this.getScene().hasCore("geometry", coreId)) { - return { - type: "geometry", - coreId:coreId - }; - } - - // Otherwise, create a new geometry - return { - type: "geometry", - primitive:params.wire ? "lines" : "triangles", - coreId:coreId, - positions:[ 1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0 ], - normals:[ -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0 ], - uv:[ 1, 1, 0, 1, 0, 0, 1, 0 ], - indices:[ 0, 1, 2, 0, 2, 3 ] - }; - } -})(); \ No newline at end of file diff --git a/api/latest/plugins/node/reflections/london.js b/api/latest/plugins/node/reflections/london.js deleted file mode 100644 index 67e86521..00000000 --- a/api/latest/plugins/node/reflections/london.js +++ /dev/null @@ -1,33 +0,0 @@ -/** - * Reflection map of a street in London - * - * Usage example: - * - * someNode.addNode({ - * type: "reflections/london", - * intensity: 0.2 - * }); - */ -SceneJS.Types.addType("reflections/london", { - - construct: function (params) { - - var path = SceneJS.getConfigs("pluginPath") + "/node/reflections/textures/london/"; - - this.addNode({ - type: "reflect", - intensity: params.intensity, - src: [ - path + "pos-x.png", - path + "neg-x.png", - path + "pos-y.png", - path + "neg-y.png", - path + "pos-z.png", - path + "neg-z.png" - ], - - // Attach given child nodes - nodes: params.nodes - }) - } -}); diff --git a/api/latest/plugins/node/skyboxes/clouds.js b/api/latest/plugins/node/skyboxes/clouds.js deleted file mode 100644 index d6ff14d0..00000000 --- a/api/latest/plugins/node/skyboxes/clouds.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Cloudy skybox node type, with fine clouds - * - * Usage example: - * - * someNode.addNode({ - * type: "skyboxes/clouds" - * }); - */ -SceneJS.Types.addType("skyboxes/clouds", { - construct:function (params) { - - // Wraps a 'custom' skybox node type, passing in a clouds texture - this.addNode({ - type:"skyboxes/custom", - src:SceneJS.getConfigs("pluginPath") + "/node/skyboxes/textures/clouds.jpg" - }) - } -}); diff --git a/api/latest/plugins/node/skyboxes/cloudySea.js b/api/latest/plugins/node/skyboxes/cloudySea.js deleted file mode 100644 index 46e74aa4..00000000 --- a/api/latest/plugins/node/skyboxes/cloudySea.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Cloudy skybox node type, with clouds reflected in a calm sea - * - * Usage example: - * - * someNode.addNode({ - * type: "skyboxes/cloudySea" - * }); - */ -SceneJS.Types.addType("skyboxes/cloudySea", { - construct:function (params) { - - // Wraps a 'custom' skybox node type, passing in a cloudySea texture - this.addNode({ - type:"skyboxes/custom", - src:SceneJS.getConfigs("pluginPath") + "/node/skyboxes/textures/cloudySea.jpg" - }) - } -}); diff --git a/api/latest/plugins/node/skyboxes/custom.js b/api/latest/plugins/node/skyboxes/custom.js deleted file mode 100644 index 5cdb9f13..00000000 --- a/api/latest/plugins/node/skyboxes/custom.js +++ /dev/null @@ -1,163 +0,0 @@ -/** - * Customizable skybox node type, which allows you to customize its texture - * - * Usage example: - * - * someNode.addNode({ - * type: "skyboxes/custom", - * texture: "foo/bar/mySkyboxTexture.jpg", - * size: 5000 // Box half-size on each axis - default is 5000 - * }); - */ -SceneJS.Types.addType("skyboxes/custom", { - - // TODO: expose node props to tweak the geometry coords to map to variations in texture UV mappings? - - construct: function (params) { - - var self = this; - - // Fall back on clouds texture by default - var src = params.src || SceneJS.getConfigs("pluginPath") + "/node/skyboxes/textures/clouds.jpg"; - - var image = new Image(); - image.onload = function () { - buildNodes(); - }; - image.onerror = function () { - }; - image.src = src; - - function buildNodes() { - - // Sky box dimensions on each axis - var size = params.size || 5000.0; - - // Vertex shader which anchors the skybox translation - self.addNode({ - - // Special pick name so that we can ignore picks on sky boxes - type: "name", - name: "__SceneJS_dontPickMe", - - nodes: [ - { - type: "shader", - shaders: [ - { - stage: "vertex", - code: [ - "mat4 myViewMatrix(mat4 m) {", - " m[3][0] =m[3][1] = m[3][2] = 0.0;", - "return m;", - "}" - ], - // Bind our injected functions to SceneJS hook points - hooks: { - viewMatrix: "myViewMatrix" - } - } - ], - nodes: [ - // Disable lighting for the sky box - { - type: "flags", - flags: { - specular: false, - diffuse: false, - ambient: false - }, - nodes: [ - { - type: "material", - color: { r: 0, g: 0, b: 0 }, - emit: 0.0, - nodes: [ - // Clouds texture - { - type: "texture", - layers: [ - { - src: src, - blendMode: "add" - } - ], - nodes: [ - { - type: "scale", - x: size, y: size, z: size, - nodes: [ - // Sky box geometry - { - type: "geometry", - positions: [ - 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // v0-v1-v2-v3 front - 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // v0-v3-v4-v5 right - 1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // v0-v5-v6-v1 top - -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // v1-v6-v7-v2 left - -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, // v7-v4-v3-v2 bottom - 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1 // v4-v7-v6-v5 back - ], - uv: [ - 0.5, 0.6666, - 0.25, 0.6666, - 0.25, 0.3333, - 0.5, 0.3333, - - 0.5, 0.6666, - 0.5, 0.3333, - 0.75, 0.3333, - 0.75, 0.6666, - - 0.5, 0.6666, - 0.5, 1, - 0.25, 1, - 0.25, 0.6666, - - 0.25, 0.6666, - 0.0, 0.6666, - 0.0, 0.3333, - 0.25, 0.3333, - - 0.25, 0, - 0.50, 0, - 0.50, 0.3333, - 0.25, 0.3333, - - 0.75, 0.3333, - 1.0, 0.3333, - 1.0, 0.6666, - 0.75, 0.6666 - ], - indices: [ - 0, 1, 2, - 0, 2, 3, - 4, 5, 6, - 4, 6, 7, - 8, 9, 10, - 8, 10, 11, - 12, 13, 14, - 12, 14, 15, - - 16, 17, 18, - 16, 18, 19, - - 20, 21, 22, - 20, 22, 23 - ] - } - ] - } - ] - } - ] - } - ] - } - ] - } - ] - }); - } - } -}); diff --git a/api/latest/plugins/node/skyboxes/grimmNight.js b/api/latest/plugins/node/skyboxes/grimmNight.js deleted file mode 100644 index a06e0f43..00000000 --- a/api/latest/plugins/node/skyboxes/grimmNight.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Skybox node type, with gloomy night clouds - * - * Usage example: - * - * someNode.addNode({ - * type: "skyboxes/grimmNight" - * }); - */ -SceneJS.Types.addType("skyboxes/grimmNight", { - construct:function (params) { - - // Wraps a 'custom' skybox node type, passing in a the grimmNight texture - this.addNode({ - type:"skyboxes/custom", - src:SceneJS.getConfigs("pluginPath") + "/node/skyboxes/textures/grimmNight.jpg" - }) - } -}); diff --git a/api/latest/plugins/node/skyboxes/violentDays.js b/api/latest/plugins/node/skyboxes/violentDays.js deleted file mode 100644 index 5355c80e..00000000 --- a/api/latest/plugins/node/skyboxes/violentDays.js +++ /dev/null @@ -1,19 +0,0 @@ -/** - * Skybox node type, with firey apocalyptic clouds - * - * Usage example: - * - * someNode.addNode({ - * type: "skyboxes/violentDays" - * }); - */ -SceneJS.Types.addType("skyboxes/violentDays", { - construct:function (params) { - - // Wraps a 'custom' skybox node type, passing in the violentDays texture - this.addNode({ - type:"skyboxes/custom", - src:SceneJS.getConfigs("pluginPath") + "/node/skyboxes/textures/violentDays.jpg" - }) - } -}); diff --git a/api/latest/plugins/node/textures/video.js b/api/latest/plugins/node/textures/video.js deleted file mode 100644 index d1b42bf9..00000000 --- a/api/latest/plugins/node/textures/video.js +++ /dev/null @@ -1,102 +0,0 @@ -/** - * Video texture - * - */ - -SceneJS.Types.addType("textures/video", { - - construct: function (params) { - - if (!params.src) { - this.log("error", "Attribute expected: src"); - } - - this._texture = this.addNode({ - type: "textureMap", - minFilter: "linear", - magFilter: "linear", - wrapS: params.wrapS, - wrapT: params.wrapT, - applyTo: params.applyTo, - nodes: params.nodes - }); - - var canvas = document.createElement("canvas"); - document.getElementsByTagName("body")[0].appendChild(canvas); - var ctx = canvas.getContext("2d"); - - // Create hidden video canvas - var video = document.createElement("video"); - video.style.display = "none"; - video.setAttribute("loop", "loop"); - video.autoplay = true; - video.addEventListener("ended", // looping broken in FF - function () { - this.play(); - }, - true); - document.getElementsByTagName("body")[0].appendChild(video); - //video.crossOrigin = "anonymous"; - video.src = params.src; - - var self = this; - - // Periodically feed images from canvas into texture - this._tick = this.getScene().on("tick", - function () { - if (video.readyState > 0) { - if (video.height <= 0) { - video.style.display = ""; - video.height = video.offsetHeight; - video.width = video.offsetWidth; - video.style.display = "none"; - } - self._texture.setImage(video); - } - }); - }, - - /** - * Sets the texture's blend factor with respect to other active textures. - * @param {number} blendFactor The blend factor, in range [0..1] - */ - setBlendFactor: function (blendFactor) { - this._texture.setBlendFactor(blendFactor); - }, - - getBlendFactor: function () { - return this._texture.getBlendFactor(); - }, - - setTranslate: function (t) { - this._texture.setTranslate(t); - }, - - getTranslate: function () { - return this._texture.getTranslate(); - }, - - setScale: function (s) { - this._texture.setScale(s); - }, - - getScale: function () { - return this._texture.getScale(); - }, - - setRotate: function (angle) { - this._texture.setRotate(s); - }, - - getRotate: function () { - return this._texture.getRotate(); - }, - - getMatrix: function () { - return this._texture.getMatrix(); - }, - - destruct: function () { - this.getScene.off(this._tick); - } -}); diff --git a/api/latest/scenejs.js b/api/latest/scenejs.js index 8e5e509c..0b20d679 100644 --- a/api/latest/scenejs.js +++ b/api/latest/scenejs.js @@ -1231,6 +1231,29 @@ var SceneJS = new (function () { return o2; }; + var hasOwnProperty = Object.prototype.hasOwnProperty; + + /** + * Tests is an object is empty + * @param obj + * @returns {boolean} + * @private + */ + this._isEmpty =function(obj) { + // null and undefined are "empty" + if (obj == null) return true; + // Assume if it has a length property with a non-zero value + // that that property is correct. + if (obj.length > 0) return false; + if (obj.length === 0) return true; + // Otherwise, does it have any properties of its own? + // Note that this doesn't handle + // toString and valueOf enumeration bugs in IE < 9 + for (var key in obj) { + if (hasOwnProperty.call(obj, key)) return false; + } + return true; + }; /** * Resets SceneJS, destroying all existing scenes @@ -1761,7 +1784,6 @@ SceneJS_Canvas.prototype.initWebGL = function () { for (var i = 0; !this.gl && i < this._WEBGL_CONTEXT_NAMES.length; i++) { try { this.gl = this.canvas.getContext(this._WEBGL_CONTEXT_NAMES[i], this.contextAttr); - } catch (e) { // Try with next context name } } @@ -1772,13 +1794,14 @@ SceneJS_Canvas.prototype.initWebGL = function () { 'Failed to get a WebGL context'); } + // this.gl.enable(this.gl.SCISSOR_TEST); // this.gl.clearColor(1.0, 1.0, 1.0, 1.0); - this.gl.clearDepth(1.0); - this.gl.enable(this.gl.DEPTH_TEST); - this.gl.disable(this.gl.CULL_FACE); - this.gl.depthRange(0, 1); - this.gl.disable(this.gl.SCISSOR_TEST); - this.gl.viewport(0, 0, this.canvas.width, this.canvas.height); +// this.gl.clearDepth(1.0); +// this.gl.enable(this.gl.DEPTH_TEST); +// this.gl.disable(this.gl.CULL_FACE); +// this.gl.depthRange(0, 1); +// this.gl.disable(this.gl.SCISSOR_TEST); +// this.gl.viewport(0, 0, this.canvas.width, this.canvas.height); }; @@ -1809,6 +1832,14 @@ var SceneJS_Engine = function (json, options) { */ this.id = json.id; + + /** + * Number of times the scene is drawn each time it's rendered. + *

This is useful for when we need to do things like render for left and right eyes. + * @type {*|number} + */ + this._numPasses = json.numPasses || 1; + /** * Canvas and GL context for this engine */ @@ -1834,8 +1865,9 @@ var SceneJS_Engine = function (json, options) { * @type SceneJS_Display */ this.display = new SceneJS_Display({ - canvas:this.canvas, - transparent: json.transparent + canvas: this.canvas, + transparent: json.transparent, + dof: json.dof }); /** @@ -1878,8 +1910,8 @@ var SceneJS_Engine = function (json, options) { * The current scene graph status */ this.sceneStatus = { - nodes:{}, // Status for each node - numTasks:0 // Number of loads currently in progress + nodes: {}, // Status for each node + numTasks: 0 // Number of loads currently in progress }; var self = this; @@ -1901,7 +1933,7 @@ var SceneJS_Engine = function (json, options) { function (event) { event.preventDefault(); self.stop(); - SceneJS_events.fireEvent(SceneJS_events.WEBGL_CONTEXT_LOST, { scene:self.scene }); + SceneJS_events.fireEvent(SceneJS_events.WEBGL_CONTEXT_LOST, { scene: self.scene }); }, false); @@ -1911,12 +1943,22 @@ var SceneJS_Engine = function (json, options) { self.canvas.initWebGL(); self._coreFactory.webglRestored(); // Reallocate WebGL resources for node state cores self.display.webglRestored(); // Reallocate shaders and re-cache shader var locations for display state chunks - SceneJS_events.fireEvent(SceneJS_events.WEBGL_CONTEXT_RESTORED, { scene:self.scene }); + SceneJS_events.fireEvent(SceneJS_events.WEBGL_CONTEXT_RESTORED, { scene: self.scene }); self.start(); }, false); }; +/** + * Sets the number of times the scene is drawn on each render. + *

This is useful for when we need to do things like render for left and right eyes. + * @param {Number} numPasses The number of times the scene is drawn on each frame. + * @see #getTagMask + * @see SceneJS.Tag + */ +SceneJS_Engine.prototype.setNumPasses = function (numPasses) { + this._numPasses = numPasses; +}; /** * Simulate a lost WebGL context. @@ -1996,17 +2038,11 @@ SceneJS_Engine.prototype.createNode = function (json, ok) { * node and core pools for reuse, respectively. */ SceneJS_Engine.prototype._doDestroyNodes = function () { - var node; - while (this._numNodesToDestroy > 0) { - node = this._nodesToDestroy[--this._numNodesToDestroy]; - node._doDestroy(); - this._coreFactory.putCore(node._core); // Release state core for reuse - this._nodeFactory.putNode(node); // Release node for reuse } }; @@ -2083,18 +2119,49 @@ SceneJS_Engine.prototype.branchDirty = function (node) { * Ordinarily the frame is rendered only if compilations or draw graph updates were performed, * but may be forced to render the frame regardless. * - * @param {{String:String}} params Rendering parameters + * @param {*} params Rendering parameters + * @param {Boolean} params.clear True to clear the display first (default) */ SceneJS_Engine.prototype.renderFrame = function (params) { - if (this._tryCompile() || (params && params.force)) { // Do any pending (re)compilations + var rendered = false; - this.display.render(params); + if (this._needCompile() || (params && params.force)) { - return true; +// // Render display graph +// this.display.render(params); + + var time = (new Date()).getTime(); + + // Render the scene once for each pass + for (var i = 0; i < this._numPasses; i++) { + + // Notify that render is upcoming + this.scene.publish("rendering", { + pass: i + }); + + // Compile scene graph to display graph, if necessary + this._doCompile(); + + // Render display graph + // Clear buffers only on first frame + this.display.render({ + clear: i == 0 + }); + + // Notify that render completed + this.scene.publish("rendered", { + sceneId: this.id, + time: time, + pass: i + }); + + rendered = true; + } } - return false; + return rendered; }; /** @@ -2102,78 +2169,101 @@ SceneJS_Engine.prototype.renderFrame = function (params) { */ SceneJS_Engine.prototype.start = function () { - if (!this.running) { + if (!this.running) { // Do nothing if already started this.running = true; this.paused = false; + this.sceneDirty = true; var self = this; var fnName = "__scenejs_sceneLoop" + this.id; - var sleeping = false; - - this.sceneDirty = true; - - var tick = { - sceneId:this.id, - startTime:(new Date()).getTime() - }; - - self.events.fireEvent("started", tick); - var time = (new Date()).getTime(); - + var prevTime = time; + var startTime = time; var scene = this.scene; + var rendered = false; + + // Notify started + this.events.fireEvent("started", { + sceneId: self.id, + startTime: startTime + }); + // Animation frame callback window[fnName] = function () { - if (self.running && !self.paused) { // idleFunc may have paused scene + if (self.running && !self.paused) { - tick.prevTime = time; time = (new Date()).getTime(); - tick.time = time; - scene.publish("tick", tick); + scene.publish("tick", { + sceneId: self.id, + startTime: startTime, + prevTime: prevTime, + time: time + }); + + prevTime = time; - if (!self.running) { // idleFunc may have destroyed scene + if (!self.running) { // "tick" handler have destroyed scene return; } - if (self._tryCompile()) { // Attempt pending compile and redraw + rendered = false; - sleeping = false; + // Render the scene once for each pass + for (var i = 0; i < self._numPasses; i++) { - self.display.render(); + if (self._needCompile() || rendered) { - scene.publish("rendered", tick); + sleeping = false; - if (self.running) { - window.requestAnimationFrame(window[fnName]); - } + // Notify we're about to do a render + scene.publish("rendering", { + pass: i + }); - } else { + // Compile scene graph to display graph, if necessary + self._doCompile(); - if (!sleeping) { - scene.publish("sleep", tick); - } + // Render display graph + // Clear buffers only on first frame + self.display.render({ + clear: i == 0 + }); - sleeping = true; + // Notify that we've just done a render + scene.publish("rendered", { + sceneId: self.id, + time: time, + pass: i + }); - if (self.running) { - window.requestAnimationFrame(window[fnName]); + rendered = true; } } - } else { - if (self.running) { - window.requestAnimationFrame(window[fnName]); + // If any of the passes did not render anything, then put the render loop to sleep again + if (!rendered) { + if (!sleeping) { + scene.publish("sleep", { + sceneId: self.id, + startTime: startTime, + prevTime: time, + time: time + }); + } + sleeping = true; } } + + if (self.running) { + window.requestAnimationFrame(window[fnName]); + } }; - if (self.running) { - window.requestAnimationFrame(window[fnName]); - } + window.requestAnimationFrame(window[fnName]); } }; @@ -2193,59 +2283,52 @@ SceneJS_Engine.prototype.start = function () { */ SceneJS_Engine.prototype.pick = function (canvasX, canvasY, options) { - this._tryCompile(); // Do any pending scene compilations + // Do any pending scene compilations + if (this._needCompile()) { + this._doCompile(); + } var hit = this.display.pick({ - canvasX:canvasX, - canvasY:canvasY, - rayPick:options ? options.rayPick : false + canvasX: canvasX, + canvasY: canvasY, + rayPick: options ? options.rayPick : false }); return hit; }; /** - * Performs any pending scene compilations or display rebuilds, returns true if any of those were done, - * in which case a display re-render is then needed - * - * @returns {Boolean} True when any compilations or display rebuilds were done + * Returns true if view needs refreshing from scene + * @returns {Boolean} + * @private */ -SceneJS_Engine.prototype._tryCompile = function () { - - // this._doAddNodes(); - - if (this.display.imageDirty // Frame buffer needs redraw +SceneJS_Engine.prototype._needCompile = function () { + return (this.display.imageDirty // Frame buffer needs redraw || this.display.drawListDirty // Draw list needs rebuild || this.display.stateSortDirty // Draw list needs to redetermine state order || this.display.stateOrderDirty // Draw list needs state sort || this.display.objectListDirty // Draw list needs to be rebuilt || this._sceneBranchesDirty // One or more branches in scene graph need (re)compilation - || this.sceneDirty) { // Whole scene needs recompilation - - if (this._sceneBranchesDirty || this.sceneDirty) { // Need scene graph compilation - - this._sceneBranchesDirty = false; - - SceneJS_events.fireEvent(SceneJS_events.SCENE_COMPILING, { // Notify compilation support start - engine:this // Compilation support modules get ready - }); - - this.pubSubProxy = new SceneJS_PubSubProxy(this.scene, null); - var ctx = { - pubSubProxy : this.pubSubProxy - }; - - this.scene._compileNodes(ctx); // Begin depth-first compilation descent into scene sub-nodes - - this.sceneDirty = false; - } - - this._doDestroyNodes(); // Garbage collect destroyed nodes - node destructions set imageDirty true + || this.sceneDirty); // Whole scene needs recompilation +}; - return true; // Compilation was performed, need frame redraw now +/** + * Performs any pending scene compilations or display rebuilds + */ +SceneJS_Engine.prototype._doCompile = function () { + if (this._sceneBranchesDirty || this.sceneDirty) { // Need scene graph compilation + this._sceneBranchesDirty = false; + SceneJS_events.fireEvent(SceneJS_events.SCENE_COMPILING, { // Notify compilation support start + engine: this // Compilation support modules get ready + }); + this.pubSubProxy = new SceneJS_PubSubProxy(this.scene, null); + var ctx = { + pubSubProxy: this.pubSubProxy + }; + this.scene._compileNodes(ctx); // Begin depth-first compilation descent into scene sub-nodes + this.sceneDirty = false; } - - return false; + this._doDestroyNodes(); // Garbage collect destroyed nodes - node destructions set imageDirty true }; /** @@ -2260,14 +2343,10 @@ SceneJS_Engine.prototype.pause = function (doPause) { * Stops the render loop */ SceneJS_Engine.prototype.stop = function () { - if (this.running) { - this.running = false; this.paused = false; - window["__scenejs_sceneLoop" + this.id] = null; - // this.events.fireEvent("stopped", { sceneId: this.id }); } }; @@ -2297,9 +2376,7 @@ SceneJS_Engine.prototype.destroyNode = function (node) { * Destroys this engine */ SceneJS_Engine.prototype.destroy = function () { - this.destroyed = true; - // this.events.fireEvent("destroyed", { sceneId: this.id }); }; @@ -2486,7 +2563,7 @@ var SceneJS_configsModule = new (function () { for (var i = 0; cfg && i < parts.length; i++) { cfg = cfg[parts[i]]; } - return cfg || {}; + return (cfg != undefined) ? cfg : {}; } }; @@ -4872,7 +4949,9 @@ var SceneJS_sceneStatusModule = new (function () { dismissPopup(task.element); } var nodeState = task.nodeState; - nodeState.numTasks--; + if (--nodeState.numTasks < 0) { + nodeState.numTasks = 0; + } delete nodeState.tasks[taskId]; if (nodeState.numTasks == 0) { delete sceneState.nodeStates[nodeState.nodeId]; @@ -5091,7 +5170,7 @@ SceneJS._webgl.RenderBuffer = function (cfg) { this._touch = function () { var width = canvas.canvas.width; var height = canvas.canvas.height; - if (buf) { // Currently have a pick buffer + if (buf) { // Currently have a buffer if (buf.width == width && buf.height == height) { // Canvas size unchanged, buffer still good return; } else { // Buffer needs reallocation for new canvas size @@ -5155,7 +5234,7 @@ SceneJS._webgl.RenderBuffer = function (cfg) { */ this.clear = function () { if (!bound) { - throw "Pick buffer not bound"; + throw "Render buffer not bound"; } gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); gl.disable(gl.BLEND); @@ -5182,15 +5261,20 @@ SceneJS._webgl.RenderBuffer = function (cfg) { /** Returns the texture */ this.getTexture = function () { - this._touch(); return { bind: function (unit) { - gl.activeTexture(gl["TEXTURE" + unit]); - gl.bindTexture(gl.TEXTURE_2D, buf.texture); + if (buf && buf.texture) { + gl.activeTexture(gl["TEXTURE" + unit]); + gl.bindTexture(gl.TEXTURE_2D, buf.texture); + return true; + } + return false; }, unbind: function (unit) { - gl.activeTexture(gl["TEXTURE" + unit]); - gl.bindTexture(gl.TEXTURE_2D, null); + if (buf && buf.texture) { + gl.activeTexture(gl["TEXTURE" + unit]); + gl.bindTexture(gl.TEXTURE_2D, null); + } } }; }; @@ -6020,6 +6104,12 @@ SceneJS.Node.prototype._construct = function (engine, core, cfg, nodeId) { */ this._core = core; + /** + * The core ID + * @type {String|Number} + */ + this.coreId = core.coreId; + /** * ID of this node, unique within its scene. The ID is a string if it was defined by the application * via the node's JSON configuration, otherwise it is a number if it was left to SceneJS to automatically create. @@ -6405,9 +6495,12 @@ SceneJS.Node.prototype.disconnect = function () { if (this.parent) { for (var i = 0; i < this.parent.nodes.length; i++) { if (this.parent.nodes[i] === this) { - return this.parent.disconnectNodeAt(i); + var node = this.parent.disconnectNodeAt(i); + this.parent = null; + return node; } } + this.parent = null; } return null; }; @@ -6465,19 +6558,13 @@ SceneJS.Node.prototype.removeNode = function (node) { /** Disconnects all child nodes from their parent node and returns them in an array. */ SceneJS.Node.prototype.disconnectNodes = function () { - var len = this.nodes.length; - for (var i = 0; i < len; i++) { // Unlink nodes from this this.nodes[i].parent = null; } - var nodes = this.nodes; - this.nodes = []; - this._engine.display.objectListDirty = true; - return nodes; }; @@ -7580,14 +7667,14 @@ SceneJS_NodeFactory.prototype.putNode = function (node) { if (this._core.useCount == 1) { this.setOptics(params.optics); // Can be undefined - // Rebuild on every scene tick - // https://github.com/xeolabs/scenejs/issues/277 - var self = this; - this._tick = this.getScene().on("tick", function () { - if (self._core.dirty) { - self._core.rebuild(); - } - }); +// // Rebuild on every scene tick +// // https://github.com/xeolabs/scenejs/issues/277 +// var self = this; +// this._tick = this.getScene().on("tick", function () { +// if (self._core.dirty) { +// self._core.rebuild(); +// } +// }); } }; @@ -8195,12 +8282,12 @@ SceneJS_NodeFactory.prototype.putNode = function (node) { new (function () { var defaultCore = { - type: "framebuf", + type: "renderTarget", stateId: SceneJS._baseStateId++, - framebuf: null + targets: null }; - // Map of framebuf nodes to cores, for reallocation on WebGL context restore + // Map of nodes to cores, for reallocation on WebGL context restore var nodeCoreMap = {}; var coreStack = []; @@ -8209,11 +8296,12 @@ new (function () { SceneJS_events.addListener( SceneJS_events.SCENE_COMPILING, function (params) { - params.engine.display.framebuf = defaultCore; + params.engine.display.renderTarget = defaultCore; stackLen = 0; }); - SceneJS_events.addListener(// Reallocate VBOs when context restored after loss + // Reallocate VBOs when context restored after loss + SceneJS_events.addListener( SceneJS_events.WEBGL_CONTEXT_RESTORED, function () { for (var nodeId in nodeCoreMap) { @@ -8223,32 +8311,90 @@ new (function () { } }); - /** - * @class Scene graph node which sets up a frame buffer to which the {@link SceneJS.Geometry} nodes in its subgraph will be rendered. - * The frame buffer may be referenced as an image source by successive {@link SceneJS.Texture} nodes. - * @extends SceneJS.Node - */ - SceneJS.Framebuf = SceneJS_NodeFactory.createNodeType("framebuf"); + SceneJS.ColorTarget = SceneJS_NodeFactory.createNodeType("colorTarget"); - SceneJS.Framebuf.prototype._init = function () { + SceneJS.ColorTarget.prototype._init = function (params) { nodeCoreMap[this._core.coreId] = this; - this._buildNodeCore(); + this._core.bufType = "color"; + this._core.renderBuf = new SceneJS._webgl.RenderBuffer({ canvas: this._engine.canvas }); + }; + + SceneJS.ColorTarget.prototype._compile = function (ctx) { + if (!this.__core) { + this.__core = this._engine._coreFactory.getCore("renderTarget"); + } + var parentCore = this._engine.display.renderTarget; + if (!this._core.empty) { + this.__core.targets = (parentCore && parentCore.targets) ? parentCore.targets.concat([this._core]) : [this._core]; + } + coreStack[stackLen++] = this.__core; + this._engine.display.renderTarget = this.__core; + this._compileNodes(ctx); + this._engine.display.renderTarget = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; }; - SceneJS.Framebuf.prototype._buildNodeCore = function () { - if (!this._core) { - this._core = {}; + + SceneJS.ColorTarget.prototype._destroy = function () { + if (this._core) { + delete nodeCoreMap[this._core.coreId]; } - this._core.framebuf = new SceneJS._webgl.RenderBuffer({ canvas: this._engine.canvas }); + }; +})();new (function () { + + var defaultCore = { + type: "renderTarget", + stateId: SceneJS._baseStateId++, + targets: null + }; + + // Map of nodes to cores, for reallocation on WebGL context restore + var nodeCoreMap = {}; + + var coreStack = []; + var stackLen = 0; + + SceneJS_events.addListener( + SceneJS_events.SCENE_COMPILING, + function (params) { + params.engine.display.renderTarget = defaultCore; + stackLen = 0; + }); + + // Reallocate VBOs when context restored after loss + SceneJS_events.addListener( + SceneJS_events.WEBGL_CONTEXT_RESTORED, + function () { + for (var nodeId in nodeCoreMap) { + if (nodeCoreMap.hasOwnProperty(nodeId)) { + nodeCoreMap[nodeId]._buildNodeCore(); + } + } + }); + + SceneJS.DepthTarget = SceneJS_NodeFactory.createNodeType("depthTarget"); + + SceneJS.DepthTarget.prototype._init = function (params) { + nodeCoreMap[this._core.coreId] = this; + this._core.bufType = "depth"; + this._core.renderBuf = new SceneJS._webgl.RenderBuffer({ canvas: this._engine.canvas }); }; - SceneJS.Framebuf.prototype._compile = function (ctx) { - this._engine.display.framebuf = coreStack[stackLen++] = this._core; + SceneJS.DepthTarget.prototype._compile = function (ctx) { + if (!this.__core) { + this.__core = this._engine._coreFactory.getCore("renderTarget"); + } + var parentCore = this._engine.display.renderTarget; + if (!this._core.empty) { + this.__core.targets = (parentCore && parentCore.targets) ? parentCore.targets.concat([this._core]) : [this._core]; + } + coreStack[stackLen++] = this.__core; + this._engine.display.renderTarget = this.__core; this._compileNodes(ctx); - this._engine.display.framebuf = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; + this._engine.display.renderTarget = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; }; - SceneJS.Framebuf.prototype._destroy = function () { + + SceneJS.DepthTarget.prototype._destroy = function () { if (this._core) { delete nodeCoreMap[this._core.coreId]; } @@ -8283,10 +8429,12 @@ new (function () { autoNormals: params.normals == "auto" }); - SceneJS.Geometry._buildNodeCore(this._engine.canvas.gl, this._core); + this._buildNodeCore(this._engine.canvas.gl, this._core); + + var self = this; this._core.webglRestored = function () { - SceneJS.Geometry._buildNodeCore(self._engine.canvas.gl, self._core); + self._buildNodeCore(self._engine.canvas.gl, self._core); }; } @@ -8454,20 +8602,20 @@ new (function () { * In addition to initially allocating those, this is called to reallocate them after * WebGL context is regained after being lost. */ - SceneJS.Geometry._buildNodeCore = function (gl, core) { + SceneJS.Geometry.prototype._buildNodeCore = function (gl, core) { var usage = gl.STATIC_DRAW; //var usage = (!arrays.fixed) ? gl.STREAM_DRAW : gl.STATIC_DRAW; try { // TODO: Modify usage flags in accordance with how often geometry is evicted var arrays = core.arrays; - var canInterleave = true; + var canInterleave = (SceneJS.getConfigs("enableInterleaving") !== false); var dataLength = 0; var interleavedValues = 0; var interleavedArrays = []; var interleavedArrayStrides = []; - var prepareInterleaveBuffer = function (array, strideInElements) { + var prepareInterleaveBuffer = function(array, strideInElements) { if (dataLength == 0) { dataLength = array.length / strideInElements; } else if (array.length / strideInElements != dataLength) { @@ -8480,27 +8628,37 @@ new (function () { }; if (arrays.positions) { - core.interleavedPositionOffset = prepareInterleaveBuffer(arrays.positions, 3); + if (canInterleave) { + core.interleavedPositionOffset = prepareInterleaveBuffer(arrays.positions, 3); + } core.vertexBuf = new SceneJS._webgl.ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.positions, arrays.positions.length, 3, usage); } if (arrays.normals) { - core.interleavedNormalOffset = prepareInterleaveBuffer(arrays.normals, 3); + if (canInterleave) { + core.interleavedNormalOffset = prepareInterleaveBuffer(arrays.normals, 3); + } core.normalBuf = new SceneJS._webgl.ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.normals, arrays.normals.length, 3, usage); } if (arrays.uv) { - core.interleavedUVOffset = prepareInterleaveBuffer(arrays.uv, 2); + if (canInterleave) { + core.interleavedUVOffset = prepareInterleaveBuffer(arrays.uv, 2); + } core.uvBuf = new SceneJS._webgl.ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.uv, arrays.uv.length, 2, usage); } if (arrays.uv2) { - core.interleavedUV2Offset = prepareInterleaveBuffer(arrays.uv2, 2); + if (canInterleave) { + core.interleavedUV2Offset = prepareInterleaveBuffer(arrays.uv2, 2); + } core.uvBuf2 = new SceneJS._webgl.ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.uv2, arrays.uv2.length, 2, usage); } if (arrays.colors) { - core.interleavedColorOffset = prepareInterleaveBuffer(arrays.colors, 4); + if (canInterleave) { + core.interleavedColorOffset = prepareInterleaveBuffer(arrays.colors, 4); + } core.colorBuf = new SceneJS._webgl.ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.colors, arrays.colors.length, 4, usage); } @@ -8713,6 +8871,10 @@ new (function () { return this.primitive; }; + /** Returns the Model-space boundary of this geometry + * + * @returns {*} + */ SceneJS.Geometry.prototype.getBoundary = function () { if (this._boundary) { return this._boundary; @@ -8886,17 +9048,17 @@ new (function () { } }; -}) - (); +})(); (function() { /** - * The default state core singleton for {@link SceneJS.Layer} nodes + * The default state core singleton for {@link SceneJS.Stage} nodes */ var defaultCore = { - type: "layer", + type: "stage", stateId: SceneJS._baseStateId++, priority: 0, + pickable: true, enabled: true }; @@ -8906,24 +9068,96 @@ new (function () { SceneJS_events.addListener( SceneJS_events.SCENE_COMPILING, function(params) { - params.engine.display.layer = defaultCore; + params.engine.display.stage = defaultCore; stackLen = 0; }); + /** + * @class Scene graph node which assigns the {@link SceneJS.Geometry}s within its subgraph to a prioritised render bin + * @extends SceneJS.Node + */ + SceneJS.Stage = SceneJS_NodeFactory.createNodeType("stage"); + + SceneJS.Stage.prototype._init = function(params) { + if (this._core.useCount == 1) { // This node defines the resource + this._core.priority = params.priority || 0; + this._core.enabled = params.enabled !== false; + this._core.pickable = !!params.pickable; + } + }; + + SceneJS.Stage.prototype.setPriority = function(priority) { + priority = priority || 0; + if (this._core.priority != priority) { + this._core.priority = priority; + this._engine.display.stateOrderDirty = true; + } + }; + + SceneJS.Stage.prototype.getPriority = function() { + return this._core.priority; + }; + + SceneJS.Stage.prototype.setEnabled = function(enabled) { + enabled = !!enabled; + if (this._core.enabled != enabled) { + this._core.enabled = enabled; + this._engine.display.drawListDirty = true; + } + }; + + SceneJS.Stage.prototype.getEnabled = function() { + return this._core.enabled; + }; + + SceneJS.Stage.prototype.getEnabled = function() { + return this._core.enabled; + }; + + SceneJS.Stage.prototype._compile = function(ctx) { + this._engine.display.stage = coreStack[stackLen++] = this._core; + this._compileNodes(ctx); + this._engine.display.stage = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; + }; + +})(); + +(function () { + + /** + * The default state core singleton for {@link SceneJS.Layer} nodes + */ + var defaultCore = { + type: "layer", + stateId: SceneJS._baseStateId++, + priority: 0, + enabled: true + }; + + var coreStack = []; + var stackLen = 0; + + SceneJS_events.addListener( + SceneJS_events.SCENE_COMPILING, + function (params) { + params.engine.display.layer = defaultCore; + stackLen = 0; + }); + /** * @class Scene graph node which assigns the {@link SceneJS.Geometry}s within its subgraph to a prioritised render bin * @extends SceneJS.Node */ SceneJS.Layer = SceneJS_NodeFactory.createNodeType("layer"); - SceneJS.Layer.prototype._init = function(params) { + SceneJS.Layer.prototype._init = function (params) { if (this._core.useCount == 1) { // This node defines the resource this._core.priority = params.priority || 0; this._core.enabled = params.enabled !== false; } }; - SceneJS.Layer.prototype.setPriority = function(priority) { + SceneJS.Layer.prototype.setPriority = function (priority) { priority = priority || 0; if (this._core.priority != priority) { this._core.priority = priority; @@ -8931,11 +9165,11 @@ new (function () { } }; - SceneJS.Layer.prototype.getPriority = function() { + SceneJS.Layer.prototype.getPriority = function () { return this._core.priority; }; - SceneJS.Layer.prototype.setEnabled = function(enabled) { + SceneJS.Layer.prototype.setEnabled = function (enabled) { enabled = !!enabled; if (this._core.enabled != enabled) { this._core.enabled = enabled; @@ -8943,15 +9177,15 @@ new (function () { } }; - SceneJS.Layer.prototype.getEnabled = function() { + SceneJS.Layer.prototype.getEnabled = function () { return this._core.enabled; }; - SceneJS.Layer.prototype.getEnabled = function() { + SceneJS.Layer.prototype.getEnabled = function () { return this._core.enabled; }; - SceneJS.Layer.prototype.setClearDepth = function(clearDepth) { + SceneJS.Layer.prototype.setClearDepth = function (clearDepth) { clearDepth = clearDepth || 0; if (this._core.clearDepth != clearDepth) { this._core.clearDepth = clearDepth; @@ -8959,7 +9193,7 @@ new (function () { } }; - SceneJS.Layer.prototype.getClearDepth = function() { + SceneJS.Layer.prototype.getClearDepth = function () { return this._core.clearDepth; }; @@ -10230,7 +10464,7 @@ new (function () { SceneJS.Name.prototype.setName = function (name) { this._core.name = name || "unnamed"; - this._engine.display.imageDirty = true; + this._engine.branchDirty(this); // Need to recompile name path }; SceneJS.Name.prototype.getName = function () { @@ -10255,7 +10489,7 @@ new (function () { this._compileNodes(ctx); this._engine.display.name = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; }; -})();new (function() { +})();new (function () { /** * The default state core singleton for {@link SceneJS.Renderer} nodes @@ -10271,10 +10505,10 @@ new (function () { var stackLen = 0; SceneJS_events.addListener( - SceneJS_events.SCENE_COMPILING, - function(params) { + SceneJS_events.SCENE_COMPILING, + function (params) { - canvas = params.engine.canvas; + canvas = params.engine.canvas; // // TODO: Below is a HACK // @@ -10309,10 +10543,10 @@ new (function () { // } // }); - stackLen = 0; + stackLen = 0; - params.engine.display.renderer = coreStack[stackLen++] = defaultCore; - }); + params.engine.display.renderer = coreStack[stackLen++] = defaultCore; + }); function createProps(props) { @@ -10334,11 +10568,11 @@ new (function () { props: props, - setProps: function(gl) { + setProps: function (gl) { setProperties(gl, props); }, - restoreProps : function(gl) { + restoreProps: function (gl) { if (restore) { restoreProperties(gl, restore); } @@ -10346,14 +10580,16 @@ new (function () { }; } - var getSuperProperty = function(name) { + var getSuperProperty = function (name) { var props; var prop; for (var i = stackLen - 1; i >= 0; i--) { props = coreStack[i].props; - prop = props[name]; - if (prop != undefined && prop != null) { - return props[name]; + if (props) { + prop = props[name]; + if (prop != undefined && prop != null) { + return props[name]; + } } } return null; // Cause default to be set @@ -10375,7 +10611,7 @@ new (function () { } } - var setProperties = function(gl, props) { + var setProperties = function (gl, props) { for (var key in props) { // Set order-insensitive properties (modes) if (props.hasOwnProperty(key)) { @@ -10403,7 +10639,7 @@ new (function () { * Restores previous renderer properties, except for clear - that's the reason we * have a seperate set and restore semantic - we don't want to keep clearing the buffer. */ - var restoreProperties = function(gl, props) { + var restoreProperties = function (gl, props) { var value; @@ -10433,23 +10669,23 @@ new (function () { * Maps renderer node properties to WebGL gl enums * @private */ - var glEnum = function(gl, name) { + var glEnum = function (gl, name) { if (!name) { throw SceneJS_error.fatalError( - SceneJS.errors.ILLEGAL_NODE_CONFIG, - "Null SceneJS.State node config: \"" + name + "\""); + SceneJS.errors.ILLEGAL_NODE_CONFIG, + "Null SceneJS.State node config: \"" + name + "\""); } var result = SceneJS._webgl.enumMap[name]; if (!result) { throw SceneJS_error.fatalError( - SceneJS.errors.ILLEGAL_NODE_CONFIG, - "Unrecognised SceneJS.State node config value: \"" + name + "\""); + SceneJS.errors.ILLEGAL_NODE_CONFIG, + "Unrecognised SceneJS.State node config value: \"" + name + "\""); } var value = gl[result]; if (!value) { throw SceneJS_error.fatalError( - SceneJS.errors.ILLEGAL_NODE_CONFIG, - "This browser's WebGL does not support renderer node config value: \"" + name + "\""); + SceneJS.errors.ILLEGAL_NODE_CONFIG, + "This browser's WebGL does not support renderer node config value: \"" + name + "\""); } return value; }; @@ -10474,7 +10710,7 @@ new (function () { */ var glModeSetters = { - enableBlend: function(gl, flag) { + enableBlend: function (gl, flag) { if (!gl) { if (flag == null || flag == undefined) { flag = false; @@ -10488,7 +10724,7 @@ new (function () { } }, - blendColor: function(gl, color) { + blendColor: function (gl, color) { if (!gl) { color = color || {}; return { @@ -10501,7 +10737,7 @@ new (function () { gl.blendColor(color.r, color.g, color.b, color.a); }, - blendEquation: function(gl, eqn) { + blendEquation: function (gl, eqn) { if (!gl) { return eqn || "funcAdd"; } @@ -10510,87 +10746,87 @@ new (function () { /** Sets the RGB blend equation and the alpha blend equation separately */ - blendEquationSeparate: function(gl, eqn) { + blendEquationSeparate: function (gl, eqn) { if (!gl) { eqn = eqn || {}; return { - rgb : eqn.rgb || "funcAdd", - alpha : eqn.alpha || "funcAdd" + rgb: eqn.rgb || "funcAdd", + alpha: eqn.alpha || "funcAdd" }; } gl.blendEquation(glEnum(gl, eqn.rgb), glEnum(gl, eqn.alpha)); }, - blendFunc: function(gl, funcs) { + blendFunc: function (gl, funcs) { if (!gl) { funcs = funcs || {}; return { - sfactor : funcs.sfactor || "srcAlpha", - dfactor : funcs.dfactor || "oneMinusSrcAlpha" + sfactor: funcs.sfactor || "srcAlpha", + dfactor: funcs.dfactor || "oneMinusSrcAlpha" }; } gl.blendFunc(glEnum(gl, funcs.sfactor || "srcAlpha"), glEnum(gl, funcs.dfactor || "oneMinusSrcAlpha")); }, - blendFuncSeparate: function(gl, func) { + blendFuncSeparate: function (gl, func) { if (!gl) { func = func || {}; return { - srcRGB : func.srcRGB || "zero", - dstRGB : func.dstRGB || "zero", - srcAlpha : func.srcAlpha || "zero", - dstAlpha : func.dstAlpha || "zero" + srcRGB: func.srcRGB || "zero", + dstRGB: func.dstRGB || "zero", + srcAlpha: func.srcAlpha || "zero", + dstAlpha: func.dstAlpha || "zero" }; } gl.blendFuncSeparate( - glEnum(gl, func.srcRGB || "zero"), - glEnum(gl, func.dstRGB || "zero"), - glEnum(gl, func.srcAlpha || "zero"), - glEnum(gl, func.dstAlpha || "zero")); + glEnum(gl, func.srcRGB || "zero"), + glEnum(gl, func.dstRGB || "zero"), + glEnum(gl, func.srcAlpha || "zero"), + glEnum(gl, func.dstAlpha || "zero")); }, - clearColor: function(gl, color) { + clearColor: function (gl, color) { if (!gl) { color = color || {}; return { - r : color.r || 0, - g : color.g || 0, - b : color.b || 0, - a : (color.a == undefined || color.a == null) ? 1 : color.a + r: color.r || 0, + g: color.g || 0, + b: color.b || 0, + a: (color.a == undefined || color.a == null) ? 1 : color.a }; } gl.clearColor(color.r, color.g, color.b, color.a); }, - clearDepth: function(gl, depth) { + clearDepth: function (gl, depth) { if (!gl) { return (depth == null || depth == undefined) ? 1 : depth; } gl.clearDepth(depth); }, - clearStencil: function(gl, clearValue) { + clearStencil: function (gl, clearValue) { if (!gl) { return clearValue || 0; } gl.clearStencil(clearValue); }, - colorMask: function(gl, color) { + colorMask: function (gl, color) { if (!gl) { color = color || {}; return { - r : color.r || 0, - g : color.g || 0, - b : color.b || 0, - a : (color.a == undefined || color.a == null) ? 1 : color.a + r: color.r || 0, + g: color.g || 0, + b: color.b || 0, + a: (color.a == undefined || color.a == null) ? 1 : color.a }; } gl.colorMask(color.r, color.g, color.b, color.a); }, - enableCullFace: function(gl, flag) { + enableCullFace: function (gl, flag) { if (!gl) { return flag; } @@ -10601,14 +10837,14 @@ new (function () { } }, - cullFace: function(gl, mode) { + cullFace: function (gl, mode) { if (!gl) { return mode || "back"; } gl.cullFace(glEnum(gl, mode)); }, - enableDepthTest: function(gl, flag) { + enableDepthTest: function (gl, flag) { if (!gl) { if (flag == null || flag == undefined) { flag = true; @@ -10622,14 +10858,14 @@ new (function () { } }, - depthFunc: function(gl, func) { + depthFunc: function (gl, func) { if (!gl) { return func || "less"; } gl.depthFunc(glEnum(gl, func)); }, - enableDepthMask: function(gl, flag) { + enableDepthMask: function (gl, flag) { if (!gl) { if (flag == null || flag == undefined) { flag = true; @@ -10639,32 +10875,32 @@ new (function () { gl.depthMask(flag); }, - depthRange: function(gl, range) { + depthRange: function (gl, range) { if (!gl) { range = range || {}; return { - zNear : (range.zNear == undefined || range.zNear == null) ? 0 : range.zNear, - zFar : (range.zFar == undefined || range.zFar == null) ? 1 : range.zFar + zNear: (range.zNear == undefined || range.zNear == null) ? 0 : range.zNear, + zFar: (range.zFar == undefined || range.zFar == null) ? 1 : range.zFar }; } gl.depthRange(range.zNear, range.zFar); - } , + }, - frontFace: function(gl, mode) { + frontFace: function (gl, mode) { if (!gl) { return mode || "ccw"; } gl.frontFace(glEnum(gl, mode)); }, - lineWidth: function(gl, width) { + lineWidth: function (gl, width) { if (!gl) { return width || 1; } gl.lineWidth(width); }, - enableScissorTest: function(gl, flag) { + enableScissorTest: function (gl, flag) { if (!gl) { return flag; } @@ -10693,12 +10929,12 @@ new (function () { /** Set viewport on the given gl */ - viewport: function(gl, v) { + viewport: function (gl, v) { if (!gl) { v = v || {}; return { - x : v.x || 1, - y : v.y || 1, + x: v.x || 1, + y: v.y || 1, width: v.width || canvas.canvas.width, height: v.height || canvas.canvas.height }; @@ -10708,12 +10944,12 @@ new (function () { /** Sets scissor region on the given gl */ - scissor: function(gl, s) { + scissor: function (gl, s) { if (!gl) { s = s || {}; return { - x : s.x || 0, - y : s.y || 0, + x: s.x || 0, + y: s.y || 0, width: s.width || 1.0, height: s.height || 1.0 }; @@ -10723,7 +10959,7 @@ new (function () { /** Clears buffers on the given gl as specified in mask */ - clear:function(gl, mask) { + clear: function (gl, mask) { if (!gl) { mask = mask || {}; return mask; @@ -10739,14 +10975,14 @@ new (function () { m = m | gl.STENCIL_BUFFER_BIT; } if (m) { - // gl.clear(m); + // gl.clear(m); } } }; SceneJS.Renderer = SceneJS_NodeFactory.createNodeType("renderer"); - SceneJS.Renderer.prototype._init = function(params) { + SceneJS.Renderer.prototype._init = function (params) { if (this._core.useCount == 1) { // This node defines the resource for (var key in params) { if (params.hasOwnProperty(key)) { @@ -10757,282 +10993,289 @@ new (function () { } }; - SceneJS.Renderer.prototype.setViewport = function(viewport) { + SceneJS.Renderer.prototype.setViewport = function (viewport) { this._core.viewport = viewport ? { - x : viewport.x || 1, - y : viewport.y || 1, + x: viewport.x || 1, + y: viewport.y || 1, width: viewport.width || 1000, height: viewport.height || 1000 } : undefined; this._core.dirty = true; + this._engine.display.imageDirty = true; }; - SceneJS.Renderer.prototype.getViewport = function() { + SceneJS.Renderer.prototype.getViewport = function () { return this._core.viewport ? { - x : this._core.viewport.x, - y : this._core.viewport.y, + x: this._core.viewport.x, + y: this._core.viewport.y, width: this._core.viewport.width, height: this._core.viewport.height } : undefined; }; - SceneJS.Renderer.prototype.setScissor = function(scissor) { + SceneJS.Renderer.prototype.setScissor = function (scissor) { this._core.scissor = scissor ? { - x : scissor.x || 1, - y : scissor.y || 1, + x: scissor.x || 1, + y: scissor.y || 1, width: scissor.width || 1000, height: scissor.height || 1000 } : undefined; this._core.dirty = true; + this._engine.display.imageDirty = true; }; - SceneJS.Renderer.prototype.getScissor = function() { + SceneJS.Renderer.prototype.getScissor = function () { return this._core.scissor ? { - x : this._core.scissor.x, - y : this._core.scissor.y, + x: this._core.scissor.x, + y: this._core.scissor.y, width: this._core.scissor.width, height: this._core.scissor.height } : undefined; }; - SceneJS.Renderer.prototype.setClear = function(clear) { + SceneJS.Renderer.prototype.setClear = function (clear) { this._core.clear = clear ? { - r : clear.r || 0, - g : clear.g || 0, - b : clear.b || 0 + r: clear.r || 0, + g: clear.g || 0, + b: clear.b || 0 } : undefined; this._core.dirty = true; + this._engine.display.imageDirty = true; }; - SceneJS.Renderer.prototype.getClear = function() { + SceneJS.Renderer.prototype.getClear = function () { return this._core.clear ? { - r : this._core.clear.r, - g : this._core.clear.g, - b : this._core.clear.b + r: this._core.clear.r, + g: this._core.clear.g, + b: this._core.clear.b } : null; }; - SceneJS.Renderer.prototype.setEnableBlend = function(enableBlend) { + SceneJS.Renderer.prototype.setEnableBlend = function (enableBlend) { this._core.enableBlend = enableBlend; this._core.dirty = true; + this._engine.display.imageDirty = true; }; - SceneJS.Renderer.prototype.getEnableBlend = function() { + SceneJS.Renderer.prototype.getEnableBlend = function () { return this._core.enableBlend; }; - SceneJS.Renderer.prototype.setBlendColor = function(color) { + SceneJS.Renderer.prototype.setBlendColor = function (color) { this._core.blendColor = color ? { - r : color.r || 0, - g : color.g || 0, - b : color.b || 0, - a : (color.a == undefined || color.a == null) ? 1 : color.a + r: color.r || 0, + g: color.g || 0, + b: color.b || 0, + a: (color.a == undefined || color.a == null) ? 1 : color.a } : undefined; this._core.dirty = true; + this._engine.display.imageDirty = true; }; - SceneJS.Renderer.prototype.getBlendColor = function() { + SceneJS.Renderer.prototype.getBlendColor = function () { return this._core.blendColor ? { - r : this._core.blendColor.r, - g : this._core.blendColor.g, - b : this._core.blendColor.b, - a : this._core.blendColor.a + r: this._core.blendColor.r, + g: this._core.blendColor.g, + b: this._core.blendColor.b, + a: this._core.blendColor.a } : undefined; }; - SceneJS.Renderer.prototype.setBlendEquation = function(eqn) { + SceneJS.Renderer.prototype.setBlendEquation = function (eqn) { this._core.blendEquation = eqn; this._core.dirty = true; + this._engine.display.imageDirty = true; }; - SceneJS.Renderer.prototype.getBlendEquation = function() { + SceneJS.Renderer.prototype.getBlendEquation = function () { return this._core.blendEquation; }; - SceneJS.Renderer.prototype.setBlendEquationSeparate = function(eqn) { + SceneJS.Renderer.prototype.setBlendEquationSeparate = function (eqn) { this._core.blendEquationSeparate = eqn ? { - rgb : eqn.rgb || "funcAdd", - alpha : eqn.alpha || "funcAdd" + rgb: eqn.rgb || "funcAdd", + alpha: eqn.alpha || "funcAdd" } : undefined; this._core.dirty = true; + this._engine.display.imageDirty = true; }; - SceneJS.Renderer.prototype.getBlendEquationSeparate = function() { + SceneJS.Renderer.prototype.getBlendEquationSeparate = function () { return this._core.blendEquationSeparate ? { - rgb : this._core.rgb, - alpha : this._core.alpha + rgb: this._core.rgb, + alpha: this._core.alpha } : undefined; + this._engine.display.imageDirty = true; }; - SceneJS.Renderer.prototype.setBlendFunc = function(funcs) { + SceneJS.Renderer.prototype.setBlendFunc = function (funcs) { this._core.blendFunc = funcs ? { - sfactor : funcs.sfactor || "srcAlpha", - dfactor : funcs.dfactor || "one" + sfactor: funcs.sfactor || "srcAlpha", + dfactor: funcs.dfactor || "one" } : undefined; this._core.dirty = true; + this._engine.display.imageDirty = true; }; - SceneJS.Renderer.prototype.getBlendFunc = function() { + SceneJS.Renderer.prototype.getBlendFunc = function () { return this._core.blendFunc ? { - sfactor : this._core.sfactor, - dfactor : this._core.dfactor + sfactor: this._core.sfactor, + dfactor: this._core.dfactor } : undefined; }; - SceneJS.Renderer.prototype.setBlendFuncSeparate = function(eqn) { + SceneJS.Renderer.prototype.setBlendFuncSeparate = function (eqn) { this._core.blendFuncSeparate = eqn ? { - srcRGB : eqn.srcRGB || "zero", - dstRGB : eqn.dstRGB || "zero", - srcAlpha : eqn.srcAlpha || "zero", - dstAlpha : eqn.dstAlpha || "zero" + srcRGB: eqn.srcRGB || "zero", + dstRGB: eqn.dstRGB || "zero", + srcAlpha: eqn.srcAlpha || "zero", + dstAlpha: eqn.dstAlpha || "zero" } : undefined; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getBlendFuncSeparate = function() { + SceneJS.Renderer.prototype.getBlendFuncSeparate = function () { return this._core.blendFuncSeparate ? { - srcRGB : this._core.blendFuncSeparate.srcRGB, - dstRGB : this._core.blendFuncSeparate.dstRGB, - srcAlpha : this._core.blendFuncSeparate.srcAlpha, - dstAlpha : this._core.blendFuncSeparate.dstAlpha + srcRGB: this._core.blendFuncSeparate.srcRGB, + dstRGB: this._core.blendFuncSeparate.dstRGB, + srcAlpha: this._core.blendFuncSeparate.srcAlpha, + dstAlpha: this._core.blendFuncSeparate.dstAlpha } : undefined; }; - SceneJS.Renderer.prototype.setEnableCullFace = function(enableCullFace) { + SceneJS.Renderer.prototype.setEnableCullFace = function (enableCullFace) { this._core.enableCullFace = enableCullFace; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getEnableCullFace = function() { + SceneJS.Renderer.prototype.getEnableCullFace = function () { return this._core.enableCullFace; }; - SceneJS.Renderer.prototype.setCullFace = function(cullFace) { + SceneJS.Renderer.prototype.setCullFace = function (cullFace) { this._core.cullFace = cullFace; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getCullFace = function() { + SceneJS.Renderer.prototype.getCullFace = function () { return this._core.cullFace; }; - SceneJS.Renderer.prototype.setEnableDepthTest = function(enableDepthTest) { + SceneJS.Renderer.prototype.setEnableDepthTest = function (enableDepthTest) { this._core.enableDepthTest = enableDepthTest; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getEnableDepthTest = function() { + SceneJS.Renderer.prototype.getEnableDepthTest = function () { return this._core.enableDepthTest; }; - SceneJS.Renderer.prototype.setDepthFunc = function(depthFunc) { + SceneJS.Renderer.prototype.setDepthFunc = function (depthFunc) { this._core.depthFunc = depthFunc; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getDepthFunc = function() { + SceneJS.Renderer.prototype.getDepthFunc = function () { return this._core.depthFunc; }; - SceneJS.Renderer.prototype.setEnableDepthMask = function(enableDepthMask) { + SceneJS.Renderer.prototype.setEnableDepthMask = function (enableDepthMask) { this._core.enableDepthMask = enableDepthMask; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getEnableDepthMask = function() { + SceneJS.Renderer.prototype.getEnableDepthMask = function () { return this._core.enableDepthMask; }; - SceneJS.Renderer.prototype.setClearDepth = function(clearDepth) { + SceneJS.Renderer.prototype.setClearDepth = function (clearDepth) { this._core.clearDepth = clearDepth; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getClearDepth = function() { + SceneJS.Renderer.prototype.getClearDepth = function () { return this._core.clearDepth; }; - SceneJS.Renderer.prototype.setDepthRange = function(range) { + SceneJS.Renderer.prototype.setDepthRange = function (range) { this._core.depthRange = range ? { - zNear : (range.zNear == undefined || range.zNear == null) ? 0 : range.zNear, - zFar : (range.zFar == undefined || range.zFar == null) ? 1 : range.zFar + zNear: (range.zNear == undefined || range.zNear == null) ? 0 : range.zNear, + zFar: (range.zFar == undefined || range.zFar == null) ? 1 : range.zFar } : undefined; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getDepthRange = function() { + SceneJS.Renderer.prototype.getDepthRange = function () { return this._core.depthRange ? { - zNear : this._core.depthRange.zNear, - zFar : this._core.depthRange.zFar + zNear: this._core.depthRange.zNear, + zFar: this._core.depthRange.zFar } : undefined; }; - SceneJS.Renderer.prototype.setFrontFace = function(frontFace) { + SceneJS.Renderer.prototype.setFrontFace = function (frontFace) { this._core.frontFace = frontFace; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getFrontFace = function() { + SceneJS.Renderer.prototype.getFrontFace = function () { return this._core.frontFace; }; - SceneJS.Renderer.prototype.setLineWidth = function(lineWidth) { + SceneJS.Renderer.prototype.setLineWidth = function (lineWidth) { this._core.lineWidth = lineWidth; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getLineWidth = function() { + SceneJS.Renderer.prototype.getLineWidth = function () { return this._core.lineWidth; }; - SceneJS.Renderer.prototype.setEnableScissorTest = function(enableScissorTest) { + SceneJS.Renderer.prototype.setEnableScissorTest = function (enableScissorTest) { this._core.enableScissorTest = enableScissorTest; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getEnableScissorTest = function() { + SceneJS.Renderer.prototype.getEnableScissorTest = function () { return this._core.enableScissorTest; }; - SceneJS.Renderer.prototype.setClearStencil = function(clearStencil) { + SceneJS.Renderer.prototype.setClearStencil = function (clearStencil) { this._core.clearStencil = clearStencil; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getClearStencil = function() { + SceneJS.Renderer.prototype.getClearStencil = function () { return this._core.clearStencil; }; - SceneJS.Renderer.prototype.setColorMask = function(color) { + SceneJS.Renderer.prototype.setColorMask = function (color) { this._core.colorMask = color ? { - r : color.r || 0, - g : color.g || 0, - b : color.b || 0, - a : (color.a == undefined || color.a == null) ? 1 : color.a + r: color.r || 0, + g: color.g || 0, + b: color.b || 0, + a: (color.a == undefined || color.a == null) ? 1 : color.a } : undefined; this._core.dirty = true; }; - SceneJS.Renderer.prototype.getColorMask = function() { + SceneJS.Renderer.prototype.getColorMask = function () { return this._core.colorMask ? { - r : this._core.colorMask.r, - g : this._core.colorMask.g, - b : this._core.colorMask.b, - a : this._core.colorMask.a + r: this._core.colorMask.r, + g: this._core.colorMask.g, + b: this._core.colorMask.b, + a: this._core.colorMask.a } : undefined; }; - SceneJS.Renderer.prototype._compile = function(ctx) { - -// if (this._core.dirty) { -// this._core.props = createProps(this._core); -// this._core.dirty = false; -// } -// -// this._engine.display.renderer = coreStack[stackLen++] = this._core; + SceneJS.Renderer.prototype._compile = function (ctx) { + if (this._core.dirty) { + this._core.props = createProps(this._core); + this._core.dirty = false; + } + this._engine.display.renderer = coreStack[stackLen++] = this._core; this._compileNodes(ctx); - //this._engine.display.renderer = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; + this._engine.display.renderer = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; }; })();(function () { @@ -11047,7 +11290,7 @@ new (function () { // The default state core singleton for {@link SceneJS.DepthBuf} nodes var defaultCore = { - type:"depthbuf", + type:"depthBuffer", stateId:SceneJS._baseStateId++, enabled:true, clearDepth:1, @@ -11064,7 +11307,7 @@ new (function () { if (defaultCore.depthFunc === null) { // Lazy-init depthFunc now we can get a context defaultCore.depthFunc = params.engine.canvas.gl.LESS; } - params.engine.display.depthbuf = defaultCore; + params.engine.display.depthBuffer = defaultCore; stackLen = 0; }); @@ -11072,7 +11315,7 @@ new (function () { * @class Scene graph node which configures the depth buffer for its subgraph * @extends SceneJS.Node */ - SceneJS.DepthBuf = SceneJS_NodeFactory.createNodeType("depthbuf"); + SceneJS.DepthBuf = SceneJS_NodeFactory.createNodeType("depthBuffer"); SceneJS.DepthBuf.prototype._init = function (params) { @@ -11093,6 +11336,12 @@ new (function () { } else if (this._core.useCount == 1) { this.setDepthFunc("less"); } + + if (params.clear != undefined) { + this.setClear(params.clear); + } else if (this._core.useCount == 1) { + this.setClear(true); + } }; /** @@ -11118,6 +11367,29 @@ new (function () { return this._core.enabled; }; + /** + * Sets whether or not to clear the depth buffer before each render + * + * @param clear + * @return {*} + */ + SceneJS.DepthBuf.prototype.setClear = function (clear) { + if (this._core.clear != clear) { + this._core.clear = clear; + this._engine.display.imageDirty = true; + } + return this; + }; + + /** + * Get whether or not the depth buffer is cleared before each render + * + * @return Boolean + */ + SceneJS.DepthBuf.prototype.getClear = function () { + return this._core.clear; + }; + /** * Specify the clear value for the depth buffer. * Initial value is 1, and the given value will be clamped to [0..1]. @@ -11151,7 +11423,7 @@ new (function () { if (this._core._depthFuncName != depthFunc) { var enumName = lookup[depthFunc]; if (enumName == undefined) { - throw "unsupported value for 'clearFunc' attribute on depthbuf node: '" + depthFunc + throw "unsupported value for 'clearFunc' attribute on depthBuffer node: '" + depthFunc + "' - supported values are 'less', 'equal', 'lequal', 'greater', 'notequal' and 'gequal'"; } this._core.depthFunc = this._engine.canvas.gl[enumName]; @@ -11170,18 +11442,19 @@ new (function () { }; SceneJS.DepthBuf.prototype._compile = function (ctx) { - this._engine.display.depthbuf = coreStack[stackLen++] = this._core; + this._engine.display.depthBuffer = coreStack[stackLen++] = this._core; this._compileNodes(ctx); - this._engine.display.depthbuf = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; + this._engine.display.depthBuffer = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; }; })();(function () { - // The default state core singleton for {@link SceneJS.ColorBuf} nodes + // The default state core singleton for {@link SceneJS.ColorBuffer} nodes var defaultCore = { - type:"colorbuf", - stateId:SceneJS._baseStateId++, - blendEnabled:false + type: "colorBuffer", + stateId: SceneJS._baseStateId++, + blendEnabled: false, + colorMask: { r: true, g: true, b: true, a: true } }; var coreStack = []; @@ -11190,7 +11463,7 @@ new (function () { SceneJS_events.addListener( SceneJS_events.SCENE_COMPILING, function (params) { - params.engine.display.colorbuf = defaultCore; + params.engine.display.colorBuffer = defaultCore; stackLen = 0; }); @@ -11198,44 +11471,66 @@ new (function () { * @class Scene graph node which configures the color buffer for its subgraph * @extends SceneJS.Node */ - SceneJS.ColorBuf = SceneJS_NodeFactory.createNodeType("colorbuf"); - - SceneJS.ColorBuf.prototype._init = function (params) { + SceneJS.ColorBuffer = SceneJS_NodeFactory.createNodeType("colorBuffer"); + SceneJS.ColorBuffer.prototype._init = function (params) { if (params.blendEnabled != undefined) { this.setBlendEnabled(params.blendEnabled); } else if (this._core.useCount == 1) { // This node defines the core this.setBlendEnabled(false); } + this.setColorMask(params); }; /** * Enable or disable blending * * @param blendEnabled Specifies whether depth buffer is blendEnabled or not - * @return {*} */ - SceneJS.ColorBuf.prototype.setBlendEnabled = function (blendEnabled) { + SceneJS.ColorBuffer.prototype.setBlendEnabled = function (blendEnabled) { if (this._core.blendEnabled != blendEnabled) { this._core.blendEnabled = blendEnabled; this._engine.display.imageDirty = true; } - return this; + this._engine.display.imageDirty = true; }; /** * Get whether or not blending is enabled - * * @return Boolean */ - SceneJS.ColorBuf.prototype.getBlendEnabled = function () { + SceneJS.ColorBuffer.prototype.getBlendEnabled = function () { return this._core.blendEnabled; }; - SceneJS.ColorBuf.prototype._compile = function (ctx) { - this._engine.display.colorbuf = coreStack[stackLen++] = this._core; + /** + * Enable and disable writing of buffer's color components. + * Components default to true where not given. + * @param mask The mask + */ + SceneJS.ColorBuffer.prototype.setColorMask = function (mask) { + this._core.colorMask = { + r: mask.r != undefined && mask.r != null ? mask.r : true, + g: mask.g != undefined && mask.g != null ? mask.g : true, + b: mask.b != undefined && mask.b != null ? mask.b : true, + a: mask.a != undefined && mask.a != null ? mask.a : true + }; + this._engine.display.imageDirty = true; + }; + + /** + * Gets the color mask + * @return {{}} + */ + SceneJS.ColorBuffer.prototype.getColorMask = function () { + return this._core.colorMask; + }; + + SceneJS.ColorBuffer.prototype._compile = function (ctx) { + this._engine.display.colorBuffer = coreStack[stackLen++] = this._core; this._compileNodes(ctx); - this._engine.display.colorbuf = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; + this._engine.display.colorBuffer = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore; + this._engine.display.imageDirty = true; }; })();(function () { @@ -11362,9 +11657,7 @@ SceneJS.Scene.prototype.getGL = function () { /** Returns the Z-buffer depth in bits of the webgl context that this scene is to bound to. */ SceneJS.Scene.prototype.getZBufferDepth = function () { - var gl = this._engine.canvas.gl; - return gl.getParameter(gl.DEPTH_BITS); }; @@ -11375,16 +11668,12 @@ SceneJS.Scene.prototype.getZBufferDepth = function () { * @see SceneJS.Tag */ SceneJS.Scene.prototype.setTagMask = function (tagMask) { - tagMask = tagMask || "XXXXXXXXXXXXXXXXXXXXXXXXXX"; // HACK to select nothing by default - if (!this._tagSelector) { this._tagSelector = {}; } - this._tagSelector.mask = tagMask; this._tagSelector.regex = tagMask ? new RegExp(tagMask) : null; - this._engine.display.selectTags(this._tagSelector); }; @@ -11398,6 +11687,17 @@ SceneJS.Scene.prototype.getTagMask = function () { return this._tagSelector ? this._tagSelector.mask : null; }; +/** + * Sets the number of times this scene is drawn on each render. + *

This is useful for when we need to do things like render for left and right eyes. + * @param {Number} numPasses The number of times the scene is drawn on each frame. + * @see #getTagMask + * @see SceneJS.Tag + */ +SceneJS.Scene.prototype.setNumPasses = function (numPasses) { + this._engine.setNumPasses(numPasses); +}; + /** * Render a single frame if new frame pending, or force a new frame * Returns true if frame rendered @@ -11406,6 +11706,14 @@ SceneJS.Scene.prototype.renderFrame = function (params) { return this._engine.renderFrame(params); }; +/** + * Signals that a new frame will be needed + * @param params + */ +SceneJS.Scene.prototype.needFrame = function () { + this._engine.display.imageDirty = true; +}; + /** * Starts the render loop for this scene */ @@ -11434,7 +11742,7 @@ SceneJS.Scene.prototype.isRunning = function () { */ SceneJS.Scene.prototype.pick = function (canvasX, canvasY, options) { var result = this._engine.pick(canvasX, canvasY, options); - this.renderFrame({force:true }); // HACK: canvas blanks after picking + this.renderFrame({force: true }); // HACK: canvas blanks after picking if (result) { this.publish("pick", result); return result; @@ -11448,12 +11756,9 @@ SceneJS.Scene.prototype.pick = function (canvasX, canvasY, options) { * @private */ SceneJS.Scene.prototype._destroy = function () { - if (!this.destroyed) { - delete SceneJS._engines[this.id]; // HACK: circular dependency SceneJS._engineIds.removeItem(this.id); // HACK: circular dependency - this.destroyed = true; } }; @@ -11553,7 +11858,7 @@ SceneJS.Scene.prototype.getStatus = function () { var sceneStatus = SceneJS_sceneStatusModule.sceneStatus[this.id]; if (!sceneStatus) { return { - destroyed:true + destroyed: true }; } return SceneJS._shallowClone(sceneStatus); @@ -11607,11 +11912,11 @@ new (function() { shaders: { fragment: { - code: shaderFragmentCodeStack.slice(0, stackLen).join("\n"), + code: shaderFragmentCodeStack.slice(0, stackLen).join(""), hooks: combineMapStack(shaderFragmentHooksStack) }, vertex: { - code: shaderVertexCodeStack.slice(0, stackLen).join("\n"), + code: shaderVertexCodeStack.slice(0, stackLen).join(""), hooks: combineMapStack(shaderVertexHooksStack) } }, @@ -12028,11 +12333,11 @@ new (function () { layerParams = params.layers[i]; - if (!layerParams.source && !layerParams.uri && !layerParams.src && !layerParams.framebuf && !layerParams.video) { + if (!layerParams.source && !layerParams.uri && !layerParams.src && !layerParams.colorTarget && !layerParams.video) { throw SceneJS_error.fatalError( SceneJS.errors.NODE_CONFIG_EXPECTED, - "texture layer " + i + " has no uri, src, source, framebuf, video or canvasId specified"); + "texture layer " + i + " has no uri, src, source, colorTarget, video or canvasId specified"); } if (layerParams.applyFrom) { @@ -12063,11 +12368,11 @@ new (function () { } if (layerParams.blendMode) { - if (layerParams.blendMode != "add" && layerParams.blendMode != "multiply") { + if (layerParams.blendMode != "add" && layerParams.blendMode != "multiply" && layerParams.blendMode != "mix") { throw SceneJS_error.fatalError( SceneJS.errors.NODE_CONFIG_EXPECTED, "texture layer " + i + " blendMode value is unsupported - " + - "should be either 'add' or 'multiply'"); + "should be either 'add', 'multiply' or 'mix'"); } } @@ -12091,10 +12396,10 @@ new (function () { this._setLayerTransform(layerParams, layer); - if (layer.framebuf) { // Create from a framebuf node preceeding this texture in the scene graph - var targetNode = this._engine.findNode(layer.framebuf); - if (targetNode && targetNode.type == "framebuf") { - layer.texture = targetNode._core.framebuf.getTexture(); // TODO: what happens when the framebuf is destroyed? + if (layer.colorTarget) { // Create from a colorTarget node preceeding this texture in the scene graph + var targetNode = this._engine.findNode(layer.colorTarget); + if (targetNode && targetNode.type == "colorTarget") { + layer.texture = targetNode._core.colorTarget.getTexture(); // TODO: what happens when the colorTarget is destroyed? } } else { // Create from texture node's layer configs this._loadLayerTexture(gl, layer); @@ -12556,10 +12861,10 @@ new (function () { this._core.image = params.image; this._initTexture(params.image); - } else if (params.framebuf) { // Render to this texture - this.getScene().getNode(params.framebuf, - function (framebuf) { - self.setFramebuf(framebuf); + } else if (params.target) { // Render to this texture + this.getScene().getNode(params.target, + function (target) { + self.setTarget(target); }); } @@ -12570,12 +12875,11 @@ new (function () { } else if (self._core.image) { self._initTexture(self._core.image); - } else if (self._core.framebuf) { - self.getScene().getNode(params.framebuf, - function (framebuf) { - self.setFramebuf(framebuf); - }); - self.setFramebuf(self._core.framebuf); + } else if (self._core.target) { +// self.getScene().getNode(params.target, +// function (target) { +// self.setTarget(self._core.target); +// }); } }; } @@ -12707,27 +13011,28 @@ new (function () { SceneJS.TextureMap.prototype.setSrc = function (src) { this._core.image = null; this._core.src = src; - this._core.framebuf = null; + this._core.target = null; this._loadTexture(src); }; SceneJS.TextureMap.prototype.setImage = function (image) { this._core.image = image; this._core.src = null; - this._core.framebuf = null; + this._core.target = null; this._initTexture(image); }; - SceneJS.TextureMap.prototype.setFramebuf = function (framebuf) { - if (!framebuf.type == "framebuf") { - console.log("Not a 'framebuf' node - ignoring"); + SceneJS.TextureMap.prototype.setTarget = function (target) { + if (target.type != "colorTarget" && target.type != "depthTarget") { + console.log("Target node type not compatible: " + target.type); return; } delete this._core.src; - this._core.framebuf = framebuf; + this._core.target = target; this._core.src = null; this._core.image = null; - this._core.texture = framebuf._core.framebuf.getTexture(); // TODO: what happens when the framebuf is destroyed? + this._core.texture = target._core.renderBuf.getTexture(); // TODO: what happens when the target is destroyed? + this._core.texture.bufType = target._core.bufType; this._engine.display.imageDirty = true; }; @@ -12833,13 +13138,13 @@ new (function () { SceneJS.TextureMap.prototype._destroy = function () { if (this._core.useCount == 1) { // Last core user - if (this._core.texture && !this._core.framebuf) { // Don't wipe out framebuf texture + if (this._core.texture && !this._core.target) { // Don't wipe out target texture this._core.texture.destroy(); this._core.texture = null; } } if (this._core) { - this._coreFactory.putCore(this._core); + this._engine._coreFactory.putCore(this._core); } }; @@ -12910,8 +13215,6 @@ new (function () { gl.bindTexture(gl.TEXTURE_CUBE_MAP, texture); gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, false); gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, ensureImageSizePowerOfTwo(image)); - //self._core.texture = texture; - //gl.texImage2D(face, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, ensureImageSizePowerOfTwo(image)); if (++numImagesLoaded == faces.length) { self._core.texture = new SceneJS._webgl.Texture2D(gl, { texture: texture, @@ -13900,11 +14203,11 @@ SceneJS.Types = new (function () { })(); /** - * @class Renders and picks a {@link SceneJS.Scene} + * @class Display compiled from a {@link SceneJS.Scene}, providing methods to render and pick. * @private * *

A Display is a container of {@link SceneJS_Object}s which are created (or updated) by a depth-first - * compilation traversal of the nodes within a {@link SceneJS.Scene}. + * compilation traversal of a {@link SceneJS.Scene}. * *

Rendering Pipeline

* @@ -13959,29 +14262,24 @@ SceneJS.Types = new (function () { * in the branch.

* *

Draw List

- *

The draw list is actually comprised of three lists of state chunks: a "pick" list to render a pick buffer - * for colour-indexed GPU picking, along with an "opaque" list and "transparent" list for normal image rendering. - * For normal rendering the opaque list is rendered, then blending is enabled and the transparent list is rendered. - * The chunks in these lists are held in the state-sorted order of their objects in #_objectList, with runs of - * duplicate states removed, as mentioned.

+ *

The draw list is actually comprised of two lists of state chunks: a "pick" list to render a pick buffer + * for colour-indexed GPU picking, along with a "draw" list for normal image rendering. The chunks in these lists + * are held in the state-sorted order of their objects in #_objectList, with runs of duplicate states removed.

* *

After a scene update, we set a flag on the display to indicate the stage we will need to redo from. The pipeline is * then lazy-redone on the next call to #render or #pick.

*/ var SceneJS_Display = function (cfg) { - /* Display is bound to the lifetime of an HTML5 canvas - */ + // Display is bound to the lifetime of an HTML5 canvas this._canvas = cfg.canvas; - /* Factory which creates and recycles {@link SceneJS_Program} instances - */ + // Factory which creates and recycles {@link SceneJS_Program} instances this._programFactory = new SceneJS_ProgramFactory({ canvas: cfg.canvas }); - /* Factory which creates and recycles {@link SceneJS.Chunk} instances - */ + // Factory which creates and recycles {@link SceneJS.Chunk} instances this._chunkFactory = new SceneJS_ChunkFactory(); /** @@ -14008,6 +14306,12 @@ var SceneJS_Display = function (cfg) { */ this.layer = null; + /** + * Node state core for the last {@link SceneJS.Stage} visited during scene graph compilation traversal + * @type Object + */ + this.stage = null; + /** * Node state core for the last {@link SceneJS.Renderer} visited during scene graph compilation traversal * @type Object @@ -14018,13 +14322,13 @@ var SceneJS_Display = function (cfg) { * Node state core for the last {@link SceneJS.DepthBuf} visited during scene graph compilation traversal * @type Object */ - this.depthbuf = null; + this.depthBuffer = null; /** * Node state core for the last {@link SceneJS.ColorBuf} visited during scene graph compilation traversal * @type Object */ - this.colorbuf = null; + this.colorBuffer = null; /** * Node state core for the last {@link SceneJS.View} visited during scene graph compilation traversal @@ -14075,10 +14379,10 @@ var SceneJS_Display = function (cfg) { this.projTransform = null; /** - * Node state core for the last {@link SceneJS.Framebuf} visited during scene graph compilation traversal + * Node state core for the last {@link SceneJS.ColorTarget} visited during scene graph compilation traversal * @type Object */ - this.framebuf = null; + this.renderTarget = null; /** * Node state core for the last {@link SceneJS.Clips} visited during scene graph compilation traversal @@ -14156,22 +14460,18 @@ var SceneJS_Display = function (cfg) { /* The "draw list", comprised collectively of three lists of state chunks belong to visible objects * within #_objectList: a "pick" list to render a pick buffer for colour-indexed GPU picking, along with an - * "opaque" list and "transparent" list for normal image rendering. For normal rendering the opaque list is - * rendered, then blending is enabled and the transparent list is rendered. The chunks in these lists - * are held in the state-sorted order of their objects in #_objectList, with runs of duplicate states removed. + * "draw" list for normal image rendering. The chunks in these lists are held in the state-sorted order of + * their objects in #_objectList, with runs of duplicate states removed. */ this._drawList = []; // State chunk list to render all objects this._drawListLen = 0; - this._opaqueDrawList = []; // State chunk list to render opaque objects - this._opaqueDrawListLen = 0; - - this._transparentDrawList = []; // State chunk list to render transparent objects - this._transparentDrawListLen = 0; - - this._pickDrawList = []; // State chunk list to render scene to pick buffer + this._pickDrawList = []; // State chunk list to render scene to pick buffer this._pickDrawListLen = 0; + this._targetList = []; + this._targetListLen = 0; + /* The frame context holds state shared across a single render of the draw list, along with any results of * the render, such as pick hits */ @@ -14242,21 +14542,15 @@ var SceneJS_Display = function (cfg) { * Reallocates WebGL resources for objects within this display */ SceneJS_Display.prototype.webglRestored = function () { - this._programFactory.webglRestored();// Reallocate programs - this._chunkFactory.webglRestored(); // Recache shader var locations - var gl = this._canvas.gl; - if (this.pickBuf) { this.pickBuf.webglRestored(gl); // Rebuild pick buffers } - if (this.rayPickBuf) { this.rayPickBuf.webglRestored(gl); } - this.imageDirty = true; // Need redraw }; @@ -14272,13 +14566,13 @@ SceneJS_Display.prototype.buildObject = function (objectId) { var object = this._objects[objectId]; if (!object) { // Create object - object = this._objects[objectId] = this._objectFactory.getObject(objectId); - this.objectListDirty = true; } + object.stage = this.stage; object.layer = this.layer; + object.renderTarget = this.renderTarget; object.texture = this.texture; object.cubemap = this.cubemap; object.geometry = this.geometry; @@ -14296,25 +14590,20 @@ SceneJS_Display.prototype.buildObject = function (objectId) { this.texture.hash, this.cubemap.hash, this.lights.hash - ]).join(";"); if (!object.program || hash != object.hash) { - - /* Get new program for object if no program or hash mismatch - */ - + // Get new program for object if no program or hash mismatch if (object.program) { this._programFactory.putProgram(object.program); } - object.program = this._programFactory.getProgram(hash, this); object.hash = hash; } //} - /* Build draw chunks for object - */ + // Build draw chunks for object + this._setChunk(object, 0, "program"); // Must be first this._setChunk(object, 1, "xform", this.modelTransform); this._setChunk(object, 2, "lookAt", this.viewTransform); @@ -14323,16 +14612,16 @@ SceneJS_Display.prototype.buildObject = function (objectId) { this._setChunk(object, 5, "shader", this.shader); this._setChunk(object, 6, "shaderParams", this.shaderParams); this._setChunk(object, 7, "style", this.style); - this._setChunk(object, 8, "depthbuf", this.depthbuf); - this._setChunk(object, 9, "colorbuf", this.colorbuf); + this._setChunk(object, 8, "depthBuffer", this.depthBuffer); + this._setChunk(object, 9, "colorBuffer", this.colorBuffer); this._setChunk(object, 10, "view", this.view); this._setChunk(object, 11, "name", this.name); this._setChunk(object, 12, "lights", this.lights); this._setChunk(object, 13, "material", this.material); this._setChunk(object, 14, "texture", this.texture); this._setChunk(object, 15, "cubemap", this.cubemap); - this._setChunk(object, 16, "framebuf", this.framebuf); - this._setChunk(object, 17, "clips", this.clips); + this._setChunk(object, 16, "clips", this.clips); + this._setChunk(object, 17, "renderer", this.renderer); this._setChunk(object, 18, "geometry", this.morphGeometry, this.geometry); this._setChunk(object, 19, "listeners", this.renderListeners); // Must be after the above chunks this._setChunk(object, 20, "draw", this.geometry); // Must be last @@ -14347,20 +14636,16 @@ SceneJS_Display.prototype._setChunk = function (object, order, chunkType, core, // Core supplied if (core.empty) { // Only set default cores for state types that have them - var oldChunk = object.chunks[order]; - if (oldChunk) { this._chunkFactory.putChunk(oldChunk); // Release previous chunk to pool } - object.chunks[order] = null; - return; } // Note that core.stateId can be either a number or a string, that's why we make - // chunkId a string here. String stateId can come from at least nodeEvents.js. + // chunkId a string here. // TODO: Would it be better if all were numbers? chunkId = chunkClass.prototype.programGlobal ? '_' + core.stateId @@ -14384,11 +14669,9 @@ SceneJS_Display.prototype._setChunk = function (object, order, chunkType, core, var oldChunk = object.chunks[order]; if (oldChunk) { - if (oldChunk.id == chunkId) { // Avoid needless chunk reattachment return; } - this._chunkFactory.putChunk(oldChunk); // Release previous chunk to pool } @@ -14421,22 +14704,15 @@ SceneJS_Display.prototype._setAmbient = function (core) { * @param {String} objectId ID of object to remove */ SceneJS_Display.prototype.removeObject = function (objectId) { - var object = this._objects[objectId]; - if (!object) { return; } - this._programFactory.putProgram(object.program); - object.program = null; object.hash = null; - this._objectFactory.putObject(object); - delete this._objects[objectId]; - this.objectListDirty = true; }; @@ -14450,46 +14726,42 @@ SceneJS_Display.prototype.selectTags = function (tagSelector) { /** * Render this display. What actually happens in the method depends on what flags are set. + * */ SceneJS_Display.prototype.render = function (params) { params = params || {}; if (this.objectListDirty) { - this._buildObjectList(); // Build object render bin - this.objectListDirty = false; this.stateOrderDirty = true; // Now needs state ordering } if (this.stateOrderDirty) { - this._makeStateSortKeys(); // Compute state sort order - this.stateOrderDirty = false; this.stateSortDirty = true; // Now needs state sorting } if (this.stateSortDirty) { - this._stateSort(); // State sort the object render bin - this.stateSortDirty = false; this.drawListDirty = true; // Now needs new visible object bin + //this._logObjectList(); } if (this.drawListDirty) { // Render visible list while building transparent list - this._buildDrawList(); - this.imageDirty = true; + //this._logDrawList(); + //this._logPickList(); } if (this.imageDirty || params.force) { - - this._render({}); // Render, no pick - + this._doDrawList({ // Render, no pick + clear: (params.clear !== false) // Clear buffers by default + }); this.imageDirty = false; this.pickBufDirty = true; // Pick buff will now need rendering on next pick } @@ -14504,31 +14776,36 @@ SceneJS_Display.prototype._buildObjectList = function () { } }; -SceneJS_Display.prototype._makeStateSortKeys = function () { // TODO: state sort for sound objects? +SceneJS_Display.prototype._makeStateSortKeys = function () { + // console.log("--------------------------------------------------------------------------------------------------"); + // console.log("SceneJS_Display_makeSortKeys"); var object; for (var i = 0, len = this._objectListLen; i < len; i++) { object = this._objectList[i]; - object.sortKey = object.program - ? (((object.layer.priority + 1) * 1000000) - + ((object.program.id + 1) * 1000) - + (object.texture.stateId)) - : -1; // Non-visual object (eg. sound) - } -}; - -//SceneJS_Display.prototype._makeStateSortKeys = function () { // TODO: state sort for sound objects? -// var object; -// for (var i = 0, len = this._objectListLen; i < len; i++) { -// object = this._objectList[i]; -// object.sortKey = object.program -// ? (((object.layer.priority + 1) * 1000000000) -// + ((object.program.id + 1) * 1000000) -// + (object.texture.stateId * 10000) -// + (object.geometry.stateId)) -// // + i // Force stability among same-priority objects across multiple sorts -// : -1; // Non-visual object (eg. sound) -// } -//}; + if (!object.program) { + // Non-visual object (eg. sound) + object.sortKey = -1; + } else { + +// console.log("object.stage.priority = " + ((object.stage.priority + 1) * 1000000000000)); +// console.log("object.flags.transparent = " + ((object.flags.transparent ? 2 : 1) * 1000000000)); +// console.log("object.layer.priority = " + ((object.layer.priority + 1) * 1000000)); +// console.log("object.program.id = " + ((object.program.id + 1) * 1000)); +// console.log("object.texture.stateId = " + object.texture.stateId); + + object.sortKey = + ((object.stage.priority + 1) * 1000000000000) + + ((object.flags.transparent ? 2 : 1) * 1000000000) + + ((object.layer.priority + 1) * 1000000) + + ((object.program.id + 1) * 1000) + + object.texture.stateId; + + //console.log("object.sortKey = " + object.sortKey); + // console.log(""); + } + } + // console.log("--------------------------------------------------------------------------------------------------"); +}; SceneJS_Display.prototype._stateSort = function () { this._objectList.length = this._objectListLen; @@ -14539,40 +14816,51 @@ SceneJS_Display.prototype._stateSortObjects = function (a, b) { return a.sortKey - b.sortKey; }; +SceneJS_Display.prototype._logObjectList = function () { + console.log("--------------------------------------------------------------------------------------------------"); + console.log(this._objectListLen + " objects"); + for (var i = 0, len = this._objectListLen; i < len; i++) { + var object = this._objectList[i]; + console.log("SceneJS_Display : object[" + i + "] sortKey = " + object.sortKey); + } + console.log("--------------------------------------------------------------------------------------------------"); +}; + SceneJS_Display.prototype._buildDrawList = function () { this._lastStateId = this._lastStateId || []; this._lastPickStateId = this._lastPickStateId || []; - for (var i = 0; i < 21; i++) { + for (var i = 0; i < 23; i++) { this._lastStateId[i] = null; this._lastPickStateId[i] = null; } this._drawListLen = 0; - this._opaqueDrawListLen = 0; this._pickDrawListLen = 0; - this._transparentDrawListLen = 0; + + // For each render target, a list of objects to render to that target + var targetObjectLists = {}; + + // A list of all the render target object lists + var targetListList = []; + + // List of all targets + var targetList = []; var object; var tagMask; var tagRegex; var tagCore; var flags; - var chunks; - var chunk; - var transparent; - var picking; if (this._tagSelector) { tagMask = this._tagSelector.mask; tagRegex = this._tagSelector.regex; } - if (!this._xpBuf) { - this._xpBuf = []; - } - this._xpBufLen = 0; + this._objectDrawList = this._objectDrawList || []; + this._objectDrawListLen = 0; for (var i = 0, len = this._objectListLen; i < len; i++) { @@ -14590,157 +14878,187 @@ SceneJS_Display.prototype._buildDrawList = function () { continue; } - if (!object.layer.enabled) { // Skip disabled layers + // Cull objects in disabled layers + if (!object.layer.enabled) { continue; } - if (tagMask) { // Skip unmatched tags. No tag matching in visible bin prevent this being done on every frame. - + // Cull objects with unmatched tags + if (tagMask) { tagCore = object.tag; - if (tagCore.tag) { - if (tagCore.mask != tagMask) { // Scene tag mask was updated since last render tagCore.mask = tagMask; tagCore.matches = tagRegex.test(tagCore.tag); } - if (!tagCore.matches) { continue; } } } - transparent = flags.transparent; + // Put objects with render targets into a bin for each target + if (object.renderTarget.targets) { + var targets = object.renderTarget.targets; + var target; + var coreId; + var list; + for (var j = 0, lenj = targets.length; j < lenj; j++) { + target = targets[j]; + coreId = target.coreId; + list = targetObjectLists[coreId]; + if (!list) { + list = []; + targetObjectLists[coreId] = list; + targetListList.push(list); + targetList.push(this._chunkFactory.getChunk(target.stateId, "renderTarget", object.program, target)); + } + list.push(object); + } + } else { - if (transparent) { - this._xpBuf[this._xpBufLen++] = object; + // + this._objectDrawList[this._objectDrawListLen++] = object; } + } - /* Add object's chunks to appropriate chunk list - */ - - chunks = object.chunks; - - picking = flags.picking; - - for (var j = 0, lenj = chunks.length; j < lenj; j++) { - - chunk = chunks[j]; + // Append chunks for objects within render targets first - if (chunk) { + var list; + var target; + var object; + var pickable; - // As we apply the state chunk lists we track the ID of most types of chunk in order - // to cull redundant re-applications of runs of the same chunk - except for those chunks with a - // 'unique' flag. We don't want to cull runs of draw chunks because they contain the GL - // drawElements calls which render the objects. + for (var i = 0, len = targetListList.length; i < len; i++) { - // Chunk IDs are only considered unique within the same program. Therefore, whenever we do a - // program switch, we'll be applying all the different types of chunk again. + list = targetListList[i]; + target = targetList[i]; - if (!transparent && chunk.draw) { - if (chunk.unique || this._lastStateId[j] != chunk.id) { - this._opaqueDrawList[this._opaqueDrawListLen++] = chunk; - this._drawList[this._drawListLen++] = chunk; - this._lastStateId[j] = chunk.id; - } - } + this._appendRenderTargetChunk(target); - if (chunk.pick) { // Transparent objects are pickable - if (picking) { // Don't pick unpickable objects - if (chunk.unique || this._lastPickStateId[j] != chunk.id) { - this._pickDrawList[this._pickDrawListLen++] = chunk; - this._lastPickStateId[j] = chunk.id; - } - } - } - } + for (var j = 0, lenj = list.length; j < lenj; j++) { + object = list[j]; + pickable = object.stage && object.stage.pickable; // We'll only pick objects in pickable stages + this._appendObjectToDrawLists(object, pickable); } } - if (this._xpBufLen > 0) { + if (object) { - for (var i = 0; i < this._lastStateId.length; i++) { - this._lastStateId[i] = null; - } + // Unbinds any render target bound previously + this._appendRenderTargetChunk(this._chunkFactory.getChunk(-1, "renderTarget", object.program, {})); + } - for (var i = 0; i < this._xpBufLen; i++) { + // Append chunks for objects not in render targets + for (var i = 0, len = this._objectDrawListLen; i < len; i++) { + object = this._objectDrawList[i]; + pickable = !object.stage || (object.stage && object.stage.pickable); // We'll only pick objects in pickable stages + this._appendObjectToDrawLists(object, pickable); + } - object = this._xpBuf[i]; - chunks = object.chunks; + this.drawListDirty = false; +}; - for (var j = 0, lenj = chunks.length; j < lenj; j++) { - chunk = chunks[j]; +SceneJS_Display.prototype._appendRenderTargetChunk = function (chunk) { + this._drawList[this._drawListLen++] = chunk; +}; - if (chunk && chunk.draw) { +/** + * Appends an object to the draw and pick lists. + * @param object + * @param pickable + * @private + */ +SceneJS_Display.prototype._appendObjectToDrawLists = function (object, pickable) { + var chunks = object.chunks; + var picking = object.flags.picking; + var chunk; + for (var i = 0, len = chunks.length; i < len; i++) { + chunk = chunks[i]; + if (chunk) { + + // As we apply the state chunk lists we track the ID of most types of chunk in order + // to cull redundant re-applications of runs of the same chunk - except for those chunks with a + // 'unique' flag, because we don't want to cull runs of draw chunks because they contain the GL + // drawElements calls which render the objects. + + if (chunk.draw) { + if (chunk.unique || this._lastStateId[i] != chunk.id) { // Don't reapply repeated states + this._drawList[this._drawListLen++] = chunk; + this._lastStateId[i] = chunk.id; + } + } - if (chunk.unique || this._lastStateId[j] != chunk.id) { - this._transparentDrawList[this._transparentDrawListLen++] = chunk; - this._drawList[this._drawListLen++] = chunk; - this._lastStateId[j] = chunk.id; + if (chunk.pick) { + if (pickable !== false) { // Don't pick objects in unpickable stages + if (picking) { // Don't pick unpickable objects + if (chunk.unique || this._lastPickStateId[i] != chunk.id) { // Don't reapply repeated states + this._pickDrawList[this._pickDrawListLen++] = chunk; + this._lastPickStateId[i] = chunk.id; + } } } } } } - - this.drawListDirty = false; }; -SceneJS_Display.prototype._render = function (params) { - - if (params.dof) { - - // Multi-pass depth-of-field (DOF) render - - // DOF image - - var dofImageBuf = this.dofImageBuf; // Lazy-create pick buffer - if (!dofImageBuf) { - dofImageBuf = this.dofImageBuf = new SceneJS._webgl.RenderBuffer({ canvas: this._canvas }); +/** + * Logs the contents of the draw list to the console. + * @private + */ +SceneJS_Display.prototype._logDrawList = function () { + console.log("--------------------------------------------------------------------------------------------------"); + console.log(this._drawListLen + " draw list chunks"); + for (var i = 0, len = this._drawListLen; i < len; i++) { + var chunk = this._drawList[i]; + console.log("[chunk " + i + "] type = " + chunk.type); + switch (chunk.type) { + case "draw": + console.log("\n"); + break; + case "renderTarget": + console.log(" bufType = " + chunk.core.bufType); + break; } - dofImageBuf.bind(); // Bind pick buffer - dofImageBuf.clear(); - this._doDrawList({}); - this._canvas.gl.finish(); - - // DOF depth + } + console.log("--------------------------------------------------------------------------------------------------"); +}; - var dofDepthBuf = this.dofDepthBuf; // Lazy-create pick buffer - if (!dofDepthBuf) { - dofDepthBuf = this.dofDepthBuf = new SceneJS._webgl.RenderBuffer({ canvas: this._canvas }); +/** + * Logs the contents of the pick list to the console. + * @private + */ +SceneJS_Display.prototype._logPickList = function () { + console.log("--------------------------------------------------------------------------------------------------"); + console.log(this._pickDrawListLen + " pick list chunks"); + for (var i = 0, len = this._pickDrawListLen; i < len; i++) { + var chunk = this._pickDrawList[i]; + console.log("[chunk " + i + "] type = " + chunk.type); + switch (chunk.type) { + case "draw": + console.log("\n"); + break; + case "renderTarget": + console.log(" bufType = " + chunk.core.bufType); + break; } - dofDepthBuf.bind(); // Bind pick buffer - dofDepthBuf.clear(); - this._doDrawList({ - all: true - }); - this._canvas.gl.finish(); - - // DOF blur - // .. TODO - - // DOF image - // .. TODO - - } else { - - // Default render - - this._doDrawList({}); } + console.log("--------------------------------------------------------------------------------------------------"); }; +/** + * Performs a pick on the display graph and returns info on the result. + * @param {*} params + * @returns {*} + */ SceneJS_Display.prototype.pick = function (params) { var canvas = this._canvas.canvas; - var hit = null; - var canvasX = params.canvasX; var canvasY = params.canvasY; - var pickBuf = this.pickBuf; // Lazy-create pick buffer if (!pickBuf) { @@ -14753,15 +15071,12 @@ SceneJS_Display.prototype.pick = function (params) { pickBuf.bind(); // Bind pick buffer if (this.pickBufDirty) { // Render pick buffer - pickBuf.clear(); - this._doDrawList({ - pick: true + pick: true, + clear: true }); - this._canvas.gl.finish(); - this.pickBufDirty = false; // Pick buffer up to date this.rayPickBufDirty = true; // Ray pick buffer now dirty } @@ -14769,7 +15084,6 @@ SceneJS_Display.prototype.pick = function (params) { var pix = pickBuf.read(canvasX, canvasY); // Read pick buffer var pickedObjectIndex = pix[0] + pix[1] * 256 + pix[2] * 65536; var pickIndex = (pickedObjectIndex >= 1) ? pickedObjectIndex - 1 : -1; - pickBuf.unbind(); // Unbind pick buffer var pickName = this._frameCtx.pickNames[pickIndex]; // Map pixel to name @@ -14784,7 +15098,6 @@ SceneJS_Display.prototype.pick = function (params) { }; if (params.rayPick) { // Ray pick to find position - var rayPickBuf = this.rayPickBuf; // Lazy-create Z-pick buffer if (!rayPickBuf) { rayPickBuf = this.rayPickBuf = new SceneJS._webgl.RenderBuffer({ canvas: this._canvas }); @@ -14793,14 +15106,12 @@ SceneJS_Display.prototype.pick = function (params) { rayPickBuf.bind(); if (this.rayPickBufDirty) { - rayPickBuf.clear(); - this._doDrawList({ pick: true, - rayPick: true + rayPick: true, + clear: true }); - this.rayPickBufDirty = false; } @@ -14808,34 +15119,24 @@ SceneJS_Display.prototype.pick = function (params) { rayPickBuf.unbind(); - /* Read normalised device Z coordinate, which will be - * in range of [0..1] with z=0 at front - */ + // Read normalised device Z coordinate, which will be + // in range of [0..1] with z=0 at front var screenZ = this._unpackDepth(pix); - var w = canvas.width; var h = canvas.height; - - /* Calculate clip space coordinates, which will be in range - * of x=[-1..1] and y=[-1..1], with y=(+1) at top - */ + // Calculate clip space coordinates, which will be in range + // of x=[-1..1] and y=[-1..1], with y=(+1) at top var x = (canvasX - w / 2) / (w / 2); // Calculate clip space coordinates var y = -(canvasY - h / 2) / (h / 2); - var projMat = this._frameCtx.cameraMat; var viewMat = this._frameCtx.viewMat; - var pvMat = SceneJS_math_mulMat4(projMat, viewMat, []); var pvMatInverse = SceneJS_math_inverseMat4(pvMat, []); - var world1 = SceneJS_math_transformVector4(pvMatInverse, [x, y, -1, 1]); world1 = SceneJS_math_mulVec4Scalar(world1, 1 / world1[3]); - var world2 = SceneJS_math_transformVector4(pvMatInverse, [x, y, 1, 1]); world2 = SceneJS_math_mulVec4Scalar(world2, 1 / world2[3]); - var dir = SceneJS_math_subVec3(world2, world1, []); - var vWorld = SceneJS_math_addVec3(world1, SceneJS_math_mulVec4Scalar(dir, screenZ, []), []); hit.worldPos = vWorld; @@ -14845,117 +15146,105 @@ SceneJS_Display.prototype.pick = function (params) { return hit; }; +/** + * Unpacks a color-encoded depth + * @param {Array(Number)} depthZ Depth encoded as an RGBA color value + * @returns {Number} + * @private + */ SceneJS_Display.prototype._unpackDepth = function (depthZ) { var vec = [depthZ[0] / 256.0, depthZ[1] / 256.0, depthZ[2] / 256.0, depthZ[3] / 256.0]; var bitShift = [1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0]; return SceneJS_math_dotVector4(vec, bitShift); }; +/** Renders either the draw or pick list. + * + * @param {*} params + * @param {Boolean} params.clear Set true to clear the color, depth and stencil buffers first + * @param {Boolean} params.pick Set true to render for picking + * @param {Boolean} params.rayPick Set true to render for ray-picking + * @private + */ SceneJS_Display.prototype._doDrawList = function (params) { - var frameCtx = this._frameCtx; // Reset rendering context - var gl = this._canvas.gl; - frameCtx.framebuf = null; + // Reset frame context + var frameCtx = this._frameCtx; + frameCtx.renderTarget = null; + frameCtx.targetIndex = 0; + frameCtx.renderBuf = null; frameCtx.viewMat = null; frameCtx.modelMat = null; frameCtx.cameraMat = null; frameCtx.renderer = null; - frameCtx.depthbufEnabled = null; frameCtx.clearDepth = null; frameCtx.depthFunc = gl.LESS; - frameCtx.scissorTestEnabled = false; - frameCtx.blendEnabled = false; - frameCtx.backfaces = true; frameCtx.frontface = "ccw"; frameCtx.pick = !!params.pick; + frameCtx.rayPick = !!params.rayPick; + frameCtx.pickIndex = 0; frameCtx.textureUnit = 0; - frameCtx.lineWidth = 1; + frameCtx.transparent = false; + frameCtx.ambientColor = this._ambientColor; - frameCtx.transparencyPass = false; - - // The extension needs to be re-queried in case the context was lost and - // has been recreated. + // The extension needs to be re-queried in case the context was lost and has been recreated. var VAO = gl.getExtension("OES_vertex_array_object"); - if (VAO) { - frameCtx.VAO = VAO; - } + frameCtx.VAO = (VAO) ? VAO : null; gl.viewport(0, 0, this._canvas.canvas.width, this._canvas.canvas.height); + if (this.transparent) { gl.clearColor(0, 0, 0, 0); } else { gl.clearColor(this._ambientColor[0], this._ambientColor[1], this._ambientColor[2], 1.0); } - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + + if (params.clear) { + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + } + gl.frontFace(gl.CCW); gl.disable(gl.CULL_FACE); if (params.pick) { - - // Render to pick buffer - - frameCtx.pickIndex = 0; - frameCtx.rayPick = !!params.rayPick; - - for (var i = 0, len = this._pickDrawListLen; i < len; i++) { // Push picking chunks + // Render for pick + for (var i = 0, len = this._pickDrawListLen; i < len; i++) { this._pickDrawList[i].pick(frameCtx); } - - } else if (params.all) { - - // Render all - + } else { + // Render for draw for (var i = 0, len = this._drawListLen; i < len; i++) { // Push opaque rendering chunks this._drawList[i].draw(frameCtx); } + } - } else { - - // Normal draw - - for (var i = 0, len = this._opaqueDrawListLen; i < len; i++) { // Push opaque rendering chunks - this._opaqueDrawList[i].draw(frameCtx); - } - - if (this._transparentDrawListLen > 0) { - - // Disables some types of state changes during - // transparency pass, such as blending disable - frameCtx.transparencyPass = true; - - // Enable blending - gl.enable(gl.BLEND); - frameCtx.blendEnabled = true; - - gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); - - for (var i = 0, len = this._transparentDrawListLen; i < len; i++) { // Push transparent rendering chunks - this._transparentDrawList[i].draw(frameCtx); - } - - // Disable blending - gl.disable(gl.BLEND); - frameCtx.blendEnabled = false; + gl.flush(); - frameCtx.transparencyPass = false; - } + if (frameCtx.renderBuf) { + gl.finish(); + frameCtx.renderBuf.unbind(); } - gl.flush(); // Flush GL - if (frameCtx.VAO) { frameCtx.VAO.bindVertexArrayOES(null); for (var i = 0; i < 10; i++) { gl.disableVertexAttribArray(i); } } +// +// var numTextureUnits = gl.getParameter(gl.MAX_TEXTURE_IMAGE_UNITS); +// for (var ii = 0; ii < numTextureUnits; ++ii) { +// gl.activeTexture(gl.TEXTURE0 + ii); +// gl.bindTexture(gl.TEXTURE_CUBE_MAP, null); +// gl.bindTexture(gl.TEXTURE_2D, null); +// } }; SceneJS_Display.prototype.destroy = function () { @@ -15014,6 +15303,15 @@ var SceneJS_ProgramSourceFactory = new (function () { var customFragmentShader = customShaders.fragment || {}; var fragmentHooks = customFragmentShader.hooks || {}; + // Do a full custom shader replacement if code supplied without hooks + if (customShaders.vertex + && customShaders.vertex.code + && customShaders.vertex.code != "" + && SceneJS._isEmpty(customShaders.vertex.hooks)) { + return [customShaders.vertex.code]; + } + + var clipping = states.clips.clips.length > 0; var morphing = !!states.morphGeometry.targets; var normals = this._hasNormals(states); @@ -15126,6 +15424,14 @@ var SceneJS_ProgramSourceFactory = new (function () { var customFragmentShader = customShaders.fragment || {}; var fragmentHooks = customFragmentShader.hooks || {}; + // Do a full custom shader replacement if code supplied without hooks + if (customShaders.fragment + && customShaders.fragment.code + && customShaders.fragment.code != "" + && SceneJS._isEmpty(customShaders.fragment.hooks)) { + return [customShaders.fragment.code]; + } + var clipping = states.clips.clips.length > 0; var normals = this._hasNormals(states); @@ -15142,6 +15448,7 @@ var SceneJS_ProgramSourceFactory = new (function () { src.push(" return res;"); src.push("}"); + src.push("varying vec4 SCENEJS_vWorldVertex;"); src.push("varying vec4 SCENEJS_vViewVertex;"); // View-space vertex src.push("varying vec4 SCENEJS_vProjVertex;"); @@ -15272,10 +15579,12 @@ var SceneJS_ProgramSourceFactory = new (function () { var customShaders = states.shader.shaders || {}; - /* Do a full custom shader replacement if code supplied without hooks - */ - if (customShaders.vertex && customShaders.vertex.code && !customShaders.vertex.hooks) { - return customShaders.vertex.code; + // Do a full custom shader replacement if code supplied without hooks + if (customShaders.vertex + && customShaders.vertex.code + && customShaders.vertex.code != "" + && SceneJS._isEmpty(customShaders.vertex.hooks)) { + return [customShaders.vertex.code]; } var customVertexShader = customShaders.vertex || {}; @@ -15356,9 +15665,9 @@ var SceneJS_ProgramSourceFactory = new (function () { src.push("varying vec4 SCENEJS_vWorldVertex;"); // Varying for fragment clip or world pos hook } - if (fragmentHooks.viewPos) { - src.push("varying vec4 SCENEJS_vViewVertex;"); // Varying for fragment view clip hook - } + // if (fragmentHooks.viewPos) { + src.push("varying vec4 SCENEJS_vViewVertex;"); // Varying for fragment view clip hook + // } if (texturing) { // Varyings for fragment texturing if (states.geometry.uvBuf) { @@ -15444,9 +15753,9 @@ var SceneJS_ProgramSourceFactory = new (function () { src.push(" SCENEJS_vWorldVertex = worldVertex;"); // Varying for fragment world clip or hooks } - if (fragmentHooks.viewPos) { - src.push(" SCENEJS_vViewVertex = viewVertex;"); // Varying for fragment hooks - } + // if (fragmentHooks.viewPos) { + src.push(" SCENEJS_vViewVertex = viewVertex;"); // Varying for fragment hooks + // } if (vertexHooks.projMatrix) { src.push("gl_Position = " + vertexHooks.projMatrix + "(SCENEJS_uPMatrix) * viewVertex;"); @@ -15542,10 +15851,12 @@ var SceneJS_ProgramSourceFactory = new (function () { var customShaders = states.shader.shaders || {}; - /* Do a full custom shader replacement if code supplied without hooks - */ - if (customShaders.fragment && customShaders.fragment.code && !customShaders.fragment.hooks) { - return customShaders.fragment.code; + // Do a full custom shader replacement if code supplied without hooks + if (customShaders.fragment + && customShaders.fragment.code + && customShaders.fragment.code != "" + && SceneJS._isEmpty(customShaders.fragment.hooks)) { + return [customShaders.fragment.code]; } var customFragmentShader = customShaders.fragment || {}; @@ -15565,9 +15876,13 @@ var SceneJS_ProgramSourceFactory = new (function () { src.push("varying vec4 SCENEJS_vWorldVertex;"); // World-space vertex } - if (fragmentHooks.viewPos) { - src.push("varying vec4 SCENEJS_vViewVertex;"); // View-space vertex - } + // if (fragmentHooks.viewPos) { + src.push("varying vec4 SCENEJS_vViewVertex;"); // View-space vertex + // } + + src.push("uniform float SCENEJS_uZNear;"); // Used in Z-pick mode + src.push("uniform float SCENEJS_uZFar;"); // Used in Z-pick mode + /*----------------------------------------------------------------------------------- * Variables @@ -15617,6 +15932,9 @@ var SceneJS_ProgramSourceFactory = new (function () { src.push("uniform bool SCENEJS_uDiffuse;"); src.push("uniform bool SCENEJS_uReflection;"); + // Added in v4.0 to support depth targets + src.push("uniform bool SCENEJS_uDepthMode;"); + /* True when rendering transparency */ src.push("uniform bool SCENEJS_uTransparent;"); @@ -15629,7 +15947,7 @@ var SceneJS_ProgramSourceFactory = new (function () { src.push("uniform vec3 SCENEJS_uAmbientColor;"); // Scene ambient colour - taken from clear colour - src.push("uniform vec3 SCENEJS_uMaterialBaseColor;"); + src.push("uniform vec3 SCENEJS_uMaterialColor;"); src.push("uniform float SCENEJS_uMaterialAlpha;"); src.push("uniform float SCENEJS_uMaterialEmit;"); src.push("uniform vec3 SCENEJS_uMaterialSpecularColor;"); @@ -15713,7 +16031,7 @@ var SceneJS_ProgramSourceFactory = new (function () { if (states.geometry.colorBuf) { src.push(" vec3 color = SCENEJS_vColor.rgb;"); } else { - src.push(" vec3 color = SCENEJS_uMaterialBaseColor;") + src.push(" vec3 color = SCENEJS_uMaterialColor;") } src.push(" float alpha = SCENEJS_uMaterialAlpha;"); @@ -15744,6 +16062,7 @@ var SceneJS_ProgramSourceFactory = new (function () { if (normals) { src.push(" float attenuation = 1.0;"); src.push(" vec3 viewNormalVec = SCENEJS_vViewNormal;"); + src.push(" vec3 worldNormalVec = SCENEJS_vWorldNormal;"); } var layer; @@ -15802,6 +16121,10 @@ var SceneJS_ProgramSourceFactory = new (function () { } else if (layer.blendMode == "add") { src.push("alpha = ((1.0 - SCENEJS_uLayer" + i + "BlendFactor) * alpha) + (SCENEJS_uLayer" + i + "BlendFactor * texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, 1.0 - textureCoord.y)).b);"); } + + //===================================================================== + // TODO: "mix" blendMode + //===================================================================== } /* Texture output @@ -15840,7 +16163,7 @@ var SceneJS_ProgramSourceFactory = new (function () { if (layer.applyTo == "normals" && normals) { src.push("vec3 bump = normalize(texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, -textureCoord.y)).xyz * 2.0 - 1.0);"); - src.push("viewNormalVec *= -bump;"); + src.push("worldNormalVec = bump;"); } } if (normals) { @@ -15850,7 +16173,7 @@ var SceneJS_ProgramSourceFactory = new (function () { if (normals && cubeMapping) { src.push("if (SCENEJS_uReflection) {"); // Flag which can enable/disable reflection - src.push("vec3 envLookup = reflect(normalize(SCENEJS_vWorldEyeVec), normalize(SCENEJS_vWorldNormal));"); + src.push("vec3 envLookup = reflect(normalize(SCENEJS_vWorldEyeVec), normalize(worldNormalVec));"); src.push("envLookup.y = envLookup.y * -1.0;"); // Need to flip textures on Y-axis for some reason src.push("vec4 envColor;"); for (var i = 0, len = states.cubemap.layers.length; i < len; i++) { @@ -15945,11 +16268,24 @@ var SceneJS_ProgramSourceFactory = new (function () { if (fragmentHooks.pixelColor) { src.push("fragColor=" + fragmentHooks.pixelColor + "(fragColor);"); } - if (false && debugCfg.whitewash === true) { src.push(" gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);"); } else { - src.push(" gl_FragColor = fragColor;"); + src.push(" if (SCENEJS_uDepthMode) {"); + src.push(" float depth = length(SCENEJS_vViewVertex) / (SCENEJS_uZFar - SCENEJS_uZNear);"); + src.push(" const vec4 bias = vec4(1.0 / 255.0,"); + src.push(" 1.0 / 255.0,"); + src.push(" 1.0 / 255.0,"); + src.push(" 0.0);"); + src.push(" float r = depth;"); + src.push(" float g = fract(r * 255.0);"); + src.push(" float b = fract(g * 255.0);"); + src.push(" float a = fract(b * 255.0);"); + src.push(" vec4 colour = vec4(r, g, b, a);"); + src.push(" gl_FragColor = colour - (colour.yzww * bias);"); + src.push(" } else {"); + src.push(" gl_FragColor = fragColor;"); + src.push(" };"); } src.push("}"); @@ -16466,6 +16802,8 @@ SceneJS_ChunkFactory.prototype.getChunk = function(chunkId, type, program, core, } + chunk.type = type; + chunk.useCount = 1; this._chunks[chunkId] = chunk; @@ -16524,13 +16862,15 @@ SceneJS_ChunkFactory.createChunkType({ build : function() { this._uPMatrixDraw = this.program.draw.getUniformLocation("SCENEJS_uPMatrix"); + this._uZNearDraw = this.program.draw.getUniformLocation("SCENEJS_uZNear"); + this._uZFarDraw = this.program.draw.getUniformLocation("SCENEJS_uZFar"); this._uPMatrixPick = this.program.pick.getUniformLocation("SCENEJS_uPMatrix"); this._uZNearPick = this.program.pick.getUniformLocation("SCENEJS_uZNear"); this._uZFarPick = this.program.pick.getUniformLocation("SCENEJS_uZFar"); }, - draw : function(ctx) { + draw : function(frameCtx) { if (this.core.dirty) { this.core.rebuild(); @@ -16542,11 +16882,19 @@ SceneJS_ChunkFactory.createChunkType({ gl.uniformMatrix4fv(this._uPMatrixDraw, gl.FALSE, this.core.mat); } - ctx.cameraMat = this.core.mat; // Query only in draw pass + if (this._uZNearDraw) { + gl.uniform1f(this._uZNearDraw, this.core.optics.near); + } + + if (this._uZFarDraw) { + gl.uniform1f(this._uZFarDraw, this.core.optics.far); + } + + frameCtx.cameraMat = this.core.mat; // Query only in draw pass }, - pick : function(ctx) { + pick : function(frameCtx) { var gl = this.program.gl; @@ -16554,7 +16902,7 @@ SceneJS_ChunkFactory.createChunkType({ gl.uniformMatrix4fv(this._uPMatrixPick, gl.FALSE, this.core.mat); } - if (ctx.rayPick) { // Z-pick pass: feed near and far clip planes into shader + if (frameCtx.rayPick) { // Z-pick pass: feed near and far clip planes into shader if (this._uZNearPick) { gl.uniform1f(this._uZNearPick, this.core.optics.near); @@ -16565,7 +16913,7 @@ SceneJS_ChunkFactory.createChunkType({ } } - ctx.cameraMat = this.core.mat; // Query only in draw pass + frameCtx.cameraMat = this.core.mat; // Query only in draw pass } });/** * Create display state chunk type for draw and pick render of user clipping planes @@ -16599,9 +16947,9 @@ SceneJS_ChunkFactory.createChunkType({ } }, - drawAndPick: function(ctx) { + drawAndPick: function(frameCtx) { - var vars = (ctx.pick) ? this._pick : this._draw; + var vars = (frameCtx.pick) ? this._pick : this._draw; var mode; var normalAndDist; @@ -16611,7 +16959,7 @@ SceneJS_ChunkFactory.createChunkType({ for (var i = 0, len = clips.length; i < len; i++) { - if (ctx.pick) { + if (frameCtx.pick) { mode = vars[i].uClipMode; normalAndDist = vars[i].uClipNormalAndDist; } else { @@ -16655,13 +17003,16 @@ SceneJS_ChunkFactory.createChunkType({ */ unique:true, - build:function () {}, - - drawAndPick:function (ctx) { + build:function () { + this._depthModeDraw = this.program.draw.getUniformLocation("SCENEJS_uDepthMode"); + this._depthModePick = this.program.pick.getUniformLocation("SCENEJS_uDepthMode"); + }, + drawAndPick:function (frameCtx) { var gl = this.program.gl; - + gl.uniform1i(frameCtx.pick ? this._depthModePick : this._depthModeDraw, frameCtx.depthMode); gl.drawElements(this.core.primitive, this.core.indexBuf.numItems, gl.UNSIGNED_SHORT, 0); + //frameCtx.textureUnit = 0; } }); /** @@ -16669,9 +17020,9 @@ SceneJS_ChunkFactory.createChunkType({ */ SceneJS_ChunkFactory.createChunkType({ - type:"flags", + type: "flags", - build:function () { + build: function () { var draw = this.program.draw; @@ -16688,43 +17039,64 @@ SceneJS_ChunkFactory.createChunkType({ this._uClippingPick = pick.getUniformLocation("SCENEJS_uClipping"); }, - drawAndPick:function (ctx) { + drawAndPick: function (frameCtx) { var gl = this.program.gl; var backfaces = this.core.backfaces; - if (ctx.backfaces != backfaces) { + if (frameCtx.backfaces != backfaces) { if (backfaces) { gl.disable(gl.CULL_FACE); } else { gl.enable(gl.CULL_FACE); } - ctx.backfaces = backfaces; + frameCtx.backfaces = backfaces; } var frontface = this.core.frontface; - if (ctx.frontface != frontface) { + if (frameCtx.frontface != frontface) { if (frontface == "ccw") { gl.frontFace(gl.CCW); } else { gl.frontFace(gl.CW); } - ctx.frontface = frontface; + frameCtx.frontface = frontface; } - if (ctx.pick) { + var transparent = this.core.transparent; + + if (frameCtx.transparent != transparent) { + if (transparent) { + + // Entering a transparency bin + + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + frameCtx.blendEnabled = true; + + } else { + + // Leaving a transparency bin + + gl.disable(gl.BLEND); + frameCtx.blendEnabled = false; + } + frameCtx.transparent = transparent; + } + + if (frameCtx.pick) { gl.uniform1i(this._uClippingPick, this.core.clipping); } else { var drawUniforms = (this.core.backfaceTexturing ? 1 : 0) + - (this.core.backfaceLighting ? 2 : 0) + - (this.core.specular ? 4 : 0) + - (this.core.clipping ? 8 : 0) + - (this.core.ambient ? 16 : 0) + - (this.core.diffuse ? 32 : 0) + - (this.core.reflection ? 64 : 0); + (this.core.backfaceLighting ? 2 : 0) + + (this.core.specular ? 4 : 0) + + (this.core.clipping ? 8 : 0) + + (this.core.ambient ? 16 : 0) + + (this.core.diffuse ? 32 : 0) + + (this.core.reflection ? 64 : 0); if (this.program.drawUniformFlags != drawUniforms) { gl.uniform1i(this._uBackfaceTexturingDraw, this.core.backfaceTexturing); gl.uniform1i(this._uBackfaceLightingDraw, this.core.backfaceLighting); @@ -16739,41 +17111,54 @@ SceneJS_ChunkFactory.createChunkType({ } }); /** - * Create display state chunk type for draw and pick render of framebuf + * Create display state chunk type for draw and pick render of renderTarget */ SceneJS_ChunkFactory.createChunkType({ - type: "framebuf", + type: "renderTarget", - // Avoid reapplication of a chunk after a program switch. - programGlobal:true, - - build: function() { - }, + // Avoid reapplication of this chunk type after a program switch. + programGlobal: true, - drawAndPick: function(ctx) { + draw: function (frameCtx) { var gl = this.program.gl; - if (ctx.framebuf) { - - gl.finish(); // Force framebuf to complete - - ctx.framebuf.unbind(); - - ctx.framebuf = null; + // Flush and unbind any render buffer already bound + if (frameCtx.renderBuf) { + gl.finish(); + frameCtx.renderBuf.unbind(); + frameCtx.renderBuf = null; } - var framebuf = this.core.framebuf; + // Set depthMode false and bail if no render buffer for this chunk + var renderBuf = this.core.renderBuf; + if (!renderBuf) { + frameCtx.depthMode = false; + return; + } - if (framebuf) { + // Bind this chunk's render buffer, set depthMode, enable blend if depthMode false, clear buffer + renderBuf.bind(); - framebuf.bind(); + frameCtx.depthMode = (this.core.bufType === "depth"); - gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + if (!frameCtx.depthMode) { - ctx.framebuf = framebuf; // Must flush on cleanup + // Enable blending for non-depth targets + if (frameCtx.blendEnabled) { + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + } } + + var canvas = frameCtx.canvas.canvas; + gl.viewport(0, 0, canvas.width, canvas.height); + gl.clearColor(frameCtx.ambientColor[0], frameCtx.ambientColor[1], frameCtx.ambientColor[2], 1.0); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT); + // gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + frameCtx.renderBuf = renderBuf; } });/** * Create display state chunk type for draw and pick render of geometry @@ -16866,12 +17251,12 @@ SceneJS_ChunkFactory.createChunkType({ }, - draw:function (ctx) { + draw:function (frameCtx) { var doMorph = this.core.targets && this.core.targets.length; var cleanInterleavedBuf = this.core2.interleavedBuf && !this.core2.interleavedBuf.dirty; if (this.VAO) { - ctx.VAO.bindVertexArrayOES(this.VAO); + frameCtx.VAO.bindVertexArrayOES(this.VAO); if (doMorph) { if (this.VAOMorphKey1 == this.core.key1 && this.VAOMorphKey2 == this.core.key2) { this.setDrawMorphFactor(); @@ -16880,11 +17265,11 @@ SceneJS_ChunkFactory.createChunkType({ } else if (cleanInterleavedBuf || !this.VAOHasInterleavedBuf) { return; } - } else if (ctx.VAO) { + } else if (frameCtx.VAO) { // Start creating a new VAO by switching to the default VAO, which doesn't have attribs enabled. - ctx.VAO.bindVertexArrayOES(null); - this.VAO = ctx.VAO.createVertexArrayOES(); - ctx.VAO.bindVertexArrayOES(this.VAO); + frameCtx.VAO.bindVertexArrayOES(null); + this.VAO = frameCtx.VAO.createVertexArrayOES(); + frameCtx.VAO.bindVertexArrayOES(this.VAO); var gl = this.program.gl; } @@ -16970,7 +17355,7 @@ SceneJS_ChunkFactory.createChunkType({ }, - pick:function (ctx) { + pick:function (frameCtx) { if (this.core.targets && this.core.targets.length) { this.morphPick(); @@ -17041,9 +17426,9 @@ SceneJS_ChunkFactory.createChunkType({ } }, - draw:function (ctx) { + draw:function (frameCtx) { - if (ctx.dirty) { + if (frameCtx.dirty) { this.build(); } @@ -17092,10 +17477,10 @@ SceneJS_ChunkFactory.createChunkType({ build : function() { }, - draw : function(ctx) { + draw : function(frameCtx) { var listeners = this.core.listeners; - var renderListenerCtx = ctx.renderListenerCtx; + var renderListenerCtx = frameCtx.renderListenerCtx; for (var i = listeners.length - 1; i >= 0; i--) { // Child listeners first if (listeners[i](renderListenerCtx) === true) { // Call listener with query facade object as scope @@ -17119,7 +17504,7 @@ SceneJS_ChunkFactory.createChunkType({ this._uvMatrixPick = this.program.pick.getUniformLocation("SCENEJS_uVMatrix"); }, - draw : function(ctx) { + draw : function(frameCtx) { if (this.core.dirty) { this.core.rebuild(); @@ -17139,10 +17524,10 @@ SceneJS_ChunkFactory.createChunkType({ gl.uniform3fv(this._uWorldEyeDraw, this.core.lookAt.eye); } - ctx.viewMat = this.core.mat; + frameCtx.viewMat = this.core.mat; }, - pick : function(ctx) { + pick : function(frameCtx) { var gl = this.program.gl; @@ -17150,7 +17535,7 @@ SceneJS_ChunkFactory.createChunkType({ gl.uniformMatrix4fv(this._uvMatrixPick, gl.FALSE, this.core.mat); } - ctx.viewMat = this.core.mat; + frameCtx.viewMat = this.core.mat; } });/** * Create display state chunk type for draw render of material transform @@ -17163,7 +17548,7 @@ SceneJS_ChunkFactory.createChunkType({ var draw = this.program.draw; - this._uMaterialBaseColor = draw.getUniformLocation("SCENEJS_uMaterialBaseColor"); + this._uMaterialBaseColor = draw.getUniformLocation("SCENEJS_uMaterialColor"); this._uMaterialSpecularColor = draw.getUniformLocation("SCENEJS_uMaterialSpecularColor"); this._uMaterialSpecular = draw.getUniformLocation("SCENEJS_uMaterialSpecular"); this._uMaterialShine = draw.getUniformLocation("SCENEJS_uMaterialShine"); @@ -17222,15 +17607,15 @@ SceneJS_ChunkFactory.createChunkType({ this._uPickColor = this.program.pick.getUniformLocation("SCENEJS_uPickColor"); }, - pick : function(ctx) { + pick : function(frameCtx) { if (this._uPickColor && this.core.name) { - ctx.pickNames[ctx.pickIndex++] = this.core; + frameCtx.pickNames[frameCtx.pickIndex++] = this.core; - var b = ctx.pickIndex >> 16 & 0xFF; - var g = ctx.pickIndex >> 8 & 0xFF; - var r = ctx.pickIndex & 0xFF; + var b = frameCtx.pickIndex >> 16 & 0xFF; + var g = frameCtx.pickIndex >> 8 & 0xFF; + var r = frameCtx.pickIndex & 0xFF; this.program.gl.uniform3fv(this._uPickColor, [r / 255, g / 255, b / 255]); } @@ -17240,38 +17625,35 @@ SceneJS_ChunkFactory.createChunkType({ type: "program", build : function() { + + // Note that "program" chunks are always after "renderTarget" chunks + this._depthModeDraw = this.program.draw.getUniformLocation("SCENEJS_uDepthMode"); + this._depthModePick = this.program.pick.getUniformLocation("SCENEJS_uDepthMode"); this._rayPickMode = this.program.pick.getUniformLocation("SCENEJS_uRayPickMode"); }, draw : function(frameCtx) { - var drawProgram = this.program.draw; - drawProgram.bind(); - frameCtx.textureUnit = 0; - var gl = this.program.gl; - + gl.uniform1i(this._depthModeDraw, frameCtx.depthMode); if (!frameCtx.VAO) { for (var i = 0; i < 10; i++) { gl.disableVertexAttribArray(i); } } + + frameCtx.drawProgram = this.program.draw; }, pick : function(frameCtx) { - var pickProgram = this.program.pick; - pickProgram.bind(); - var gl = this.program.gl; - gl.uniform1i(this._rayPickMode, frameCtx.rayPick); - + gl.uniform1i(this._depthModePick, frameCtx.depthMode); frameCtx.textureUnit = 0; - for (var i = 0; i < 10; i++) { gl.disableVertexAttribArray(i); } @@ -17284,23 +17666,20 @@ SceneJS_ChunkFactory.createChunkType({ * */ SceneJS_ChunkFactory.createChunkType({ - + type: "renderer", - build : function() { + build: function () { }, - drawAndPick : function(ctx) { + drawAndPick: function (frameCtx) { if (this.core.props) { - var gl = this.program.gl; - - if (ctx.renderer) { - ctx.renderer.props.restoreProps(gl); - ctx.renderer = this.core; + if (frameCtx.renderer) { + frameCtx.renderer.props.restoreProps(gl); + frameCtx.renderer = this.core; } - this.core.props.setProps(gl); } } @@ -17310,37 +17689,41 @@ SceneJS_ChunkFactory.createChunkType({ */ SceneJS_ChunkFactory.createChunkType({ - type:"depthbuf", + type:"depthBuffer", // Avoid reapplication of a chunk after a program switch. programGlobal:true, - drawAndPick:function (ctx) { + drawAndPick:function (frameCtx) { var enabled = this.core.enabled; - if (ctx.depthbufEnabled != enabled) { + if (frameCtx.depthbufEnabled != enabled) { var gl = this.program.gl; if (enabled) { gl.enable(gl.DEPTH_TEST); } else { gl.disable(gl.DEPTH_TEST); } - ctx.depthbufEnabled = enabled; + frameCtx.depthbufEnabled = enabled; } var clearDepth = this.core.clearDepth; - if (ctx.clearDepth != clearDepth) { + if (frameCtx.clearDepth != clearDepth) { gl.clearDepth(clearDepth); - ctx.clearDepth = clearDepth; + frameCtx.clearDepth = clearDepth; } var depthFunc = this.core.depthFunc; - if (ctx.depthFunc != depthFunc) { + if (frameCtx.depthFunc != depthFunc) { gl.depthFunc(depthFunc); - ctx.depthFunc = depthFunc; + frameCtx.depthFunc = depthFunc; + } + + if (this.core.clear) { + gl.clear(gl.DEPTH_BUFFER_BIT); } } }); @@ -17349,7 +17732,7 @@ SceneJS_ChunkFactory.createChunkType({ */ SceneJS_ChunkFactory.createChunkType({ - type:"colorbuf", + type:"colorBuffer", // Avoid reapplication of a chunk after a program switch. programGlobal:true, @@ -17357,21 +17740,25 @@ SceneJS_ChunkFactory.createChunkType({ build:function () { }, - drawAndPick:function (ctx) { + drawAndPick:function (frameCtx) { - if (!ctx.transparencyPass) { // Blending forced when rendering transparent bin + if (!frameCtx.transparent) { // Blending forced when rendering transparent bin var blendEnabled = this.core.blendEnabled; - if (ctx.blendEnabled != blendEnabled) { - var gl = this.program.gl; + var gl = this.program.gl; + + if (frameCtx.blendEnabled != blendEnabled) { if (blendEnabled) { gl.enable(gl.BLEND); } else { gl.disable(gl.BLEND); } - ctx.blendEnabled = blendEnabled; + frameCtx.blendEnabled = blendEnabled; } + + var colorMask = this.core.colorMask; + gl.colorMask(colorMask.r, colorMask.g, colorMask.b, colorMask.a); } } }); @@ -17388,18 +17775,18 @@ SceneJS_ChunkFactory.createChunkType({ build:function () { }, - drawAndPick:function (ctx) { + drawAndPick:function (frameCtx) { var scissorTestEnabled = this.core.scissorTestEnabled; - if (ctx.scissorTestEnabled != scissorTestEnabled) { + if (frameCtx.scissorTestEnabled != scissorTestEnabled) { var gl = this.program.gl; if (scissorTestEnabled) { gl.enable(gl.SCISSOR_TEST); } else { gl.disable(gl.SCISSOR_TEST); } - ctx.scissorTestEnabled = scissorTestEnabled; + frameCtx.scissorTestEnabled = scissorTestEnabled; } } }); @@ -17413,13 +17800,13 @@ SceneJS_ChunkFactory.createChunkType({ build : function() { }, - drawAndPick : function(ctx) { + drawAndPick : function(frameCtx) { var paramsStack = this.core.paramsStack; if (paramsStack) { - var program = ctx.pick ? this.program.pick : this.program.draw; + var program = frameCtx.pick ? this.program.pick : this.program.draw; var params; var name; @@ -17443,13 +17830,13 @@ SceneJS_ChunkFactory.createChunkType({ build : function() { }, - drawAndPick: function(ctx) { + drawAndPick: function(frameCtx) { var paramsStack = this.core.paramsStack; if (paramsStack) { - var program = ctx.pick ? this.program.pick : this.program.draw; + var program = frameCtx.pick ? this.program.pick : this.program.draw; var params; var name; @@ -17473,14 +17860,14 @@ SceneJS_ChunkFactory.createChunkType({ // Avoid reapplication of a chunk after a program switch. programGlobal:true, - drawAndPick:function (ctx) { + drawAndPick:function (frameCtx) { var lineWidth = this.core.lineWidth; - if (ctx.lineWidth != lineWidth) { + if (frameCtx.lineWidth != lineWidth) { var gl = this.program.gl; gl.lineWidth(lineWidth); - ctx.lineWidth = lineWidth; + frameCtx.lineWidth = lineWidth; } } }); @@ -17518,7 +17905,9 @@ SceneJS_ChunkFactory.createChunkType({ } }, - draw : function(ctx) { + draw : function(frameCtx) { + + frameCtx.textureUnit = 0; var layers = this.core.layers; @@ -17533,7 +17922,7 @@ SceneJS_ChunkFactory.createChunkType({ if (this._uTexSampler[i] && layer.texture) { // Lazy-loads - draw.bindTexture(this._uTexSampler[i], layer.texture, ctx.textureUnit++); + draw.bindTexture(this._uTexSampler[i], layer.texture, frameCtx.textureUnit++); if (layer._matrixDirty && layer.buildMatrix) { layer.buildMatrix.call(layer); @@ -17548,13 +17937,13 @@ SceneJS_ChunkFactory.createChunkType({ } } else { - // draw.bindTexture(this._uTexSampler[i], null, i); // Unbind + // draw.bindTexture(this._uTexSampler[i], null, i); // Unbind } } } - if (ctx.textureUnit > 10) { // TODO: Find how many textures allowed - ctx.textureUnit = 0; + if (frameCtx.textureUnit > 10) { // TODO: Find how many textures allowed + frameCtx.textureUnit = 0; } } });SceneJS_ChunkFactory.createChunkType({ @@ -17576,7 +17965,7 @@ SceneJS_ChunkFactory.createChunkType({ } }, - draw: function (ctx) { + draw: function (frameCtx) { var layers = this.core.layers; if (layers) { var layer; @@ -17584,7 +17973,7 @@ SceneJS_ChunkFactory.createChunkType({ for (var i = 0, len = layers.length; i < len; i++) { layer = layers[i]; if (this._uCubeMapSampler[i] && layer.texture) { - draw.bindTexture(this._uCubeMapSampler[i], layer.texture, ctx.textureUnit++); + draw.bindTexture(this._uCubeMapSampler[i], layer.texture, frameCtx.textureUnit++); if (this._uCubeMapIntensity[i]) { this._uCubeMapIntensity[i].setValue(layer.intensity); } @@ -17592,8 +17981,8 @@ SceneJS_ChunkFactory.createChunkType({ } } - if (ctx.textureUnit > 10) { // TODO: Find how many textures allowed - ctx.textureUnit = 0; + if (frameCtx.textureUnit > 10) { // TODO: Find how many textures allowed + frameCtx.textureUnit = 0; } } });SceneJS_ChunkFactory.createChunkType({ @@ -17613,7 +18002,7 @@ SceneJS_ChunkFactory.createChunkType({ this._uNormalMatLocationPick = pick.getUniformLocation("SCENEJS_uMNMatrix"); }, - draw : function(ctx) { + draw : function(frameCtx) { /* Rebuild core's matrix from matrices at cores on path up to root */ @@ -17631,10 +18020,10 @@ SceneJS_ChunkFactory.createChunkType({ gl.uniformMatrix4fv(this._uNormalMatLocationDraw, gl.FALSE, this.core.normalMat); } - ctx.modelMat = this.core.mat; + frameCtx.modelMat = this.core.mat; }, - pick : function(ctx) { + pick : function(frameCtx) { /* Rebuild core's matrix from matrices at cores on path up to root */ @@ -17652,7 +18041,7 @@ SceneJS_ChunkFactory.createChunkType({ gl.uniformMatrix4fv(this._uNormalMatLocationPick, gl.FALSE, this.core.normalMat); } - ctx.modelMat = this.core.mat; + frameCtx.modelMat = this.core.mat; } }); SceneJS.configure({ pluginPath: "http://xeolabs.github.com/scenejs/api/latest/plugins" }); \ No newline at end of file diff --git a/build.js b/build.js index 3ed67711..a4249473 100755 --- a/build.js +++ b/build.js @@ -152,8 +152,10 @@ "src/core/scene/clips.js", "src/core/scene/enable.js", "src/core/scene/flags.js", - "src/core/scene/framebuf.js", + "src/core/scene/colorTarget.js", + "src/core/scene/depthTarget.js", "src/core/scene/geometry.js", + "src/core/scene/stage.js", "src/core/scene/layer.js", "src/core/scene/library.js", "src/core/scene/lights.js", @@ -162,8 +164,8 @@ "src/core/scene/morphGeometry.js", "src/core/scene/name.js", "src/core/scene/renderer.js", - "src/core/scene/depthbuf.js", - "src/core/scene/colorbuf.js", + "src/core/scene/depthBuffer.js", + "src/core/scene/colorBuffer.js", "src/core/scene/view.js", "src/core/scene/scene.js", "src/core/scene/shader.js", @@ -200,7 +202,7 @@ "src/core/display/chunks/clipsChunk.js", "src/core/display/chunks/drawChunk.js", "src/core/display/chunks/flagsChunk.js", - "src/core/display/chunks/framebufChunk.js", + "src/core/display/chunks/renderTargetChunk.js", "src/core/display/chunks/geometryChunk.js", "src/core/display/chunks/lightsChunk.js", "src/core/display/chunks/listenersChunk.js", @@ -209,8 +211,8 @@ "src/core/display/chunks/nameChunk.js", "src/core/display/chunks/programChunk.js", "src/core/display/chunks/rendererChunk.js", - "src/core/display/chunks/depthbufChunk.js", - "src/core/display/chunks/colorbufChunk.js", + "src/core/display/chunks/depthBufferChunk.js", + "src/core/display/chunks/colorBufferChunk.js", "src/core/display/chunks/viewChunk.js", "src/core/display/chunks/shaderChunk.js", "src/core/display/chunks/shaderParamsChunk.js", @@ -253,6 +255,7 @@ var productionBuild = true; var distDir = "api/" + (productionBuild ? "latest" : "dev"); +// var distDir = "/media/lindsay/3d58a38b-6943-4956-9cd2-94656da3c188/xeolabs/human-web6/human-web/lib/scenejs"; var distPluginDir = distDir + "/plugins"; var distExtrasDir = distDir + "/extras"; diff --git a/css/styles.css b/css/styles.css index 939de699..0a5808a9 100644 --- a/css/styles.css +++ b/css/styles.css @@ -661,6 +661,30 @@ h3.feature-category { background: url("../images/bullet-point.png") no-repeat 8px 2px !important; } + +.feature-category-description { + color: #71705a; + text-decoration: none; + font-size: 14px; + padding-top: 4px; + padding-bottom: 4px; + margin-top: 10px; + margin-bottom: 10px; + font-weight: normal; +} + +/*.infoFirst {*/ + /*color: #71705a;*/ + /*text-decoration: none;*/ + /*font-style: italic;*/ + /*font-size: 14px;*/ + /*background-color: aliceblue;*/ + /*padding-top: 4px;*/ + /*padding-bottom: 4px;*/ + /*margin-top: 0;*/ + /*margin-bottom: 4px;*/ +/*}*/ + pre { font-family: 'Droid Sans Mono', 'Courier New', monospace; diff --git a/demos/cameras-pickFlyOrbit-city.html b/demos/cameras-pickFlyOrbit-city.html deleted file mode 100644 index 0c6ffac0..00000000 --- a/demos/cameras-pickFlyOrbit-city.html +++ /dev/null @@ -1,188 +0,0 @@ - - - - SceneJS Example - - - - - - - - -
- SceneJS experimental camera - plugin - -
- - - - \ No newline at end of file diff --git a/demos/cameras-pickFlyOrbit-terrain.html b/demos/cameras-pickFlyOrbit-terrain.html deleted file mode 100644 index 03fb05a3..00000000 --- a/demos/cameras-pickFlyOrbit-terrain.html +++ /dev/null @@ -1,140 +0,0 @@ - - - - SceneJS Example - - - - - - - - -
- SceneJS experimental camera plugin - -
- - - - \ No newline at end of file diff --git a/demos/heightmaps-custom.html b/demos/heightmaps-custom.html deleted file mode 100644 index b46bfbe8..00000000 --- a/demos/heightmaps-custom.html +++ /dev/null @@ -1,108 +0,0 @@ - - - - SceneJS Example - - - - - - - - - - - - \ No newline at end of file diff --git a/demos/heightmaps-snowypeaks.html b/demos/heightmaps-snowypeaks.html deleted file mode 100644 index 196fb180..00000000 --- a/demos/heightmaps-snowypeaks.html +++ /dev/null @@ -1,143 +0,0 @@ - - - - SceneJS Example - - - - - - - - - - - - \ No newline at end of file diff --git a/demos/nodes-custom-tank.html b/demos/nodes-custom-tank.html deleted file mode 100644 index d0749c0a..00000000 --- a/demos/nodes-custom-tank.html +++ /dev/null @@ -1,109 +0,0 @@ - - - - SceneJS Example - - - - - - - - - - - - \ No newline at end of file diff --git a/demos/physics-spheres.html b/demos/physics-spheres.html deleted file mode 100644 index 8d8a244c..00000000 --- a/demos/physics-spheres.html +++ /dev/null @@ -1,224 +0,0 @@ - - - - SceneJS Example - - - - - - - - - - - - - - \ No newline at end of file diff --git a/demos/textures-bumpMap-add.html b/demos/textures-bumpMap-add.html deleted file mode 100644 index 376d0980..00000000 --- a/demos/textures-bumpMap-add.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - SceneJS Example - - - - - - - - - - \ No newline at end of file diff --git a/demos/textures-bumpMap-colorMap.html b/demos/textures-bumpMap-colorMap.html deleted file mode 100644 index c5ba09ac..00000000 --- a/demos/textures-bumpMap-colorMap.html +++ /dev/null @@ -1,105 +0,0 @@ - - - - SceneJS Example - - - - - - - - - - \ No newline at end of file diff --git a/demos/textures-bumpMap-multiply.html b/demos/textures-bumpMap-multiply.html deleted file mode 100644 index 16ec4a40..00000000 --- a/demos/textures-bumpMap-multiply.html +++ /dev/null @@ -1,93 +0,0 @@ - - - - SceneJS Example - - - - - - - - - - \ No newline at end of file diff --git a/demos/textures-glowMap-vertexDisplace.html b/demos/textures-glowMap-vertexDisplace.html deleted file mode 100644 index a7f50cfe..00000000 --- a/demos/textures-glowMap-vertexDisplace.html +++ /dev/null @@ -1,179 +0,0 @@ - - - - SceneJS Example - - - - - - - - - - \ No newline at end of file diff --git a/demos/textures-rtt.html b/demos/textures-rtt.html deleted file mode 100644 index 16f4968a..00000000 --- a/demos/textures-rtt.html +++ /dev/null @@ -1,175 +0,0 @@ - - - - SceneJS Example - - - - - - - - - - - - \ No newline at end of file diff --git a/docs/files.html b/docs/files.html deleted file mode 100644 index 2cc77a37..00000000 --- a/docs/files.html +++ /dev/null @@ -1,1116 +0,0 @@ - - - - - - JsDoc Reference - File Index - - - - - - - - -
-
Class Index -| File Index
-
-

Classes

- -
-
- -
-

File Index

- - -
-

licenses/license-header.js

- -
- - - - -
-
-
- -
-

src/core/canvas.js

- -
- - - - -
-
-
- -
-

src/core/config.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/cameraChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/chunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/chunkFactory.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/clipsChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/drawChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/flagsChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/framebufChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/geometryChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/lightsChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/listenersChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/lookAtChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/materialChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/morphGeometryChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/nameChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/programChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/rendererChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/shaderChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/shaderParamsChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/textureChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/chunks/xformChunk.js

- -
- - - - -
-
-
- -
-

src/core/display/display.js

- -
- - - - -
-
-
- -
-

src/core/display/object.js

- -
- - - - -
-
-
- -
-

src/core/display/objectFactory.js

- -
- - - - -
-
-
- -
-

src/core/display/program.js

- -
- - - - -
-
-
- -
-

src/core/display/programFactory.js

- -
- - - - -
-
-
- -
-

src/core/display/programSource.js

- -
- - - - -
-
-
- -
-

src/core/display/programSourceFactory.js

- -
- - - - -
-
-
- -
-

src/core/display/renderContext.js

- -
- - - - -
-
-
- -
-

src/core/engine.js

- -
- - - - -
-
-
- -
-

src/core/errors.js

- -
- - - - -
-
-
- -
-

src/core/eventManager.js

- -
- - - - -
-
-
- -
-

src/core/events.js

- -
- - - - -
-
-
- -
-

src/core/log.js

- -
- - - - -
-
-
- -
-

src/core/map.js

- -
- - - - -
-
-
- -
-

src/core/math.js

- -
- - - - -
-
-
- -
-

src/core/plugins.js

- -
- - - - -
-
-
- -
-

src/core/scene/camera.js

- -
- - - - -
-
-
- -
-

src/core/scene/clips.js

- -
- - - - -
-
-
- -
-

src/core/scene/core.js

- -
- - - - -
-
-
- -
-

src/core/scene/coreFactory.js

- -
- - - - -
-
-
- -
-

src/core/scene/flags.js

- -
- - - - -
-
-
- -
-

src/core/scene/framebuf.js

- -
- - - - -
-
-
- -
-

src/core/scene/geometry.js

- -
- - - - -
-
-
- -
-

src/core/scene/layer.js

- -
- - - - -
-
-
- -
-

src/core/scene/library.js

- -
- - - - -
-
-
- -
-

src/core/scene/lights.js

- -
- - - - -
-
-
- -
-

src/core/scene/lookAt.js

- -
- - - - -
-
-
- -
-

src/core/scene/material.js

- -
- - - - -
-
-
- -
-

src/core/scene/matrix.js

- -
- - - - -
-
-
- -
-

src/core/scene/modelXFormStack.js

- -
- - - - -
-
-
- -
-

src/core/scene/morphGeometry.js

- -
- - - - -
-
-
- -
-

src/core/scene/name.js

- -
- - - - -
-
-
- -
-

src/core/scene/node.js

- -
- - - - -
-
-
- -
-

src/core/scene/nodeEvents.js

- -
- - - - -
-
-
- -
-

src/core/scene/nodeFactory.js

- -
- - - - -
-
-
- -
-

src/core/scene/renderer.js

- -
- - - - -
-
-
- -
-

src/core/scene/rotate.js

- -
- - - - -
-
-
- -
-

src/core/scene/scale.js

- -
- - - - -
-
-
- -
-

src/core/scene/scene.js

- -
- - - - -
-
-
- -
-

src/core/scene/shader.js

- -
- - - - -
-
-
- -
-

src/core/scene/shaderParams.js

- -
- - - - -
-
-
- -
-

src/core/scene/tag.js

- -
- - - - -
-
-
- -
-

src/core/scene/texture.js

- -
- - - - -
-
-
- -
-

src/core/scene/translate.js

- -
- - - - -
-
-
- -
-

src/core/scene/xform.js

- -
- - - - -
-
-
- -
-

src/core/scenejs.js

- -
- - - - -
-
-
- -
-

src/core/status.js

- -
- - - - -
-
-
- -
-

src/core/webgl-debug-utils.js

- -
- - - - -
-
-
- -
-

src/core/webgl.js

- -
- - - - -
-
-
- - -
-
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - \ No newline at end of file diff --git a/docs/index.html b/docs/index.html deleted file mode 100644 index 88cc8444..00000000 --- a/docs/index.html +++ /dev/null @@ -1,402 +0,0 @@ - - - - - - JsDoc Reference - Index - - - - - - - - -
-
Class Index -| File Index
-
-

Classes

- -
-
- -
-

Class Index

- - -
-

_global_

- -
-
- -
-

SceneJS.Camera

- Scene graph node which defines the projection transform to apply to the SceneJS.Geometry nodes in its subgraph -
-
- -
-

SceneJS.Clips

- Scene graph node which defines one or more arbitrarily-aligned clip planes to clip the SceneJS.Geometry nodes in its subgraph -
-
- -
-

SceneJS.Flags

- Scene graph node which sets rendering mode flags for its subgraph -
-
- -
-

SceneJS.Framebuf

- Scene graph node which sets up a frame buffer to which the SceneJS.Geometry nodes in its subgraph will be rendered. -
-
- -
-

SceneJS.Geometry

- Scene graph node that defines geometry. -
-
- -
-

SceneJS.Layer

- Scene graph node which assigns the SceneJS.Geometrys within its subgraph to a prioritised render bin -
-
- -
-

SceneJS.Library

- Scene graph node which assigns nodes in its subgraph to a library -
-
- -
-

SceneJS.Lights

- Scene graph node which defines light sources to illuminate the SceneJS.Geometrys within its subgraph -
-
- -
-

SceneJS.Lookat

- Scene graph node which defines the viewing transform for the SceneJS.Geometrys within its subgraph -
-
- -
-

SceneJS.Material

- Scene graph node which defines surface material properties for the SceneJS.Geometrys within its subgraph -
-
- -
-

SceneJS.Matrix

- Scene graph node which defines a modelling transform matrix to apply to the objects in its subgraph -
-
- -
-

SceneJS.MorphGeometry

- Scene graph node which defines morphing behaviour for the SceneJS.Geometrys within its subgraph -
-
- -
-

SceneJS.Name

- Scene graph node which assigns a pick name to the SceneJS.Geometry nodes in its subgraph. -
-
- -
-

SceneJS.Node

- The basic scene graph node type -
-
- -
-

SceneJS.Node#constructor

- Basic scene graph node -
-
- -
-

SceneJS.RenderContext

- A facade which exposes internal scene rendering state to "rendered" event listeners bound to scene graph nodes with SceneJS.Node#bind. -
-
- -
-

SceneJS.Rotate

- Scene graph node which defines a rotation modelling transform to apply to the objects in its subgraph -
-
- -
-

SceneJS.Scale

- Scene graph node which defines a rotation modelling transform to apply to the objects in its subgraph -
-
- -
-

SceneJS.Scene

- The root node of a scenegraph -
-
- -
-

SceneJS.Tag

- Scene graph node which assigns a symbolic tag name to the SceneJS.Geometry nodes in its subgraph. -
-
- -
-

SceneJS.Texture

- Scene graph node which defines one or more textures to apply to the SceneJS.Geometry nodes in its subgraph -
-
- -
-

SceneJS.Translate

- Scene graph node which defines a translation modelling transform to apply to the objects in its subgraph -
-
- -
-

SceneJS.XForm

- Scene graph node which defines the modelling transform to apply to the objects in its subgraph -
-
- -
-

SceneJS_webgl_Program

- Wrapper for a WebGL program -
-
- - -
-
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - \ No newline at end of file diff --git a/docs/symbols/SceneJS.Camera.html b/docs/symbols/SceneJS.Camera.html deleted file mode 100644 index 6d27acae..00000000 --- a/docs/symbols/SceneJS.Camera.html +++ /dev/null @@ -1,498 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Camera - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Camera -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines the projection transform to apply to the SceneJS.Geometry nodes in its subgraph - - -
Defined in: camera.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
-
  - -
-
  -
setOptics(optics) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Camera() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getMatrix() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getOptics() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - setOptics(optics) - -
-
- - - -
- - - - -
-
Parameters:
- -
- optics - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Clips.html b/docs/symbols/SceneJS.Clips.html deleted file mode 100644 index 3478038c..00000000 --- a/docs/symbols/SceneJS.Clips.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Clips - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Clips -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines one or more arbitrarily-aligned clip planes to clip the SceneJS.Geometry nodes in its subgraph - - -
Defined in: clips.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
setClips(clips) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Clips() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - setClips(clips) - -
-
- - - -
- - - - -
-
Parameters:
- -
- clips - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Flags.html b/docs/symbols/SceneJS.Flags.html deleted file mode 100644 index 602ff817..00000000 --- a/docs/symbols/SceneJS.Flags.html +++ /dev/null @@ -1,1220 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Flags - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Flags -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which sets rendering mode flags for its subgraph - - -
Defined in: flags.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
addFlags(flags) -
-
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  -
setAmbient(ambient) -
-
-
  -
setBackfaceLighting(backfaceLighting) -
-
-
  -
setBackfaces(backfaces) -
-
-
  -
setBackfaceTexturing(backfaceTexturing) -
-
-
  -
setClipping(clipping) -
-
-
  -
setEnabled(enabled) -
-
-
  -
setFlags(flags) -
-
-
  -
setFrontface(frontface) -
-
-
  -
setPicking(picking) -
-
-
  -
setTransparent(transparent) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Flags() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - addFlags(flags) - -
-
- - - -
- - - - -
-
Parameters:
- -
- flags - -
-
- -
- - - - - - - - -
- - -
- - - getAmbient() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getBackfaceLighting() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getBackfaces() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getBackfaceTexturing() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getClipping() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getEnabled() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getFlags() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getFrontface() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getPicking() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getTransparent() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - setAmbient(ambient) - -
-
- - - -
- - - - -
-
Parameters:
- -
- ambient - -
-
- -
- - - - - - - - -
- - -
- - - setBackfaceLighting(backfaceLighting) - -
-
- - - -
- - - - -
-
Parameters:
- -
- backfaceLighting - -
-
- -
- - - - - - - - -
- - -
- - - setBackfaces(backfaces) - -
-
- - - -
- - - - -
-
Parameters:
- -
- backfaces - -
-
- -
- - - - - - - - -
- - -
- - - setBackfaceTexturing(backfaceTexturing) - -
-
- - - -
- - - - -
-
Parameters:
- -
- backfaceTexturing - -
-
- -
- - - - - - - - -
- - -
- - - setClipping(clipping) - -
-
- - - -
- - - - -
-
Parameters:
- -
- clipping - -
-
- -
- - - - - - - - -
- - -
- - - setEnabled(enabled) - -
-
- - - -
- - - - -
-
Parameters:
- -
- enabled - -
-
- -
- - - - - - - - -
- - -
- - - setFlags(flags) - -
-
- - - -
- - - - -
-
Parameters:
- -
- flags - -
-
- -
- - - - - - - - -
- - -
- - - setFrontface(frontface) - -
-
- - - -
- - - - -
-
Parameters:
- -
- frontface - -
-
- -
- - - - - - - - -
- - -
- - - setPicking(picking) - -
-
- - - -
- - - - -
-
Parameters:
- -
- picking - -
-
- -
- - - - - - - - -
- - -
- - - setTransparent(transparent) - -
-
- - - -
- - - - -
-
Parameters:
- -
- transparent - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Framebuf.html b/docs/symbols/SceneJS.Framebuf.html deleted file mode 100644 index 51c06287..00000000 --- a/docs/symbols/SceneJS.Framebuf.html +++ /dev/null @@ -1,368 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Framebuf - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Framebuf -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which sets up a frame buffer to which the SceneJS.Geometry nodes in its subgraph will be rendered. -The frame buffer may be referenced as an image source by successive SceneJS.Texture nodes. - - -
Defined in: framebuf.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Framebuf() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Geometry.html b/docs/symbols/SceneJS.Geometry.html deleted file mode 100644 index 52b230e7..00000000 --- a/docs/symbols/SceneJS.Geometry.html +++ /dev/null @@ -1,951 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Geometry - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Geometry -

- - -

- -
Extends - SceneJS.Node -When this node is at a leaf, it defines a scene object which inherits the state set up by all the nodes above it -on the path up to the root. These nodes can be nested, so that child geometries inherit arrays -defined by parent geometries..
- - - Scene graph node that defines geometry. - - -
Defined in: geometry.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  -
getUV() -
-
-
  -
getUV2() -
-
-
  -
setColors(data) -
-
-
  -
setNormals(data) -
-
-
  -
setPositions(data) -
-
-
  -
setSource(sourceConfigs) -
-
-
  -
setUV(data) -
-
-
  -
setUV2(data) -
-
-
- - - - - - - - - -
-
- Class Detail -
- -
- SceneJS.Geometry() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getBoundary() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getColors() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getIndices() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getNormals() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getPositions() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getPrimitive() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getSource() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getUV() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getUV2() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - setColors(data) - -
-
- - - -
- - - - -
-
Parameters:
- -
- data - -
-
- -
- - - - - - - - -
- - -
- - - setNormals(data) - -
-
- - - -
- - - - -
-
Parameters:
- -
- data - -
-
- -
- - - - - - - - -
- - -
- - - setPositions(data) - -
-
- - - -
- - - - -
-
Parameters:
- -
- data - -
-
- -
- - - - - - - - -
- - -
- - - setSource(sourceConfigs) - -
-
- - - -
- - - - -
-
Parameters:
- -
- sourceConfigs - -
-
- -
- - - - - - - - -
- - -
- - - setUV(data) - -
-
- - - -
- - - - -
-
Parameters:
- -
- data - -
-
- -
- - - - - - - - -
- - -
- - - setUV2(data) - -
-
- - - -
- - - - -
-
Parameters:
- -
- data - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Layer.html b/docs/symbols/SceneJS.Layer.html deleted file mode 100644 index f638e99f..00000000 --- a/docs/symbols/SceneJS.Layer.html +++ /dev/null @@ -1,543 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Layer - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Layer -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which assigns the SceneJS.Geometrys within its subgraph to a prioritised render bin - - -
Defined in: layer.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
-
  - -
-
  -
setEnabled(enabled) -
-
-
  -
setPriority(priority) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Layer() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getEnabled() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getPriority() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - setEnabled(enabled) - -
-
- - - -
- - - - -
-
Parameters:
- -
- enabled - -
-
- -
- - - - - - - - -
- - -
- - - setPriority(priority) - -
-
- - - -
- - - - -
-
Parameters:
- -
- priority - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Library.html b/docs/symbols/SceneJS.Library.html deleted file mode 100644 index 8eead211..00000000 --- a/docs/symbols/SceneJS.Library.html +++ /dev/null @@ -1,367 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Library - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Library -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which assigns nodes in its subgraph to a library - - -
Defined in: library.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Library() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Lights.html b/docs/symbols/SceneJS.Lights.html deleted file mode 100644 index d92f381b..00000000 --- a/docs/symbols/SceneJS.Lights.html +++ /dev/null @@ -1,430 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Lights - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Lights -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines light sources to illuminate the SceneJS.Geometrys within its subgraph - - -
Defined in: lights.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
setLights(lights) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Lights() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - setLights(lights) - -
-
- - - -
- - - - -
-
Parameters:
- -
- lights - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Lookat.html b/docs/symbols/SceneJS.Lookat.html deleted file mode 100644 index 074555bb..00000000 --- a/docs/symbols/SceneJS.Lookat.html +++ /dev/null @@ -1,1642 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Lookat - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Lookat -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines the viewing transform for the SceneJS.Geometrys within its subgraph - - -
Defined in: lookAt.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
-
  -
getEye() -
-
-
  -
getLook() -
-
-
  - -
Returns a copy of the matrix as a 1D array of 16 elements
-
  -
getUp() -
-
-
  -
incEye(eye) -
-
-
  -
incEyeX(x) -
-
-
  -
incEyeY(y) -
-
-
  -
incEyeZ(z) -
-
-
  -
incLook(look) -
-
-
  -
incLookX(x) -
-
-
  -
incLookY(y) -
-
-
  -
incLookZ(z) -
-
-
  -
incUp(up) -
-
-
  -
incUpX(x) -
-
-
  -
incUpY(y) -
-
-
  -
incUpZ(z) -
-
-
  -
setEye(eye) -
-
-
  -
setEyeX(x) -
-
-
  -
setEyeY(y) -
-
-
  -
setEyeZ(z) -
-
-
  -
setLook(look) -
-
-
  -
setLookX(x) -
-
-
  -
setLookY(y) -
-
-
  -
setLookZ(z) -
-
-
  -
setUp(up) -
-
-
  -
setUpX(x) -
-
-
  -
setUpY(y) -
-
-
  -
setUpZ(z) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Lookat() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getAttributes() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getEye() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getLook() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - {Number[16]} - getMatrix() - -
-
- Returns a copy of the matrix as a 1D array of 16 elements - - -
- - - - - - - - -
-
Returns:
- -
{Number[16]}
- -
- - - - -
- - -
- - - getUp() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - incEye(eye) - -
-
- - - -
- - - - -
-
Parameters:
- -
- eye - -
-
- -
- - - - - - - - -
- - -
- - - incEyeX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - incEyeY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - incEyeZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - -
- - -
- - - incLook(look) - -
-
- - - -
- - - - -
-
Parameters:
- -
- look - -
-
- -
- - - - - - - - -
- - -
- - - incLookX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - incLookY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - incLookZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - -
- - -
- - - incUp(up) - -
-
- - - -
- - - - -
-
Parameters:
- -
- up - -
-
- -
- - - - - - - - -
- - -
- - - incUpX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - incUpY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - incUpZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - -
- - -
- - - setEye(eye) - -
-
- - - -
- - - - -
-
Parameters:
- -
- eye - -
-
- -
- - - - - - - - -
- - -
- - - setEyeX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - setEyeY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - setEyeZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - -
- - -
- - - setLook(look) - -
-
- - - -
- - - - -
-
Parameters:
- -
- look - -
-
- -
- - - - - - - - -
- - -
- - - setLookX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - setLookY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - setLookZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - -
- - -
- - - setUp(up) - -
-
- - - -
- - - - -
-
Parameters:
- -
- up - -
-
- -
- - - - - - - - -
- - -
- - - setUpX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - setUpY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - setUpZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Material.html b/docs/symbols/SceneJS.Material.html deleted file mode 100644 index 5bc87d7c..00000000 --- a/docs/symbols/SceneJS.Material.html +++ /dev/null @@ -1,859 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Material - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Material -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines surface material properties for the SceneJS.Geometrys within its subgraph - - -
Defined in: material.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
-
  - -
-
  -
getEmit() -
-
-
  - -
-
  - -
-
  - -
-
  -
setAlpha(alpha) -
-
-
  -
setBaseColor(color) -
-
-
  -
setEmit(emit) -
-
-
  -
setShine(shine) -
-
-
  -
setSpecular(specular) -
-
-
  - -
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Material() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getAlpha() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getBaseColor() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getEmit() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getShine() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getSpecular() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getSpecularColor() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - setAlpha(alpha) - -
-
- - - -
- - - - -
-
Parameters:
- -
- alpha - -
-
- -
- - - - - - - - -
- - -
- - - setBaseColor(color) - -
-
- - - -
- - - - -
-
Parameters:
- -
- color - -
-
- -
- - - - - - - - -
- - -
- - - setEmit(emit) - -
-
- - - -
- - - - -
-
Parameters:
- -
- emit - -
-
- -
- - - - - - - - -
- - -
- - - setShine(shine) - -
-
- - - -
- - - - -
-
Parameters:
- -
- shine - -
-
- -
- - - - - - - - -
- - -
- - - setSpecular(specular) - -
-
- - - -
- - - - -
-
Parameters:
- -
- specular - -
-
- -
- - - - - - - - -
- - -
- - - setSpecularColor(color) - -
-
- - - -
- - - - -
-
Parameters:
- -
- color - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Matrix.html b/docs/symbols/SceneJS.Matrix.html deleted file mode 100644 index 9ad624f6..00000000 --- a/docs/symbols/SceneJS.Matrix.html +++ /dev/null @@ -1,563 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Matrix - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Matrix -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines a modelling transform matrix to apply to the objects in its subgraph - - -
Defined in: matrix.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - - - - - - - - - - - - - - - -
Field Summary
Field AttributesField Name and Description
  - -
Sets the matrix elements
-
- - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
Get Model matrix
-
  - -
Get World matrix.
-
  -
setMatrix(elements) -
-
Sets the matrix elements
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Matrix() -
- -
- - -
- - - - - - - - - - - - -
- - - - -
- Field Detail -
- - -
- - - setElements - -
-
- Sets the matrix elements - - -
- - - - - - - - - - - - - - -
- Method Detail -
- - -
- - {*} - getModelMatrix() - -
-
- Get Model matrix - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - {*} - getWorldMatrix() - -
-
- Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next -tranform (scale, matrix, translate etc) node on the path to the scene root. - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - - setMatrix(elements) - -
-
- Sets the matrix elements - - -
- - - - -
-
Parameters:
- -
- elements - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.MorphGeometry.html b/docs/symbols/SceneJS.MorphGeometry.html deleted file mode 100644 index e29ff10d..00000000 --- a/docs/symbols/SceneJS.MorphGeometry.html +++ /dev/null @@ -1,543 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.MorphGeometry - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.MorphGeometry -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines morphing behaviour for the SceneJS.Geometrys within its subgraph - - -
Defined in: morphGeometry.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
-
  - -
-
  -
setFactor(factor) -
-
-
  -
setSource(sourceConfigs) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.MorphGeometry() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getFactor() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getSource() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - setFactor(factor) - -
-
- - - -
- - - - -
-
Parameters:
- -
- factor - -
-
- -
- - - - - - - - -
- - -
- - - setSource(sourceConfigs) - -
-
- - - -
- - - - -
-
Parameters:
- -
- sourceConfigs - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Name.html b/docs/symbols/SceneJS.Name.html deleted file mode 100644 index 964a8806..00000000 --- a/docs/symbols/SceneJS.Name.html +++ /dev/null @@ -1,464 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Name - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Name -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which assigns a pick name to the SceneJS.Geometry nodes in its subgraph. - - -
Defined in: name.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  -
- SceneJS.Name() -
-
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
getName() -
-
-
  -
setName(name) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Name() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getName() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - setName(name) - -
-
- - - -
- - - - -
-
Parameters:
- -
- name - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Node#constructor.html b/docs/symbols/SceneJS.Node#constructor.html deleted file mode 100644 index a277e8f2..00000000 --- a/docs/symbols/SceneJS.Node#constructor.html +++ /dev/null @@ -1,347 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Node#constructor - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Node#constructor -

- - -

- - - - Basic scene graph node - - -
Defined in: node.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - - - - - -
-
- Class Detail -
- -
- SceneJS.Node#constructor() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Node.html b/docs/symbols/SceneJS.Node.html deleted file mode 100644 index f5fba29b..00000000 --- a/docs/symbols/SceneJS.Node.html +++ /dev/null @@ -1,2757 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Node - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Node -

- - -

- - - - The basic scene graph node type - - -
Defined in: node.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  -
- SceneJS.Node() -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field Summary
Field AttributesField Name and Description
  - -
-
  -
- data -
-
Optional arbitrary JSON object attached to this node
-
  -
- dirty -
-
-
  -
- id -
-
ID of this node, unique within its scene.
-
  -
- nodes -
-
Child nodes
-
  -
- parent -
-
Parent node
-
  -
- type -
-
Type of this node (eg.
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
add(attr, value) -
-
-
  -
addListener(eventName, fn, options) -
-
Registers a listener for a given event on this node.
-
  -
addNode(node) -
-
Appends a child node
-
  -
addNodes(nodes) -
-
Appends multiple child nodes
-
  -
bind(name, handler) -
-
Binds a listener to an event on the selected node
-
  -
destroy() -
-
Destroys this node.
-
  -
disconnect(id) -
-
Disconnects the child node from its parent, given as a node object
-
  - -
Disconnects the child node at the given index from its parent node
-
  - -
Disconnects all child nodes from their parent node and returns them in an array.
-
  -
eachNode(fn, options) -
-
Iterates over sub-nodes of the selected node, executing a function -for each.
-
  -
eachParent(fn) -
-
Iterates over parent nodes on the path from the selected node to the root, executing a function -for each.
-
  -
findNodesByType(type, recursive) -
-
Returns either all child or all sub-nodes of the given type, depending on whether search is recursive or not.
-
  - -
Finds the first node on path up to root whose type equals that given
-
  -
get(attr) -
-
-
  - -
Returns the ID of this node's core
-
  -
getData() -
-
Returns the data object attached to this node.
-
  - -
Returns first child node.
-
  -
getId() -
-
Alias for getID
-
  -
getID() -
-
Get the node's ID
-
  -
getJSON() -
-
Returns an object containing the attributes that were given when creating the node.
-
  - -
Returns last child node.
-
  -
getNode(id) -
-
Returns child node with the given ID.
-
  -
getNodeAt(index) -
-
Returns child node at given index.
-
  - -
Alias for getID
-
  - -
Returns child nodes
-
  - -
Returns the number of child nodes
-
  - -
Returns the parent node
-
  - -
Returns this node's SceneJS.Scene
-
  -
getType() -
-
Returns the node's type.
-
  -
hasListener(eventName) -
-
Returns true if this node has any listeners for the given event
-
  - -
Returns true if this node has any listeners at all.
-
  -
hasNode(node) -
-
Returns true if a child node matching given ID or index exists on this node
-
  -
inc(attr, value) -
-
-
  -
insert(attr, value) -
-
-
  -
insertNode(node, i) -
-
Inserts a subgraph into child nodes
-
  -
mapNodes(func) -
-
Calls the given function on each node in the subgraph rooted by this node, including this node.
-
  -
node(node) -
-
Selects a child node matching given ID or index
-
  - -
-
  -
remove(attr, value) -
-
-
  -
removeListener(eventName, fn) -
-
Removes a handler that is registered for the given event on this node.
-
  - -
Removes all listeners registered on this node.
-
  -
removeNode(id) -
-
Removes the child node, given as either a node object or an ID string.
-
  -
removeNodeAt(index) -
-
Removes the child node at the given index
-
  - -
Removes all child nodes and returns them in an array.
-
  -
set(attr, value) -
-
Given a map of name-value pairs, calls a getter method for each name, -feeding into it the corresponding value.
-
  -
setData(data) -
-
Sets a data object on this node.
-
  -
splice() -
-
Destroys this node and moves children up to parent, inserting them where this node resided.
-
  -
unbind(name, handler) -
-
Unbinds a listener for an event on the selected node
-
- - - - - - - - - -
-
- Class Detail -
- -
- SceneJS.Node() -
- -
- - -
- - - - - - - - - - - - -
- - - - -
- Field Detail -
- - -
- - - branchDirty - -
-
- - - -
- - - - - - - - -
- - -
- - {JSON} - data - -
-
- Optional arbitrary JSON object attached to this node - - -
- - - - - - - - -
- - -
- - - dirty - -
-
- - - -
- - - - - - - - -
- - -
- - {String|Number} - id - -
-
- ID of this node, unique within its scene. The ID is a string if it was defined by the application -via the node's JSON configuration, otherwise it is a number if it was left to SceneJS to automatically create. - - -
- - - - - - - - -
- - -
- - {SceneJS.Node[]} - nodes - -
-
- Child nodes - - -
- - - - - - - - -
- - -
- - {SceneJS.Node} - parent - -
-
- Parent node - - -
- - - - - - - - -
- - -
- - {String} - type - -
-
- Type of this node (eg. "material", "texture" etc) - - -
- - - - - - - - - - - - - - -
- Method Detail -
- - -
- - - add(attr, value) - -
-
- - - -
- - - - -
-
Parameters:
- -
- attr - -
-
- -
- value - -
-
- -
- - - - - - - - -
- - -
- - {Node} - addListener(eventName, fn, options) - -
-
- Registers a listener for a given event on this node. If the event type -is not supported by this node type, then the listener will never be called. -

Example: -


-var node = new Node();
-
-node.addListener(
-
-             // eventName
-             "some-event",
-
-             // handler
-             function(node,      // Node we are listening to
-                      params) {  // Whatever params accompany the event type
-
-                    // ...
-             }
-);
-
-
-
- - -
- - - - -
-
Parameters:
- -
- {String} eventName - -
-
One of the event types supported by this node
- -
- {Function} fn - -
-
- Handler function that be called as specified
- -
- options - -
-
- Optional options for the handler as specified
- -
- - - - - -
-
Returns:
- -
{Node} this
- -
- - - - -
- - -
- - - addNode(node) - -
-
- Appends a child node - - -
- - - - -
-
Parameters:
- -
- node - -
-
- -
- - - - - - - - -
- - -
- - - addNodes(nodes) - -
-
- Appends multiple child nodes - - -
- - - - -
-
Parameters:
- -
- nodes - -
-
- -
- - - - - - - - -
- - -
- - - bind(name, handler) - -
-
- Binds a listener to an event on the selected node - - -
- - - - -
-
Parameters:
- -
- {String} name - -
-
Event name
- -
- {Function} handler - -
-
Event handler
- -
- - - - - - - - -
- - -
- - - destroy() - -
-
- Destroys this node. It is marked for destruction; when the next scene traversal begins (or the current one ends) -it will be destroyed and removed from it's parent. - - -
- - - - - - - - - - - -
- - -
- - {Node} - disconnect(id) - -
-
- Disconnects the child node from its parent, given as a node object - - -
- - - - -
-
Parameters:
- -
- {String | Node} id - -
-
The target child node, or its ID
- -
- - - - - -
-
Returns:
- -
{Node} The removed child node if located
- -
- - - - -
- - -
- - {Node} - disconnectNodeAt(index) - -
-
- Disconnects the child node at the given index from its parent node - - -
- - - - -
-
Parameters:
- -
- {int} index - -
-
Child node index
- -
- - - - - -
-
Returns:
- -
{Node} The disconnected child node if located, else null
- -
- - - - -
- - -
- - - disconnectNodes() - -
-
- Disconnects all child nodes from their parent node and returns them in an array. - - -
- - - - - - - - - - - -
- - -
- - {Object} - eachNode(fn, options) - -
-
- Iterates over sub-nodes of the selected node, executing a function -for each. With the optional options object we can configure is depth-first or breadth-first order. -If neither, then only the child nodes are iterated. -If the function returns true at any node, then traversal stops and a selector is -returned for that node. - - -
- - - - -
-
Parameters:
- -
- {Function(index|node)} fn - -
-
Function to execute on each child node
- -
- options - -
-
- -
- - - - - -
-
Returns:
- -
{Object} Selector for selected node, if any
- -
- - - - -
- - -
- - {Object} - eachParent(fn) - -
-
- Iterates over parent nodes on the path from the selected node to the root, executing a function -for each. -If the function returns true at any node, then traversal stops and a selector is -returned for that node. - - -
- - - - -
-
Parameters:
- -
- {Function(node|index)} fn - -
-
Function to execute on each instance node
- -
- - - - - -
-
Returns:
- -
{Object} Selector for selected node, if any
- -
- - - - -
- - -
- - - findNodesByType(type, recursive) - -
-
- Returns either all child or all sub-nodes of the given type, depending on whether search is recursive or not. - - -
- - - - -
-
Parameters:
- -
- type - -
-
- -
- recursive - -
-
- -
- - - - - - - - -
- - -
- - - findParentByType(type) - -
-
- Finds the first node on path up to root whose type equals that given - - -
- - - - -
-
Parameters:
- -
- type - -
-
- -
- - - - - - - - -
- - -
- - - get(attr) - -
-
- - - -
- - - - -
-
Parameters:
- -
- attr - -
-
- -
- - - - - - - - -
- - -
- - - getCoreId() - -
-
- Returns the ID of this node's core - - -
- - - - - - - - - - - -
- - -
- - - getData() - -
-
- Returns the data object attached to this node. - - -
- - - - - - - - - - - -
- - -
- - {Node} - getFirstNode() - -
-
- Returns first child node. Returns null if no child nodes. - - -
- - - - - - - - -
-
Returns:
- -
{Node} First child node, or null if not found
- -
- - - - -
- - -
- - - getId() - -
-
- Alias for getID - - -
- - - - - - - - - - - -
- - -
- - - getID() - -
-
- Get the node's ID - - -
- - - - - - - - - - - -
- - -
- - - getJSON() - -
-
- Returns an object containing the attributes that were given when creating the node. Obviously, the map will have -the current values, plus any attributes that were later added through set/add methods on the node - - -
- - - - - - - - - - - -
- - -
- - {Node} - getLastNode() - -
-
- Returns last child node. Returns null if no child nodes. - - -
- - - - - - - - -
-
Returns:
- -
{Node} Last child node, or null if not found
- -
- - - - -
- - -
- - - getNode(id) - -
-
- Returns child node with the given ID. -Returns null if no such child node found. - - -
- - - - -
-
Parameters:
- -
- id - -
-
- -
- - - - - - - - -
- - -
- - {Node} - getNodeAt(index) - -
-
- Returns child node at given index. Returns null if no node at that index. - - -
- - - - -
-
Parameters:
- -
- {Number} index - -
-
The child index
- -
- - - - - -
-
Returns:
- -
{Node} Child node, or null if not found
- -
- - - - -
- - -
- - - getNodeId() - -
-
- Alias for getID - - -
- - - - - - - - - - - -
- - -
- - {Array} - getNodes() - -
-
- Returns child nodes - - -
- - - - - - - - -
-
Returns:
- -
{Array} Child nodes
- -
- - - - -
- - -
- - - getNumNodes() - -
-
- Returns the number of child nodes - - -
- - - - - - - - - - - -
- - -
- - - getParent() - -
-
- Returns the parent node - - -
- - - - - - - - - - - -
- - -
- - - getScene() - -
-
- Returns this node's SceneJS.Scene - - -
- - - - - - - - - - - -
- - -
- - - getType() - -
-
- Returns the node's type. For the Node base class, it is "node", overridden in sub-classes. - - -
- - - - - - - - - - - -
- - -
- - - hasListener(eventName) - -
-
- Returns true if this node has any listeners for the given event - - -
- - - - -
-
Parameters:
- -
- eventName - -
-
- -
- - - - - - - - -
- - -
- - - hasListeners() - -
-
- Returns true if this node has any listeners at all. - - -
- - - - - - - - - - - -
- - -
- - - hasNode(node) - -
-
- Returns true if a child node matching given ID or index exists on this node - - -
- - - - -
-
Parameters:
- -
- {Number|String} node - -
-
Child node index or ID
- -
- - - - - - - - -
- - -
- - - inc(attr, value) - -
-
- - - -
- - - - -
-
Parameters:
- -
- attr - -
-
- -
- value - -
-
- -
- - - - - - - - -
- - -
- - - insert(attr, value) - -
-
- - - -
- - - - -
-
Parameters:
- -
- attr - -
-
- -
- value - -
-
- -
- - - - - - - - -
- - -
- - {Node} - insertNode(node, i) - -
-
- Inserts a subgraph into child nodes - - -
- - - - -
-
Parameters:
- -
- {Node} node - -
-
Child node
- -
- {int} i - -
-
Index for new child node
- -
- - - - - -
-
Returns:
- -
{Node} The child node
- -
- - - - -
- - -
- - - mapNodes(func) - -
-
- Calls the given function on each node in the subgraph rooted by this node, including this node. -The callback takes each node as it's sole argument and traversal stops as soon as the function returns -true and returns the node. - - -
- - - - -
-
Parameters:
- -
- {function(Node)} func - -
-
The function
- -
- - - - - - - - -
- - -
- - - node(node) - -
-
- Selects a child node matching given ID or index - - -
- - - - -
-
Parameters:
- -
- {Number|String} node - -
-
Child node index or ID
- -
- - - - - - - - -
- - -
- - - numNodes() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - remove(attr, value) - -
-
- - - -
- - - - -
-
Parameters:
- -
- attr - -
-
- -
- value - -
-
- -
- - - - - - - - -
- - -
- - - removeListener(eventName, fn) - -
-
- Removes a handler that is registered for the given event on this node. -Does nothing if no such handler registered. - - -
- - - - -
-
Parameters:
- -
- eventName - -
-
- -
- fn - -
-
- -
- - - - - - - - -
- - -
- - - removeListeners() - -
-
- Removes all listeners registered on this node. - - -
- - - - - - - - - - - -
- - -
- - {Node} - removeNode(id) - -
-
- Removes the child node, given as either a node object or an ID string. - - -
- - - - -
-
Parameters:
- -
- {String | Node} id - -
-
The target child node, or its ID
- -
- - - - - -
-
Returns:
- -
{Node} The removed child node if located
- -
- - - - -
- - -
- - - removeNodeAt(index) - -
-
- Removes the child node at the given index - - -
- - - - -
-
Parameters:
- -
- {int} index - -
-
Child node index
- -
- - - - - - - - -
- - -
- - - removeNodes() - -
-
- Removes all child nodes and returns them in an array. - - -
- - - - - - - - - - - -
- - -
- - {*} - set(attr, value) - -
-
- Given a map of name-value pairs, calls a getter method for each name, -feeding into it the corresponding value. - - -
- - - - -
-
Parameters:
- -
- attr - -
-
- -
- value - -
-
- -
- - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - - setData(data) - -
-
- Sets a data object on this node. - - -
- - - - -
-
Parameters:
- -
- data - -
-
- -
- - - - - - - - -
- - -
- - - splice() - -
-
- Destroys this node and moves children up to parent, inserting them where this node resided. - - -
- - - - - - - - - - - -
- - -
- - - unbind(name, handler) - -
-
- Unbinds a listener for an event on the selected node - - -
- - - - -
-
Parameters:
- -
- {String} name - -
-
Event name
- -
- {Function} handler - -
-
Event handler
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.RenderContext.html b/docs/symbols/SceneJS.RenderContext.html deleted file mode 100644 index 69190523..00000000 --- a/docs/symbols/SceneJS.RenderContext.html +++ /dev/null @@ -1,729 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.RenderContext - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.RenderContext -

- - -

- - - - A facade which exposes internal scene rendering state to "rendered" event listeners bound to scene graph nodes with SceneJS.Node#bind. - -

The listener is fired for each SceneJS.Geometry that is rendered within the subgraph of the bound node. -An instance of this facade is passed into the listener's handler, enabling the listener to obtain the various transform -matrices that are active at that SceneJS.Geometry.

- -

The facade instance is only valid within the callback's execution; internally, SceneJS reuses the same instance of the -facade with each scene.

- - -
Defined in: renderContext.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  -
- SceneJS.RenderContext(frameCtx) -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
Get the projection matrix, as defined by the active SceneJS.Camera node.
-
  -
getCameraPos(offset) -
-
Transforms the given world coordinate by the model and view matrices defined by the active SceneJS.XForm and SceneJS.LookAt nodes.
-
  -
getCanvasPos(offset) -
-
Transforms the given world coordinate by the model, view and projection matrices defined by the active SceneJS.XForm, SceneJS.LookAt and SceneJS.Camera nodes.
-
  - -
Get the model matrix, as defined by the active SceneJS.XForm node.
-
  -
getProjPos(offset) -
-
-
  - -
Get the view matrix, as defined by the active SceneJS.LookAt node.
-
  -
getViewPos(offset) -
-
-
  -
getWorldPos(offset) -
-
-
- - - - - - - - - -
-
- Class Detail -
- -
- SceneJS.RenderContext(frameCtx) -
- -
- - -
- - - - - -
-
Parameters:
- -
- frameCtx - -
-
- -
- - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getCameraMatrix() - -
-
- Get the projection matrix, as defined by the active SceneJS.Camera node. - - -
- - - - - - - - - - - -
- - -
- - - getCameraPos(offset) - -
-
- Transforms the given world coordinate by the model and view matrices defined by the active SceneJS.XForm and SceneJS.LookAt nodes. - - -
- - - - -
-
Parameters:
- -
- offset - -
-
- -
- - - - - -
-
Returns:
- -
[Number] The 3D Projection-space coordinate
- -
- - - - -
- - -
- - - getCanvasPos(offset) - -
-
- Transforms the given world coordinate by the model, view and projection matrices defined by the active SceneJS.XForm, SceneJS.LookAt and SceneJS.Camera nodes. - - -
- - - - -
-
Parameters:
- -
- offset - -
-
- -
- - - - - -
-
Returns:
- -
[Number] The 2D Canvas-space coordinate
- -
- - - - -
- - -
- - - getModelMatrix() - -
-
- Get the model matrix, as defined by the active SceneJS.XForm node. - - -
- - - - - - - - - - - -
- - -
- - - getProjPos(offset) - -
-
- - - -
- - - - -
-
Parameters:
- -
- offset - -
-
- -
- - - - - - - - -
- - -
- - - getViewMatrix() - -
-
- Get the view matrix, as defined by the active SceneJS.LookAt node. - - -
- - - - - - - - - - - -
- - -
- - - getViewPos(offset) - -
-
- - - -
- - - - -
-
Parameters:
- -
- offset - -
-
- -
- - - - - - - - -
- - -
- - - getWorldPos(offset) - -
-
- - - -
- - - - -
-
Parameters:
- -
- offset - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Rotate.html b/docs/symbols/SceneJS.Rotate.html deleted file mode 100644 index 5eff20b9..00000000 --- a/docs/symbols/SceneJS.Rotate.html +++ /dev/null @@ -1,955 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Rotate - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Rotate -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines a rotation modelling transform to apply to the objects in its subgraph - - -
Defined in: rotate.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
-
  - -
Get Model matrix
-
  - -
Get World matrix.
-
  -
getX() -
-
-
  -
getXYZ() -
-
-
  -
getY() -
-
-
  -
getZ() -
-
-
  -
incAngle(angle) -
-
-
  -
setAngle(angle) -
-
-
  -
setMultOrder(multOrder) -
-
Sets the multiplication order of this node's transform matrix with respect to the parent modeling transform -in the scene graph.
-
  -
setX(x) -
-
-
  -
setXYZ(xyz) -
-
-
  -
setY(y) -
-
-
  -
setZ(z) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Rotate() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getAngle() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - {*} - getModelMatrix() - -
-
- Get Model matrix - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - {*} - getWorldMatrix() - -
-
- Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next -tranform (scale, rotate, translate etc) node on the path to the scene root. - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - - getX() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getXYZ() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getY() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getZ() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - incAngle(angle) - -
-
- - - -
- - - - -
-
Parameters:
- -
- angle - -
-
- -
- - - - - - - - -
- - -
- - - setAngle(angle) - -
-
- - - -
- - - - -
-
Parameters:
- -
- angle - -
-
- -
- - - - - - - - -
- - -
- - - setMultOrder(multOrder) - -
-
- Sets the multiplication order of this node's transform matrix with respect to the parent modeling transform -in the scene graph. - - -
- - - - -
-
Parameters:
- -
- {String} multOrder - -
-
Mulplication order - "post" and "pre"
- -
- - - - - - - - -
- - -
- - - setX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - setXYZ(xyz) - -
-
- - - -
- - - - -
-
Parameters:
- -
- xyz - -
-
- -
- - - - - - - - -
- - -
- - - setY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - setZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Scale.html b/docs/symbols/SceneJS.Scale.html deleted file mode 100644 index 04aac2d9..00000000 --- a/docs/symbols/SceneJS.Scale.html +++ /dev/null @@ -1,1000 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Scale - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Scale -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines a rotation modelling transform to apply to the objects in its subgraph - - -
Defined in: scale.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
-
  - -
Get Model matrix
-
  - -
Get World matrix.
-
  -
getX() -
-
-
  -
getXYZ() -
-
-
  -
getY() -
-
-
  -
getZ() -
-
-
  -
incX(x) -
-
-
  -
incY(y) -
-
-
  -
incZ(z) -
-
-
  -
setMultOrder(multOrder) -
-
Sets the multiplication order of this node's transform matrix with respect to the parent modeling transform -in the scene graph.
-
  -
setX(x) -
-
-
  -
setXYZ(xyz) -
-
-
  -
setY(y) -
-
-
  -
setZ(z) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Scale() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getAngle() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - {*} - getModelMatrix() - -
-
- Get Model matrix - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - {*} - getWorldMatrix() - -
-
- Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next -tranform (scale, scale, translate etc) node on the path to the scene root. - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - - getX() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getXYZ() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getY() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getZ() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - incX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - incY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - incZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - -
- - -
- - - setMultOrder(multOrder) - -
-
- Sets the multiplication order of this node's transform matrix with respect to the parent modeling transform -in the scene graph. - - -
- - - - -
-
Parameters:
- -
- {String} multOrder - -
-
Mulplication order - "post" and "pre"
- -
- - - - - - - - -
- - -
- - - setX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - setXYZ(xyz) - -
-
- - - -
- - - - -
-
Parameters:
- -
- xyz - -
-
- -
- - - - - - - - -
- - -
- - - setY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - setZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Scene.html b/docs/symbols/SceneJS.Scene.html deleted file mode 100644 index f7974668..00000000 --- a/docs/symbols/SceneJS.Scene.html +++ /dev/null @@ -1,1287 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Scene - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Scene -

- - -

- -
Extends - SceneJS.Node.
- - - The root node of a scenegraph - - -
Defined in: scene.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
containsNode(nodeId) -
-
Determines if node exists in this scene
-
  -
findNode(nodeId) -
-
Finds the node with the given ID in this scene
-
  -
findNodes(nodeIdRegex) -
-
Finds nodes in this scene that have nodes IDs matching the given regular expression
-
  - -
Returns the HTML canvas for this scene
-
  -
getGL() -
-
Returns the WebGL context for this scene
-
  -
getNode(nodeId) -
-
-
  - -
Returns the current status of this scene.
-
  - -
Gets the regular expression which will select which of the scene subgraphs that are rooted by SceneJS.Tag nodes are included in scene renders
-
  - -
Returns the Z-buffer depth in bits of the webgl context that this scene is to bound to.
-
  - -
Returns true if scene active, ie.
-
  - -
Returns true if the scene's render loop is currently running.
-
  - -
Simulate a lost WebGL context for testing purposes.
-
  -
onEvent(type, callback) -
-
Subscribes to an event on this scene
-
  -
pause(doPause) -
-
Pauses/unpauses current render loop that was started with #start.
-
  -
pick(canvasX, canvasY, options) -
-
Picks whatever geometry will be rendered at the given canvas coordinates.
-
  -
renderFrame(params) -
-
Render a single frame if new frame pending, or force a new frame -Returns true if frame rendered
-
  -
setTagMask(tagMask) -
-
Sets a regular expression to select which of the scene subgraphs that are rooted by SceneJS.Tag nodes are included in scene renders
-
  -
start(params) -
-
Starts the render loop for this scene
-
  -
stop() -
-
Stops current render loop that was started with #start.
-
  -
unEvent(handle) -
-
Unsubscribes to an event previously subscribed to on scene
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Scene() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - containsNode(nodeId) - -
-
- Determines if node exists in this scene - - -
- - - - -
-
Parameters:
- -
- nodeId - -
-
- -
- - - - - - - - -
- - -
- - {SceneJS.Node} - findNode(nodeId) - -
-
- Finds the node with the given ID in this scene - - -
- - - - -
-
Parameters:
- -
- nodeId - -
-
- -
- - - - - -
-
Returns:
- -
{SceneJS.Node} The node if found, else null
- -
- - - - -
- - -
- - {[SceneJS.Node]} - findNodes(nodeIdRegex) - -
-
- Finds nodes in this scene that have nodes IDs matching the given regular expression - - -
- - - - -
-
Parameters:
- -
- {String} nodeIdRegex - -
-
Regular expression to match on node IDs
- -
- - - - - -
-
Returns:
- -
{[SceneJS.Node]} Array of nodes whose IDs match the given regex
- -
- - - - -
- - -
- - {HTMLCanvas} - getCanvas() - -
-
- Returns the HTML canvas for this scene - - -
- - - - - - - - -
-
Returns:
- -
{HTMLCanvas} The canvas
- -
- - - - -
- - -
- - - getGL() - -
-
- Returns the WebGL context for this scene - - -
- - - - - - - - - - - -
- - -
- - {SceneJS.Node} - getNode(nodeId) - -
-
- - - -
- - - - -
-
Parameters:
- -
- nodeId - -
-
- -
- - - - - -
-
Returns:
- -
{SceneJS.Node} The node if found, else null
- -
- - - - -
- - -
- - - getStatus() - -
-
- Returns the current status of this scene. - -When the scene has been destroyed, the returned status will be a map like this: - -{ - destroyed: true -} - -Otherwise, the status will be: - -{ - numTasks: Number // Number of asset loads (eg. texture, geometry stream etc.) currently in progress -} - - -
- - - - - - - - - - - -
- - -
- - {String} - getTagMask() - -
-
- Gets the regular expression which will select which of the scene subgraphs that are rooted by SceneJS.Tag nodes are included in scene renders - - -
- - - - - - - - -
-
Returns:
- -
{String} Regular expression string that will be matched on the tag attributes of SceneJS.Tag nodes
- -
- - - -
-
See:
- -
#setTagMask
- -
SceneJS.Tag
- -
- - -
- - -
- - - getZBufferDepth() - -
-
- Returns the Z-buffer depth in bits of the webgl context that this scene is to bound to. - - -
- - - - - - - - - - - -
- - -
- - - isActive() - -
-
- Returns true if scene active, ie. not destroyed. A destroyed scene becomes active again -when you render it. - - -
- - - - - - - - - - - -
- - -
- - {Boolean} - isRunning() - -
-
- Returns true if the scene's render loop is currently running. - - -
- - - - - - - - -
-
Returns:
- -
{Boolean} True when scene render loop is running
- -
- - - - -
- - -
- - - loseWebGLContext() - -
-
- Simulate a lost WebGL context for testing purposes. -Only works if the simulateWebGLLost was given as an option to SceneJS.createScene. - - -
- - - - - - - - - - - -
- - -
- - {String} - onEvent(type, callback) - -
-
- Subscribes to an event on this scene - - -
- - - - -
-
Parameters:
- -
- {String} type - -
-
Event type
- -
- {Function} callback - -
-
Callback that will be called with the event parameters
- -
- - - - - -
-
Returns:
- -
{String} handle Handle to the subcription
- -
- - - - -
- - -
- - - pause(doPause) - -
-
- Pauses/unpauses current render loop that was started with #start. After this, #isRunning will return false. - - -
- - - - -
-
Parameters:
- -
- {Boolean} doPause - -
-
Indicates whether to pause or unpause the render loop
- -
- - - - - - - - -
- - -
- - - pick(canvasX, canvasY, options) - -
-
- Picks whatever geometry will be rendered at the given canvas coordinates. - - -
- - - - -
-
Parameters:
- -
- canvasX - -
-
- -
- canvasY - -
-
- -
- options - -
-
- -
- - - - - - - - -
- - -
- - - renderFrame(params) - -
-
- Render a single frame if new frame pending, or force a new frame -Returns true if frame rendered - - -
- - - - -
-
Parameters:
- -
- params - -
-
- -
- - - - - - - - -
- - -
- - - setTagMask(tagMask) - -
-
- Sets a regular expression to select which of the scene subgraphs that are rooted by SceneJS.Tag nodes are included in scene renders - - -
- - - - -
-
Parameters:
- -
- {String} tagMask - -
-
Regular expression string to match on the tag attributes of SceneJS.Tag nodes
- -
- - - - - - - -
-
See:
- -
#getTagMask
- -
SceneJS.Tag
- -
- - -
- - -
- - - start(params) - -
-
- Starts the render loop for this scene - - -
- - - - -
-
Parameters:
- -
- params - -
-
- -
- - - - - - - - -
- - -
- - - stop() - -
-
- Stops current render loop that was started with #start. After this, #isRunning will return false. - - -
- - - - - - - - - - - -
- - -
- - - unEvent(handle) - -
-
- Unsubscribes to an event previously subscribed to on scene - - -
- - - - -
-
Parameters:
- -
- {String} handle - -
-
Subscription handle
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Tag.html b/docs/symbols/SceneJS.Tag.html deleted file mode 100644 index 0fbe501e..00000000 --- a/docs/symbols/SceneJS.Tag.html +++ /dev/null @@ -1,465 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Tag - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Tag -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which assigns a symbolic tag name to the SceneJS.Geometry nodes in its subgraph. -The subgraph can then be included or excluded from scene rendering using SceneJS.Scene#setTagMask. - - -
Defined in: tag.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  -
- SceneJS.Tag() -
-
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
getTag() -
-
-
  -
setTag(tag) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Tag() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - getTag() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - setTag(tag) - -
-
- - - -
- - - - -
-
Parameters:
- -
- tag - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Texture.html b/docs/symbols/SceneJS.Texture.html deleted file mode 100644 index 69654868..00000000 --- a/docs/symbols/SceneJS.Texture.html +++ /dev/null @@ -1,475 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Texture - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Texture -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines one or more textures to apply to the SceneJS.Geometry nodes in its subgraph - - -
Defined in: texture.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
setLayer(cfg) -
-
Set some writeable properties on a layer
-
  -
setLayers(layers) -
-
Set some writeable properties on multiple layers
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Texture() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - setLayer(cfg) - -
-
- Set some writeable properties on a layer - - -
- - - - -
-
Parameters:
- -
- cfg - -
-
- -
- - - - - - - - -
- - -
- - - setLayers(layers) - -
-
- Set some writeable properties on multiple layers - - -
- - - - -
-
Parameters:
- -
- layers - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.Translate.html b/docs/symbols/SceneJS.Translate.html deleted file mode 100644 index 97e881ad..00000000 --- a/docs/symbols/SceneJS.Translate.html +++ /dev/null @@ -1,966 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.Translate - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.Translate -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines a translation modelling transform to apply to the objects in its subgraph - - -
Defined in: translate.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
Get Model matrix
-
  - -
Get World matrix.
-
  -
getX() -
-
-
  -
getXYZ() -
-
-
  -
getY() -
-
-
  -
getZ() -
-
-
  -
incX(x) -
-
-
  -
incY(y) -
-
-
  -
incZ(z) -
-
-
  -
setMultOrder(multOrder) -
-
Sets the multiplication order of this node's transform matrix with respect to the parent modeling transform -in the scene graph.
-
  -
setX(x) -
-
-
  -
setXYZ(xyz) -
-
-
  -
setY(y) -
-
-
  -
setZ(z) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.Translate() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - {*} - getModelMatrix() - -
-
- Get Model matrix - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - {*} - getWorldMatrix() - -
-
- Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next -tranform (scale, translate, translate etc) node on the path to the scene root. - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - - getX() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getXYZ() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getY() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getZ() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - incX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - incY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - incZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - -
- - -
- - - setMultOrder(multOrder) - -
-
- Sets the multiplication order of this node's transform matrix with respect to the parent modeling transform -in the scene graph. - - -
- - - - -
-
Parameters:
- -
- {String} multOrder - -
-
Mulplication order - "post" and "pre"
- -
- - - - - - - - -
- - -
- - - setX(x) - -
-
- - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - setXYZ(xyz) - -
-
- - - -
- - - - -
-
Parameters:
- -
- xyz - -
-
- -
- - - - - - - - -
- - -
- - - setY(y) - -
-
- - - -
- - - - -
-
Parameters:
- -
- y - -
-
- -
- - - - - - - - -
- - -
- - - setZ(z) - -
-
- - - -
- - - - -
-
Parameters:
- -
- z - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS.XForm.html b/docs/symbols/SceneJS.XForm.html deleted file mode 100644 index 0262a8b3..00000000 --- a/docs/symbols/SceneJS.XForm.html +++ /dev/null @@ -1,513 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS.XForm - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS.XForm -

- - -

- -
Extends - SceneJS.Node.
- - - Scene graph node which defines the modelling transform to apply to the objects in its subgraph - - -
Defined in: xform.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  - -
-
- - - - - - - - -
-
Fields borrowed from class SceneJS.Node:
branchDirty, data, dirty, id, nodes, parent, type
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  - -
Get Model matrix
-
  - -
Get World matrix.
-
  -
setElements(elements) -
-
-
- - - -
-
Methods borrowed from class SceneJS.Node:
add, addListener, addNode, addNodes, bind, destroy, disconnect, disconnectNodeAt, disconnectNodes, eachNode, eachParent, findNodesByType, findParentByType, get, getCoreId, getData, getFirstNode, getId, getID, getJSON, getLastNode, getNode, getNodeAt, getNodeId, getNodes, getNumNodes, getParent, getScene, getType, hasListener, hasListeners, hasNode, inc, insert, insertNode, mapNodes, node, numNodes, remove, removeListener, removeListeners, removeNode, removeNodeAt, removeNodes, set, setData, splice, unbind
-
- - - - - - - -
-
- Class Detail -
- -
- SceneJS.XForm() -
- -
- - -
- - - - - - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - {*} - getModelMatrix() - -
-
- Get Model matrix - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - {*} - getWorldMatrix() - -
-
- Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next -tranform (scale, XForm, translate etc) node on the path to the scene root. - - -
- - - - - - - - -
-
Returns:
- -
{*}
- -
- - - - -
- - -
- - - setElements(elements) - -
-
- - - -
- - - - -
-
Parameters:
- -
- elements - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/SceneJS_webgl_Program.html b/docs/symbols/SceneJS_webgl_Program.html deleted file mode 100644 index 15449d68..00000000 --- a/docs/symbols/SceneJS_webgl_Program.html +++ /dev/null @@ -1,846 +0,0 @@ - - - - - - - JsDoc Reference - SceneJS_webgl_Program - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Class SceneJS_webgl_Program -

- - -

- - - - Wrapper for a WebGL program - - -
Defined in: webgl.js. - -

- - - - - - - - - - - - - - - - - -
Class Summary
Constructor AttributesConstructor Name and Description
  -
- SceneJS_webgl_Program(hash, gl, vertexSources, fragmentSources, logging) -
-
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
bind() -
-
-
  -
bindFloatArrayBuffer(name, buffer) -
-
-
  -
bindTexture(name, texture, unit) -
-
-
  -
destroy() -
-
-
  -
getAttribute(name) -
-
-
  -
getUniform(name) -
-
-
  - -
-
  -
setProfile(profile) -
-
-
  -
setUniform(name, value) -
-
-
  -
unbind() -
-
-
- - - - - - - - - -
-
- Class Detail -
- -
- SceneJS_webgl_Program(hash, gl, vertexSources, fragmentSources, logging) -
- -
- - -
- - - - - -
-
Parameters:
- -
- hash - -
-
SceneJS-managed ID for program
- -
- gl - -
-
WebGL gl
- -
- vertexSources - -
-
Source codes for vertex shaders
- -
- fragmentSources - -
-
Source codes for fragment shaders
- -
- logging - -
-
Program and shaders will write to logging's debug channel as they compile and link
- -
- - - - - - - - -
- - - - - - - -
- Method Detail -
- - -
- - - bind() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - bindFloatArrayBuffer(name, buffer) - -
-
- - - -
- - - - -
-
Parameters:
- -
- name - -
-
- -
- buffer - -
-
- -
- - - - - - - - -
- - -
- - - bindTexture(name, texture, unit) - -
-
- - - -
- - - - -
-
Parameters:
- -
- name - -
-
- -
- texture - -
-
- -
- unit - -
-
- -
- - - - - - - - -
- - -
- - - destroy() - -
-
- - - -
- - - - - - - - - - - -
- - -
- - - getAttribute(name) - -
-
- - - -
- - - - -
-
Parameters:
- -
- name - -
-
- -
- - - - - - - - -
- - -
- - - getUniform(name) - -
-
- - - -
- - - - -
-
Parameters:
- -
- name - -
-
- -
- - - - - - - - -
- - -
- - - getUniformLocation(name) - -
-
- - - -
- - - - -
-
Parameters:
- -
- name - -
-
- -
- - - - - - - - -
- - -
- - - setProfile(profile) - -
-
- - - -
- - - - -
-
Parameters:
- -
- profile - -
-
- -
- - - - - - - - -
- - -
- - - setUniform(name, value) - -
-
- - - -
- - - - -
-
Parameters:
- -
- name - -
-
- -
- value - -
-
- -
- - - - - - - - -
- - -
- - - unbind() - -
-
- - - -
- - - - - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/_global_.html b/docs/symbols/_global_.html deleted file mode 100644 index d9408376..00000000 --- a/docs/symbols/_global_.html +++ /dev/null @@ -1,4539 +0,0 @@ - - - - - - - JsDoc Reference - _global_ - - - - - - - - - - - -
- -
Class Index -| File Index
-
-

Classes

- -
- -
- -
- -

- - Built-In Namespace _global_ -

- - -

- - - - - - -

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Field Summary
Field AttributesField Name and Description
  -
- _engines -
-
-
  - -
Attributes given when initialising the WebGL context
-
  -
- gl -
-
The WebGL context
-
  -
- options -
-
WebGL context options
-
  -
- SceneJS -
-
The SceneJS object.
-
  - -
Default lookat properties in array form - eye at 0,0,1, looking at 0,0,0, up vector pointing up Y-axis
-
  - -
Default lookat properties - eye at 0,0,1, looking at 0,0,0, up vector pointing up Y-axis
-
  - -
Default orthographic projection properties
-
  - -
Provides a model transform stack in front of the renderer.
-
  -
- VERSION -
-
This SceneJS version
-
  - -
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Method Summary
Method AttributesMethod Name and Description
  -
__log(channel, message) -
-
-
  -
_allocate(values, numItems) -
-
-
  - -
-
  - -
-
  - -
-
  -
_flush(channel) -
-
-
  -
_hasNormals(states) -
-
-
  -
_isTexturing(states) -
-
-
  -
_log(channel, message) -
-
-
  -
_setIndent(_indent) -
-
-
  - -
-
  -
_touch() -
-
-
  -
addPlugin(nodeType, pluginType, plugin) -
-
Installs a plugin into SceneJS
-
  -
bind() -
-
-
  - -
-
  -
bindTexture(texture, unit) -
-
-
  -
buildCore(core) -
-
Creates a fresh transformation core
-
  -
clear() -
-
-
  -
createScene(json, options) -
-
Creates a new scene from the given JSON description
-
  -
debug(msg) -
-
-
  -
destroy() -
-
-
  -
error(msg) -
-
-
  -
fatalError(code, message) -
-
-
  -
func(v) -
-
-
  -
getConfigs(path) -
-
-
  - -
-
  - -
-
  -
getPlugin(nodeType, pluginType, ok) -
-
Returns installed plugin of given type and ID
-
  -
getProjectedState(modelCoords) -
-
-
  -
getScene(sceneId) -
-
Gets an existing scene
-
  - -
Gets existing scenes
-
  -
getSource(hash, states) -
-
Get sourcecode for a program to render the given states
-
  - -
-
  -
hasPlugin(nodeType, pluginType) -
-
Tests if given plugin is installed
-
  -
info(msg) -
-
-
  -
init(_gl) -
-
Initialises the pick buffer
-
  -
nodeLoaded(node) -
-
-
  -
nodeLoading(node) -
-
-
  -
pop() -
-
-
  -
postVisitNode(node) -
-
-
  -
preVisitNode(node) -
-
-
  -
push(core) -
-
-
  -
putSource(hash) -
-
Releases program source code
-
  -
read(pickX, pickY) -
-
Reads pick buffer pixel at given coordinates, returns index of associated object else (-1)
-
  -
removeListener(handle) -
-
Removes a listener
-
  -
reset() -
-
Resets SceneJS, destroying all existing scenes
-
  -
scene(sceneId) -
-
Gets an existing scene
-
  -
SceneJS_Canvas(id, canvasId, contextAttr, options) -
-
-
  - -
-
  - -
-
  - -
-
  - -
-
  -
SceneJS_math_lerpVec3(t, t1, t2, p1, p2) -
-
-
  -
SceneJS_math_lookAtMat4v(pos, target, up, dest) -
-
-
  - -
-
  - -
-
  - -
-
  - -
-
  -
SceneJS_math_slerp(t, q1, q2) -
-
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  - -
-
  -
SceneJS_webgl_ProgramAttribute(gl, program, name, type, size, location) -
-
An attribute within a shader
-
  -
SceneJS_webgl_ProgramSampler(gl, program, name, type, size, location) -
-
-
  -
SceneJS_webgl_ProgramUniform(gl, program, name, type, size, location, logging) -
-
-
  - -
-
  -
setConfigs(path, data) -
-
-
  -
setData(data, offset) -
-
-
  -
setFuncs(l) -
-
-
  -
unbind() -
-
-
  -
warn(msg) -
-
-
  - -
Called when WebGL context restored
-
- - - - - - - - - - - - -
- Field Detail -
- - -
- - - _engines - -
-
- - -
- Defined in: scenejs.js. - - -
- - - - - - - - -
- - -
- - - contextAttr - -
-
- Attributes given when initialising the WebGL context - -
- Defined in: canvas.js. - - -
- - - - - - - - -
- - -
- - - gl - -
-
- The WebGL context - -
- Defined in: canvas.js. - - -
- - - - - - - - -
- - -
- - - options - -
-
- WebGL context options - -
- Defined in: canvas.js. - - -
- - - - - - - - -
- - -
- - - SceneJS - -
-
- The SceneJS object. - -
- Defined in: scenejs.js. - - -
- - - - - - - - -
- - -
- - - SceneJS_math_LOOKAT_ARRAYS - -
-
- Default lookat properties in array form - eye at 0,0,1, looking at 0,0,0, up vector pointing up Y-axis - -
- Defined in: math.js. - - -
- - - - - - - - -
- - -
- - - SceneJS_math_LOOKAT_OBJ - -
-
- Default lookat properties - eye at 0,0,1, looking at 0,0,0, up vector pointing up Y-axis - -
- Defined in: math.js. - - -
- - - - - - - - -
- - -
- - - SceneJS_math_ORTHO_OBJ - -
-
- Default orthographic projection properties - -
- Defined in: math.js. - - -
- - - - - - - - -
- - -
- - - SceneJS_modelXFormStack - -
-
- Provides a model transform stack in front of the renderer. -Nodes peek push and pop to the stack, while the renderer peeks at -the transform on the top of the stack whenever it builds a renderer node. - -
- Defined in: modelXFormStack.js. - - -
- - - - - - - - -
- - -
- - - VERSION - -
-
- This SceneJS version - -
- Defined in: scenejs.js. - - -
- - - - - - - - -
- - -
- - - WebGLDebugUtils - -
-
- - -
- Defined in: webgl-debug-utils.js. - - -
- - - - - - - - - - - - - - -
- Method Detail -
- - -
- - - __log(channel, message) - -
-
- - -
- Defined in: log.js. - - -
- - - - -
-
Parameters:
- -
- channel - -
-
- -
- message - -
-
- -
- - - - - - - - -
- - -
- - - _allocate(values, numItems) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- values - -
-
- -
- numItems - -
-
- -
- - - - - - - - -
- - -
- - - _composePickingVertexShader(states) - -
-
- - -
- Defined in: programSourceFactory.js. - - -
- - - - -
-
Parameters:
- -
- states - -
-
- -
- - - - - - - - -
- - -
- - - _composeRenderingFragmentShader(states) - -
-
- - -
- Defined in: programSourceFactory.js. - - -
- - - - -
-
Parameters:
- -
- states - -
-
- -
- - - - - - - - -
- - -
- - - _composeRenderingVertexShader(states) - -
-
- - -
- Defined in: programSourceFactory.js. - - -
- - - - -
-
Parameters:
- -
- states - -
-
- -
- - - - - - - - -
- - -
- - - _flush(channel) - -
-
- - -
- Defined in: log.js. - - -
- - - - -
-
Parameters:
- -
- channel - -
-
- -
- - - - - - - - -
- - -
- - - _hasNormals(states) - -
-
- - -
- Defined in: programSourceFactory.js. - - -
- - - - -
-
Parameters:
- -
- states - -
-
- -
- - - - - - - - -
- - -
- - - _isTexturing(states) - -
-
- - -
- Defined in: programSourceFactory.js. - - -
- - - - -
-
Parameters:
- -
- states - -
-
- -
- - - - - - - - -
- - -
- - - _log(channel, message) - -
-
- - -
- Defined in: log.js. - - -
- - - - -
-
Parameters:
- -
- channel - -
-
- -
- message - -
-
- -
- - - - - - - - -
- - -
- - - _setIndent(_indent) - -
-
- - -
- Defined in: log.js. - - -
- - - - -
-
Parameters:
- -
- _indent - -
-
- -
- - - - - - - - -
- - -
- - - _shallowClone(o) - -
-
- - -
- Defined in: scenejs.js. - - -
- - - - -
-
Parameters:
- -
- o - -
-
- -
- - - - - - - - -
- - -
- - - _touch() - -
-
- - -
- Defined in: webgl.js. - - -
- - - - - - - - - - - -
- - -
- - - addPlugin(nodeType, pluginType, plugin) - -
-
- Installs a plugin into SceneJS - -
- Defined in: plugins.js. - - -
- - - - -
-
Parameters:
- -
- nodeType - -
-
- -
- pluginType - -
-
- -
- plugin - -
-
- -
- - - - - - - - -
- - -
- - - bind() - -
-
- - -
- Defined in: webgl.js. - - -
- - - - - - - - - - - -
- - -
- - - bindFloatArrayBuffer(buffer) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- buffer - -
-
- -
- - - - - - - - -
- - -
- - - bindTexture(texture, unit) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- texture - -
-
- -
- unit - -
-
- -
- - - - - - - - -
- - -
- - - buildCore(core) - -
-
- Creates a fresh transformation core - -
- Defined in: modelXFormStack.js. - - -
- - - - -
-
Parameters:
- -
- core - -
-
- -
- - - - - - - - -
- - -
- - - clear() - -
-
- - -
- Defined in: webgl.js. - - -
- - - - - - - - - - - -
- - -
- - {SceneJS.Scene} - createScene(json, options) - -
-
- Creates a new scene from the given JSON description - -
- Defined in: scenejs.js. - - -
- - - - -
-
Parameters:
- -
- {String} json - -
-
JSON scene description
- -
- options - -
-
Optional options
- -
- options.simulateWebGLContextLost - -
-
Optional options
- -
- - - - - -
-
Returns:
- -
{SceneJS.Scene} New scene
- -
- - - - -
- - -
- - - debug(msg) - -
-
- - -
- Defined in: log.js. - - -
- - - - -
-
Parameters:
- -
- msg - -
-
- -
- - - - - - - - -
- - -
- - - destroy() - -
-
- - -
- Defined in: webgl.js. - - -
- - - - - - - - - - - -
- - -
- - - error(msg) - -
-
- - -
- Defined in: log.js. - - -
- - - - -
-
Parameters:
- -
- msg - -
-
- -
- - - - - - - - -
- - -
- - - fatalError(code, message) - -
-
- - -
- Defined in: errors.js. - - -
- - - - -
-
Parameters:
- -
- code - -
-
- -
- message - -
-
- -
- - - - - - - - -
- - -
- - - func(v) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- v - -
-
- -
- - - - - - - - -
- - -
- - - getConfigs(path) - -
-
- - -
- Defined in: config.js. - - -
- - - - -
-
Parameters:
- -
- path - -
-
- -
- - - - - - - - -
- - -
- - - getFuncs() - -
-
- - -
- Defined in: log.js. - - -
- - - - - - - - - - - -
- - -
- - - getLocation() - -
-
- - -
- Defined in: webgl.js. - - -
- - - - - - - - - - - -
- - -
- - - getPlugin(nodeType, pluginType, ok) - -
-
- Returns installed plugin of given type and ID - -
- Defined in: plugins.js. - - -
- - - - -
-
Parameters:
- -
- nodeType - -
-
- -
- pluginType - -
-
- -
- ok - -
-
- -
- - - - - - - - -
- - -
- - - getProjectedState(modelCoords) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- modelCoords - -
-
- -
- - - - - - - - -
- - -
- - {SceneJS.Scene} - getScene(sceneId) - -
-
- Gets an existing scene - -
- Defined in: scenejs.js. - - -
- - - - -
-
Parameters:
- -
- {String} sceneId - -
-
ID of target scene
- -
- - - - - -
-
Returns:
- -
{SceneJS.Scene} The selected scene
- -
- - - - -
- - -
- - - getScenes() - -
-
- Gets existing scenes - -
- Defined in: scenejs.js. - - -
- - - - - - - - -
-
Returns:
- -
Existing scenes, mapped to their IDs
- -
- - - - -
- - -
- - - getSource(hash, states) - -
-
- Get sourcecode for a program to render the given states - -
- Defined in: programSourceFactory.js. - - -
- - - - -
-
Parameters:
- -
- hash - -
-
- -
- states - -
-
- -
- - - - - - - - -
- - -
- - - getValue() - -
-
- - -
- Defined in: webgl.js. - - -
- - - - - - - - - - - -
- - -
- - - hasPlugin(nodeType, pluginType) - -
-
- Tests if given plugin is installed - -
- Defined in: plugins.js. - - -
- - - - -
-
Parameters:
- -
- nodeType - -
-
- -
- pluginType - -
-
- -
- - - - - - - - -
- - -
- - - info(msg) - -
-
- - -
- Defined in: log.js. - - -
- - - - -
-
Parameters:
- -
- msg - -
-
- -
- - - - - - - - -
- - -
- - - init(_gl) - -
-
- Initialises the pick buffer - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- _gl - -
-
WebGL context
- -
- - - - - - - - -
- - -
- - - nodeLoaded(node) - -
-
- - -
- Defined in: status.js. - - -
- - - - -
-
Parameters:
- -
- node - -
-
- -
- - - - - - - - -
- - -
- - - nodeLoading(node) - -
-
- - -
- Defined in: status.js. - - -
- - - - -
-
Parameters:
- -
- node - -
-
- -
- - - - - - - - -
- - -
- - - pop() - -
-
- - -
- Defined in: modelXFormStack.js. - - -
- - - - - - - - - - - -
- - -
- - - postVisitNode(node) - -
-
- - -
- Defined in: nodeEvents.js. - - -
- - - - -
-
Parameters:
- -
- node - -
-
- -
- - - - - - - - -
- - -
- - - preVisitNode(node) - -
-
- - -
- Defined in: nodeEvents.js. - - -
- - - - -
-
Parameters:
- -
- node - -
-
- -
- - - - - - - - -
- - -
- - - push(core) - -
-
- - -
- Defined in: modelXFormStack.js. - - -
- - - - -
-
Parameters:
- -
- core - -
-
- -
- - - - - - - - -
- - -
- - - putSource(hash) - -
-
- Releases program source code - -
- Defined in: programSourceFactory.js. - - -
- - - - -
-
Parameters:
- -
- hash - -
-
- -
- - - - - - - - -
- - -
- - - read(pickX, pickY) - -
-
- Reads pick buffer pixel at given coordinates, returns index of associated object else (-1) - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- pickX - -
-
- -
- pickY - -
-
- -
- - - - - - - - -
- - -
- - - removeListener(handle) - -
-
- Removes a listener - -
- Defined in: events.js. - - -
- - - - -
-
Parameters:
- -
- handle - -
-
Subscription handle
- -
- - - - - - - - -
- - -
- - - reset() - -
-
- Resets SceneJS, destroying all existing scenes - -
- Defined in: scenejs.js. - - -
- - - - - - - - - - - -
- - -
- - {SceneJS.Scene} - scene(sceneId) - -
-
- Gets an existing scene - -
- Defined in: scenejs.js. - - -
- - - - -
-
Parameters:
- -
- {String} sceneId - -
-
ID of target scene
- -
- - - - - -
-
Returns:
- -
{SceneJS.Scene} The selected scene
- -
- - - - -
- - -
- - - SceneJS_Canvas(id, canvasId, contextAttr, options) - -
-
- - -
- Defined in: canvas.js. - - -
- - - - -
-
Parameters:
- -
- id - -
-
- -
- canvasId - -
-
- -
- contextAttr - -
-
- -
- options - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_math_angleAxisFromQuaternion(q) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- q - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_math_angleAxisQuaternion(x, y, z, degrees) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- y - -
-
- -
- z - -
-
- -
- degrees - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_math_conjugateQuaternion(q) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- q - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_math_identityQuaternion() - -
-
- - -
- Defined in: math.js. - - -
- - - - - - - - - - - -
- - -
- - - SceneJS_math_lerpVec3(t, t1, t2, p1, p2) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- t - -
-
- -
- t1 - -
-
- -
- t2 - -
-
- -
- p1 - -
-
- -
- p2 - -
-
- -
- - - - - - - - -
- - -
- - {mat4} - SceneJS_math_lookAtMat4v(pos, target, up, dest) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- pos - -
-
vec3 position of the viewer
- -
- target - -
-
vec3 point the viewer is looking at
- -
- up - -
-
vec3 pointing "up"
- -
- dest - -
-
mat4 Optional, mat4 frustum matrix will be written into
- -
- - - - - -
-
Returns:
- -
{mat4} dest if specified, a new mat4 otherwise
- -
- - - - -
- - -
- - - SceneJS_math_mulQuaternions(p, q) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- p - -
-
- -
- q - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_math_newMat4FromQuaternion(q) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- q - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_math_normalizeQuaternion(q) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- q - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_math_normalizeVec2(v, dest) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- v - -
-
- -
- dest - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_math_slerp(t, q1, q2) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- t - -
-
- -
- q1 - -
-
- -
- q2 - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_math_transformVector4(m, v) - -
-
- - -
- Defined in: math.js. - - -
- - - - -
-
Parameters:
- -
- m - -
-
- -
- v - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_PickBuffer(cfg) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- cfg - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_PickBufferOLD(cfg) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- cfg - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_webgl_ensureImageSizePowerOfTwo(image) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- image - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_webgl_isPowerOfTwo(x) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_webgl_nextHighestPowerOfTwo(x) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- x - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_webgl_ProgramAttribute(gl, program, name, type, size, location) - -
-
- An attribute within a shader - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- gl - -
-
- -
- program - -
-
- -
- name - -
-
- -
- type - -
-
- -
- size - -
-
- -
- location - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_webgl_ProgramSampler(gl, program, name, type, size, location) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- gl - -
-
- -
- program - -
-
- -
- name - -
-
- -
- type - -
-
- -
- size - -
-
- -
- location - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_webgl_ProgramUniform(gl, program, name, type, size, location, logging) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- gl - -
-
- -
- program - -
-
- -
- name - -
-
- -
- type - -
-
- -
- size - -
-
- -
- location - -
-
- -
- logging - -
-
- -
- - - - - - - - -
- - -
- - - SceneJS_webgl_Texture2D(gl, cfg) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- gl - -
-
- -
- cfg - -
-
- -
- - - - - - - - -
- - -
- - - setConfigs(path, data) - -
-
- - -
- Defined in: config.js. - - -
- - - - -
-
Parameters:
- -
- path - -
-
- -
- data - -
-
- -
- - - - - - - - -
- - -
- - - setData(data, offset) - -
-
- - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- data - -
-
- -
- offset - -
-
- -
- - - - - - - - -
- - -
- - - setFuncs(l) - -
-
- - -
- Defined in: log.js. - - -
- - - - -
-
Parameters:
- -
- l - -
-
- -
- - - - - - - - -
- - -
- - - unbind() - -
-
- - -
- Defined in: webgl.js. - - -
- - - - - - - - - - - -
- - -
- - - warn(msg) - -
-
- - -
- Defined in: log.js. - - -
- - - - -
-
Parameters:
- -
- msg - -
-
- -
- - - - - - - - -
- - -
- - - webglRestored(_gl) - -
-
- Called when WebGL context restored - -
- Defined in: webgl.js. - - -
- - - - -
-
Parameters:
- -
- _gl - -
-
- -
- - - - - - - - - - - - - - - -
-
- - - -
- - Documentation generated by JsDoc Toolkit 2.4.0 on Fri Mar 22 2013 02:49:02 GMT+0100 (CET) -
- - diff --git a/docs/symbols/src/licenses_license-header.js.html b/docs/symbols/src/licenses_license-header.js.html deleted file mode 100644 index 8a21f2a4..00000000 --- a/docs/symbols/src/licenses_license-header.js.html +++ /dev/null @@ -1,24 +0,0 @@ -
  1 /*
-  2  * SceneJS WebGL Scene Graph Library for JavaScript
-  3  * http://scenejs.org/
-  4  * Dual licensed under the MIT or GPL Version 2 licenses.
-  5  * http://scenejs.org/license
-  6   * Copyright 2010, Lindsay Kay
-  7  *
-  8  * Includes WebGLTrace
-  9  * Various functions for helping debug WebGL apps.
- 10  * http://github.com/jackpal/webgltrace
- 11  * Copyright (c) 2009 The Chromium Authors. All rights reserved.
- 12  *
- 13  * Includes WebGL-Debug
- 14  * Various functions for helping debug WebGL apps.
- 15  * http://khronos.org/webgl/wiki/Debugging
- 16  * Copyright (c) 2009 The Chromium Authors. All rights reserved.
- 17  */
\ No newline at end of file diff --git a/docs/symbols/src/src_core_canvas.js.html b/docs/symbols/src/src_core_canvas.js.html deleted file mode 100644 index 361a709f..00000000 --- a/docs/symbols/src/src_core_canvas.js.html +++ /dev/null @@ -1,114 +0,0 @@ -
  1 /**
-  2  *
-  3  */
-  4 var SceneJS_Canvas = function (id, canvasId, contextAttr, options) {
-  5 
-  6     /**
-  7      * ID of this canvas
-  8      */
-  9     this.canvasId;
- 10 
- 11     if (!canvasId) {
- 12         // Automatic default canvas
- 13         canvasId = "canvas-" + id;
- 14         var body = document.getElementsByTagName("body")[0];
- 15         body.innerHTML = '';
- 16         var newdiv = document.createElement('div');
- 17         newdiv.style.height = "100%";
- 18         newdiv.style.width = "100%";
- 19         newdiv.innerHTML = '<canvas id="' + canvasId + '" style="width: 100%; height: 100%; margin: 0; padding: 0;"></canvas>';
- 20         body.appendChild(newdiv);
- 21     }
- 22 
- 23     // Bind to canvas
- 24     var canvas = document.getElementById(canvasId);
- 25     if (!canvas) {
- 26         throw SceneJS_error.fatalError(SceneJS.errors.CANVAS_NOT_FOUND,
- 27             "SceneJS.Scene attribute 'canvasId' does not match any elements in the page");
- 28     }
- 29     this.canvasId = canvasId;
- 30 
- 31     /**
- 32      * WebGL context options
- 33      */
- 34     this.options = options || {};
- 35 
- 36     this.canvas = (this.options.simulateWebGLContextLost)
- 37         ? WebGLDebugUtils.makeLostContextSimulatingCanvas(canvas)
- 38         : canvas;
- 39 
- 40     // If the canvas uses css styles to specify the sizes make sure the basic
- 41     // width and height attributes match or the WebGL context will use 300 x 150
- 42 
- 43     this.canvas.width = this.canvas.clientWidth;
- 44     this.canvas.height = this.canvas.clientHeight;
- 45 
- 46     /**
- 47      * Attributes given when initialising the WebGL context
- 48      */
- 49     this.contextAttr = contextAttr;
- 50 
- 51     /**
- 52      * The WebGL context
- 53      */
- 54     this.gl = null;
- 55 
- 56     this.initWebGL();
- 57 };
- 58 
- 59 /**
- 60  * Names of recognised WebGL contexts
- 61  */
- 62 SceneJS_Canvas.prototype._WEBGL_CONTEXT_NAMES = [
- 63     "webgl",
- 64     "experimental-webgl",
- 65     "webkit-3d",
- 66     "moz-webgl",
- 67     "moz-glweb20"
- 68 ];
- 69 
- 70 /**
- 71  * Initialise the WebGL context
- 72 
- 73  */
- 74 SceneJS_Canvas.prototype.initWebGL = function () {
- 75 
- 76     for (var i = 0; !this.gl && i < this._WEBGL_CONTEXT_NAMES.length; i++) {
- 77         try {
- 78             this.gl = this.canvas.getContext(this._WEBGL_CONTEXT_NAMES[i], this.contextAttr);
- 79 
- 80         } catch (e) { // Try with next context name
- 81         }
- 82     }
- 83 
- 84     if (!this.gl) {
- 85         throw SceneJS_error.fatalError(
- 86             SceneJS.errors.WEBGL_NOT_SUPPORTED,
- 87             'Failed to get a WebGL context');
- 88     }
- 89 
- 90 //    this.gl.clearColor(1.0, 1.0, 1.0, 1.0);
- 91     this.gl.clearDepth(1.0);
- 92     this.gl.enable(this.gl.DEPTH_TEST);
- 93     this.gl.disable(this.gl.CULL_FACE);
- 94     this.gl.depthRange(0, 1);
- 95     this.gl.disable(this.gl.SCISSOR_TEST);
- 96 };
- 97 
- 98 
- 99 /**
-100  * Simulate a lost WebGL context.
-101  * Only works if the simulateWebGLContextLost was given as an option to the canvas' constructor.
-102  */
-103 SceneJS_Canvas.prototype.loseWebGLContext = function () {
-104     if (this.options.simulateWebGLContextLost) {
-105         this.canvas.loseContext();
-106     }
-107 };
\ No newline at end of file diff --git a/docs/symbols/src/src_core_config.js.html b/docs/symbols/src/src_core_config.js.html deleted file mode 100644 index 89b305eb..00000000 --- a/docs/symbols/src/src_core_config.js.html +++ /dev/null @@ -1,71 +0,0 @@ -
  1 /**
-  2  * Backend that manages configurations.
-  3  *
-  4  * @class SceneJS_debugModule
-  5  * @private
-  6  */
-  7 var SceneJS_debugModule = new (function() {
-  8 
-  9     this.configs = {};
- 10 
- 11     this.getConfigs = function(path) {
- 12         if (!path) {
- 13             return this.configs;
- 14         } else {
- 15             var cfg = this.configs;
- 16             var parts = path.split(".");
- 17             for (var i = 0; cfg && i < parts.length; i++) {
- 18                 cfg = cfg[parts[i]];
- 19             }
- 20             return cfg || {};
- 21         }
- 22     };
- 23 
- 24     this.setConfigs = function(path, data) {
- 25         if (!path) {
- 26             this.configs = data;
- 27         } else {
- 28             var parts = path.split(".");
- 29             var cfg = this.configs;
- 30             var subCfg;
- 31             var name;
- 32             for (var i = 0; i < parts.length - 1; i++) {
- 33                 name = parts[i];
- 34                 subCfg = cfg[name];
- 35                 if (!subCfg) {
- 36                     subCfg = cfg[name] = {};
- 37                 }
- 38                 cfg = subCfg;
- 39             }
- 40             cfg[parts.length - 1] = data;
- 41         }
- 42     };
- 43 
- 44 })();
- 45 
- 46 /** Sets configurations.
- 47  */
- 48 SceneJS.configure = SceneJS.setConfigs = SceneJS.setDebugConfigs = function () {
- 49     if (arguments.length == 1) {
- 50         SceneJS_debugModule.setConfigs(null, arguments[0]);
- 51     } else if (arguments.length == 2) {
- 52         SceneJS_debugModule.setConfigs(arguments[0], arguments[1]);
- 53     } else {
- 54         throw SceneJS_error.fatalError("Illegal arguments given to SceneJS.setDebugs - should be either ({String}:name, {Object}:cfg) or ({Object}:cfg)");
- 55     }
- 56 };
- 57 
- 58 /** Gets configurations
- 59  */
- 60 SceneJS.getConfigs = SceneJS.getDebugConfigs = function (path) {
- 61     return SceneJS_debugModule.getConfigs(path);
- 62 };
- 63 
- 64 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_cameraChunk.js.html b/docs/symbols/src/src_core_display_chunks_cameraChunk.js.html deleted file mode 100644 index 91bca006..00000000 --- a/docs/symbols/src/src_core_display_chunks_cameraChunk.js.html +++ /dev/null @@ -1,54 +0,0 @@ -
  1 SceneJS_ChunkFactory.createChunkType({
-  2 
-  3     type: "camera",
-  4 
-  5     build : function() {
-  6 
-  7         this._uPMatrixDraw = this.program.draw.getUniformLocation("SCENEJS_uPMatrix");
-  8 
-  9         this._uPMatrixPick = this.program.pick.getUniformLocation("SCENEJS_uPMatrix");
- 10         this._uZNearPick = this.program.pick.getUniformLocation("SCENEJS_uZNear");
- 11         this._uZFarPick = this.program.pick.getUniformLocation("SCENEJS_uZFar");
- 12     },
- 13 
- 14     draw : function(ctx) {
- 15 
- 16         var gl = this.program.gl;
- 17 
- 18         if (this._uPMatrixDraw) {
- 19             gl.uniformMatrix4fv(this._uPMatrixDraw, gl.FALSE, this.core.mat);
- 20         }
- 21 
- 22         ctx.cameraMat = this.core.mat; // Query only in draw pass
- 23     },
- 24 
- 25 
- 26     pick : function(ctx) {
- 27 
- 28         var gl = this.program.gl;
- 29 
- 30         if (this._uPMatrixPick) {
- 31             gl.uniformMatrix4fv(this._uPMatrixPick, gl.FALSE, this.core.mat);
- 32         }
- 33 
- 34         if (ctx.rayPick) { // Z-pick pass: feed near and far clip planes into shader
- 35 
- 36             if (this._uZNearPick) {
- 37                 gl.uniform1f(this._uZNearPick, this.core.optics.near);
- 38             }
- 39 
- 40             if (this._uZFarPick) {
- 41                 gl.uniform1f(this._uZFarPick, this.core.optics.far);
- 42             }
- 43         }
- 44 
- 45         ctx.cameraMat = this.core.mat; // Query only in draw pass
- 46     }
- 47 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_chunk.js.html b/docs/symbols/src/src_core_display_chunks_chunk.js.html deleted file mode 100644 index 21cada62..00000000 --- a/docs/symbols/src/src_core_display_chunks_chunk.js.html +++ /dev/null @@ -1,74 +0,0 @@ -
  1 /**
-  2  * @class A chunk of WebGL state changes to render a {@link SceneJS_Core} for drawing and picking (if applicable to the core type).
-  3  *
-  4  * <p>Instances of this class are created and recycled by a {@link SceneJS_ChunkFactory}.</p>
-  5  *
-  6  * <p>Each {@link SceneJS_Object} has a list of chunks to render it's {@link SceneJS_Core}s</p>
-  7  *
-  8  * @private
-  9  */
- 10 var SceneJS_Chunk = function(id, type, program, core) {
- 11 
- 12     /**
- 13      * The type of the corresponding {@link SceneJS_Core}
- 14      * @type String
- 15      * @see {SceneJS_Core#type}
- 16      */
- 17     this.type = type;
- 18 
- 19     /**
- 20      * The chunk ID
- 21      * @type Number
- 22      */
- 23     this.id = id;
- 24 
- 25     /**
- 26      * The program this chunk will render with
- 27      * @type {SceneJS_Program}
- 28      */
- 29     this.program = program;
- 30 
- 31     /**
- 32      * The state core rendered by this chunk
- 33      * @type {SceneJS_Core}
- 34      */
- 35     this.core = core;
- 36 
- 37     /**
- 38      * Count of {@link SceneJS_Object} instances using this chunk
- 39      * @type Number
- 40      */
- 41     this.useCount = 0;
- 42 
- 43     if (this.build) {
- 44         this.build();
- 45     }
- 46 };
- 47 
- 48 /**
- 49  * Initialises the chunk. This is called within the constructor, and also to by the owner {@link SceneJS_ChunkFactory}
- 50  * when recycling a chunk from its free chunk pool. This method sets the given properties on the chunk, then calls the
- 51  * chunk instance's <b>build</b> method if the chunk has been augmented with one.
- 52  *
- 53  * @param {Number} id Chunk ID
- 54  * @param {SceneJS_Program} program Program to render the chunk
- 55  * @param {SceneJS_Core} core The state core rendered by this chunk
- 56  */
- 57 SceneJS_Chunk.prototype.init = function(id, program, core) {
- 58 
- 59     this.id = id;
- 60     this.program = program;
- 61     this.core = core;
- 62 
- 63     if (this.build) {
- 64         this.build();
- 65     }
- 66 };
- 67 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_chunkFactory.js.html b/docs/symbols/src/src_core_display_chunks_chunkFactory.js.html deleted file mode 100644 index 7cb1ab44..00000000 --- a/docs/symbols/src/src_core_display_chunks_chunkFactory.js.html +++ /dev/null @@ -1,148 +0,0 @@ -
  1 /**
-  2  * @class Manages creation, reuse and destruction of {@link SceneJS_Chunk}s for the nodes within a single {@link SceneJS_Display}.
-  3  * @private
-  4  */
-  5 var SceneJS_ChunkFactory = function() {
-  6 
-  7     this._chunks = {};
-  8 };
-  9 
- 10 /**
- 11  * Sub-classes of {@link SceneJS_Chunk} provided by this factory
- 12  */
- 13 SceneJS_ChunkFactory._chunkTypes = {};    // Supported chunk classes, installed by #createChunkType
- 14 
- 15 /**
- 16  * Free pool of unused {@link SceneJS_Chunk} instances
- 17  */
- 18 SceneJS_ChunkFactory._freeChunks = {};    // Free chunk pool for each type
- 19 
- 20 /**
- 21  * Creates a chunk class for instantiation by this factory
- 22  *
- 23  * @param params Members to augment the chunk class prototype with
- 24  * @param params.type Type name for the new chunk class
- 25  * @param params.draw Method to render the chunk in draw render
- 26  * @param params.pick Method to render the chunk in pick render
- 27  * @param params.drawAndPick Method to render the chunk in both draw and pick renders
- 28  */
- 29 SceneJS_ChunkFactory.createChunkType = function(params) {
- 30 
- 31     if (!params.type) {
- 32         throw "'type' expected in params";
- 33     }
- 34 
- 35     var supa = SceneJS_Chunk;
- 36 
- 37     var chunkClass = function() { // Create the class
- 38         supa.apply(this, arguments);
- 39         this.type = params.type;
- 40     };
- 41 
- 42     chunkClass.prototype = new supa();              // Inherit from base class
- 43     chunkClass.prototype.constructor = chunkClass;
- 44 
- 45     if (params.drawAndPick) {                       // Common method for draw and pick render
- 46         params.draw = params.pick = params.drawAndPick;
- 47     }
- 48 
- 49     SceneJS_ChunkFactory._chunkTypes[params.type] = chunkClass;
- 50 
- 51     SceneJS._apply(params, chunkClass.prototype);   // Augment subclass
- 52 
- 53     SceneJS_ChunkFactory._freeChunks[params.type] = { // Set up free chunk pool for this type
- 54         chunks: [],
- 55         chunksLen: 0
- 56     };
- 57 
- 58     return chunkClass;
- 59 };
- 60 
- 61 /**
- 62  *
- 63  */
- 64 SceneJS_ChunkFactory.prototype.getChunk = function(chunkId, type, program, core) {
- 65 
- 66     var chunkClass = SceneJS_ChunkFactory._chunkTypes[type]; // Check type supported
- 67 
- 68     if (!chunkClass) {
- 69         throw "chunk type not supported: '" + type + "'";
- 70     }
- 71 
- 72     var chunk = this._chunks[chunkId];  // Try to reference an existing chunk
- 73 
- 74     if (chunk) {
- 75         chunk.useCount++;
- 76         return chunk;
- 77     }
- 78 
- 79     var freeChunks = SceneJS_ChunkFactory._freeChunks[type]; // Try to recycle a free chunk
- 80 
- 81     if (freeChunks.chunksLen > 0) {
- 82         chunk = freeChunks.chunks[--freeChunks.chunksLen];
- 83     }
- 84 
- 85     if (chunk) {    // Reinitialise the recycled chunk
- 86 
- 87         chunk.init(chunkId, program, core);
- 88 
- 89     } else {        // Instantiate a fresh chunk
- 90 
- 91         chunk = new chunkClass(chunkId, type, program, core); // Create new chunk
- 92     }
- 93 
- 94     chunk.useCount = 1;
- 95 
- 96     this._chunks[chunkId] = chunk;
- 97 
- 98     return chunk;
- 99 };
-100 
-101 /**
-102  * Releases a display state chunk back to this factory, destroying it if the chunk's use count is then zero.
-103  *
-104  * @param {SceneJS_Chunk} chunk Chunk to release
-105  */
-106 SceneJS_ChunkFactory.prototype.putChunk = function (chunk) {
-107 
-108     if (chunk.useCount == 0) {
-109         return; // In case of excess puts
-110     }
-111 
-112     if (--chunk.useCount <= 0) {    // Release shared core if use count now zero
-113 
-114         this._chunks[chunk.id] = null;
-115 
-116         var freeChunks = SceneJS_ChunkFactory._freeChunks[chunk.type];
-117 
-118         freeChunks.chunks[freeChunks.chunksLen++] = chunk;
-119     }
-120 };
-121 
-122 /**
-123  * Re-cache shader variable locations for each active chunk
-124  */
-125 SceneJS_ChunkFactory.prototype.webglRestored = function () {
-126 
-127     var chunk;
-128 
-129     for (var chunkId in this._chunks) {
-130 
-131         if (this._chunks.hasOwnProperty(chunkId)) {
-132 
-133             chunk = this._chunks[chunkId]; // Re-cache chunk's shader variable locations
-134 
-135             if (chunk.build) {
-136                 chunk.build();
-137             }
-138         }
-139     }
-140 };
-141 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_clipsChunk.js.html b/docs/symbols/src/src_core_display_chunks_clipsChunk.js.html deleted file mode 100644 index 1211382e..00000000 --- a/docs/symbols/src/src_core_display_chunks_clipsChunk.js.html +++ /dev/null @@ -1,80 +0,0 @@ -
  1 /**
-  2  * Create display state chunk type for draw and pick render of user clipping planes
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type: "clips",
-  7 
-  8     build : function() {
-  9 
- 10         this._draw = this._draw || [];
- 11 
- 12         var draw = this.program.draw;
- 13 
- 14         for (var i = 0, len = this.core.clips.length; i < len; i++) {
- 15             this._draw[i] = {
- 16                 uClipMode :draw.getUniformLocation("SCENEJS_uClipMode" + i),
- 17                 uClipNormalAndDist: draw.getUniformLocation("SCENEJS_uClipNormalAndDist" + i)
- 18             };
- 19         }
- 20 
- 21         this._pick = this._pick || [];
- 22 
- 23         var pick = this.program.pick;
- 24 
- 25         for (var i = 0, len = this.core.clips.length; i < len; i++) {
- 26             this._pick[i] = {
- 27                 uClipMode :pick.getUniformLocation("SCENEJS_uClipMode" + i),
- 28                 uClipNormalAndDist: pick.getUniformLocation("SCENEJS_uClipNormalAndDist" + i)
- 29             };
- 30         }
- 31     },
- 32 
- 33     drawAndPick: function(ctx) {
- 34 
- 35         var vars = (ctx.pick) ? this._pick : this._draw;
- 36 
- 37         var mode;
- 38         var normalAndDist;
- 39         var clips = this.core.clips;
- 40         var clip;
- 41         var gl = this.program.gl;
- 42 
- 43         for (var i = 0, len = clips.length; i < len; i++) {
- 44 
- 45             if (ctx.pick) {
- 46                 mode = vars[i].uClipMode;
- 47                 normalAndDist = vars[i].uClipNormalAndDist;
- 48             } else {
- 49                 mode = vars[i].uClipMode;
- 50                 normalAndDist = vars[i].uClipNormalAndDist;
- 51             }
- 52 
- 53             if (mode && normalAndDist) {
- 54 
- 55                 clip = clips[i];
- 56 
- 57                 if (clip.mode == "inside") {
- 58 
- 59                     gl.uniform1f(mode, 2);
- 60                     gl.uniform4fv(normalAndDist, clip.normalAndDist);
- 61 
- 62                 } else if (clip.mode == "outside") {
- 63 
- 64                     gl.uniform1f(mode, 1);
- 65                     gl.uniform4fv(normalAndDist, clip.normalAndDist);
- 66 
- 67                 } else { // disabled
- 68                     gl.uniform1f(mode, 0);
- 69                 }
- 70             }
- 71         }
- 72     }
- 73 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_drawChunk.js.html b/docs/symbols/src/src_core_display_chunks_drawChunk.js.html deleted file mode 100644 index 643f9bd0..00000000 --- a/docs/symbols/src/src_core_display_chunks_drawChunk.js.html +++ /dev/null @@ -1,32 +0,0 @@ -
  1 /**
-  2  *
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type:"draw",
-  7 
-  8     /**
-  9      * As we apply a list of state chunks in a {@link SceneJS_Display}, we track the ID of each chunk
- 10      * in order to avoid redundantly re-applying the same chunk.
- 11      *
- 12      * We don't want that for draw chunks however, because they contain GL drawElements calls,
- 13      * which we need to do for each object.
- 14      */
- 15     unique:true,
- 16 
- 17     build:function () {},
- 18 
- 19     drawAndPick:function (ctx) {
- 20 
- 21         var gl = this.program.gl;
- 22 
- 23         gl.drawElements(this.core.primitive, this.core.indexBuf.numItems, gl.UNSIGNED_SHORT, 0);
- 24     }
- 25 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_flagsChunk.js.html b/docs/symbols/src/src_core_display_chunks_flagsChunk.js.html deleted file mode 100644 index b18ebd9e..00000000 --- a/docs/symbols/src/src_core_display_chunks_flagsChunk.js.html +++ /dev/null @@ -1,67 +0,0 @@ -
  1 /**
-  2  *  Create display state chunk type for draw and pick render of flags
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type: "flags",
-  7 
-  8     build : function() {
-  9 
- 10         var draw = this.program.draw;
- 11 
- 12         this._uBackfaceTexturingDraw = draw.getUniformLocation("SCENEJS_uBackfaceTexturing");
- 13         this._uBackfaceLightingDraw = draw.getUniformLocation("SCENEJS_uBackfaceLighting");
- 14         this._uSpecularLightingDraw = draw.getUniformLocation("SCENEJS_uSpecularLighting");
- 15         this._uClippingDraw = draw.getUniformLocation("SCENEJS_uClipping");
- 16         this._uAmbientDraw = draw.getUniformLocation("SCENEJS_uAmbient");
- 17 
- 18         var pick = this.program.pick;
- 19 
- 20         this._uClippingPick = pick.getUniformLocation("SCENEJS_uClipping");
- 21     },
- 22 
- 23     drawAndPick : function(ctx) {
- 24 
- 25         var gl = this.program.gl;
- 26 
- 27         var backfaces = this.core.backfaces;
- 28 
- 29         if (ctx.backfaces != backfaces) {
- 30             if (backfaces) {
- 31                 gl.disable(gl.CULL_FACE);
- 32             } else {
- 33                 gl.enable(gl.CULL_FACE);
- 34             }
- 35             ctx.backfaces = backfaces;
- 36         }
- 37 
- 38         var frontface = this.core.frontface;
- 39 
- 40 //        if (ctx.frontface != frontface) {
- 41 //            if (frontface == "ccw") {
- 42 //                gl.frontFace(gl.CCW);
- 43 //            } else {
- 44 //                gl.frontFace(gl.CW);
- 45 //            }
- 46 //            ctx.frontface = frontface;
- 47 //        }
- 48 
- 49         if (ctx.pick) {
- 50             gl.uniform1i(this._uClippingPick, this.core.clipping);
- 51 
- 52         } else {
- 53             gl.uniform1i(this._uBackfaceTexturingDraw, this.core.backfaceTexturing);
- 54             gl.uniform1i(this._uBackfaceLightingDraw, this.core.backfaceLighting);
- 55             gl.uniform1i(this._uSpecularLightingDraw, this.core.specular);
- 56             gl.uniform1i(this._uClippingDraw, this.core.clipping);
- 57             gl.uniform1i(this._uAmbientDraw, this.core.ambient);
- 58         }
- 59     }
- 60 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_framebufChunk.js.html b/docs/symbols/src/src_core_display_chunks_framebufChunk.js.html deleted file mode 100644 index 4ae40059..00000000 --- a/docs/symbols/src/src_core_display_chunks_framebufChunk.js.html +++ /dev/null @@ -1,36 +0,0 @@ -
  1 /**
-  2  *   Create display state chunk type for draw and pick render of framebuf
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type: "framebuf",
-  7 
-  8     build: function() {
-  9     },
- 10 
- 11     drawAndPick: function(ctx) {
- 12 
- 13         if (ctx.framebuf) {
- 14 
- 15             this.program.gl.finish(); // Force framebuf to complete
- 16 
- 17             ctx.framebuf.unbind();
- 18         }
- 19 
- 20         var framebuf = this.core.framebuf;
- 21 
- 22         if (framebuf) {
- 23 
- 24             framebuf.bind();
- 25 
- 26             ctx.framebuf = framebuf;  // Must flush on cleanup
- 27         }
- 28     }
- 29 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_geometryChunk.js.html b/docs/symbols/src/src_core_display_chunks_geometryChunk.js.html deleted file mode 100644 index b1719de3..00000000 --- a/docs/symbols/src/src_core_display_chunks_geometryChunk.js.html +++ /dev/null @@ -1,106 +0,0 @@ -
  1 /**
-  2  *  Create display state chunk type for draw and pick render of geometry
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type:"geometry",
-  7 
-  8     /**
-  9      * As we apply a list of state chunks in a {@link SceneJS_Display}, we track the ID of each chunk
- 10      * in order to avoid redundantly re-applying the same chunk.
- 11      *
- 12      * We don't want that for draw chunks however, because they contain GL drawElements calls,
- 13      * which we need to do for each object.
- 14      */
- 15     unique:true,
- 16 
- 17     build:function () {
- 18 
- 19         var draw = this.program.draw;
- 20 
- 21         this._aVertexDraw = draw.getAttribute("SCENEJS_aVertex");
- 22         this._aNormalDraw = draw.getAttribute("SCENEJS_aNormal");
- 23         this._aUVDraw = draw.getAttribute("SCENEJS_aUVCoord");
- 24         this._aUV2Draw = draw.getAttribute("SCENEJS_aUVCoord2");
- 25         this._aColorDraw = draw.getAttribute("SCENEJS_aVertexColor");
- 26 
- 27         var pick = this.program.pick;
- 28 
- 29         this._aVertexPick = pick.getAttribute("SCENEJS_aVertex");
- 30         this._aNormalPick = pick.getAttribute("SCENEJS_aNormal");
- 31         this._aUVPick = pick.getAttribute("SCENEJS_aUVCoord");
- 32         this._aUV2Pick = pick.getAttribute("SCENEJS_aUVCoord2");
- 33         this._aColorPick = pick.getAttribute("SCENEJS_aVertexColor");
- 34     },
- 35 
- 36     draw:function (ctx) {
- 37 
- 38         var gl = this.program.gl;
- 39 
- 40         if (ctx.geoChunkId != this.id) { // HACK until we have distinct state chunks for VBOs and draw call
- 41 
- 42             if (this._aVertexDraw && !ctx.vertexBuf) {
- 43                 this._aVertexDraw.bindFloatArrayBuffer(this.core.vertexBuf);
- 44             }
- 45 
- 46             if (this._aNormalDraw && !ctx.normalBuf) {
- 47                 this._aNormalDraw.bindFloatArrayBuffer(this.core.normalBuf);
- 48             }
- 49 
- 50             if (this._aUVDraw && !ctx.uvBuf) {
- 51                 this._aUVDraw.bindFloatArrayBuffer(this.core.uvBuf);
- 52             }
- 53 
- 54             if (this._aUV2Draw && !ctx.uvBuf2) {
- 55                 this._aUV2Draw.bindFloatArrayBuffer(this.core.uvBuf2);
- 56             }
- 57 
- 58             if (this._aColorDraw && !ctx.colorBuf) {
- 59                 this._aColorDraw.bindFloatArrayBuffer(this.core.colorBuf);
- 60             }
- 61 
- 62             this.core.indexBuf.bind();
- 63 
- 64             ctx.geoChunkId = this.id;
- 65         }
- 66 
- 67         gl.drawElements(this.core.primitive, this.core.indexBuf.numItems, gl.UNSIGNED_SHORT, 0);
- 68     },
- 69 
- 70     pick:function (ctx) {
- 71 
- 72         var gl = this.program.gl;
- 73 
- 74         if (ctx.geoChunkId != this.id) { // HACK until we have distinct state chunks for VBOs and draw call
- 75 
- 76             if (this._aVertexPick && !ctx.vertexBuf) {
- 77                 this._aVertexPick.bindFloatArrayBuffer(this.core.vertexBuf);
- 78             }
- 79 
- 80             if (this._aNormalPick && !ctx.normalBuf) {
- 81                 this._aNormalPick.bindFloatArrayBuffer(this.core.normalBuf);
- 82             }
- 83 
- 84             if (this._aUVPick && !ctx.uvBuf) {
- 85                 this._aUVPick.bindFloatArrayBuffer(this.core.uvBuf);
- 86             }
- 87 
- 88             if (this._aUV2Pick && !ctx.uvBuf2) {
- 89                 this._aUV2Pick.bindFloatArrayBuffer(this.core.uvBuf2);
- 90             }
- 91 
- 92             this.core.indexBuf.bind();
- 93 
- 94             ctx.geoChunkId = this.id;
- 95         }
- 96 
- 97         gl.drawElements(this.core.primitive, this.core.indexBuf.numItems, gl.UNSIGNED_SHORT, 0);
- 98     }
- 99 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_lightsChunk.js.html b/docs/symbols/src/src_core_display_chunks_lightsChunk.js.html deleted file mode 100644 index 1fa6a267..00000000 --- a/docs/symbols/src/src_core_display_chunks_lightsChunk.js.html +++ /dev/null @@ -1,85 +0,0 @@ -
  1 /**
-  2  *  Create display state chunk type for draw render of lights projection
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type:"lights",
-  7 
-  8     build:function () {
-  9 
- 10         this._uAmbientColor = this._uAmbientColor || [];
- 11         this._uLightColor = this._uLightColor || [];
- 12         this._uLightDir = this._uLightDir || [];
- 13         this._uLightPos = this._uLightPos || [];
- 14         this._uLightCutOff = this._uLightCutOff || [];
- 15         this._uLightSpotExp = this._uLightSpotExp || [];
- 16         this._uLightAttenuation = this._uLightAttenuation || [];
- 17 
- 18         var lights = this.core.lights;
- 19         var program = this.program;
- 20 
- 21         for (var i = 0, len = lights.length; i < len; i++) {
- 22 
- 23             switch (lights[i].mode) {
- 24 
- 25                 case "ambient":
- 26                     this._uAmbientColor[i] = (program.draw.getUniformLocation("SCENEJS_uAmbientColor"));
- 27                     break;
- 28 
- 29                 case "dir":
- 30                     this._uLightColor[i] = program.draw.getUniformLocation("SCENEJS_uLightColor" + i);
- 31                     this._uLightPos[i] = null;
- 32                     this._uLightDir[i] = program.draw.getUniformLocation("SCENEJS_uLightDir" + i);
- 33                     break;
- 34 
- 35                 case "point":
- 36                     this._uLightColor[i] = program.draw.getUniformLocation("SCENEJS_uLightColor" + i);
- 37                     this._uLightPos[i] = program.draw.getUniformLocation("SCENEJS_uLightPos" + i);
- 38                     this._uLightDir[i] = null;
- 39                     break;
- 40             }
- 41         }
- 42     },
- 43 
- 44     draw:function (ctx) {
- 45 
- 46         if (ctx.dirty) {
- 47             this.build();
- 48         }
- 49 
- 50         var lights = this.core.lights;
- 51         var light;
- 52 
- 53         var gl = this.program.gl;
- 54 
- 55         for (var i = 0, len = lights.length; i < len; i++) {
- 56 
- 57             light = lights[i];
- 58 
- 59             if (this._uAmbientColor[i]) {
- 60                 gl.uniform3fv(this._uAmbientColor[i], light.color);
- 61 
- 62             } else {
- 63 
- 64                 if (this._uLightColor[i]) {
- 65                     gl.uniform3fv(this._uLightColor[i], light.color);
- 66                 }
- 67 
- 68                 if (this._uLightPos[i]) {
- 69                     gl.uniform3fv(this._uLightPos[i], light.pos);
- 70                 }
- 71 
- 72                 if (this._uLightDir[i]) {
- 73                     gl.uniform3fv(this._uLightDir[i], light.dir);
- 74                 }
- 75             }
- 76         }
- 77     }
- 78 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_listenersChunk.js.html b/docs/symbols/src/src_core_display_chunks_listenersChunk.js.html deleted file mode 100644 index 8aa00630..00000000 --- a/docs/symbols/src/src_core_display_chunks_listenersChunk.js.html +++ /dev/null @@ -1,29 +0,0 @@ -
  1 /**
-  2  *
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type: "listeners",
-  7 
-  8     build : function() {
-  9     },
- 10 
- 11     draw : function(ctx) {
- 12 
- 13         var listeners = this.core.listeners;
- 14         var renderListenerCtx = ctx.renderListenerCtx;
- 15 
- 16         for (var i = listeners.length - 1; i >= 0; i--) { // Child listeners first
- 17             if (listeners[i](renderListenerCtx) === true) { // Call listener with query facade object as scope
- 18                 return true;
- 19             }
- 20         }
- 21     }
- 22 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_lookAtChunk.js.html b/docs/symbols/src/src_core_display_chunks_lookAtChunk.js.html deleted file mode 100644 index 36ac4e8b..00000000 --- a/docs/symbols/src/src_core_display_chunks_lookAtChunk.js.html +++ /dev/null @@ -1,57 +0,0 @@ -
  1 /**
-  2  * Create display state chunk type for draw and pick render of lookAt transform
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type: "lookAt",
-  7 
-  8     build : function() {
-  9 
- 10         this._uvMatrixDraw = this.program.draw.getUniformLocation("SCENEJS_uVMatrix");
- 11         this._uVNMatrixDraw = this.program.draw.getUniformLocation("SCENEJS_uVNMatrix");
- 12         this._uWorldEyeDraw = this.program.draw.getUniformLocation("SCENEJS_uWorldEye");
- 13 
- 14         this._uvMatrixPick = this.program.pick.getUniformLocation("SCENEJS_uVMatrix");
- 15     },
- 16 
- 17     draw : function(ctx) {
- 18 
- 19         if (this.core.dirty) {
- 20             this.core.rebuild();
- 21         }
- 22 
- 23         var gl = this.program.gl;
- 24 
- 25         if (this._uvMatrixDraw) {
- 26             gl.uniformMatrix4fv(this._uvMatrixDraw, gl.FALSE, this.core.mat);
- 27         }
- 28 
- 29         if (this._uVNMatrixDraw) {
- 30             gl.uniformMatrix4fv(this._uVNMatrixDraw, gl.FALSE, this.core.normalMat);
- 31         }
- 32 
- 33         if (this._uWorldEyeDraw) {
- 34             gl.uniform3fv(this._uWorldEyeDraw, this.core.lookAt.eye);
- 35         }
- 36 
- 37         ctx.viewMat = this.core.mat;
- 38     },
- 39 
- 40     pick : function(ctx) {
- 41 
- 42         var gl = this.program.gl;
- 43 
- 44         if (this._uvMatrixPick) {
- 45             gl.uniformMatrix4fv(this._uvMatrixPick, gl.FALSE, this.core.mat);
- 46         }
- 47 
- 48         ctx.viewMat = this.core.mat;
- 49     }
- 50 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_materialChunk.js.html b/docs/symbols/src/src_core_display_chunks_materialChunk.js.html deleted file mode 100644 index cc8c2f1f..00000000 --- a/docs/symbols/src/src_core_display_chunks_materialChunk.js.html +++ /dev/null @@ -1,55 +0,0 @@ -
  1 /**
-  2  * Create display state chunk type for draw render of material transform
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type: "material",
-  7 
-  8     build : function() {
-  9 
- 10         var draw = this.program.draw;
- 11 
- 12         this._uMaterialBaseColor = draw.getUniformLocation("SCENEJS_uMaterialBaseColor");
- 13         this._uMaterialSpecularColor = draw.getUniformLocation("SCENEJS_uMaterialSpecularColor");
- 14         this._uMaterialSpecular = draw.getUniformLocation("SCENEJS_uMaterialSpecular");
- 15         this._uMaterialShine = draw.getUniformLocation("SCENEJS_uMaterialShine");
- 16         this._uMaterialEmit = draw.getUniformLocation("SCENEJS_uMaterialEmit");
- 17         this._uMaterialAlpha = draw.getUniformLocation("SCENEJS_uMaterialAlpha");
- 18     },
- 19 
- 20     draw : function() {
- 21 
- 22         var gl = this.program.gl;
- 23 
- 24         if (this._uMaterialBaseColor) {
- 25             gl.uniform3fv(this._uMaterialBaseColor, this.core.baseColor);
- 26         }
- 27 
- 28         if (this._uMaterialSpecularColor) {
- 29             gl.uniform3fv(this._uMaterialSpecularColor, this.core.specularColor);
- 30         }
- 31 
- 32         if (this._uMaterialSpecular) {
- 33             gl.uniform1f(this._uMaterialSpecular, this.core.specular);
- 34         }
- 35 
- 36         if (this._uMaterialShine) {
- 37             gl.uniform1f(this._uMaterialShine, this.core.shine);
- 38         }
- 39 
- 40         if (this._uMaterialEmit) {
- 41             gl.uniform1f(this._uMaterialEmit, this.core.emit);
- 42         }
- 43 
- 44         if (this._uMaterialAlpha) {
- 45             gl.uniform1f(this._uMaterialAlpha, this.core.alpha);
- 46         }
- 47     }
- 48 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_morphGeometryChunk.js.html b/docs/symbols/src/src_core_display_chunks_morphGeometryChunk.js.html deleted file mode 100644 index 5398193c..00000000 --- a/docs/symbols/src/src_core_display_chunks_morphGeometryChunk.js.html +++ /dev/null @@ -1,174 +0,0 @@ -
  1 /**
-  2  * Create display state chunk type for draw render of material transform
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type:"morphGeometry",
-  7 
-  8     build:function () {
-  9 
- 10         var draw = this.program.draw;
- 11 
- 12         this._aVertexDraw = draw.getAttribute("SCENEJS_aVertex");
- 13         this._aNormalDraw = draw.getAttribute("SCENEJS_aNormal");
- 14         this._aUVDraw = draw.getAttribute("SCENEJS_aUVCoord");
- 15         this._aUV2Draw = draw.getAttribute("SCENEJS_aUVCoord2");
- 16         this._aColorDraw = draw.getAttribute("SCENEJS_aVertexColor");
- 17 
- 18         this._aMorphVertexDraw = draw.getAttribute("SCENEJS_aMorphVertex");
- 19         this._aMorphNormalDraw = draw.getAttribute("SCENEJS_aMorphNormal");
- 20         this._aMorphUVDraw = draw.getAttribute("SCENEJS_aMorphUVCoord");
- 21         this._aMorphUV2Draw = draw.getAttribute("SCENEJS_aMorphUVCoord2");
- 22         this._aMorphColorDraw = draw.getAttribute("SCENEJS_aMorphColor");
- 23         this._uMorphFactorDraw = draw.getUniformLocation("SCENEJS_uMorphFactor");
- 24 
- 25         var pick = this.program.pick;
- 26 
- 27         this._aVertexPick = pick.getAttribute("SCENEJS_aVertex");
- 28         this._aNormalPick = pick.getAttribute("SCENEJS_aNormal");
- 29         this._aUVPick = pick.getAttribute("SCENEJS_aUVCoord");
- 30         this._aUV2Pick = pick.getAttribute("SCENEJS_aUVCoord2");
- 31         this._aColorPick = pick.getAttribute("SCENEJS_aVertexColor");
- 32 
- 33         this._aMorphVertexPick = pick.getAttribute("SCENEJS_aMorphVertex");
- 34         this._aMorphNormalPick = pick.getAttribute("SCENEJS_aMorphNormal");
- 35         this._aMorphUVPick = pick.getAttribute("SCENEJS_aMorphUVCoord");
- 36         this._aMorphUV2Pick = pick.getAttribute("SCENEJS_aMorphUVCoord2");
- 37         this._aMorphColorPick = pick.getAttribute("SCENEJS_aMorphColor");
- 38         this._uMorphFactorPick = pick.getUniformLocation("SCENEJS_uMorphFactor");
- 39     },
- 40 
- 41     draw:function (ctx) {
- 42 
- 43         var targets = this.core.targets;
- 44 
- 45         if (!targets || targets.length == 0) {
- 46             ctx.vertexBuf = false;
- 47             ctx.normalBuf = false;
- 48             ctx.uvBuf = false;
- 49             ctx.uvBuf2 = false;
- 50             ctx.colorBuf = false;
- 51             return;
- 52         }
- 53 
- 54         var gl = this.program.gl;
- 55 
- 56         var target1 = this.core.targets[this.core.key1]; // Keys will update
- 57         var target2 = this.core.targets[this.core.key2];
- 58 
- 59         if (this._aMorphVertexDraw) {
- 60             this._aVertexDraw.bindFloatArrayBuffer(target1.vertexBuf);
- 61             this._aMorphVertexDraw.bindFloatArrayBuffer(target2.vertexBuf);
- 62             ctx.vertexBuf = true;
- 63         } else {
- 64             ctx.vertexBuf = false;
- 65         }
- 66 
- 67         if (this._aMorphNormalDraw) {
- 68             this._aNormalDraw.bindFloatArrayBuffer(target1.normalBuf);
- 69             this._aMorphNormalDraw.bindFloatArrayBuffer(target2.normalBuf);
- 70             ctx.normalBuf = true;
- 71         } else {
- 72             ctx.normalBuf = false;
- 73         }
- 74 
- 75         if (this._aMorphUVDraw) {
- 76             this._aUVDraw.bindFloatArrayBuffer(target1.uvBuf);
- 77             this._aMorphUVDraw.bindFloatArrayBuffer(target2.uvBuf);
- 78             ctx.uvBuf = true;
- 79         } else {
- 80             ctx.uvBuf = false;
- 81         }
- 82 
- 83         if (this._aMorphUV2Draw) {
- 84             this._aUV2Draw.bindFloatArrayBuffer(target1.uvBuf2);
- 85             this._aMorphUV2Draw.bindFloatArrayBuffer(target2.uvBuf2);
- 86             ctx.uvBuf2 = true;
- 87         } else {
- 88             ctx.uvBuf2 = false;
- 89         }
- 90 
- 91         if (this._aMorphColorDraw) {
- 92             this._aColorDraw.bindFloatArrayBuffer(target1.colorBuf);
- 93             this._aMorphColorDraw.bindFloatArrayBuffer(target2.colorBuf);
- 94             ctx.colorBuf = true;
- 95         } else {
- 96             ctx.colorBuf = false;
- 97         }
- 98 
- 99         if (this._uMorphFactorDraw) {
-100             gl.uniform1f(this._uMorphFactorDraw, this.core.factor); // Bind LERP factor
-101         }
-102     },
-103 
-104     pick:function (ctx) {
-105 
-106         var targets = this.core.targets;
-107 
-108         if (!targets || targets.length == 0) {
-109             ctx.vertexBuf = false;
-110             ctx.normalBuf = false;
-111             ctx.uvBuf = false;
-112             ctx.uvBuf2 = false;
-113             ctx.colorBuf = false;
-114             return;
-115         }
-116 
-117         var gl = this.program.gl;
-118 
-119         var target1 = targets[this.core.key1]; // Keys will update
-120         var target2 = targets[this.core.key2];
-121 
-122         if (this._aMorphVertexPick) {
-123             this._aVertexPick.bindFloatArrayBuffer(target1.vertexBuf);
-124             this._aMorphVertexPick.bindFloatArrayBuffer(target2.vertexBuf);
-125             ctx.vertexBuf = true;
-126         } else {
-127             ctx.vertexBuf = false;
-128         }
-129 
-130         if (this._aMorphNormalPick) {
-131             this._aNormalPick.bindFloatArrayBuffer(target1.normalBuf);
-132             this._aMorphNormalPick.bindFloatArrayBuffer(target2.normalBuf);
-133             ctx.normalBuf = true;
-134         } else {
-135             ctx.normalBuf = false;
-136         }
-137 
-138         if (this._aMorphUVPick) {
-139             this._aUVPick.bindFloatArrayBuffer(target1.uvBuf);
-140             this._aMorphUVPick.bindFloatArrayBuffer(target2.uvBuf);
-141             ctx.uvBuf = true;
-142         } else {
-143             ctx.uvBuf = false;
-144         }
-145 
-146         if (this._aMorphUV2Pick) {
-147             this._aUV2Pick.bindFloatArrayBuffer(target1.uvBuf2);
-148             this._aMorphUV2Pick.bindFloatArrayBuffer(target2.uvBuf2);
-149             ctx.uvBuf2 = true;
-150         } else {
-151             ctx.uvBuf2 = false;
-152         }
-153 
-154         if (this._aMorphColorPick) {
-155             this._aColorPick.bindFloatArrayBuffer(target1.colorBuf);
-156             this._aMorphColorPick.bindFloatArrayBuffer(target2.colorBuf);
-157             ctx.colorBuf = true;
-158         } else {
-159             ctx.colorBuf = false;
-160         }
-161 
-162         if (this._uMorphFactorPick) {
-163             gl.uniform1f(this._uMorphFactorPick, this.core.factor); // Bind LERP factor
-164         }
-165     }
-166 });
-167 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_nameChunk.js.html b/docs/symbols/src/src_core_display_chunks_nameChunk.js.html deleted file mode 100644 index b6ef7040..00000000 --- a/docs/symbols/src/src_core_display_chunks_nameChunk.js.html +++ /dev/null @@ -1,32 +0,0 @@ -
  1 /**
-  2  * Create display state chunk type for draw render of material transform
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type: "name",
-  7 
-  8     build : function() {
-  9         this._uPickColor = this.program.pick.getUniformLocation("SCENEJS_uPickColor");
- 10     },
- 11 
- 12     pick : function(ctx) {
- 13 
- 14         if (this._uPickColor && this.core.name) {
- 15 
- 16             ctx.pickNames[ctx.pickIndex++] = this.core.name;
- 17 
- 18             var b = ctx.pickIndex >> 16 & 0xFF;
- 19             var g = ctx.pickIndex >> 8 & 0xFF;
- 20             var r = ctx.pickIndex & 0xFF;
- 21 
- 22             this.program.gl.uniform3fv(this._uPickColor, [r / 255, g / 255, b / 255]);
- 23         }
- 24     }
- 25 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_programChunk.js.html b/docs/symbols/src/src_core_display_chunks_programChunk.js.html deleted file mode 100644 index b73bfd59..00000000 --- a/docs/symbols/src/src_core_display_chunks_programChunk.js.html +++ /dev/null @@ -1,81 +0,0 @@ -
  1 SceneJS_ChunkFactory.createChunkType({
-  2 
-  3     type: "program",
-  4 
-  5     build : function() {
-  6         this._rayPickMode = this.program.pick.getUniformLocation("SCENEJS_uRayPickMode");
-  7     },
-  8 
-  9     draw : function(frameCtx) {
- 10 
- 11         var drawProgram = this.program.draw;
- 12 
- 13         if (frameCtx.program) {
- 14             frameCtx.program.unbind();
- 15         }
- 16 
- 17         drawProgram.bind();
- 18 
- 19         frameCtx.program = drawProgram;
- 20 
- 21         /*
- 22          * HACK until we have distinct chunk for each VBO (maybe)
- 23          */
- 24         frameCtx.vertexBuf = false;
- 25         frameCtx.normalBuf = false;
- 26         frameCtx.uvBuf = false;
- 27         frameCtx.uvBuf2 = false;
- 28         frameCtx.colorBuf = false;
- 29 
- 30         frameCtx.geoChunkId = null; // HACK until we have distinct state chunks for VBOs and draw call
- 31 
- 32         var gl = this.program.gl;
- 33 
- 34         for (var i = 0; i < 10; i++) {
- 35             gl.disableVertexAttribArray(i);
- 36         }
- 37     },
- 38 
- 39     pick : function(frameCtx) {
- 40 
- 41         var pickProgram = this.program.pick;
- 42 
- 43         if (frameCtx.program) {
- 44             frameCtx.program.unbind();
- 45         }
- 46 
- 47         pickProgram.bind();
- 48 
- 49         var gl = this.program.gl;
- 50 
- 51         gl.uniform1i(this._rayPickMode, frameCtx.rayPick);
- 52 
- 53         frameCtx.program = pickProgram;
- 54 
- 55         /*
- 56         * HACK until we have distinct chunk for each VBO (maybe)
- 57          */
- 58         frameCtx.vertexBuf = false;
- 59         frameCtx.normalBuf = false;
- 60         frameCtx.uvBuf = false;
- 61         frameCtx.uvBuf2 = false;
- 62         frameCtx.colorBuf = false;
- 63 
- 64         frameCtx.geoChunkId = null; // HACK until we have distinct state chunks for VBOs and draw call
- 65 
- 66         for (var i = 0; i < 10; i++) {
- 67             gl.disableVertexAttribArray(i);
- 68         }
- 69     }
- 70 });
- 71 
- 72 
- 73 
- 74 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_rendererChunk.js.html b/docs/symbols/src/src_core_display_chunks_rendererChunk.js.html deleted file mode 100644 index 75339d8f..00000000 --- a/docs/symbols/src/src_core_display_chunks_rendererChunk.js.html +++ /dev/null @@ -1,33 +0,0 @@ -
  1 /**
-  2  *
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5     
-  6     type: "renderer",
-  7 
-  8     build : function() {
-  9     },
- 10 
- 11     drawAndPick : function(ctx) {
- 12 
- 13         if (this.core.props) {
- 14 
- 15             var gl = this.program.gl;
- 16 
- 17             if (ctx.renderer) {
- 18                 ctx.renderer.props.restoreProps(gl);
- 19                 ctx.renderer = this.core;
- 20             }
- 21 
- 22             this.core.props.setProps(gl);
- 23         }
- 24     }
- 25 });
- 26 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_shaderChunk.js.html b/docs/symbols/src/src_core_display_chunks_shaderChunk.js.html deleted file mode 100644 index 13942d4e..00000000 --- a/docs/symbols/src/src_core_display_chunks_shaderChunk.js.html +++ /dev/null @@ -1,38 +0,0 @@ -
  1 /**
-  2  *
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type: "shader",
-  7 
-  8     build : function() {
-  9     },
- 10 
- 11     drawAndPick : function(ctx) {
- 12 
- 13         var paramsStack = this.core.paramsStack;
- 14 
- 15         if (paramsStack) {
- 16 
- 17             var program = ctx.pick ? this.program.pick : this.program.draw;
- 18             var params;
- 19             var name;
- 20 
- 21             for (var i = 0, len = paramsStack.length; i < len; i++) {
- 22                 params = paramsStack[i];
- 23                 for (name in params) {
- 24                     if (params.hasOwnProperty(name)) {
- 25                         program.setUniform(name, params[name]);  // TODO: cache locations
- 26                     }
- 27                 }
- 28             }
- 29         }
- 30     }
- 31 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_shaderParamsChunk.js.html b/docs/symbols/src/src_core_display_chunks_shaderParamsChunk.js.html deleted file mode 100644 index 37675bb9..00000000 --- a/docs/symbols/src/src_core_display_chunks_shaderParamsChunk.js.html +++ /dev/null @@ -1,38 +0,0 @@ -
  1 /**
-  2  *
-  3  */
-  4 SceneJS_ChunkFactory.createChunkType({
-  5 
-  6     type: "shaderParams",
-  7 
-  8     build : function() {
-  9     },
- 10 
- 11     drawAndPick: function(ctx) {
- 12 
- 13         var paramsStack = this.core.paramsStack;
- 14 
- 15         if (paramsStack) {
- 16 
- 17             var program = ctx.pick ? this.program.pick : this.program.draw;
- 18             var params;
- 19             var name;
- 20 
- 21             for (var i = 0, len = paramsStack.length; i < len; i++) {
- 22                 params = paramsStack[i];
- 23                 for (name in params) {
- 24                     if (params.hasOwnProperty(name)) {
- 25                         program.setUniform(name, params[name]);  // TODO: cache locations
- 26                     }
- 27                 }
- 28             }
- 29         }
- 30     }
- 31 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_textureChunk.js.html b/docs/symbols/src/src_core_display_chunks_textureChunk.js.html deleted file mode 100644 index 55b55735..00000000 --- a/docs/symbols/src/src_core_display_chunks_textureChunk.js.html +++ /dev/null @@ -1,71 +0,0 @@ -
  1 SceneJS_ChunkFactory.createChunkType({
-  2 
-  3     type: "texture",
-  4 
-  5     build : function() {
-  6 
-  7         this._uTexSampler = this._uTexSampler || [];
-  8         this._uTexMatrix = this._uTexMatrix || [];
-  9         this._uTexBlendFactor = this._uTexBlendFactor || [];
- 10 
- 11         var layers = this.core.layers;
- 12 
- 13         if (layers) {
- 14 
- 15             var layer;
- 16             var draw = this.program.draw;
- 17 
- 18             for (var i = 0, len = layers.length; i < len; i++) {
- 19 
- 20                 layer = layers[i];
- 21 
- 22                 this._uTexSampler[i] = "SCENEJS_uSampler" + i;
- 23 
- 24                 this._uTexMatrix[i] = layer.matrixAsArray
- 25                         ? draw.getUniform("SCENEJS_uLayer" + i + "Matrix")
- 26                         : null;
- 27 
- 28                 this._uTexBlendFactor[i] = draw.getUniform("SCENEJS_uLayer" + i + "BlendFactor");
- 29             }
- 30         }
- 31     },
- 32 
- 33     draw : function() {
- 34 
- 35         var layers = this.core.layers;
- 36 
- 37         if (layers) {
- 38 
- 39             var draw = this.program.draw;
- 40             var layer;
- 41 
- 42             for (var i = 0, len = layers.length; i < len; i++) {
- 43 
- 44                 layer = layers[i];
- 45 
- 46                 if (this._uTexSampler[i] && layer.texture) {    // Lazy-loads
- 47 
- 48                     draw.bindTexture(this._uTexSampler[i], layer.texture, i);
- 49 
- 50                     if (this._uTexMatrix[i]) {
- 51                         this._uTexMatrix[i].setValue(layer.matrixAsArray);
- 52                     }
- 53 
- 54                     if (this._uTexBlendFactor[i]) {
- 55                         this._uTexBlendFactor[i].setValue(layer.blendFactor);
- 56                     }
- 57 
- 58                 } else {
- 59                    //   draw.bindTexture(this._uTexSampler[i], null, i); // Unbind
- 60                 }
- 61             }
- 62         }
- 63     }
- 64 });
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_chunks_xformChunk.js.html b/docs/symbols/src/src_core_display_chunks_xformChunk.js.html deleted file mode 100644 index 02cfe960..00000000 --- a/docs/symbols/src/src_core_display_chunks_xformChunk.js.html +++ /dev/null @@ -1,67 +0,0 @@ -
  1 SceneJS_ChunkFactory.createChunkType({
-  2 
-  3     type: "xform",
-  4 
-  5     build : function() {
-  6 
-  7         var draw = this.program.draw;
-  8 
-  9         this._uMatLocationDraw = draw.getUniformLocation("SCENEJS_uMMatrix");
- 10         this._uNormalMatLocationDraw = draw.getUniformLocation("SCENEJS_uMNMatrix");
- 11 
- 12         var pick = this.program.pick;
- 13 
- 14         this._uMatLocationPick = pick.getUniformLocation("SCENEJS_uMMatrix");
- 15         this._uNormalMatLocationPick = pick.getUniformLocation("SCENEJS_uMNMatrix");
- 16     },
- 17 
- 18     draw : function(ctx) {
- 19 
- 20         /* Rebuild core's matrix from matrices at cores on path up to root
- 21          */
- 22        if (this.core.dirty && this.core.build) {
- 23             this.core.build();
- 24         }
- 25 
- 26         var gl = this.program.gl;
- 27 
- 28         if (this._uMatLocationDraw) {
- 29             gl.uniformMatrix4fv(this._uMatLocationDraw, gl.FALSE, this.core.mat);
- 30         }
- 31 
- 32         if (this._uNormalMatLocationDraw) {
- 33             gl.uniformMatrix4fv(this._uNormalMatLocationDraw, gl.FALSE, this.core.normalMat);
- 34         }
- 35 
- 36         ctx.modelMat = this.core.mat;
- 37     },
- 38 
- 39     pick : function(ctx) {
- 40 
- 41         /* Rebuild core's matrix from matrices at cores on path up to root
- 42          */
- 43         if (this.core.dirty) {
- 44             this.core.build();
- 45         }
- 46 
- 47         var gl = this.program.gl;
- 48 
- 49         if (this._uMatLocationPick) {
- 50             gl.uniformMatrix4fv(this._uMatLocationPick, gl.FALSE, this.core.mat);
- 51         }
- 52 
- 53         if (this._uNormalMatLocationPick) {
- 54             gl.uniformMatrix4fv(this._uNormalMatLocationPick, gl.FALSE, this.core.normalMat);
- 55         }
- 56 
- 57         ctx.modelMat = this.core.mat;
- 58     }
- 59 });
- 60 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_display.js.html b/docs/symbols/src/src_core_display_display.js.html deleted file mode 100644 index b8061c92..00000000 --- a/docs/symbols/src/src_core_display_display.js.html +++ /dev/null @@ -1,917 +0,0 @@ -
  1 /**
-  2  * @class Renders and picks a {@link SceneJS.Scene}
-  3  * @private
-  4  *
-  5  * <p>A Display is a container of {@link SceneJS_Object}s which are created (or updated) by a depth-first
-  6  * <b>compilation traversal</b> of the nodes within a {@link SceneJS.Scene}.</b>
-  7  *
-  8  * <h2>Rendering Pipeline</h2>
-  9  *
- 10  * <p>Conceptually, a Display implements a pipeline with the following stages:</p>
- 11  *
- 12  * <ol>
- 13  * <li>Create or update {@link SceneJS_Object}s during scene compilation</li>
- 14  * <li>Organise the {@link SceneJS_Object} into an <b>object list</b></li>
- 15  * <li>Determine the GL state sort order for the object list</li>
- 16  * <li>State sort the object list</li>
- 17  * <li>Create a <b>draw list</b> containing {@link SceneJS_Chunk}s belonging to the {@link SceneJS_Object}s in the object list</li>
- 18  * <li>Render the draw list to draw the image</li>
- 19  * </ol>
- 20  *
- 21  * <p>An update to the scene causes the pipeline to be re-executed from one of these stages, and SceneJS is designed
- 22  * so that the pipeline is always re-executed from the latest stage possible to avoid redoing work.</p>
- 23  *
- 24  * <p>For example:</p>
- 25  *
- 26  * <ul>
- 27  * <li>when an object is created or updated, we need to (re)do stages 2, 3, 4, 5 and 6</li>
- 28  * <li>when an object is made invisible, we need to redo stages 5 and 6</li>
- 29  * <li>when an object is assigned to a different scene render layer (works like a render bin), we need to redo
- 30  *   stages 3, 4, 5, and 6</li>
- 31  *<li>when the colour of an object changes, or maybe when the viewpoint changes, we simplt redo stage 6</li>
- 32  * </ul>
- 33  *
- 34  * <h2>Object Creation</h2>
- 35  * <p>The object soup (stage 1) is constructed by a depth-first traversal of the scene graph, which we think of as
- 36  * "compiling" the scene graph into the Display. As traversal visits each scene node, the node's state core is
- 37  * set on the Display (such as {@link #flags}, {@link #layer}, {@link #renderer} etc), which we think of as the
- 38  * cores that are active at that instant during compilation. Each of the scene's leaf nodes is always
- 39  * a {@link SceneJS.Geometry}, and when traversal visits one of those it calls {@link #buildObject} to create an
- 40  * object in the soup. For each of the currently active cores, the object is given a {@link SceneJS_Chunk}
- 41  * containing the WebGL calls for rendering it.</p>
- 42  *
- 43  * <p>The object also gets a shader (implemented by {@link SceneJS_Program}), taylored to render those state cores.</p>
- 44  *
- 45  * <p>Limited re-compilation may also be done on portions of a scene that have been added or sufficiently modified. When
- 46  * traversal visits a {@link SceneJS.Geometry} for which an object already exists in the display, {@link #buildObject}
- 47  * may update the {@link SceneJS_Chunk}s on the object as required for any changes in the core soup since the
- 48  * last time the object was built. If differences among the cores require it, then {@link #buildObject} may also replace
- 49  * the object's {@link SceneJS_Program} in order to render the new core soup configuration.</p>
- 50  *
- 51  * <p>So in summary, to each {@link SceneJS_Object} it builds, {@link #buildObject} creates a list of
- 52  * {@link SceneJS_Chunk}s to render the set of node state cores that are currently set on the {@link SceneJS_Display}.
- 53  * When {@link #buildObject} is re-building an existing object, it may replace one or more {@link SceneJS_Chunk}s
- 54  * for state cores that have changed from the last time the object was built or re-built.</p>
- 55 
- 56  * <h2>Object Destruction</h2>
- 57  * <p>Destruction of a scene graph branch simply involves a call to {@link #removeObject} for each {@link SceneJS.Geometry}
- 58  * in the branch.</p>
- 59  *
- 60  * <h2>Draw List</h2>
- 61  * <p>The draw list is actually comprised of three lists of state chunks: a "pick" list to render a pick buffer
- 62  * for colour-indexed GPU picking, along with an "opaque" list and "transparent" list for normal image rendering.
- 63  * For normal rendering the opaque list is rendered, then blending is enabled and the transparent list is rendered.
- 64  * The chunks in these lists are held in the state-sorted order of their objects in #_objectList, with runs of
- 65  * duplicate states removed, as mentioned.</p>
- 66  *
- 67  * <p>After a scene update, we set a flag on the display to indicate the stage we will need to redo from. The pipeline is
- 68  * then lazy-redone on the next call to #render or #pick.</p>
- 69  */
- 70 var SceneJS_Display = function (cfg) {
- 71 
- 72     /* Display is bound to the lifetime of an HTML5 canvas
- 73      */
- 74     this._canvas = cfg.canvas;
- 75 
- 76     /* Factory which creates and recycles {@link SceneJS_Program} instances
- 77      */
- 78     this._programFactory = new SceneJS_ProgramFactory({
- 79         canvas:cfg.canvas
- 80     });
- 81 
- 82     /* Factory which creates and recycles {@link SceneJS.Chunk} instances
- 83      */
- 84     this._chunkFactory = new SceneJS_ChunkFactory();
- 85 
- 86     /**
- 87      * Node state core for the last {@link SceneJS.Flags} visited during scene graph compilation traversal
- 88      * @type Object
- 89      */
- 90     this.flags = null;
- 91 
- 92     /**
- 93      * Node state core for the last {@link SceneJS.Layer} visited during scene graph compilation traversal
- 94      * @type Object
- 95      */
- 96     this.layer = null;
- 97 
- 98     /**
- 99      * Node state core for the last {@link SceneJS.Renderer} visited during scene graph compilation traversal
-100      * @type Object
-101      */
-102     this.renderer = null;
-103 
-104     /**
-105      * Node state core for the last {@link SceneJS.Lights} visited during scene graph compilation traversal
-106      * @type Object
-107      */
-108     this.lights = null;
-109 
-110     /**
-111      * Node state core for the last {@link SceneJS.Material} visited during scene graph compilation traversal
-112      * @type Object
-113      */
-114     this.material = null;
-115 
-116     /**
-117      * Node state core for the last {@link SceneJS.Texture} visited during scene graph compilation traversal
-118      * @type Object
-119      */
-120     this.texture = null;
-121 
-122     /**
-123      * Node state core for the last {@link SceneJS.XForm} visited during scene graph compilation traversal
-124      * @type Object
-125      */
-126     this.modelTransform = null;
-127 
-128     /**
-129      * Node state core for the last {@link SceneJS.LookAt} visited during scene graph compilation traversal
-130      * @type Object
-131      */
-132     this.viewTransform = null;
-133 
-134     /**
-135      * Node state core for the last {@link SceneJS.Camera} visited during scene graph compilation traversal
-136      * @type Object
-137      */
-138     this.projTransform = null;
-139 
-140     /**
-141      * Node state core for the last {@link SceneJS.Framebuf} visited during scene graph compilation traversal
-142      * @type Object
-143      */
-144     this.framebuf = null;
-145 
-146     /**
-147      * Node state core for the last {@link SceneJS.Clips} visited during scene graph compilation traversal
-148      * @type Object
-149      */
-150     this.clips = null;
-151 
-152     /**
-153      * Node state core for the last {@link SceneJS.MorphGeometry} visited during scene graph compilation traversal
-154      * @type Object
-155      */
-156     this.morphGeometry = null;
-157 
-158     /**
-159      * Node state core for the last {@link SceneJS.Name} visited during scene graph compilation traversal
-160      * @type Object
-161      */
-162     this.name = null;
-163 
-164     /**
-165      * Node state core for the last {@link SceneJS.Tag} visited during scene graph compilation traversal
-166      * @type Object
-167      */
-168     this.tag = null;
-169 
-170     /**
-171      * Node state core for the last render {@link SceneJS.Node} listener encountered during scene graph compilation traversal
-172      * @type Object
-173      */
-174     this.renderListeners = null;
-175 
-176     /**
-177      * Node state core for the last {@link SceneJS.Shader} visited during scene graph compilation traversal
-178      * @type Object
-179      */
-180     this.shader = null;
-181 
-182     /**
-183      * Node state core for the last {@link SceneJS.ShaderParams} visited during scene graph compilation traversal
-184      * @type Object
-185      */
-186     this.shaderParams = null;
-187 
-188     /**
-189      * Node state core for the last {@link SceneJS.Geometry} visited during scene graph compilation traversal
-190      * @type Object
-191      */
-192     this.geometry = null;
-193 
-194     /* Factory which creates and recycles {@link SceneJS_Object} instances
-195      */
-196     this._objectFactory = new SceneJS_ObjectFactory();
-197 
-198     /**
-199      * The objects in the display
-200      */
-201     this._objects = {};
-202 
-203     /**
-204      * Ambient color, which must be given to gl.clearColor before draw list iteration
-205      */
-206     this._ambientColor = [0, 0, 0];
-207 
-208     /**
-209      * The object list, containing all elements of #_objects, kept in GL state-sorted order
-210      */
-211     this._objectList = [];
-212     this._objectListLen = 0;
-213 
-214     /* The "draw list", comprised collectively of three lists of state chunks belong to visible objects
-215      * within #_objectList: a "pick" list to render a pick buffer for colour-indexed GPU picking, along with an
-216      * "opaque" list and "transparent" list for normal image rendering. For normal rendering the opaque list is
-217      * rendered, then blending is enabled and the transparent list is rendered. The chunks in these lists
-218      * are held in the state-sorted order of their objects in #_objectList, with runs of duplicate states removed.
-219      */
-220     this._opaqueDrawList = [];         // State chunk list to render opaque objects
-221     this._opaqueDrawListLen = 0;
-222 
-223     this._transparentDrawList = [];    // State chunk list to render transparent objects
-224     this._transparentDrawListLen = 0;
-225 
-226     this._pickDrawList = [];           // State chunk list to render scene to pick buffer
-227     this._pickDrawListLen = 0;
-228 
-229     /* The frame context holds state shared across a single render of the draw list, along with any results of
-230      * the render, such as pick hits
-231      */
-232     this._frameCtx = {
-233         pickNames:[], // Pick names of objects hit during pick render
-234         canvas:this._canvas            // The canvas
-235     };
-236 
-237     /* The frame context has this facade which is given to scene node "rendered" listeners
-238      * to allow application code to access things like transform matrices from within those listeners.
-239      */
-240     this._frameCtx.renderListenerCtx = new SceneJS.RenderContext(this._frameCtx);
-241 
-242     /*-------------------------------------------------------------------------------------
-243      * Flags which schedule what the display is to do when #render is next called.
-244      *------------------------------------------------------------------------------------*/
-245 
-246     /**
-247      * Flags the object list as needing to be rebuilt from existing objects on the next call to {@link #render} or {@link #pick}.
-248      * Setting this will cause the rendering pipeline to be executed from stage #2 (see class comment),
-249      * causing object list rebuild, state order determination, state sort, draw list construction and image render.
-250      * @type Boolean
-251      */
-252     this.objectListDirty = true;
-253 
-254     /**
-255      * Flags the object list as needing state orders to be computed on the next call to {@link #render} or {@link #pick}.
-256      * Setting this will cause the rendering pipeline to be executed from stage #3 (see class comment),
-257      * causing state order determination, state sort, draw list construction and image render.
-258      * @type Boolean
-259      */
-260     this.stateOrderDirty = true;
-261 
-262     /**
-263      * Flags the object list as needing to be state sorted on the next call to {@link #render} or {@link #pick}.
-264      * Setting this will cause the rendering pipeline to be executed from stage #4 (see class comment),
-265      * causing state sort, draw list construction and image render.
-266      * @type Boolean
-267      */
-268     this.stateSortDirty = true;
-269 
-270     /**
-271      * Flags the draw list as needing to be rebuilt from the object list on the next call to {@link #render} or {@link #pick}.
-272      * Setting this will cause the rendering pipeline to be executed from stage #5 (see class comment),
-273      * causing draw list construction and image render.
-274      * @type Boolean
-275      */
-276     this.drawListDirty = true;
-277 
-278     /**
-279      * Flags the image as needing to be redrawn from the draw list on the next call to {@link #render} or {@link #pick}.
-280      * Setting this will cause the rendering pipeline to be executed from stage #6 (see class comment),
-281      * causing the image render.
-282      * @type Boolean
-283      */
-284     this.imageDirty = true;
-285 
-286     /**
-287      * Flags the neccessity for the image buffer to be re-rendered from the draw list.
-288      * @type Boolean
-289      */
-290     this.pickBufDirty = true;           // Redraw pick buffer
-291     this.rayPickBufDirty = true;        // Redraw raypick buffer
-292 };
-293 
-294 /**
-295  * Reallocates WebGL resources for objects within this display
-296  */
-297 SceneJS_Display.prototype.webglRestored = function () {
-298 
-299     this._programFactory.webglRestored();// Reallocate programs
-300 
-301     this._chunkFactory.webglRestored(); // Recache shader var locations
-302 
-303     var gl = this._canvas.gl;
-304 
-305     if (this.pickBuf) {
-306         this.pickBuf.webglRestored(gl);          // Rebuild pick buffers
-307     }
-308 
-309     if (this.rayPickBuf) {
-310         this.rayPickBuf.webglRestored(gl);
-311     }
-312 
-313     this.imageDirty = true;             // Need redraw
-314 };
-315 
-316 /**
-317  * Internally creates (or updates) a {@link SceneJS_Object} of the given ID from whatever node state cores are currently set
-318  * on this {@link SceneJS_Display}. The object is created if it does not already exist in the display, otherwise it is
-319  * updated with the current state cores, possibly replacing cores already referenced by the object.
-320  *
-321  * @param {String} objectId ID of object to create or update
-322  */
-323 SceneJS_Display.prototype.buildObject = function (objectId) {
-324 
-325     var object = this._objects[objectId];
-326 
-327     if (!object) { // Create object
-328 
-329         object = this._objects[objectId] = this._objectFactory.getObject(objectId);
-330 
-331         this.objectListDirty = true;
-332     }
-333 
-334     object.layer = this.layer;
-335     object.texture = this.texture;
-336     object.geometry = this.geometry;
-337     object.flags = this.flags;
-338     object.tag = this.tag;
-339 
-340     //if (!object.hash) {
-341 
-342     var hash = ([                   // Build current state hash
-343         this.geometry.hash,
-344         this.shader.hash,
-345         this.clips.hash,
-346         this.morphGeometry.hash,
-347         this.texture.hash,
-348         this.lights.hash
-349 
-350     ]).join(";");
-351 
-352     if (!object.program || hash != object.hash) {
-353 
-354         /* Get new program for object if no program or hash mismatch
-355          */
-356 
-357         if (object.program) {
-358             this._programFactory.putProgram(object.program);
-359         }
-360 
-361         object.program = this._programFactory.getProgram(hash, this);
-362         object.hash = hash;
-363     }
-364     //}
-365 
-366     /* Build draw chunks for object
-367      */
-368     this._setChunk(object, 0, "program");          // Must be first
-369     this._setChunk(object, 1, "xform", this.modelTransform);
-370     this._setChunk(object, 2, "lookAt", this.viewTransform);
-371     this._setChunk(object, 3, "camera", this.projTransform);
-372     this._setChunk(object, 4, "flags", this.flags);
-373     this._setChunk(object, 5, "shader", this.shader);
-374     this._setChunk(object, 6, "shaderParams", this.shaderParams);
-375     //  this._setChunk(object, 7, this.renderer, true);
-376     this._setChunk(object, 7, "name", this.name);
-377     this._setChunk(object, 8, "lights", this.lights);
-378     this._setChunk(object, 9, "material", this.material);
-379     this._setChunk(object, 10, "texture", this.texture);
-380     this._setChunk(object, 11, "framebuf", this.framebuf);
-381     this._setChunk(object, 12, "clips", this.clips);
-382     this._setChunk(object, 13, "morphGeometry", this.morphGeometry);
-383     this._setChunk(object, 14, "listeners", this.renderListeners);      // Must be after the above chunks
-384     this._setChunk(object, 15, "geometry", this.geometry); // Must be last
-385 };
-386 
-387 SceneJS_Display.prototype._setChunk = function (object, order, chunkType, core, unique) {
-388 
-389     var chunkId;
-390 
-391     if (unique) {
-392 
-393         chunkId = core.stateId + 1;
-394 
-395     } else if (core) {
-396 
-397         if (core.empty) { // Only set default cores for state types that have them
-398 
-399             var oldChunk = object.chunks[order];
-400 
-401             if (oldChunk) {
-402                 this._chunkFactory.putChunk(oldChunk); // Release previous chunk to pool
-403             }
-404 
-405             object.chunks[order] = null;
-406 
-407             return;
-408         }
-409 
-410         chunkId = ((object.program.id + 1) * 50000) + core.stateId + 1;
-411 
-412     } else {
-413 
-414         chunkId = ((object.program.id + 1) * 50000);
-415     }
-416 
-417     var oldChunk = object.chunks[order];
-418 
-419     if (oldChunk) {
-420 
-421         if (oldChunk.id == chunkId) { // Avoid needless chunk reattachment
-422             return;
-423         }
-424 
-425         this._chunkFactory.putChunk(oldChunk); // Release previous chunk to pool
-426     }
-427 
-428     object.chunks[order] = this._chunkFactory.getChunk(chunkId, chunkType, object.program, core); // Attach new chunk
-429 
-430     // Ambient light is global across everything in display, and
-431     // can never be disabled, so grab it now because we want to
-432     // feed it to gl.clearColor before each display list render
-433     if (chunkType == "lights") {
-434         this._setAmbient(core);
-435     }
-436 };
-437 
-438 SceneJS_Display.prototype._setAmbient = function (core) {
-439     var lights = core.lights;
-440     var light;
-441     for (var i = 0, len = lights.length; i < len; i++) {
-442         light = lights[i];
-443         if (light.mode == "ambient") {
-444             this._ambientColor = light.color;
-445         }
-446     }
-447 };
-448 
-449 /**
-450  * Removes an object from this display
-451  *
-452  * @param {String} objectId ID of object to remove
-453  */
-454 SceneJS_Display.prototype.removeObject = function (objectId) {
-455 
-456     var object = this._objects[objectId];
-457 
-458     if (!object) {
-459         return;
-460     }
-461 
-462     this._programFactory.putProgram(object.program);
-463 
-464     object.program = null;
-465     object.hash = null;
-466 
-467     this._objectFactory.putObject(object);
-468 
-469     delete this._objects[objectId];
-470 
-471     this.objectListDirty = true;
-472 };
-473 
-474 /**
-475  * Set a tag selector to selectively activate objects that have matching SceneJS.Tag nodes
-476  */
-477 SceneJS_Display.prototype.selectTags = function (tagSelector) {
-478     this._tagSelector = tagSelector;
-479     this.drawListDirty = true;
-480 };
-481 
-482 /**
-483  * Render this display. What actually happens in the method depends on what flags are set.
-484  */
-485 SceneJS_Display.prototype.render = function (params) {
-486 
-487     params = params || {};
-488 
-489     if (this.objectListDirty) {
-490 
-491         this._buildObjectList();          // Build object render bin
-492 
-493         this.objectListDirty = false;
-494         this.stateOrderDirty = true;        // Now needs state ordering
-495     }
-496 
-497     if (this.stateOrderDirty) {
-498 
-499         this._makeStateSortKeys();       // Compute state sort order
-500 
-501         this.stateOrderDirty = false;
-502         this.stateSortDirty = true;     // Now needs state sorting
-503     }
-504 
-505     if (this.stateSortDirty) {
-506 
-507         this._stateSort();              // State sort the object render bin
-508 
-509         this.stateSortDirty = false;
-510         this.drawListDirty = true;      // Now needs new visible object bin
-511     }
-512 
-513     if (this.drawListDirty) {           // Render visible list while building transparent list
-514 
-515         this._buildDrawList();
-516 
-517         this.imageDirty = true;
-518     }
-519 
-520     if (this.imageDirty || params.force) {
-521 
-522         this._doDrawList(false);        // Render, no pick
-523 
-524         this.imageDirty = false;
-525         this.pickBufDirty = true;       // Pick buff will now need rendering on next pick
-526     }
-527 };
-528 
-529 SceneJS_Display.prototype._buildObjectList = function () {
-530     this._objectListLen = 0;
-531     for (var objectId in this._objects) {
-532         if (this._objects.hasOwnProperty(objectId)) {
-533             this._objectList[this._objectListLen++] = this._objects[objectId];
-534         }
-535     }
-536 };
-537 
-538 SceneJS_Display.prototype._makeStateSortKeys = function () { // TODO: state sort for sound objects?
-539     var object;
-540     for (var i = 0, len = this._objectListLen; i < len; i++) {
-541         object = this._objectList[i];
-542         object.sortKey = object.program
-543             ? (((object.layer.priority + 1) * 100000000)
-544             + ((object.program.id + 1) * 100000)
-545             + (object.texture.stateId * 1000))
-546             //    + i // Force stability among same-priority objects across multiple sorts
-547             : -1;   // Non-visual object (eg. sound)
-548     }
-549 };
-550 
-551 //SceneJS_Display.prototype._makeStateSortKeys = function () { // TODO: state sort for sound objects?
-552 //    var object;
-553 //    for (var i = 0, len = this._objectListLen; i < len; i++) {
-554 //        object = this._objectList[i];
-555 //        object.sortKey = object.program
-556 //            ? (((object.layer.priority + 1) * 1000000000)
-557 //            + ((object.program.id + 1) * 1000000)
-558 //            + (object.texture.stateId * 10000)
-559 //            + (object.geometry.stateId))
-560 //            //    + i // Force stability among same-priority objects across multiple sorts
-561 //            : -1;   // Non-visual object (eg. sound)
-562 //    }
-563 //};
-564 
-565 SceneJS_Display.prototype._stateSort = function () {
-566     this._objectList.length = this._objectListLen;
-567     this._objectList.sort(this._stateSortObjects);
-568 };
-569 
-570 SceneJS_Display.prototype._stateSortObjects = function (a, b) {
-571     return a.sortKey - b.sortKey;
-572 };
-573 
-574 SceneJS_Display.prototype._buildDrawList = function () {
-575 
-576     this._lastStateId = this._lastStateId || [];
-577     this._lastPickStateId = this._lastPickStateId || [];
-578 
-579     for (var i = 0; i < 20; i++) {
-580         this._lastStateId[i] = null;
-581         this._lastPickStateId[i] = null;
-582     }
-583 
-584     this._opaqueDrawListLen = 0;
-585     this._pickDrawListLen = 0;
-586     this._transparentDrawListLen = 0;
-587 
-588     var object;
-589     var tagMask;
-590     var tagRegex;
-591     var tagCore;
-592     var flags;
-593     var chunks;
-594     var chunk;
-595     var transparent;
-596     var picking;
-597 
-598     if (this._tagSelector) {
-599         tagMask = this._tagSelector.mask;
-600         tagRegex = this._tagSelector.regex;
-601     }
-602 
-603     if (!this._xpBuf) {
-604         this._xpBuf = [];
-605     }
-606     this._xpBufLen = 0;
-607 
-608     for (var i = 0, len = this._objectListLen; i < len; i++) {
-609 
-610         object = this._objectList[i];
-611 
-612         flags = object.flags;
-613 
-614         /* Cull invisible objects
-615          */
-616 
-617         if (flags.enabled === false) {                              // Skip disabled object
-618             continue;
-619         }
-620 
-621         if (!object.layer.enabled) { // Skip disabled layers
-622             continue;
-623         }
-624 
-625         if (tagMask) { // Skip unmatched tags. No tag matching in visible bin prevent this being done on every frame.
-626 
-627             tagCore = object.tag;
-628 
-629             if (tagCore.tag) {
-630 
-631                 if (tagCore.mask != tagMask) { // Scene tag mask was updated since last render
-632                     tagCore.mask = tagMask;
-633                     tagCore.matches = tagRegex.test(tagCore.tag);
-634                 }
-635 
-636                 if (!tagCore.matches) {
-637                     continue;
-638                 }
-639             }
-640         }
-641 
-642         transparent = flags.transparent;
-643 
-644         if (transparent) {
-645             this._xpBuf[this._xpBufLen++] = object;
-646         }
-647 
-648         /* Add object's chunks to appropriate chunk list
-649          */
-650 
-651         chunks = object.chunks;
-652 
-653         picking = flags.picking;
-654 
-655         for (var j = 0, lenj = chunks.length; j < lenj; j++) {
-656 
-657             chunk = chunks[j];
-658 
-659             if (chunk) {
-660 
-661                 /*
-662                  * As we apply the state chunk lists we track the ID of most types of chunk in order
-663                  * to cull redundant re-applications of runs of the same chunk - except for those chunks with a
-664                  * 'unique' flag. We don't want to cull runs of geometry chunks because they contain the GL
-665                  * drawElements calls which render the objects.
-666                  */
-667 
-668                 if (!transparent && chunk.draw) {
-669                     if (chunk.unique || this._lastStateId[j] != chunk.id) {
-670                         this._opaqueDrawList[this._opaqueDrawListLen++] = chunk;
-671                         this._lastStateId[j] = chunk.id;
-672                     }
-673                 }
-674 
-675                 if (chunk.pick) { // Transparent objects are pickable
-676                     if (picking) { // Don't pick unpickable objects
-677                         if (chunk.unique || this._lastPickStateId[j] != chunk.id) {
-678                             this._pickDrawList[this._pickDrawListLen++] = chunk;
-679                             this._lastPickStateId[j] = chunk.id;
-680                         }
-681                     }
-682                 }
-683             }
-684         }
-685     }
-686 
-687     if (this._xpBufLen > 0) {
-688 
-689         for (var i = 0; i < 20; i++) {
-690             this._lastStateId[i] = null;
-691         }
-692 
-693         for (var i = 0; i < this._xpBufLen; i++) {
-694 
-695             object = this._xpBuf[i];
-696             chunks = object.chunks;
-697 
-698             for (var j = 0, lenj = chunks.length; j < lenj; j++) {
-699 
-700                 chunk = chunks[j];
-701 
-702                 if (chunk && chunk.draw) {
-703 
-704                     if (chunk.unique || this._lastStateId[j] != chunk.id) {
-705                         this._transparentDrawList[this._transparentDrawListLen++] = chunk;
-706                         this._lastStateId[j] = chunk.id;
-707                     }
-708                 }
-709             }
-710         }
-711     }
-712 
-713     this.drawListDirty = false;
-714 };
-715 
-716 SceneJS_Display.prototype.pick = function (params) {
-717 
-718     //return;
-719 
-720     var canvas = this._canvas.canvas;
-721 
-722     var hit = null;
-723 
-724     var canvasX = params.canvasX;
-725     var canvasY = params.canvasY;
-726 
-727     /*-------------------------------------------------------------
-728      * Pick object using normal GPU colour-indexed pick
-729      *-----------------------------------------------------------*/
-730 
-731     var pickBuf = this.pickBuf;                                                   // Lazy-create pick buffer
-732 
-733     if (!pickBuf) {
-734         pickBuf = this.pickBuf = new SceneJS_PickBuffer({ canvas:this._canvas });
-735         this.pickBufDirty = true;                                                 // Freshly-created pick buffer is dirty
-736     }
-737 
-738     this.render(); // Do any pending visible render
-739 
-740     pickBuf.bind();                                                                 // Bind pick buffer
-741 
-742     if (this.pickBufDirty) {                          // Render pick buffer
-743 
-744         pickBuf.clear();
-745 
-746         this._doDrawList(true);
-747 
-748         this._canvas.gl.finish();
-749 
-750         this.pickBufDirty = false;                                                  // Pick buffer up to date
-751         this.rayPickBufDirty = true;                                                // Ray pick buffer now dirty
-752     }
-753 
-754     var pix = pickBuf.read(canvasX, canvasY);                                       // Read pick buffer
-755     var pickedObjectIndex = pix[0] + pix[1] * 256 + pix[2] * 65536;
-756     var pickIndex = (pickedObjectIndex >= 1) ? pickedObjectIndex - 1 : -1;
-757 
-758     pickBuf.unbind();                                                               // Unbind pick buffer
-759 
-760     var pickName = this._frameCtx.pickNames[pickIndex];                                   // Map pixel to name
-761 
-762     if (pickName) {
-763 
-764         hit = {
-765             name:pickName
-766         };
-767 
-768         if (params.rayPick) { // Ray pick to find position
-769 
-770             var rayPickBuf = this.rayPickBuf; // Lazy-create Z-pick buffer
-771             if (!rayPickBuf) {
-772                 rayPickBuf = this.rayPickBuf = new SceneJS_PickBuffer({ canvas:this._canvas });
-773             }
-774 
-775             rayPickBuf.bind();
-776 
-777             if (this.rayPickBufDirty) {
-778 
-779                 rayPickBuf.clear();
-780 
-781                 this._doDrawList(true, true); // pick, rayPick
-782 
-783                 this.rayPickBufDirty = false;
-784             }
-785 
-786             pix = rayPickBuf.read(canvasX, canvasY);
-787 
-788             rayPickBuf.unbind();
-789 
-790             /* Read normalised device Z coordinate, which will be
-791              * in range of [0..1] with z=0 at front
-792              */
-793             var screenZ = this._unpackDepth(pix);
-794 
-795             var w = canvas.width;
-796             var h = canvas.height;
-797 
-798             /* Calculate clip space coordinates, which will be in range
-799              * of x=[-1..1] and y=[-1..1], with y=(+1) at top
-800              */
-801             var x = (canvasX - w / 2) / (w / 2);           // Calculate clip space coordinates
-802             var y = -(canvasY - h / 2) / (h / 2);
-803 
-804             var projMat = this._frameCtx.cameraMat;
-805             var viewMat = this._frameCtx.viewMat;
-806 
-807             var pvMat = SceneJS_math_mulMat4(projMat, viewMat, []);
-808             var pvMatInverse = SceneJS_math_inverseMat4(pvMat, []);
-809 
-810             var world1 = SceneJS_math_transformVector4(pvMatInverse, [x, y, -1, 1]);
-811             world1 = SceneJS_math_mulVec4Scalar(world1, 1 / world1[3]);
-812 
-813             var world2 = SceneJS_math_transformVector4(pvMatInverse, [x, y, 1, 1]);
-814             world2 = SceneJS_math_mulVec4Scalar(world2, 1 / world2[3]);
-815 
-816             var dir = SceneJS_math_subVec3(world2, world1, []);
-817 
-818             var vWorld = SceneJS_math_addVec3(world1, SceneJS_math_mulVec4Scalar(dir, screenZ, []), []);
-819 
-820             hit.canvasPos = [canvasX, canvasY];
-821             hit.worldPos = vWorld;
-822         }
-823     }
-824 
-825     return hit;
-826 };
-827 
-828 SceneJS_Display.prototype._unpackDepth = function (depthZ) {
-829     var vec = [depthZ[0] / 256.0, depthZ[1] / 256.0, depthZ[2] / 256.0, depthZ[3] / 256.0];
-830     var bitShift = [1.0 / (256.0 * 256.0 * 256.0), 1.0 / (256.0 * 256.0), 1.0 / 256.0, 1.0];
-831     return SceneJS_math_dotVector4(vec, bitShift);
-832 };
-833 
-834 SceneJS_Display.prototype._doDrawList = function (pick, rayPick) {
-835 
-836     var frameCtx = this._frameCtx;                                                // Reset rendering context
-837 
-838     frameCtx.program = null;
-839     frameCtx.framebuf = null;
-840     frameCtx.viewMat = null;
-841     frameCtx.modelMat = null;
-842     frameCtx.cameraMat = null;
-843     frameCtx.renderer = null;
-844     frameCtx.vertexBuf = false;
-845     frameCtx.normalBuf = false;
-846     frameCtx.uvBuf = false;
-847     frameCtx.uvBuf2 = false;
-848     frameCtx.colorBuf = false;
-849     frameCtx.backfaces = false;
-850     frameCtx.frontface = "ccw";
-851     frameCtx.pick = !!pick;
-852 
-853     var gl = this._canvas.gl;
-854 
-855     gl.viewport(0, 0, this._canvas.canvas.width, this._canvas.canvas.height);
-856     gl.clearColor(this._ambientColor[0], this._ambientColor[1], this._ambientColor[2], 1.0);
-857     gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT | gl.STENCIL_BUFFER_BIT);
-858     gl.lineWidth(3);
-859     gl.frontFace(gl.CCW);
-860     //   gl.disable(gl.CULL_FACE);
-861 
-862     if (pick) { // Pick
-863 
-864         frameCtx.pickIndex = 0;
-865         frameCtx.rayPick = !!rayPick;
-866 
-867         for (var i = 0, len = this._pickDrawListLen; i < len; i++) {        // Push picking chunks
-868             this._pickDrawList[i].pick(frameCtx);
-869         }
-870 
-871     } else { // Draw
-872 
-873         for (var i = 0, len = this._opaqueDrawListLen; i < len; i++) {      // Push opaque rendering chunks
-874             this._opaqueDrawList[i].draw(frameCtx);
-875         }
-876 
-877         if (this._transparentDrawListLen > 0) {
-878 
-879             gl.enable(gl.BLEND);                                            // Enable blending
-880             gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
-881 
-882             for (var i = 0, len = this._transparentDrawListLen; i < len; i++) { // Push transparent rendering chunks
-883                 this._transparentDrawList[i].draw(frameCtx);
-884             }
-885 
-886             gl.disable(gl.BLEND);                                           //  Disable blending
-887         }
-888     }
-889 
-890     gl.flush();                                                         // Flush GL
-891 
-892     if (frameCtx.program) {                                                  // Unbind remaining program
-893         //frameCtx.program.unbind();
-894     }
-895 
-896     if (frameCtx.framebuf) {                                                 // Unbind remaining frame buffer
-897         gl.finish();
-898         frameCtx.framebuf.unbind();
-899     }
-900 
-901     if (frameCtx.renderer) {                           // Forget last call-time renderer properties
-902         //     frameCtx.renderer.props.restoreProps(gl);
-903     }
-904 };
-905 
-906 SceneJS_Display.prototype.destroy = function () {
-907     this._programFactory.destroy();
-908 };
-909 
-910 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_object.js.html b/docs/symbols/src/src_core_display_object.js.html deleted file mode 100644 index aa136780..00000000 --- a/docs/symbols/src/src_core_display_object.js.html +++ /dev/null @@ -1,69 +0,0 @@ -
  1 /**
-  2  * @class An object within a {@link SceneJS_Display}
-  3  * @private
-  4  */
-  5 var SceneJS_Object = function(id) {
-  6 
-  7     /**
-  8      * ID for this objects, unique among all objects in the display
-  9      * @type Number
- 10      */
- 11     this.id = id;
- 12 
- 13     /**
- 14      * Hash code for this object, unique among all objects in the display
- 15      * @type String
- 16      */
- 17     this.hash = null;
- 18 
- 19     /**
- 20      * State sort key, computed from {@link #layer}, {@link #program} and {@link #texture}
- 21      * @type Number
- 22      */
- 23     this.sortKey = null;
- 24 
- 25     /**
- 26      * Sequence of state chunks applied to render this object
- 27      * @type {[SceneJS_Chunk]} chunks
- 28      */
- 29     this.chunks = [];
- 30 
- 31     /**
- 32      * Number of state chunks applied to render this object
- 33      * @type Number
- 34      */
- 35     this.chunksLen = 0;
- 36 
- 37     /**
- 38      * Shader programs that render this object, also used for (re)computing {@link #sortKey}
- 39      * @type SceneJS_Program
- 40      */
- 41     this.program = null;
- 42 
- 43     /**
- 44      * State core for the {@link SceneJS.Layer} that this object was compiled from, used for (re)computing {@link #sortKey} and visibility cull
- 45      */
- 46     this.layer = null;
- 47 
- 48      /**
- 49      * State core for the {@link SceneJS.Texture} that this object was compiled from, used for (re)computing {@link #sortKey}
- 50      */
- 51     this.texture = null;
- 52 
- 53     /**
- 54      * State core for the {@link SceneJS.Flags} that this object was compiled from, used for visibility cull
- 55      */
- 56     this.flags = null;
- 57 
- 58     /**
- 59      * State core for the {@link SceneJS.Tag} that this object was compiled from, used for visibility cull
- 60      */
- 61     this.tag = null;
- 62 };
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_objectFactory.js.html b/docs/symbols/src/src_core_display_objectFactory.js.html deleted file mode 100644 index ac122322..00000000 --- a/docs/symbols/src/src_core_display_objectFactory.js.html +++ /dev/null @@ -1,54 +0,0 @@ -
  1 /**
-  2  * @class Manages creation and recycle of {@link SceneJS_Object} instances
-  3  * @private
-  4  */
-  5 var SceneJS_ObjectFactory = function() {
-  6 
-  7 };
-  8 
-  9 /**
- 10  * @property {[SceneJS_Object]} _freeObjects Pool of free display objects, shared by all object factories
- 11  */
- 12 SceneJS_ObjectFactory.prototype._freeObjects = [];
- 13 
- 14 /**
- 15  * @property {Number} _numFreeObjects Number of free objects
- 16  */
- 17 SceneJS_ObjectFactory.prototype._numFreeObjects = 0;
- 18 
- 19 /**
- 20  * Gets a display object from this factory
- 21  *
- 22  * @param {String} id ID to assign to the object
- 23  * @returns {SceneJS_Object} The object
- 24  */
- 25 SceneJS_ObjectFactory.prototype.getObject = function(id) {
- 26 
- 27     var object;
- 28 
- 29     if (this._numFreeObjects > 0) {
- 30 
- 31         object = this._freeObjects[--this._numFreeObjects];
- 32         object.id = id;
- 33 
- 34         return object;
- 35     }
- 36 
- 37     return new SceneJS_Object(id);
- 38 };
- 39 
- 40 /**
- 41  * Releases a display object back to this factory
- 42  * @param {SceneJS_Object} object Object to release
- 43  */
- 44 SceneJS_ObjectFactory.prototype.putObject = function (object) {
- 45 
- 46     this._freeObjects[this._numFreeObjects++] = object;
- 47 };
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_program.js.html b/docs/symbols/src/src_core_display_program.js.html deleted file mode 100644 index 5cdb3b4d..00000000 --- a/docs/symbols/src/src_core_display_program.js.html +++ /dev/null @@ -1,72 +0,0 @@ -
  1 /**
-  2  * @class Vertex and fragment shaders for pick and draw
-  3  * @private
-  4  *
-  5  * @param {Number} id ID unique among all programs in the owner {@link SceneJS_ProgramFactory}
-  6  * @param {String} hash Hash code which uniquely identifies the capabilities of the program, computed from hashes on the {@link Scene_Core}s that the {@link SceneJS_ProgramSource} composed to render
-  7  * @param {SceneJS_ProgramSource} source Sourcecode from which the the program is compiled in {@link #build}
-  8  * @param {WebGLRenderingContext} gl WebGL context 
-  9  */
- 10 var SceneJS_Program = function(id, hash, source, gl) {
- 11 
- 12     /**
- 13      * ID for this program, unique among all programs in the display
- 14      * @type Number
- 15      */
- 16     this.id = id;
- 17 
- 18     /**
- 19      * Hash code for this program's capabilities, same as the hash on {@link #source}
- 20      * @type String
- 21      */
- 22     this.hash = source.hash;
- 23 
- 24     /**
- 25      * Source code for this program's shaders
- 26      * @type SceneJS_ProgramSource
- 27      */
- 28     this.source = source;
- 29 
- 30     /**
- 31      * WebGL context on which this program's shaders are allocated
- 32      * @type WebGLRenderingContext
- 33      */
- 34     this.gl = gl;
- 35 
- 36     /**
- 37      * The drawing program
- 38      * @type SceneJS_webgl_Program
- 39      */
- 40     this.draw = null;
- 41 
- 42     /**
- 43      * The picking program
- 44      * @type SceneJS_webgl_Program
- 45      */
- 46     this.pick = null;
- 47 
- 48     /**
- 49      * The count of display objects using this program
- 50      * @type Number
- 51      */
- 52     this.useCount = 0;
- 53 
- 54     this.build(gl);
- 55 };
- 56 
- 57 /**
- 58  *  Creates the render and pick programs.
- 59  * This is also re-called to re-create them after WebGL context loss.
- 60  */
- 61 SceneJS_Program.prototype.build = function(gl) {
- 62     this.gl = gl;
- 63     this.draw = new SceneJS_webgl_Program(gl, [this.source.drawVertexSrc.join("\n")], [this.source.drawFragmentSrc.join("\n")]);
- 64     this.pick = new SceneJS_webgl_Program(gl, [this.source.pickVertexSrc.join("\n")], [this.source.pickFragmentSrc.join("\n")]);
- 65 };
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_programFactory.js.html b/docs/symbols/src/src_core_display_programFactory.js.html deleted file mode 100644 index 5d33a13b..00000000 --- a/docs/symbols/src/src_core_display_programFactory.js.html +++ /dev/null @@ -1,77 +0,0 @@ -
  1 /**  
-  2  * @class Manages creation, sharing and recycle of {@link SceneJS_Program} instances
-  3  * @private
-  4  */
-  5 var SceneJS_ProgramFactory = function(cfg) {
-  6 
-  7     this._canvas = cfg.canvas;
-  8 
-  9     this._programs = {};
- 10 
- 11     this._nextProgramId = 0;
- 12 };
- 13 
- 14 /**
- 15  * Gets a program to render the given states
- 16  */
- 17 SceneJS_ProgramFactory.prototype.getProgram = function(hash, states) {
- 18 
- 19     var program = this._programs[hash];
- 20 
- 21     if (!program) {
- 22 
- 23         var source = SceneJS_ProgramSourceFactory.getSource(hash, states);
- 24 
- 25         program = new SceneJS_Program(this._nextProgramId++, hash, source, this._canvas.gl);
- 26 
- 27         this._programs[hash] = program;
- 28     }
- 29 
- 30     program.useCount++;
- 31 
- 32     return program;
- 33 };
- 34 
- 35 /**
- 36  * Releases a program back to the shader factory
- 37  */
- 38 SceneJS_ProgramFactory.prototype.putProgram = function(program) {
- 39 
- 40     if (--program.useCount <= 0) {
- 41 
- 42         program.draw.destroy();
- 43         program.pick.destroy();
- 44 
- 45         SceneJS_ProgramSourceFactory.putSource(program.hash);
- 46 
- 47         this._programs[program.hash] = null;
- 48     }
- 49 };
- 50 
- 51 /**
- 52  * Notifies this shader factory that the WebGL context has been restored after previously being lost
- 53  */
- 54 SceneJS_ProgramFactory.prototype.webglRestored = function() {
- 55 
- 56     var gl = this._canvas.gl;
- 57 
- 58     for (var id in this._programs) {
- 59         if (this._programs.hasOwnProperty(id)) {
- 60             this._programs[id].build(gl);
- 61         }
- 62     }
- 63 };
- 64 
- 65 /**
- 66  * Destroys this shader factory
- 67  */
- 68 SceneJS_ProgramFactory.prototype.destroy = function() {
- 69 };
- 70 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_programSource.js.html b/docs/symbols/src/src_core_display_programSource.js.html deleted file mode 100644 index 4913ee03..00000000 --- a/docs/symbols/src/src_core_display_programSource.js.html +++ /dev/null @@ -1,57 +0,0 @@ -
  1 /**
-  2  * @class Source code for pick and draw shader programs, to be compiled into one or more {@link SceneJS_Program}s
-  3  * @private
-  4  * 
-  5  * @param {String} hash Hash code identifying the rendering capabilities of the programs
-  6  * @param {String} pickVertexSrc Source code of the pick vertex shader
-  7  * @param {String} pickFragmentSrc Source code of the pick fragment shader
-  8  * @param {String} drawVertexSrc Source code of the draw vertex shader
-  9  * @param {String} drawFragmentSrc Source code of the draw fragment shader
- 10  */
- 11 var SceneJS_ProgramSource = function(hash, pickVertexSrc, pickFragmentSrc, drawVertexSrc, drawFragmentSrc) {
- 12 
- 13     /**
- 14      * Hash code identifying the capabilities of the {@link SceneJS_Program} that is compiled from this source
- 15      * @type String
- 16      */
- 17     this.hash = hash;
- 18 
- 19     /**
- 20      * Source code for pick vertex shader
- 21      * @type String
- 22      */
- 23     this.pickVertexSrc = pickVertexSrc;
- 24 
- 25     /**
- 26      * Source code for pick fragment shader
- 27      * @type String
- 28      */
- 29     this.pickFragmentSrc = pickFragmentSrc;
- 30 
- 31     /**
- 32      * Source code for draw vertex shader
- 33      * @type String
- 34      */
- 35     this.drawVertexSrc = drawVertexSrc;
- 36 
- 37     /**
- 38      * Source code for draw fragment shader
- 39      * @type String
- 40      */
- 41     this.drawFragmentSrc = drawFragmentSrc;
- 42 
- 43     /**
- 44      * Count of {@link SceneJS_Program}s compiled from this program source code
- 45      * @type Number
- 46      */
- 47     this.useCount = 0;
- 48 };
- 49 
- 50 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_programSourceFactory.js.html b/docs/symbols/src/src_core_display_programSourceFactory.js.html deleted file mode 100644 index bd10097c..00000000 --- a/docs/symbols/src/src_core_display_programSourceFactory.js.html +++ /dev/null @@ -1,957 +0,0 @@ -
  1 /**
-  2  * @class Manages creation, sharing and recycle of {@link SceneJS_ProgramSource} instances
-  3  * @private
-  4  */
-  5 var SceneJS_ProgramSourceFactory = new (function() {
-  6 
-  7     this._sourceCache = {}; // Source codes are shared across all scenes
-  8 
-  9 
- 10     /**
- 11      * Get sourcecode for a program to render the given states
- 12      */
- 13     this.getSource = function(hash, states) {
- 14 
- 15         var source = this._sourceCache[hash];
- 16         if (source) {
- 17             source.useCount++;
- 18             return source;
- 19         }
- 20 
- 21         return this._sourceCache[hash] = new SceneJS_ProgramSource(
- 22 
- 23                 hash,
- 24 
- 25                 this._composePickingVertexShader(states), // pickVertexSrc
- 26                 this._composePickingFragmentShader(states), // pickFragmentSrc
- 27                 this._composeRenderingVertexShader(states), // drawVertexSrc
- 28                 this._composeRenderingFragmentShader(states)  // drawfragmentSrc
- 29                 );
- 30     };
- 31 
- 32     /**
- 33      * Releases program source code
- 34      */
- 35     this.putSource = function(hash) {
- 36         var source = this._sourceCache[hash];
- 37         if (source) {
- 38             if (--source.useCount == 0) {
- 39                 this._sourceCache[source.hash] = null;
- 40             }
- 41         }
- 42     };
- 43 
- 44     this._composePickingVertexShader = function(states) {
- 45 
- 46         var customShaders = states.shader.shaders || {};
- 47 
- 48         var customVertexShader = customShaders.vertex || {};
- 49         var vertexHooks = customVertexShader.hooks || {};
- 50 
- 51         var customFragmentShader = customShaders.fragment || {};
- 52         var fragmentHooks = customFragmentShader.hooks || {};
- 53 
- 54         var clipping = states.clips.clips.length > 0;
- 55         var morphing = !!states.morphGeometry.targets;
- 56         var normals = this._hasNormals(states);
- 57 
- 58         var src = [
- 59             "precision mediump float;",
- 60             "attribute vec3 SCENEJS_aVertex;",
- 61             "attribute vec3 SCENEJS_aNormal;",
- 62 
- 63             "uniform mat4 SCENEJS_uMMatrix;",
- 64             "uniform mat4 SCENEJS_uMNMatrix;",
- 65             "uniform mat4 SCENEJS_uVMatrix;",
- 66             "uniform mat4 SCENEJS_uVNMatrix;",
- 67             "uniform mat4 SCENEJS_uPMatrix;"
- 68         ];
- 69 
- 70         if (normals && (fragmentHooks.worldNormal || fragmentHooks.viewNormal)) {
- 71             src.push("varying   vec3 SCENEJS_vWorldNormal;");   // Output world-space vertex normal
- 72             src.push("varying   vec3 SCENEJS_vViewNormal;");   // Output world-space vertex normal
- 73         }
- 74 
- 75         src.push("varying vec4 SCENEJS_vModelVertex;");
- 76 
- 77         // if (clipping || fragmentHooks.worldPosClip) {
- 78         src.push("varying vec4 SCENEJS_vWorldVertex;");
- 79         // }
- 80 
- 81 
- 82         src.push("varying vec4 SCENEJS_vViewVertex;\n");
- 83         src.push("varying vec4 SCENEJS_vProjVertex;\n");
- 84 
- 85         src.push("uniform vec3 SCENEJS_uWorldEye;");                     // World-space eye position
- 86         src.push("varying vec3 SCENEJS_vWorldEyeVec;");
- 87 
- 88         if (customVertexShader.code) {
- 89             src.push("\n" + customVertexShader.code + "\n");
- 90         }
- 91 
- 92         if (morphing) {
- 93             src.push("uniform float SCENEJS_uMorphFactor;");       // LERP factor for morph
- 94             if (states.morphGeometry.targets[0].vertexBuf) {      // target2 has these arrays also
- 95                 src.push("attribute vec3 SCENEJS_aMorphVertex;");
- 96             }
- 97         }
- 98 
- 99         src.push("void main(void) {");
-100         src.push("   vec4 tmpVertex=vec4(SCENEJS_aVertex, 1.0); ");
-101 
-102         if (normals) {
-103             src.push("  vec4 modelNormal = vec4(SCENEJS_aNormal, 0.0); ");
-104         }
-105 
-106         src.push("  SCENEJS_vModelVertex = tmpVertex; ");
-107 
-108         if (vertexHooks.modelPos) {
-109             src.push("tmpVertex=" + vertexHooks.modelPos + "(tmpVertex);");
-110         }
-111 
-112         if (morphing) {
-113             if (states.morphGeometry.targets[0].vertexBuf) {
-114                 src.push("  vec4 vMorphVertex = vec4(SCENEJS_aMorphVertex, 1.0); ");
-115 
-116                 if (vertexHooks.modelPos) {
-117                     src.push("vMorphVertex=" + vertexHooks.modelPos + "(vMorphVertex);");
-118                 }
-119 
-120                 src.push("  tmpVertex = vec4(mix(tmpVertex.xyz, vMorphVertex.xyz, SCENEJS_uMorphFactor), 1.0); ");
-121             }
-122         }
-123 
-124 
-125         src.push("  tmpVertex = SCENEJS_uMMatrix * tmpVertex; ");
-126 
-127         if (vertexHooks.worldPos) {
-128             src.push("tmpVertex=" + vertexHooks.worldPos + "(tmpVertex);");
-129         }
-130 
-131         // if (clipping || fragmentHooks.worldPosClip) {
-132         src.push("  SCENEJS_vWorldVertex = tmpVertex; ");
-133         //    }
-134 
-135         src.push("SCENEJS_vWorldEyeVec = normalize(SCENEJS_uWorldEye - tmpVertex.xyz);");
-136 
-137         src.push("  tmpVertex = SCENEJS_uVMatrix * tmpVertex; ");
-138 
-139         if (vertexHooks.viewPos) {
-140             src.push("tmpVertex=" + vertexHooks.viewPos + "(tmpVertex);");
-141         }
-142 
-143         src.push("  SCENEJS_vViewVertex = tmpVertex;");
-144 
-145         if (normals && (fragmentHooks.worldNormal || fragmentHooks.viewNormal)) {
-146             src.push("  vec3 worldNormal = normalize((SCENEJS_uMNMatrix * modelNormal).xyz); ");
-147             src.push("  SCENEJS_vWorldNormal = worldNormal;");
-148             src.push("  SCENEJS_vViewNormal = (SCENEJS_uVNMatrix * vec4(worldNormal, 1.0)).xyz;");
-149         }
-150 
-151         src.push("  SCENEJS_vProjVertex = SCENEJS_uPMatrix * tmpVertex;");
-152 
-153 
-154         src.push("  gl_Position = SCENEJS_vProjVertex;");
-155         src.push("}");
-156 
-157         if (false && debugCfg.logScripts == true) {
-158             SceneJS.log.info(src);
-159         }
-160         return src;
-161     };
-162 
-163     /**
-164      * Composes a fragment shader script for rendering mode in current scene state
-165      * @private
-166      */
-167     this._composePickingFragmentShader = function(states) {
-168 
-169         var customShaders = states.shader.shaders || {};
-170         var customFragmentShader = customShaders.fragment || {};
-171         var fragmentHooks = customFragmentShader.hooks || {};
-172 
-173         var clipping = states.clips.clips.length > 0;
-174 
-175         var normals = this._hasNormals(states);
-176 
-177         var src = [
-178             "precision mediump float;"
-179         ];
-180 
-181         src.push("vec4 packDepth(const in float depth) {");
-182         src.push("  const vec4 bitShift = vec4(256.0*256.0*256.0, 256.0*256.0, 256.0, 1.0);");
-183         src.push("  const vec4 bitMask  = vec4(0.0, 1.0/256.0, 1.0/256.0, 1.0/256.0);");
-184         src.push("  vec4 res = fract(depth * bitShift);");
-185         src.push("  res -= res.xxyz * bitMask;");
-186         src.push("  return res;");
-187         src.push("}");
-188 
-189         src.push("varying vec4 SCENEJS_vModelVertex;");
-190         src.push("varying vec4 SCENEJS_vWorldVertex;");
-191         src.push("varying vec4 SCENEJS_vViewVertex;");                  // View-space vertex
-192         src.push("varying vec4 SCENEJS_vProjVertex;");
-193 
-194         src.push("uniform bool SCENEJS_uRayPickMode;");                   // Z-pick mode when true else colour-pick
-195 
-196         src.push("uniform vec3 SCENEJS_uPickColor;");                   // Used in colour-pick mode
-197 
-198         src.push("uniform float SCENEJS_uZNear;");                      // Used in Z-pick mode
-199         src.push("uniform float SCENEJS_uZFar;");                       // Used in Z-pick mode
-200 
-201         src.push("varying vec3 SCENEJS_vWorldEyeVec;");                          // Direction of view-space vertex from eye
-202 
-203         src.push("uniform bool  SCENEJS_uClipping;");
-204 
-205         if (normals && (fragmentHooks.worldNormal || fragmentHooks.viewNormal)) {
-206 
-207             src.push("varying vec3 SCENEJS_vWorldNormal;");                  // World-space normal
-208             src.push("varying vec3 SCENEJS_vViewNormal;");                   // View-space normal
-209         }
-210         /*-----------------------------------------------------------------------------------
-211          * Variables - Clipping
-212          *----------------------------------------------------------------------------------*/
-213 
-214         if (clipping) {
-215             for (var i = 0; i < states.clips.clips.length; i++) {
-216                 src.push("uniform float SCENEJS_uClipMode" + i + ";");
-217                 src.push("uniform vec4  SCENEJS_uClipNormalAndDist" + i + ";");
-218             }
-219         }
-220 
-221         /*-----------------------------------------------------------------------------------
-222          * Custom GLSL
-223          *----------------------------------------------------------------------------------*/
-224 
-225         if (customFragmentShader.code) {
-226             src.push("\n" + customFragmentShader.code + "\n");
-227         }
-228 
-229         src.push("void main(void) {");
-230 
-231         if (fragmentHooks.worldPosClip) {
-232             src.push("if (" + fragmentHooks.worldPosClip + "(SCENEJS_vWorldVertex) == false) { discard; };");
-233         }
-234         if (fragmentHooks.viewPosClip) {
-235             src.push("if (!" + fragmentHooks.viewPosClip + "(SCENEJS_vViewVertex) == false) { discard; };");
-236         }
-237 
-238         if (clipping) {
-239             src.push("if (SCENEJS_uClipping) {");
-240             src.push("  float   dist;");
-241             for (var i = 0; i < states.clips.clips.length; i++) {
-242                 src.push("    if (SCENEJS_uClipMode" + i + " != 0.0) {");
-243                 src.push("        dist = dot(SCENEJS_vWorldVertex.xyz, SCENEJS_uClipNormalAndDist" + i + ".xyz) - SCENEJS_uClipNormalAndDist" + i + ".w;");
-244                 src.push("        if (SCENEJS_uClipMode" + i + " == 1.0) {");
-245                 src.push("            if (dist > 0.0) { discard; }");
-246                 src.push("        }");
-247                 src.push("        if (SCENEJS_uClipMode" + i + " == 2.0) {");
-248                 src.push("            if (dist > 0.0) { discard; }");
-249                 src.push("        }");
-250                 src.push("    }");
-251             }
-252             src.push("}");
-253         }
-254 
-255         if (fragmentHooks.worldPos) {
-256             src.push(fragmentHooks.worldPos + "(SCENEJS_vWorldVertex);");
-257         }
-258 
-259         if (fragmentHooks.viewPos) {
-260             src.push(fragmentHooks.viewPos + "(SCENEJS_vViewVertex);");
-261         }
-262 
-263         if (fragmentHooks.worldEyeVec) {
-264             src.push(fragmentHooks.worldEyeVec + "(SCENEJS_vWorldEyeVec);");
-265         }
-266 
-267         if (normals && fragmentHooks.worldNormal) {
-268             src.push(fragmentHooks.worldNormal + "(SCENEJS_vWorldNormal);");
-269         }
-270 
-271         if (normals && fragmentHooks.viewNormal) {
-272             src.push(fragmentHooks.viewNormal + "(SCENEJS_vViewNormal);");
-273         }
-274 
-275         src.push("    if (SCENEJS_uRayPickMode) {");
-276         src.push("          float zNormalizedDepth = abs((SCENEJS_uZNear + SCENEJS_vViewVertex.z) / (SCENEJS_uZFar - SCENEJS_uZNear));");
-277         src.push("          gl_FragColor = packDepth(zNormalizedDepth); ");
-278 
-279         src.push("    } else {");
-280         src.push("          gl_FragColor = vec4(SCENEJS_uPickColor.rgb, 1.0);  ");
-281         src.push("    }");
-282         src.push("}");
-283 
-284 
-285         if (false && debugCfg.logScripts == true) {
-286             SceneJS.log.info(src);
-287         }
-288         return src;
-289     };
-290 
-291 
-292     /*===================================================================================================================
-293      *
-294      * Rendering vertex shader
-295      *
-296      *==================================================================================================================*/
-297 
-298     this._isTexturing = function(states) {
-299         if (states.texture.layers && states.texture.layers.length > 0) {
-300             if (states.geometry.uvBuf || states.geometry.uvBuf2) {
-301                 return true;
-302             }
-303             if (states.morphGeometry.targets && (states.morphGeometry.targets[0].uvBuf || states.morphGeometry.targets[0].uvBuf2)) {
-304                 return true;
-305             }
-306         }
-307         return false;
-308     };
-309 
-310     this._hasNormals = function(states) {
-311         if (states.geometry.normalBuf) {
-312             return true;
-313         }
-314         if (states.morphGeometry.targets && states.morphGeometry.targets[0].normalBuf) {
-315             return true;
-316         }
-317         return false;
-318     };
-319 
-320     this._composeRenderingVertexShader = function(states) {
-321 
-322         var customShaders = states.shader.shaders || {};
-323 
-324         /* Do a full custom shader replacement if code supplied without hooks
-325          */
-326         if (customShaders.vertex && customShaders.vertex.code && !customShaders.vertex.hooks) {
-327             return customShaders.vertex.code;
-328         }
-329 
-330         var customVertexShader = customShaders.vertex || {};
-331         var vertexHooks = customVertexShader.hooks || {};
-332 
-333         var customFragmentShader = customShaders.fragment || {};
-334         var fragmentHooks = customFragmentShader.hooks || {};
-335 
-336         var texturing = this._isTexturing(states);
-337         var normals = this._hasNormals(states);
-338         var clipping = states.clips.clips.length > 0;
-339         var morphing = !!states.morphGeometry.targets;
-340 
-341         var src = [
-342             "precision mediump float;"
-343         ];
-344 
-345         src.push("attribute vec3 SCENEJS_aVertex;");                // Model coordinates
-346 
-347         src.push("uniform vec3 SCENEJS_uWorldEye;");                     // World-space eye position
-348         src.push("varying vec3 SCENEJS_vWorldEyeVec;");                  // Output world-space eye vector
-349 
-350         /*-----------------------------------------------------------------------------------
-351          * Variables - normals
-352          *----------------------------------------------------------------------------------*/
-353 
-354         if (normals) {
-355 
-356             src.push("attribute vec3 SCENEJS_aNormal;");        // Normal vectors
-357             src.push("uniform   mat4 SCENEJS_uMNMatrix;");      // Model normal matrix
-358             src.push("uniform   mat4 SCENEJS_uVNMatrix;");      // View normal matrix
-359 
-360             src.push("varying   vec3 SCENEJS_vWorldNormal;");   // Output world-space vertex normal
-361             src.push("varying   vec3 SCENEJS_vViewNormal;");    // Output view-space vertex normal
-362 
-363             for (var i = 0; i < states.lights.lights.length; i++) {
-364                 var light = states.lights.lights[i];
-365                 if (light.mode == "dir") {
-366                     src.push("uniform vec3 SCENEJS_uLightDir" + i + ";");
-367                 }
-368                 if (light.mode == "point") {
-369                     src.push("uniform vec4 SCENEJS_uLightPos" + i + ";");
-370                 }
-371                 if (light.mode == "spot") {
-372                     src.push("uniform vec4 SCENEJS_uLightPos" + i + ";");
-373                 }
-374 
-375                 /* Vector from vertex to light, packaged with the pre-computed length of that vector
-376                  */
-377                 src.push("varying vec4 SCENEJS_vViewLightVecAndDist" + i + ";");    // varying for fragment lighting
-378             }
-379         }
-380 
-381         if (texturing) {
-382             if (states.geometry.uvBuf) {
-383                 src.push("attribute vec2 SCENEJS_aUVCoord;");      // UV coords
-384             }
-385             if (states.geometry.uvBuf2) {
-386                 src.push("attribute vec2 SCENEJS_aUVCoord2;");     // UV2 coords
-387             }
-388         }
-389 
-390         /* Vertex color variables
-391          */
-392         if (states.geometry.colorBuf) {
-393             src.push("attribute vec4 SCENEJS_aVertexColor;");       // UV2 coords
-394             src.push("varying vec4 SCENEJS_vColor;");               // Varying for fragment texturing
-395         }
-396 
-397         src.push("uniform mat4 SCENEJS_uMMatrix;");                 // Model matrix
-398         src.push("uniform mat4 SCENEJS_uVMatrix;");                 // View matrix
-399         src.push("uniform mat4 SCENEJS_uPMatrix;");                 // Projection matrix
-400 
-401         if (clipping || fragmentHooks.worldPos) {
-402             src.push("varying vec4 SCENEJS_vWorldVertex;");         // Varying for fragment clip or world pos hook
-403         }
-404 
-405         if (fragmentHooks.viewPos) {
-406             src.push("varying vec4 SCENEJS_vViewVertex;");          // Varying for fragment view clip hook
-407         }
-408 
-409         if (texturing) {                                            // Varyings for fragment texturing
-410             if (states.geometry.uvBuf) {
-411                 src.push("varying vec2 SCENEJS_vUVCoord;");
-412             }
-413             if (states.geometry.uvBuf2) {
-414                 src.push("varying vec2 SCENEJS_vUVCoord2;");
-415             }
-416         }
-417 
-418         /*-----------------------------------------------------------------------------------
-419          * Variables - Morphing
-420          *----------------------------------------------------------------------------------*/
-421 
-422         if (morphing) {
-423             src.push("uniform float SCENEJS_uMorphFactor;");       // LERP factor for morph
-424             if (states.morphGeometry.targets[0].vertexBuf) {      // target2 has these arrays also
-425                 src.push("attribute vec3 SCENEJS_aMorphVertex;");
-426             }
-427             if (normals) {
-428                 if (states.morphGeometry.targets[0].normalBuf) {
-429                     src.push("attribute vec3 SCENEJS_aMorphNormal;");
-430                 }
-431             }
-432         }
-433 
-434         if (customVertexShader.code) {
-435             src.push("\n" + customVertexShader.code + "\n");
-436         }
-437 
-438 
-439         src.push("void main(void) {");
-440         src.push("vec4 tmpVertex=vec4(SCENEJS_aVertex, 1.0); ");
-441 
-442         if (vertexHooks.modelPos) {
-443             src.push("tmpVertex=" + vertexHooks.modelPos + "(tmpVertex);");
-444         }
-445 
-446         src.push("  vec4 modelVertex = tmpVertex; ");
-447         if (normals) {
-448             src.push("  vec4 modelNormal = vec4(SCENEJS_aNormal, 0.0); ");
-449         }
-450 
-451         /*
-452          * Morphing - morph targets are in same model space as the geometry
-453          */
-454         if (morphing) {
-455             if (states.morphGeometry.targets[0].vertexBuf) {
-456                 src.push("  vec4 vMorphVertex = vec4(SCENEJS_aMorphVertex, 1.0); ");
-457                 src.push("  modelVertex = vec4(mix(modelVertex.xyz, vMorphVertex.xyz, SCENEJS_uMorphFactor), 1.0); ");
-458             }
-459             if (normals) {
-460                 if (states.morphGeometry.targets[0].normalBuf) {
-461                     src.push("  vec4 vMorphNormal = vec4(SCENEJS_aMorphNormal, 1.0); ");
-462                     src.push("  modelNormal = vec4( mix(modelNormal.xyz, vMorphNormal.xyz, SCENEJS_uMorphFactor), 1.0); ");
-463                 }
-464             }
-465         }
-466 
-467         src.push("  vec4 worldVertex = SCENEJS_uMMatrix * modelVertex; ");
-468 
-469         if (vertexHooks.worldPos) {
-470             src.push("worldVertex=" + vertexHooks.worldPos + "(worldVertex);");
-471         }
-472 
-473         if (vertexHooks.viewMatrix) {
-474             src.push("vec4 viewVertex = " + vertexHooks.viewMatrix + "(SCENEJS_uVMatrix) * worldVertex;");
-475         } else {
-476             src.push("vec4 viewVertex  = SCENEJS_uVMatrix * worldVertex; ");
-477         }
-478 
-479 
-480         if (vertexHooks.viewPos) {
-481             src.push("viewVertex=" + vertexHooks.viewPos + "(viewVertex);");    // Vertex hook function
-482         }
-483 
-484         if (normals) {
-485             src.push("  vec3 worldNormal = normalize((SCENEJS_uMNMatrix * modelNormal).xyz); ");
-486             src.push("  SCENEJS_vWorldNormal = worldNormal;");
-487             src.push("  SCENEJS_vViewNormal = (SCENEJS_uVNMatrix * vec4(worldNormal, 1.0)).xyz;");
-488         }
-489 
-490         if (clipping || fragmentHooks.worldPos) {
-491             src.push("  SCENEJS_vWorldVertex = worldVertex;");                  // Varying for fragment world clip or hooks
-492         }
-493 
-494         if (fragmentHooks.viewPos) {
-495             src.push("  SCENEJS_vViewVertex = viewVertex;");                    // Varying for fragment hooks
-496         }
-497 
-498         if (vertexHooks.projMatrix) {
-499             src.push("gl_Position = " + vertexHooks.projMatrix + "(SCENEJS_uPMatrix) * viewVertex;");
-500         } else {
-501             src.push("  gl_Position = SCENEJS_uPMatrix * viewVertex;");
-502         }
-503 
-504         /*-----------------------------------------------------------------------------------
-505          * Logic - normals
-506          *
-507          * Transform the world-space lights into view space
-508          *----------------------------------------------------------------------------------*/
-509 
-510         src.push("  vec3 tmpVec3;");
-511         if (normals) {
-512             for (var i = 0; i < states.lights.lights.length; i++) {
-513 
-514                 light = states.lights.lights[i];
-515 
-516                 if (light.mode == "dir") {
-517 
-518                     /* Directional light
-519                      */
-520                     if (light.space == "world") {
-521 
-522                         /* World space light - transform vector to View space
-523                          */
-524                         src.push("SCENEJS_vViewLightVecAndDist" + i + " = vec4(-normalize((SCENEJS_uVMatrix * vec4(SCENEJS_uLightDir" + i + ", 0.0)).xyz), 0.0);");
-525 
-526                     } else {
-527 
-528                         /* View space light
-529                          */
-530                         src.push("SCENEJS_vViewLightVecAndDist" + i + " = vec4(-normalize(SCENEJS_uLightDir" + i + "), 0.0);");
-531                     }
-532                 }
-533 
-534                 if (light.mode == "point") {
-535 
-536                     /* Positional light
-537                      */
-538                     if (light.space == "world") {
-539 
-540                         /* World space light - transform position to View space
-541                          */
-542                         src.push("tmpVec3 = ((SCENEJS_uVMatrix * vec4(SCENEJS_uLightPos" + i + ", 1.0)).xyz - worldVertex.xyz);");
-543                         src.push("SCENEJS_vViewLightVecAndDist" + i + " = vec4(normalize(tmpVec3), length(tmpVec3));");
-544 
-545                     } else {
-546 
-547                         /* View space light
-548                          */
-549                         src.push("tmpVec3 = (SCENEJS_uLightPos" + i + ".xyz - worldVertex.xyz);");
-550                         src.push("SCENEJS_vViewLightVecAndDist" + i + " = vec4(normalize(tmpVec3), length(tmpVec3));");
-551                     }
-552                 }
-553             }
-554         }
-555 
-556         src.push("SCENEJS_vWorldEyeVec = normalize(SCENEJS_uWorldEye - worldVertex.xyz);");
-557 
-558         if (texturing) {                                                        // varyings for fragment texturing
-559             if (states.geometry.uvBuf) {
-560                 src.push("SCENEJS_vUVCoord = SCENEJS_aUVCoord;");
-561             }
-562             if (states.geometry.uvBuf2) {
-563                 src.push("SCENEJS_vUVCoord2 = SCENEJS_aUVCoord2;");
-564             }
-565         }
-566 
-567         if (states.geometry.colorBuf) {
-568             src.push("SCENEJS_vColor = SCENEJS_aVertexColor;");                 // Varyings for fragment interpolated vertex coloring
-569         }
-570         src.push("}");
-571 
-572 
-573         if (false && debugCfg.logScripts === true) {
-574             SceneJS.log.info(src);
-575         }
-576         return src;
-577     };
-578 
-579     /*-----------------------------------------------------------------------------------------------------------------
-580      * Rendering Fragment shader
-581      *---------------------------------------------------------------------------------------------------------------*/
-582 
-583     this._composeRenderingFragmentShader = function(states) {
-584 
-585         var customShaders = states.shader.shaders || {};
-586 
-587         /* Do a full custom shader replacement if code supplied without hooks
-588          */
-589         if (customShaders.fragment && customShaders.fragment.code && !customShaders.fragment.hooks) {
-590             return customShaders.fragment.code;
-591         }
-592 
-593         var customFragmentShader = customShaders.fragment || {};
-594         var fragmentHooks = customFragmentShader.hooks || {};
-595 
-596         var texturing = this._isTexturing(states);
-597         var normals = this._hasNormals(states);
-598         var clipping = states.clips.clips.length > 0;
-599 
-600         var src = ["\n"];
-601 
-602         src.push("precision mediump float;");
-603 
-604 
-605         if (clipping || fragmentHooks.worldPos) {
-606             src.push("varying vec4 SCENEJS_vWorldVertex;");             // World-space vertex
-607         }
-608 
-609         if (fragmentHooks.viewPos) {
-610             src.push("varying vec4 SCENEJS_vViewVertex;");              // View-space vertex
-611         }
-612 
-613         /*-----------------------------------------------------------------------------------
-614          * Variables - Clipping
-615          *----------------------------------------------------------------------------------*/
-616 
-617         if (clipping) {
-618             for (var i = 0; i < states.clips.clips.length; i++) {
-619                 src.push("uniform float SCENEJS_uClipMode" + i + ";");
-620                 src.push("uniform vec4  SCENEJS_uClipNormalAndDist" + i + ";");
-621             }
-622         }
-623 
-624         if (texturing) {
-625             if (states.geometry.uvBuf) {
-626                 src.push("varying vec2 SCENEJS_vUVCoord;");
-627             }
-628             if (states.geometry.uvBuf2) {
-629                 src.push("varying vec2 SCENEJS_vUVCoord2;");
-630             }
-631             var layer;
-632             for (var i = 0, len = states.texture.layers.length; i < len; i++) {
-633                 layer = states.texture.layers[i];
-634                 src.push("uniform sampler2D SCENEJS_uSampler" + i + ";");
-635                 if (layer.matrix) {
-636                     src.push("uniform mat4 SCENEJS_uLayer" + i + "Matrix;");
-637                 }
-638                 src.push("uniform float SCENEJS_uLayer" + i + "BlendFactor;");
-639             }
-640         }
-641 
-642         /* True when lighting
-643          */
-644         src.push("uniform bool  SCENEJS_uBackfaceTexturing;");
-645         src.push("uniform bool  SCENEJS_uBackfaceLighting;");
-646         src.push("uniform bool  SCENEJS_uSpecularLighting;");
-647         src.push("uniform bool  SCENEJS_uClipping;");
-648         src.push("uniform bool  SCENEJS_uAmbient;");
-649 
-650         /* True when rendering transparency
-651          */
-652         src.push("uniform bool  SCENEJS_uTransparent;");
-653 
-654         /* Vertex color variable
-655          */
-656         if (states.geometry.colorBuf) {
-657             src.push("varying vec4 SCENEJS_vColor;");
-658         }
-659 
-660         src.push("uniform vec3  SCENEJS_uAmbientColor;");                         // Scene ambient colour - taken from clear colour
-661 
-662         src.push("uniform vec3  SCENEJS_uMaterialBaseColor;");
-663         src.push("uniform float SCENEJS_uMaterialAlpha;");
-664         src.push("uniform float SCENEJS_uMaterialEmit;");
-665         src.push("uniform vec3  SCENEJS_uMaterialSpecularColor;");
-666         src.push("uniform float SCENEJS_uMaterialSpecular;");
-667         src.push("uniform float SCENEJS_uMaterialShine;");
-668 
-669         src.push("  vec3    ambient= SCENEJS_uAmbient ? SCENEJS_uAmbientColor : vec3(0.0, 0.0, 0.0);");
-670         src.push("  float   emit    = SCENEJS_uMaterialEmit;");
-671 
-672         src.push("varying vec3 SCENEJS_vWorldEyeVec;");                          // Direction of view-space vertex from eye
-673 
-674         if (normals) {
-675 
-676             src.push("varying vec3 SCENEJS_vWorldNormal;");                  // World-space normal
-677             src.push("varying vec3 SCENEJS_vViewNormal;");                   // View-space normal
-678 
-679             var light;
-680             for (var i = 0; i < states.lights.lights.length; i++) {
-681                 light = states.lights.lights[i];
-682                 src.push("uniform vec3  SCENEJS_uLightColor" + i + ";");
-683                 if (light.mode == "point") {
-684                     src.push("uniform vec3  SCENEJS_uLightAttenuation" + i + ";");
-685                 }
-686                 src.push("varying vec4  SCENEJS_vViewLightVecAndDist" + i + ";");         // Vector from light to vertex
-687             }
-688         }
-689 
-690         if (customFragmentShader.code) {
-691             src.push("\n" + customFragmentShader.code + "\n");
-692         }
-693 
-694         src.push("void main(void) {");
-695 
-696         /*-----------------------------------------------------------------------------------
-697          * Logic - Clipping
-698          *----------------------------------------------------------------------------------*/
-699 
-700         if (clipping) {
-701             src.push("if (SCENEJS_uClipping) {");
-702             src.push("  float   dist;");
-703             for (var i = 0; i < states.clips.clips.length; i++) {
-704                 src.push("    if (SCENEJS_uClipMode" + i + " != 0.0) {");
-705                 src.push("        dist = dot(SCENEJS_vWorldVertex.xyz, SCENEJS_uClipNormalAndDist" + i + ".xyz) - SCENEJS_uClipNormalAndDist" + i + ".w;");
-706                 src.push("        if (SCENEJS_uClipMode" + i + " == 1.0) {");
-707                 src.push("            if (dist > 0.0) { discard; }");
-708                 src.push("        }");
-709                 src.push("        if (SCENEJS_uClipMode" + i + " == 2.0) {");
-710                 src.push("            if (dist > 0.0) { discard; }");
-711                 src.push("        }");
-712                 src.push("    }");
-713             }
-714             src.push("}");
-715         }
-716 
-717         if (fragmentHooks.worldPos) {
-718             src.push(fragmentHooks.worldPos + "(SCENEJS_vWorldVertex);");
-719         }
-720 
-721         if (fragmentHooks.viewPos) {
-722             src.push(fragmentHooks.viewPos + "(SCENEJS_vViewVertex);");
-723         }
-724 
-725         if (fragmentHooks.worldEyeVec) {
-726             src.push(fragmentHooks.worldEyeVec + "(SCENEJS_vWorldEyeVec);");
-727         }
-728 
-729         if (normals && fragmentHooks.worldNormal) {
-730             src.push(fragmentHooks.worldNormal + "(SCENEJS_vWorldNormal);");
-731         }
-732 
-733         if (normals && fragmentHooks.viewNormal) {
-734             src.push(fragmentHooks.viewNormal + "(SCENEJS_vViewNormal);");
-735         }
-736 
-737         if (states.geometry.colorBuf) {
-738             src.push("  vec3    color   = SCENEJS_vColor.rgb;");
-739         } else {
-740             src.push("  vec3    color   = SCENEJS_uMaterialBaseColor;")
-741         }
-742 
-743         src.push("  float alpha         = SCENEJS_uMaterialAlpha;");
-744         src.push("  float emit          = SCENEJS_uMaterialEmit;");
-745         src.push("  float specular      = SCENEJS_uMaterialSpecular;");
-746         src.push("  vec3  specularColor = SCENEJS_uMaterialSpecularColor;");
-747         src.push("  float shine         = SCENEJS_uMaterialShine;");
-748 
-749         if (fragmentHooks.materialBaseColor) {
-750             src.push("color=" + fragmentHooks.materialBaseColor + "(color);");
-751         }
-752         if (fragmentHooks.materialAlpha) {
-753             src.push("alpha=" + fragmentHooks.materialAlpha + "(alpha);");
-754         }
-755         if (fragmentHooks.materialEmit) {
-756             src.push("emit=" + fragmentHooks.materialEmit + "(emit);");
-757         }
-758         if (fragmentHooks.materialSpecular) {
-759             src.push("specular=" + fragmentHooks.materialSpecular + "(specular);");
-760         }
-761         if (fragmentHooks.materialSpecularColor) {
-762             src.push("specularColor=" + fragmentHooks.materialSpecularColor + "(specularColor);");
-763         }
-764         if (fragmentHooks.materialShine) {
-765             src.push("shine=" + fragmentHooks.materialShine + "(shine);");
-766         }
-767 
-768         if (normals) {
-769             src.push("  float   attenuation = 1.0;");
-770             src.push("  vec3    viewNormalVec = SCENEJS_vViewNormal;");
-771         }
-772 
-773         var layer;
-774         if (texturing) {
-775 
-776             if (normals) {
-777                 src.push("if (SCENEJS_uBackfaceTexturing || dot(SCENEJS_vWorldNormal, SCENEJS_vWorldEyeVec) > 0.0) {");
-778             }
-779 
-780             src.push("  vec4    texturePos;");
-781             src.push("  vec2    textureCoord=vec2(0.0,0.0);");
-782 
-783             for (var i = 0, len = states.texture.layers.length; i < len; i++) {
-784                 layer = states.texture.layers[i];
-785 
-786                 /* Texture input
-787                  */
-788                 if (layer.applyFrom == "normal" && normals) {
-789                     if (states.geometry.normalBuf) {
-790                         src.push("texturePos=vec4(viewNormalVec.xyz, 1.0);");
-791                     } else {
-792                         SceneJS.log.warn("Texture layer applyFrom='normal' but geo has no normal vectors");
-793                         continue;
-794                     }
-795                 }
-796                 if (layer.applyFrom == "uv") {
-797                     if (states.geometry.uvBuf) {
-798                         src.push("texturePos = vec4(SCENEJS_vUVCoord.s, SCENEJS_vUVCoord.t, 1.0, 1.0);");
-799                     } else {
-800                         SceneJS.log.warn("Texture layer applyTo='uv' but geometry has no UV coordinates");
-801                         continue;
-802                     }
-803                 }
-804                 if (layer.applyFrom == "uv2") {
-805                     if (states.geometry.uvBuf2) {
-806                         src.push("texturePos = vec4(SCENEJS_vUVCoord2.s, SCENEJS_vUVCoord2.t, 1.0, 1.0);");
-807                     } else {
-808                         SceneJS.log.warn("Texture layer applyTo='uv2' but geometry has no UV2 coordinates");
-809                         continue;
-810                     }
-811                 }
-812 
-813                 /* Texture matrix
-814                  */
-815                 if (layer.matrix) {
-816                     src.push("textureCoord=(SCENEJS_uLayer" + i + "Matrix * texturePos).xy;");
-817                 } else {
-818                     src.push("textureCoord=texturePos.xy;");
-819                 }
-820 
-821                 /* Alpha from Texture
-822                  * */
-823                 if (layer.applyTo == "alpha") {
-824                     if (layer.blendMode == "multiply") {
-825                         src.push("alpha = alpha * (SCENEJS_uLayer" + i + "BlendFactor * texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, 1.0 - textureCoord.y)).b);");
-826                     } else if (layer.blendMode == "add") {
-827                         src.push("alpha = ((1.0 - SCENEJS_uLayer" + i + "BlendFactor) * alpha) + (SCENEJS_uLayer" + i + "BlendFactor * texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, 1.0 - textureCoord.y)).b);");
-828                     }
-829                 }
-830 
-831                 /* Texture output
-832                  */
-833                 if (layer.applyTo == "baseColor") {
-834                     if (layer.blendMode == "multiply") {
-835                         src.push("color = color * (SCENEJS_uLayer" + i + "BlendFactor * texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, 1.0 - textureCoord.y)).rgb);");
-836                     } else {
-837                         src.push("color = ((1.0 - SCENEJS_uLayer" + i + "BlendFactor) * color) + (SCENEJS_uLayer" + i + "BlendFactor * texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, 1.0 - textureCoord.y)).rgb);");
-838                     }
-839                 }
-840 
-841                 if (layer.applyTo == "emit") {
-842                     if (layer.blendMode == "multiply") {
-843                         src.push("emit  = emit * (SCENEJS_uLayer" + i + "BlendFactor * texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, 1.0 - textureCoord.y)).r);");
-844                     } else {
-845                         src.push("emit = ((1.0 - SCENEJS_uLayer" + i + "BlendFactor) * emit) + (SCENEJS_uLayer" + i + "BlendFactor * texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, 1.0 - textureCoord.y)).r);");
-846                     }
-847                 }
-848 
-849                 if (layer.applyTo == "specular" && normals) {
-850                     if (layer.blendMode == "multiply") {
-851                         src.push("specular  = specular * (SCENEJS_uLayer" + i + "BlendFactor * texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, 1.0 - textureCoord.y)).r);");
-852                     } else {
-853                         src.push("specular = ((1.0 - SCENEJS_uLayer" + i + "BlendFactor) * specular) + (SCENEJS_uLayer" + i + "BlendFactor * texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, 1.0 - textureCoord.y)).r);");
-854                     }
-855                 }
-856 
-857                 if (layer.applyTo == "normals" && normals) {
-858                     src.push("vec3 bump = normalize(texture2D(SCENEJS_uSampler" + i + ", vec2(textureCoord.x, -textureCoord.y)).xyz * 2.0 - 1.0);");
-859                     src.push("viewNormalVec *= -bump;");
-860                 }
-861             }
-862             if (normals) {
-863                 src.push("}");
-864             }
-865         }
-866 
-867         src.push("  vec4    fragColor;");
-868 
-869         if (normals) {
-870 
-871             src.push("if (SCENEJS_uBackfaceLighting || dot(SCENEJS_vWorldNormal, SCENEJS_vWorldEyeVec) > 0.0) {");
-872 
-873             src.push("  vec3    lightValue      = vec3(0.0, 0.0, 0.0);");
-874             src.push("  vec3    specularValue   = vec3(0.0, 0.0, 0.0);");
-875             src.push("  vec3    viewLightVec;");
-876             src.push("  float   dotN;");
-877             src.push("  float   lightDist;");
-878 
-879             var light;
-880 
-881             for (var i = 0, len = states.lights.lights.length; i < len; i++) {
-882                 light = states.lights.lights[i];
-883 
-884                 src.push("viewLightVec = SCENEJS_vViewLightVecAndDist" + i + ".xyz;");
-885 
-886                 if (light.mode == "point") {
-887 
-888                     src.push("dotN = max(dot(viewNormalVec, viewLightVec) ,0.0);");
-889 
-890                     //src.push("if (dotN > 0.0) {");
-891 
-892                     src.push("lightDist = SCENEJS_vViewLightVecAndDist" + i + ".w;");
-893 
-894                     src.push("  attenuation = 1.0 / (" +
-895                              "  SCENEJS_uLightAttenuation" + i + "[0] + " +
-896                              "  SCENEJS_uLightAttenuation" + i + "[1] * lightDist + " +
-897                              "  SCENEJS_uLightAttenuation" + i + "[2] * lightDist * lightDist);");
-898 
-899                     if (light.diffuse) {
-900                         src.push("  lightValue += dotN *  SCENEJS_uLightColor" + i + " * attenuation;");
-901                     }
-902 
-903                     if (light.specular) {
-904                         src.push("if (SCENEJS_uSpecularLighting) specularValue += attenuation * specularColor * SCENEJS_uLightColor" + i +
-905                                  " * specular * pow(max(dot(reflect(viewLightVec, viewNormalVec), vec3(0.0,0.0,1.0)), 0.0), shine);");
-906                     }
-907                     //src.push("}");
-908                 }
-909 
-910                 if (light.mode == "dir") {
-911 
-912                     src.push("dotN = max(dot(viewNormalVec,viewLightVec),0.0);");
-913 
-914                     //src.push("if (dotN > 0.0) {");
-915                     if (light.diffuse) {
-916                         src.push("lightValue += dotN * SCENEJS_uLightColor" + i + ";");
-917                     }
-918 
-919                     if (light.specular) {
-920                         src.push("if (SCENEJS_uSpecularLighting) specularValue += specularColor * SCENEJS_uLightColor" + i +
-921                                  " * specular * pow(max(dot(reflect(viewLightVec, viewNormalVec), vec3(0.0,0.0,1.0)), 0.0), shine);");
-922                     }
-923                     // src.push("}");
-924                 }
-925             }
-926 
-927             src.push("      fragColor = vec4((specularValue.rgb + color.rgb * (lightValue.rgb + ambient.rgb)) + (emit * color.rgb), alpha);");
-928             src.push("   } else {");
-929             src.push("      fragColor = vec4((color.rgb + (emit * color.rgb)) *  (vec3(1.0, 1.0, 1.0) + ambient.rgb), alpha);");
-930             src.push("   }");
-931 
-932         } else { // No normals
-933             src.push("fragColor = vec4((color.rgb + (emit * color.rgb)) *  (vec3(1.0, 1.0, 1.0) + ambient.rgb), alpha);");
-934         }
-935 
-936         if (fragmentHooks.pixelColor) {
-937             src.push("fragColor=" + fragmentHooks.pixelColor + "(fragColor);");
-938         }
-939 
-940         if (false && debugCfg.whitewash === true) {
-941             src.push("    gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);");
-942         } else {
-943             src.push("    gl_FragColor = fragColor;");
-944         }
-945         src.push("}");
-946 
-947         return src;
-948     };
-949 
-950 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_display_renderContext.js.html b/docs/symbols/src/src_core_display_renderContext.js.html deleted file mode 100644 index 36717e89..00000000 --- a/docs/symbols/src/src_core_display_renderContext.js.html +++ /dev/null @@ -1,95 +0,0 @@ -
  1 /**
-  2  * @class A facade which exposes internal scene rendering state to "rendered" event listeners bound to scene graph nodes with {@link SceneJS.Node#bind}.
-  3  *
-  4  * <p>The listener is fired for each {@link SceneJS.Geometry} that is rendered within the subgraph of the bound node.
-  5  * An instance of this facade is passed into the listener's handler, enabling the listener to obtain the various transform
-  6  * matrices that are active at that {@link SceneJS.Geometry}.</p>
-  7  *
-  8  * <p>The facade instance is only valid within the callback's execution; internally, SceneJS reuses the same instance of the
-  9  * facade with each scene.</p>
- 10  */
- 11 SceneJS.RenderContext = function(frameCtx) {
- 12     this._frameCtx = frameCtx;
- 13 };
- 14 
- 15 /**
- 16  * Get the projection matrix, as defined by the active {@link SceneJS.Camera} node.
- 17  */
- 18 SceneJS.RenderContext.prototype.getCameraMatrix = function() {
- 19     return this._frameCtx.cameraMat;
- 20 };
- 21 
- 22 /**
- 23  * Get the view matrix, as defined by the active {@link SceneJS.LookAt} node.
- 24  */
- 25 SceneJS.RenderContext.prototype.getViewMatrix = function() {
- 26     return this._frameCtx.viewMat;
- 27 };
- 28 
- 29 /**
- 30  * Get the model matrix, as defined by the active {@link SceneJS.XForm} node.
- 31  */
- 32 SceneJS.RenderContext.prototype.getModelMatrix = function() {
- 33     return this._frameCtx.modelMat;
- 34 };
- 35 
- 36 /**
- 37  * Transforms the given world coordinate by the model, view and projection matrices defined by the active {@link SceneJS.XForm}, {@link SceneJS.LookAt} and {@link SceneJS.Camera} nodes.
- 38  * @returns [Number] The 2D Canvas-space coordinate
- 39  */
- 40 SceneJS.RenderContext.prototype.getCanvasPos = function(offset) {
- 41 
- 42     this.getProjPos(offset);
- 43 
- 44     var canvas = this._frameCtx.canvas.canvas;
- 45     var canvasWidth = canvas.width;
- 46     var canvasHeight = canvas.height;
- 47 
- 48     /* Projection division and map to canvas
- 49      */
- 50     var pc = this._pc;
- 51 
- 52     var x = (pc[0] / pc[3]) * canvasWidth * 0.5;
- 53     var y = (pc[1] / pc[3]) * canvasHeight * 0.5;
- 54 
- 55     return {
- 56         x: x + (canvasWidth * 0.5),
- 57         y: canvasHeight - y - (canvasHeight * 0.5)
- 58     };
- 59 };
- 60 
- 61 /**
- 62  * Transforms the given world coordinate by the model and view matrices defined by the active {@link SceneJS.XForm} and {@link SceneJS.LookAt} nodes.
- 63  * @returns [Number] The 3D Projection-space coordinate
- 64  */
- 65 SceneJS.RenderContext.prototype.getCameraPos = function(offset) {
- 66     this.getProjPos(offset);
- 67     this._camPos = SceneJS_math_normalizeVec3(this._pc, [0,0,0]);
- 68     return { x: this._camPos[0], y: this._camPos[1], z: this._camPos[2] }; // TODO: return _camPos and lose the temp object
- 69 };
- 70 
- 71 
- 72 SceneJS.RenderContext.prototype.getProjPos = function(offset) {
- 73     this.getViewPos(offset);
- 74     this._pc = SceneJS_math_transformPoint3(this._frameCtx.cameraMat, this._vc);
- 75     return { x: this._pc[0], y: this._pc[1], z: this._pc[2],  w: this._pc[3] };
- 76 };
- 77 
- 78 SceneJS.RenderContext.prototype.getViewPos = function(offset) {
- 79     this.getWorldPos(offset);
- 80     this._vc = SceneJS_math_transformPoint3(this._frameCtx.viewMat, this._wc);
- 81     return { x: this._vc[0], y: this._vc[1], z: this._vc[2],  w: this._vc[3] };
- 82 };
- 83 
- 84 SceneJS.RenderContext.prototype.getWorldPos = function(offset) {
- 85     this._wc = SceneJS_math_transformPoint3(this._frameCtx.modelMat, offset || [0,0,0]);
- 86     return { x: this._wc[0], y: this._wc[1], z: this._wc[2],  w: this._wc[3] };
- 87 };
- 88 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_engine.js.html b/docs/symbols/src/src_core_engine.js.html deleted file mode 100644 index 19375543..00000000 --- a/docs/symbols/src/src_core_engine.js.html +++ /dev/null @@ -1,567 +0,0 @@ -
  1 /**
-  2  * @class A container for a scene graph and its display
-  3  *
-  4  *
-  5  * @private
-  6  */
-  7 var SceneJS_Engine = function(json, options) {
-  8 
-  9     json.type = "scene"; // The type property supplied by user on the root JSON node is ignored - would always be 'scene'
- 10 
- 11     /**
- 12      * ID of this engine, also the ID of this engine's {@link SceneJS.Scene}
- 13      * @type String
- 14      */
- 15     this.id = json.id;
- 16 
- 17     /**
- 18      * Canvas and GL context for this engine
- 19      */
- 20     this.canvas = new SceneJS_Canvas(this.id, json.canvasId, json.contextAttr, options);
- 21 
- 22     /**
- 23      * Manages firing of and subscription to events
- 24      */
- 25     this.events = new SceneJS_eventManager();
- 26 
- 27     this.events.createEvent("started");
- 28     this.events.createEvent("tick");
- 29     this.events.createEvent("rendered");
- 30     this.events.createEvent("sleep");
- 31     this.events.createEvent("stopped");
- 32     this.events.createEvent("loading");     // Loading processes now exist
- 33     this.events.createEvent("loaded");      // No loading processes now exist
- 34     this.events.createEvent("destroyed");
- 35 
- 36     /**
- 37      * State core factory - creates, stores, shares and destroys cores
- 38      */
- 39     this._coreFactory = new SceneJS_CoreFactory();
- 40 
- 41     /**
- 42      * Manages creation, recycle and destruction of {@link SceneJS.Node} instances for this engine's scene graph
- 43      */
- 44     this._nodeFactory = new SceneJS_NodeFactory();
- 45 
- 46     /**
- 47      * The engine's scene renderer
- 48      * @type SceneJS_Display
- 49      */
- 50     this.display = new SceneJS_Display({
- 51         canvas:  this.canvas
- 52     });
- 53 
- 54     /**
- 55      * Flags the entirety of the scene graph as needing to be (re)compiled into the display
- 56      */
- 57     this.sceneDirty = false;
- 58 
- 59     /**
- 60      * Flag set when at least one branch of the scene graph needs recompilation
- 61      */
- 62     this._sceneBranchesDirty = false;
- 63 
- 64     /**
- 65      * List of nodes scheduled for destruction by #destroyNode
- 66      * Destructions are done in a batch at the end of each render so as not to disrupt the render.
- 67      */
- 68     this._nodesToDestroy = [];
- 69 
- 70     /**
- 71      * Number of nodes in destruction list
- 72      */
- 73     this._numNodesToDestroy = 0;
- 74 
- 75     /**
- 76      * Flag which is set while this engine is running - set after call to #start, unset after #stop or #pause
- 77      */
- 78     this.running = false;
- 79 
- 80     /**
- 81      * Flag which is set while this engine is paused - set after call to #pause, unset after #stop or #start
- 82      */
- 83     this.paused = false;
- 84 
- 85     /**
- 86      * Flag set once this engine has been destroyed
- 87      */
- 88     this.destroyed = false;
- 89 
- 90     /**
- 91      * The current scene graph status
- 92      */
- 93     this.sceneStatus = {
- 94         nodes: {},          // Status for each node 
- 95         numTasks: 0       // Number of loads currently in progress
- 96     };
- 97 
- 98     /**
- 99      * The engine's scene graph
-100      * @type SceneJS.Scene
-101      */
-102     this.scene = this.createNode(json); // Scene back-references this engine, so is defined after other engine members
-103 
-104     var self = this;
-105 
-106     this.canvas.canvas.addEventListener(// WebGL context lost
-107             "webglcontextlost",
-108             function(event) {
-109 
-110                 event.preventDefault();
-111 
-112                 SceneJS_events.fireEvent(SceneJS_events.WEBGL_CONTEXT_LOST, { scene: self.scene });
-113 
-114             },
-115             false);
-116 
-117     this.canvas.canvas.addEventListener(// WebGL context recovered
-118             "webglcontextrestored",
-119             function(event) {
-120 
-121                 event.preventDefault();
-122 
-123                 self.canvas.initWebGL();
-124 
-125                 self._coreFactory.webglRestored();  // Reallocate WebGL resources for node state cores
-126 
-127                 self.display.webglRestored(); // Reallocate shaders and re-cache shader var locations for display state chunks
-128 
-129                 SceneJS_events.fireEvent(SceneJS_events.WEBGL_CONTEXT_RESTORED, { scene: self.scene });
-130             },
-131             false);
-132 };
-133 
-134 
-135 /**
-136  * Simulate a lost WebGL context.
-137  * Only works if the simulateWebGLContextLost was given as an option to the engine's constructor.
-138  */
-139 SceneJS_Engine.prototype.loseWebGLContext = function() {
-140     this.canvas.loseWebGLContext();
-141 };
-142 
-143 /**
-144  * Recursively parse the given JSON scene graph representation and return a scene (sub)graph.
-145  *
-146  * @param {Object} json JSON definition of a scene graph or subgraph
-147  * @returns {SceneJS.Node} Root of the new (sub)graph
-148  */
-149 SceneJS_Engine.prototype.createNode = function(json) {
-150 
-151     json.type = json.type || "node"; // Nodes are SceneJS.Node type by default
-152 
-153     var core = this._coreFactory.getCore(json.type, json.coreId); // Create or share a core
-154 
-155     var node;
-156 
-157     //try {
-158     node = this._nodeFactory.getNode(this, json, core);
-159 
-160     SceneJS_events.fireEvent(SceneJS_events.NODE_CREATED, {
-161         sceneId: this.id, // Engine ID is same as scene ID
-162         nodeId: node.nodeId
-163     });
-164 
-165 
-166     //    } catch (e) {
-167     //
-168     //        this._coreFactory.putCore(core); // Clean up after node create failed
-169     //
-170     //        throw e;
-171     //    }
-172 
-173     if (json.nodes) {
-174 
-175         for (var i = 0, len = json.nodes.length; i < len; i++) { // Create sub-nodes
-176             node.addNode(this.createNode(json.nodes[i]));
-177         }
-178     }
-179 
-180     return node;
-181 };
-182 
-183 /**
-184  * Finds the node with the given ID in this engine's scene graph
-185  * @return {SceneJS.Node} The node if found, else null
-186  */
-187 SceneJS_Engine.prototype.findNode = function(nodeId) {
-188     return this._nodeFactory.nodes.items[nodeId];
-189 };
-190 
-191 /** Finds nodes in this engine's scene graph that have nodes IDs matching the given regular expression
-192  * @param {String} nodeIdRegex Regular expression to match on node IDs
-193  * @return {[SceneJS.Node]} Array of nodes whose IDs match the given regex
-194  */
-195 SceneJS_Engine.prototype.findNodes = function(nodeIdRegex) {
-196 
-197     var regex = new RegExp(nodeIdRegex);
-198     var nodes = [];
-199     var nodeMap = this._nodeFactory.nodes.items;
-200 
-201     for (var nodeId in nodeMap) {
-202         if (nodeMap.hasOwnProperty(nodeId)) {
-203 
-204             if (regex.test(nodeId)) {
-205                 nodes.push(nodeMap[nodeId]);
-206             }
-207         }
-208     }
-209 
-210     return nodes;
-211 };
-212 
-213 /**
-214  * Schedules the given subtree of this engine's {@link SceneJS.Scene} for recompilation
-215  *
-216  * @param {SceneJS.Node} node Root node of the subtree to recompile
-217  */
-218 SceneJS_Engine.prototype.branchDirty = function(node) {
-219 
-220     if (this.sceneDirty) {
-221         return; // Whole scene will recompile anyway
-222     }
-223 
-224     /* Dealing with some weirdness with the embedded window and iframe / window fascism.
-225      */
-226     if (node == window) {
-227         return;
-228     }
-229 
-230     node.branchDirty = true;
-231     node.dirty = true;
-232 
-233     for (var n = node.parent; n && !(n.dirty || n.branchDirty); n = n.parent) { // Flag path down to this node
-234         n.dirty = true;
-235     }
-236 
-237     this._sceneBranchesDirty = true;
-238 };
-239 
-240 
-241 SceneJS_Engine.prototype.nodeLoading = function(node) {
-242 
-243     var nodeStatus = this.sceneStatus.nodes[node.id] || (this.sceneStatus.nodes[node.id] = { numTasks: 0 });
-244 
-245     nodeStatus.numTasks++;
-246 
-247     this.sceneStatus.numTasks++;
-248 
-249     this.events.fireEvent("loading", this.sceneStatus);
-250 };
-251 
-252 SceneJS_Engine.prototype.nodeLoaded = function(node) {
-253 
-254     var nodeStatus = this.sceneStatus.nodes[node.id];
-255 
-256     if (!nodeStatus) {
-257         return;
-258     }
-259 
-260     nodeStatus.numTasks--;
-261 
-262     this.sceneStatus.numTasks--;
-263 
-264     if (nodeStatus.numTasks == 0) {
-265         delete this.sceneStatus.nodes[node.id];
-266     }
-267 
-268     this.events.fireEvent("loaded", this.sceneStatus);
-269 };
-270 
-271 
-272 /**
-273  * Renders a single frame. Does any pending scene compilations or draw graph updates first.
-274  * Ordinarily the frame is rendered only if compilations or draw graph updates were performed,
-275  * but may be forced to render the frame regardless.
-276  *
-277  * @param {{String:String}} params Rendering parameters
-278  */
-279 SceneJS_Engine.prototype.renderFrame = function(params) {
-280 
-281     if (this._tryCompile() || (params && params.force)) { // Do any pending (re)compilations
-282 
-283 //        var eventParams = {
-284 //            sceneId: this.id
-285 //        };
-286 //
-287         //self.events.fireEvent("tick", eventParams);
-288 
-289         this.display.render(params);
-290 
-291         return true;
-292     }
-293 
-294     return false;
-295 };
-296 
-297 /**
-298  * Starts the render loop on this engine.
-299  * @params cfg Render loop configs
-300  * @params cfg.idleFunc {Function} Callback to call on each loop iteration
-301  * @params cfg.frameFunc {Function} Callback to call after a render is done to update the scene image
-302  * @params cfg.sleepFunc {Function}
-303  */
-304 SceneJS_Engine.prototype.start = function(cfg) {
-305 
-306     if (!this.running) {
-307 
-308         cfg = cfg || {};
-309 
-310         this.running = true;
-311         this.paused = false;
-312 
-313         var self = this;
-314         var fnName = "__scenejs_sceneLoop" + this.id;
-315 
-316         var sleeping = false;
-317 
-318         this.sceneDirty = true;
-319 
-320         var idleEventParams = {
-321             sceneId: this.id
-322         };
-323 
-324         self.events.fireEvent("started", idleEventParams);
-325 
-326         window[fnName] = function() {
-327 
-328             if (self.running && !self.paused) {  // idleFunc may have paused scene
-329 
-330                 self.events.fireEvent("tick", idleEventParams);
-331 
-332                 if (cfg.idleFunc) {
-333                     cfg.idleFunc();
-334                 }
-335 
-336                 if (!self.running) { // idleFunc may have destroyed scene
-337                     return;
-338                 }
-339 
-340                 if (self._tryCompile()) {         // Attempt pending compile and redraw
-341 
-342                     sleeping = false;
-343 
-344                     self.display.render();
-345 
-346                     self.events.fireEvent("rendered", idleEventParams);
-347 
-348                     if (cfg.frameFunc) {
-349                         cfg.frameFunc();
-350                     }
-351 
-352                     window.requestAnimationFrame(window[fnName]);
-353 
-354                 } else {
-355 
-356                     if (!sleeping && cfg.sleepFunc) {
-357                         cfg.sleepFunc();
-358                     }
-359 
-360                     sleeping = true;
-361 
-362                     self.events.fireEvent("sleep", idleEventParams);
-363 
-364                     window.requestAnimationFrame(window[fnName]);
-365                 }
-366             } else {
-367 
-368                 window.requestAnimationFrame(window[fnName]);
-369             }
-370         };
-371 
-372         this._startCfg = cfg;
-373 
-374         window.requestAnimationFrame(window[fnName]);
-375     }
-376 };
-377 
-378 /**
-379  * Performs a pick on this engine and returns a hit record containing at least the name of the picked
-380  * scene object (as configured by SceneJS.Name nodes) and the canvas pick coordinates. Ordinarily, picking
-381  * is the simple GPU color-name mapped method, but this method can instead perform a ray-intersect pick
-382  * when the 'rayPick' flag is set on the options parameter for this method. For that mode, this method will
-383  * also find the intersection point on the picked object's near surface with a ray cast from the eye that passes
-384  * through the mouse position on the projection plane.
-385  *
-386  * @param {Number} canvasX X-axis canvas pick coordinate
-387  * @param {Number} canvasY Y-axis canvas pick coordinate
-388  * @param options Pick options
-389  * @param options.rayPick Performs additional ray-intersect pick when true
-390  * @returns The pick record
-391  */
-392 SceneJS_Engine.prototype.pick = function(canvasX, canvasY, options) {
-393 
-394     this._tryCompile();  // Do any pending scene compilations
-395 
-396     var hit = this.display.pick({
-397         canvasX : canvasX,
-398         canvasY : canvasY,
-399         rayPick: options ? options.rayPick : false
-400     });
-401 
-402     if (hit) {
-403         hit.canvasX = canvasX;
-404         hit.canvasY = canvasY;
-405     }
-406 
-407     return hit;
-408 };
-409 
-410 /**
-411  * Performs any pending scene compilations or display rebuilds, returns true if any of those were done,
-412  * in which case a display re-render is then needed
-413  *
-414  * @returns {Boolean} True when any compilations or display rebuilds were done
-415  */
-416 SceneJS_Engine.prototype._tryCompile = function() {
-417 
-418     if (this.display.imageDirty // Frame buffer needs redraw
-419             || this.display.drawListDirty // Draw list needs rebuild
-420             || this.display.stateSortDirty // Draw list needs to redetermine state order
-421             || this.display.stateOrderDirty // Draw list needs state sort
-422             || this.display.objectListDirty // Draw list needs to be rebuilt
-423             || this._sceneBranchesDirty // One or more branches in scene graph need (re)compilation
-424             || this.sceneDirty) { // Whole scene needs recompilation
-425 
-426         this._doDestroyNodes(); // Garbage collect destroyed nodes - node destructions set imageDirty true
-427 
-428         if (this._sceneBranchesDirty || this.sceneDirty) { // Need scene graph compilation
-429 
-430             SceneJS_events.fireEvent(SceneJS_events.SCENE_COMPILING, {  // Notify compilation support start
-431                 engine: this                                            // Compilation support modules get ready
-432             });
-433 
-434             this.scene._compileNodes(); // Begin depth-first compilation descent into scene sub-nodes
-435         }
-436 
-437         this._sceneBranchesDirty = false;
-438         this.sceneDirty = false;
-439 
-440         return true; // Compilation was performed, need frame redraw now
-441     }
-442 
-443     return false;
-444 };
-445 
-446 /**
-447  * Pauses/unpauses the render loop
-448  * @param {Boolean} doPause Pauses or unpauses the render loop
-449  */
-450 SceneJS_Engine.prototype.pause = function(doPause) {
-451     this.paused = doPause;
-452 };
-453 
-454 /**
-455  * Stops the render loop
-456  */
-457 SceneJS_Engine.prototype.stop = function() {
-458 
-459     if (this.running) {
-460 
-461         this.running = false;
-462         this.paused = false;
-463 
-464         window["__scenejs_sceneLoop" + this.id] = null;
-465 
-466         this.events.fireEvent("stopped", { sceneId: this.id });
-467     }
-468 };
-469 
-470 /**
-471  * Destroys a node within this engine's {@link SceneJS.Scene}
-472  *
-473  * @param {SceneJS.Node} node Node to destroy
-474  */
-475 SceneJS_Engine.prototype.destroyNode = function(node) {
-476 
-477     /* The node is actually scheduled for lazy destruction within the next invocation of #_tryCompile
-478      */
-479     this._nodesToDestroy[this._numNodesToDestroy++] = node;
-480 
-481     /* Stop tracking node's status
-482      */
-483     var nodeStatus = this.sceneStatus.nodes[node.id];
-484 
-485     if (nodeStatus) {
-486         this.sceneStatus.numTasks -= nodeStatus.numTasks;
-487         delete this.sceneStatus.nodes[node.id];
-488     }
-489 };
-490 
-491 /**
-492  * Performs pending node destructions. When destroyed, each node and its core is released back to the
-493  * node and core pools for reuse, respectively.
-494  */
-495 SceneJS_Engine.prototype._doDestroyNodes = function() {
-496 
-497     var node;
-498 
-499     while (this._numNodesToDestroy > 0) {
-500 
-501         node = this._nodesToDestroy[--this._numNodesToDestroy];
-502 
-503         node._doDestroy();
-504 
-505         this._coreFactory.putCore(node._core);    // Release state core for reuse
-506 
-507         this._nodeFactory.putNode(node);         // Release node for reuse
-508     }
-509 };
-510 
-511 /**
-512  * Destroys this engine
-513  */
-514 SceneJS_Engine.prototype.destroy = function() {
-515 
-516     this.destroyed = true;
-517 
-518     this.events.fireEvent("destroyed", { sceneId: this.id });
-519 };
-520 
-521 /*---------------------------------------------------------------------------------------------------------------------
-522  * JavaScript augmentations to support render loop
-523  *--------------------------------------------------------------------------------------------------------------------*/
-524 
-525 if (! self.Int32Array) {
-526     self.Int32Array = Array;
-527     self.Float32Array = Array;
-528 }
-529 
-530 // Ripped off from THREE.js - https://github.com/mrdoob/three.js/blob/master/src/Three.js
-531 // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
-532 // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
-533 
-534 (function() {
-535     var lastTime = 0;
-536     var vendors = ['ms', 'moz', 'webkit', 'o'];
-537     for (var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
-538         window.requestAnimationFrame = window[vendors[x] + 'RequestAnimationFrame'];
-539         window.cancelAnimationFrame = window[vendors[x] + 'CancelAnimationFrame']
-540                 || window[vendors[x] + 'RequestCancelAnimationFrame'];
-541     }
-542 
-543     if (!window.requestAnimationFrame)
-544         window.requestAnimationFrame = function(callback, element) {
-545             var currTime = new Date().getTime();
-546             var timeToCall = Math.max(0, 16 - (currTime - lastTime));
-547             var id = window.setTimeout(function() {
-548                 callback(currTime + timeToCall);
-549             },
-550                     timeToCall);
-551             lastTime = currTime + timeToCall;
-552             return id;
-553         };
-554 
-555     if (!window.cancelAnimationFrame)
-556         window.cancelAnimationFrame = function(id) {
-557             clearTimeout(id);
-558         };
-559 }());
-560 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_errors.js.html b/docs/symbols/src/src_core_errors.js.html deleted file mode 100644 index 6c6c8752..00000000 --- a/docs/symbols/src/src_core_errors.js.html +++ /dev/null @@ -1,92 +0,0 @@ -
  1 /**
-  2  * Backend module that provides single point through which exceptions may be raised
-  3  *
-  4  * @class SceneJS_error
-  5  * @private
-  6  */
-  7 var SceneJS_error = new (function() {
-  8 
-  9     var activeSceneId;
- 10 
- 11     SceneJS_events.addListener(
- 12             SceneJS_events.SCENE_COMPILING, // Set default logging for scene root
- 13             function(params) {
- 14                 activeSceneId = params.engine.id;
- 15             });
- 16 
- 17     SceneJS_events.addListener(
- 18             SceneJS_events.RESET,
- 19             function() {
- 20                 activeSceneId = null;
- 21             },
- 22             100000);  // Really low priority - must be reset last
- 23 
- 24     this.fatalError = function(code, message) {
- 25         if (typeof code == "string") {
- 26             message = code;
- 27             code = SceneJS.errors.ERROR;
- 28         }
- 29         var error = {
- 30             errorName: SceneJS.errors._getErrorName(code) || "ERROR",
- 31             code: code,
- 32             exception: message,
- 33             fatal: true
- 34         };
- 35         if (activeSceneId) {
- 36             error.sceneId = activeSceneId;
- 37         }
- 38         SceneJS_events.fireEvent(SceneJS_events.ERROR, error);
- 39         return message;
- 40     };
- 41 
- 42     this.error = function(code, message) {
- 43         var error = {
- 44             errorName: SceneJS.errors._getErrorName(code) || "ERROR",
- 45             code: code,
- 46             exception: message,
- 47             fatal: false
- 48         };
- 49         if (activeSceneId) {
- 50             error.sceneId = activeSceneId;
- 51         }
- 52         SceneJS_events.fireEvent(SceneJS_events.ERROR, error);
- 53     };
- 54 })();
- 55 
- 56 (function() {
- 57     SceneJS.errors = {};
- 58 
- 59     var n = 0;
- 60     SceneJS.errors.ERROR = n++;
- 61     SceneJS.errors.WEBGL_NOT_SUPPORTED = n++;
- 62     SceneJS.errors.WEBGL_CONTEXT_LOST = n++;
- 63     SceneJS.errors.NODE_CONFIG_EXPECTED = n++;
- 64     SceneJS.errors.ILLEGAL_NODE_CONFIG = n++;
- 65     SceneJS.errors.SHADER_COMPILATION_FAILURE = n++;
- 66     SceneJS.errors.SHADER_LINK_FAILURE = n++;
- 67     SceneJS.errors.CANVAS_NOT_FOUND = n++;
- 68     SceneJS.errors.OUT_OF_VRAM = n++;
- 69     SceneJS.errors.WEBGL_UNSUPPORTED_NODE_CONFIG = n++;
- 70     SceneJS.errors.NODE_NOT_FOUND = n++;
- 71     SceneJS.errors.NODE_ILLEGAL_STATE = n++;
- 72     SceneJS.errors.ID_CLASH = n++;
- 73     SceneJS.errors.PLUGIN_INVALID = n++;
- 74 })();
- 75 
- 76 SceneJS.errors._getErrorName = function(code) {
- 77     for (var key in SceneJS.errors) {
- 78         if (SceneJS.errors.hasOwnProperty(key) && SceneJS.errors[key] == code) {
- 79             return key;
- 80         }
- 81     }
- 82     return null;
- 83 };
- 84 
- 85 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_eventManager.js.html b/docs/symbols/src/src_core_eventManager.js.html deleted file mode 100644 index 74adda52..00000000 --- a/docs/symbols/src/src_core_eventManager.js.html +++ /dev/null @@ -1,103 +0,0 @@ -
  1 /**
-  2  *  @private
-  3  */
-  4 var SceneJS_eventManager = function() {
-  5 
-  6     this._handlerIds = new SceneJS_Map();
-  7 
-  8     this.typeHandlers = {};
-  9 };
- 10 
- 11 /**
- 12  *
- 13  */
- 14 SceneJS_eventManager.prototype.createEvent = function(type) {
- 15 
- 16     if (this.typeHandlers[type]) {
- 17         return;
- 18     }
- 19 
- 20     this.typeHandlers[type] = {
- 21         handlers: {},
- 22         numSubs: 0
- 23     };
- 24 };
- 25 
- 26 /**
- 27  * Subscribes to an event defined on this event manager
- 28  *
- 29  * @param {String} type Event type one of the values in SceneJS_events
- 30  * @param {Function} callback Handler function that will accept whatever parameter object accompanies the event
- 31  * @return {String} handle Handle to the event binding
- 32  */
- 33 SceneJS_eventManager.prototype.onEvent = function(type, callback) {
- 34 
- 35     var handlersForType = this.typeHandlers[type];
- 36 
- 37     if (!handlersForType) {
- 38         throw "event type not supported: '" + type + "'";
- 39     }
- 40 
- 41     var handlerId = this._handlerIds.addItem(type);
- 42 
- 43     var handlers = handlersForType.handlers;
- 44     handlers[handlerId] = callback;
- 45     handlersForType.numSubs++;
- 46 
- 47     return handlerId;
- 48 };
- 49 
- 50 /**
- 51  *
- 52  */
- 53 SceneJS_eventManager.prototype.fireEvent = function(type, params) {
- 54 
- 55     var handlersForType = this.typeHandlers[type];
- 56 
- 57     if (!handlersForType) {
- 58         throw "event not supported: '" + type + "'";
- 59     }
- 60 
- 61     if (handlersForType.numSubs > 0) {
- 62 
- 63         var handlers = handlersForType.handlers;
- 64 
- 65         for (var handlerId in handlers) {
- 66             if (handlers.hasOwnProperty(handlerId)) {
- 67                 handlers[handlerId](params);
- 68             }
- 69         }
- 70     }
- 71 };
- 72 
- 73 /**
- 74  * Unsubscribes to an event previously subscribed to on this manager
- 75  *
- 76  * @param {String} handlerId Subscription handle
- 77  */
- 78 SceneJS_eventManager.prototype.unEvent = function(handlerId) {
- 79 
- 80     var type = this._handlerIds.items[handlerId];
- 81     if (!type) {
- 82         return;
- 83     }
- 84 
- 85     this._handlerIds.removeItem(handlerId);
- 86 
- 87     var handlers = this.typeHandlers[type];
- 88 
- 89     if (!handlers) {
- 90         return;
- 91     }
- 92 
- 93     delete handlers[handlerId];
- 94     this.typeHandlers[type].numSubs--;
- 95 };
- 96 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_events.js.html b/docs/symbols/src/src_core_events.js.html deleted file mode 100644 index 392e0430..00000000 --- a/docs/symbols/src/src_core_events.js.html +++ /dev/null @@ -1,194 +0,0 @@ -
  1 /**
-  2  *  @private
-  3  */
-  4 var SceneJS_events = new (function () {
-  5 
-  6     this.ERROR = 0;
-  7     this.RESET = 1;                         // SceneJS framework reset
-  8     this.NODE_CREATED = 2;                 // Scene has just been created
-  9     this.SCENE_CREATED = 3;                 // Scene has just been created
- 10     this.SCENE_COMPILING = 4;               // Scene about to be compiled and drawn
- 11     this.SCENE_DESTROYED = 5;               // Scene just been destroyed
- 12     this.OBJECT_COMPILING = 6;
- 13     this.WEBGL_CONTEXT_LOST = 7;
- 14     this.WEBGL_CONTEXT_RESTORED = 8;
- 15 
- 16     /* Priority queue for each type of event
- 17      */
- 18     var events = [];
- 19 
- 20     /**
- 21      * Registers a handler for the given event and returns a subscription handle
- 22      *
- 23      * The handler can be registered with an optional priority number which specifies the order it is
- 24      * called among the other handler already registered for the event.
- 25      *
- 26      * So, with n being the number of commands registered for the given event:
- 27      *
- 28      * (priority <= 0)      - command will be the first called
- 29      * (priority >= n)      - command will be the last called
- 30      * (0 < priority < n)   - command will be called at the order given by the priority
- 31      * @private
- 32      * @param type Event type - one of the values in SceneJS_events
- 33      * @param command - Handler function that will accept whatever parameter object accompanies the event
- 34      * @param priority - Optional priority number (see above)
- 35      * @return {String} - Subscription handle
- 36      */
- 37     this.addListener = function (type, command, priority) {
- 38 
- 39         var list = events[type];
- 40 
- 41         if (!list) {
- 42             list = [];
- 43             events[type] = list;
- 44         }
- 45 
- 46         var handler = {
- 47             command:command,
- 48             priority:(priority == undefined) ? list.length : priority
- 49         };
- 50 
- 51         var index = -1;
- 52 
- 53         for (var i = 0, len = list.length; i < len; i++) {
- 54             if (!list[i]) {
- 55                 index = i;
- 56                 break;
- 57             }
- 58         }
- 59 
- 60         if (index < 0) {
- 61             list.push(handler);
- 62             index = list.length - 1;
- 63         }
- 64 
- 65 //
- 66 //        for (var i = 0; i < list.length; i++) {
- 67 //            if (list[i].priority > handler.priority) {
- 68 //                list.splice(i, 0, handler);
- 69 //                return i;
- 70 //            }
- 71 //        }
- 72 
- 73 
- 74         var handle = type + "." + index;
- 75 
- 76         return handle;
- 77     };
- 78 
- 79     /**
- 80      * Removes a listener
- 81      * @param handle Subscription handle
- 82      */
- 83     this.removeListener = function (handle) {
- 84 
- 85         var lastIdx = handle.lastIndexOf(".");
- 86 
- 87         var type = parseInt(handle.substr(0, lastIdx));
- 88         var index = parseInt(handle.substr(lastIdx + 1));
- 89 
- 90         var list = events[type];
- 91 
- 92         if (!list) {
- 93             return;
- 94         }
- 95 
- 96         delete list[index];
- 97     };
- 98 
- 99     /**
-100      * @private
-101      */
-102     this.fireEvent = function (type, params) {
-103 
-104         var list = events[type];
-105 
-106         if (list) {
-107             params = params || {};
-108             for (var i = 0; i < list.length; i++) {
-109                 if (list[i]) {
-110                     list[i].command(params);
-111                 }
-112             }
-113         }
-114     };
-115 
-116 })();
-117 
-118 
-119 /**
-120  * Subscribe to SceneJS events
-121  * @deprecated
-122  */
-123 SceneJS.bind = function (name, func) {
-124     switch (name) {
-125 
-126         case "error" :
-127 
-128             return SceneJS_events.addListener(SceneJS_events.ERROR, func);
-129             break;
-130 
-131         case "nodeCreated" :
-132 
-133             return SceneJS_events.addListener(
-134                 SceneJS_events.NODE_CREATED,
-135                 function (params) {
-136                     func(params);
-137                 });
-138             break;
-139 
-140         case "reset" :
-141 
-142             return SceneJS_events.addListener(
-143                 SceneJS_events.RESET,
-144                 function () {
-145                     func();
-146                 });
-147             break;
-148 
-149         case "webglcontextlost" :
-150 
-151             return SceneJS_events.addListener(
-152                 SceneJS_events.WEBGL_CONTEXT_LOST,
-153                 function (params) {
-154                     func(params);
-155                 });
-156             break;
-157 
-158         case "webglcontextrestored" :
-159 
-160             return SceneJS_events.addListener(
-161                 SceneJS_events.WEBGL_CONTEXT_RESTORED,
-162                 function (params) {
-163                     func(params);
-164                 });
-165             break;
-166 
-167         default:
-168             throw SceneJS_error.fatalError("SceneJS.bind - this event type not supported: '" + name + "'");
-169     }
-170 };
-171 
-172 /* Subscribe to SceneJS events
-173  * @deprecated
-174  */
-175 SceneJS.onEvent = SceneJS.bind;
-176 
-177 /* Unsubscribe from event
-178  */
-179 SceneJS.unEvent = function (handle) {
-180     return SceneJS_events.removeListener(handle);
-181 };
-182 
-183 SceneJS.subscribe = SceneJS.addListener = SceneJS.onEvent = SceneJS.bind;
-184 
-185 SceneJS.unsubscribe = SceneJS.unEvent;
-186 
-187 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_log.js.html b/docs/symbols/src/src_core_log.js.html deleted file mode 100644 index 8fbbedfd..00000000 --- a/docs/symbols/src/src_core_log.js.html +++ /dev/null @@ -1,109 +0,0 @@ -
  1 /**
-  2  * @class Manages logging
-  3  *  @private
-  4  */
-  5 SceneJS.log = new (function() {
-  6 
-  7     var activeSceneId;
-  8     var funcs = null;
-  9     var queues = {};
- 10     var indent = 0;
- 11     var indentStr = "";
- 12 
- 13     SceneJS_events.addListener(
- 14             SceneJS_events.SCENE_COMPILING, // Set default logging for scene root
- 15             function(params) {
- 16                 activeSceneId = params.engine.id;
- 17             });
- 18 
- 19     SceneJS_events.addListener(
- 20             SceneJS_events.RESET,
- 21             function() {
- 22                 queues = {};
- 23                 funcs = null;
- 24                 activeSceneId = null;
- 25             },
- 26             100000);  // Really low priority - must be reset last
- 27 
- 28     this._setIndent = function(_indent) {
- 29         indent = _indent;
- 30         var indentArray = [];
- 31         for (var i = 0; i < indent; i++) {
- 32             indentArray.push("----");
- 33         }
- 34         indentStr = indentArray.join("");
- 35     };
- 36 
- 37     this.error = function(msg) {
- 38         this._log("error", msg);
- 39     };
- 40 
- 41     this.warn = function(msg) {
- 42         this._log("warn", msg);
- 43     };
- 44 
- 45     this.info = function(msg) {
- 46         this._log("info", msg);
- 47     };
- 48 
- 49     this.debug = function(msg) {
- 50         this._log("debug", msg);
- 51     };
- 52 
- 53     this.setFuncs = function(l) {
- 54         if (l) {
- 55             funcs = l;
- 56             for (var channel in queues) {
- 57                 this._flush(channel);
- 58             }
- 59         }
- 60     };
- 61 
- 62     this._flush = function(channel) {
- 63         var queue = queues[channel];
- 64         if (queue) {
- 65             var func = funcs ? funcs[channel] : null;
- 66             if (func) {
- 67                 for (var i = 0; i < queue.length; i++) {
- 68                     func(queue[i]);
- 69                 }
- 70                 queues[channel] = [];
- 71             }
- 72         }
- 73     };
- 74 
- 75     this._log = function(channel, message) {
- 76         if (SceneJS._isArray(message)) {
- 77             for (var i = 0; i < message.length; i++) {
- 78                 this.__log(channel, message[i]);
- 79             }
- 80         } else {
- 81             this.__log(channel, message);
- 82         }
- 83     };
- 84 
- 85     this.__log = function(channel, message) {
- 86         message = activeSceneId
- 87                 ? indentStr + activeSceneId + ": " + message
- 88                 : indentStr + message;
- 89 
- 90         if (funcs && funcs[channel]) {
- 91             funcs[channel](message);
- 92 
- 93         } else if (console && console[channel]) {
- 94             console[channel](message);
- 95         }
- 96     };
- 97 
- 98     this.getFuncs = function() {
- 99         return funcs;
-100     };
-101 
-102 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_map.js.html b/docs/symbols/src/src_core_map.js.html deleted file mode 100644 index fcb9fe01..00000000 --- a/docs/symbols/src/src_core_map.js.html +++ /dev/null @@ -1,72 +0,0 @@ -
  1 /**
-  2  * @class Generic map of IDs to items - can generate own IDs or accept given IDs. IDs should be strings in order to not
-  3  * clash with internally generated IDs, which are numbers.
-  4  * @private
-  5  */
-  6 var SceneJS_Map = function(items, _baseId) {
-  7 
-  8     /**
-  9      * @property Items in this map
- 10      */
- 11     this.items = items || [];
- 12 
- 13 
- 14     var baseId = _baseId || 0;
- 15     var lastUniqueId = baseId + 1;
- 16 
- 17     /**
- 18      * Adds an item to the map and returns the ID of the item in the map. If an ID is given, the item is
- 19      * mapped to that ID. Otherwise, the map automatically generates the ID and maps to that.
- 20      *
- 21      * id = myMap.addItem("foo") // ID internally generated
- 22      *
- 23      * id = myMap.addItem("foo", "bar") // ID is "foo"
- 24      *
- 25      */
- 26     this.addItem = function() {
- 27 
- 28         var item;
- 29 
- 30         if (arguments.length == 2) {
- 31 
- 32             var id = arguments[0];
- 33 
- 34             item = arguments[1];
- 35 
- 36             if (this.items[id]) { // Won't happen if given ID is string
- 37                 throw SceneJS_error.fatalError(SceneJS.errors.ID_CLASH, "ID clash: '" + id + "'");
- 38             }
- 39 
- 40             this.items[id] = item;
- 41 
- 42             return id;
- 43 
- 44         } else {
- 45 
- 46             while (true) {
- 47 
- 48                 item = arguments[0];
- 49                 var findId = lastUniqueId++;
- 50 
- 51                 if (!this.items[findId]) {
- 52                     this.items[findId] = item;
- 53                     return findId;
- 54                 }
- 55             }
- 56         }
- 57     };
- 58 
- 59     /**
- 60      * Removes the item of the given ID from the map
- 61      */
- 62     this.removeItem = function(id) {
- 63         delete this.items[id];
- 64     };
- 65 };
\ No newline at end of file diff --git a/docs/symbols/src/src_core_math.js.html b/docs/symbols/src/src_core_math.js.html deleted file mode 100644 index 5c97588e..00000000 --- a/docs/symbols/src/src_core_math.js.html +++ /dev/null @@ -1,2117 +0,0 @@ -
  1 /* 
-  2  * Optimizations made based on glMatrix by Brandon Jones
-  3  */
-  4 
-  5 /*
-  6  * Copyright (c) 2010 Brandon Jones
-  7  *
-  8  * This software is provided 'as-is', without any express or implied
-  9  * warranty. In no event will the authors be held liable for any damages
- 10  * arising from the use of this software.
- 11  *
- 12  * Permission is granted to anyone to use this software for any purpose,
- 13  * including commercial applications, and to alter it and redistribute it
- 14  * freely, subject to the following restrictions:
- 15  *
- 16  *    1. The origin of this software must not be misrepresented; you must not
- 17  *    claim that you wrote the original software. If you use this software
- 18  *    in a product, an acknowledgment in the product documentation would be
- 19  *    appreciated but is not required.
- 20  *
- 21  *    2. Altered source versions must be plainly marked as such, and must not
- 22  *    be misrepresented as being the original software.
- 23  *
- 24  *    3. This notice may not be removed or altered from any source
- 25  *    distribution.
- 26  */
- 27 
- 28 
- 29 /**
- 30  * @param u vec3
- 31  * @param v vec3
- 32  * @param dest vec3 - optional destination
- 33  * @return {vec3} dest if specified, u otherwise
- 34  * @private
- 35  */
- 36 var SceneJS_math_divVec3 = function(u, v, dest) {
- 37     if (!dest) {
- 38         dest = u;
- 39     }
- 40 
- 41     dest[0] = u[0] / v[0];
- 42     dest[1] = u[1] / v[1];
- 43     dest[2] = u[2] / v[2];
- 44 
- 45     return dest;
- 46 };
- 47 
- 48 /**
- 49  * @param v vec4
- 50  * @param dest vec4 - optional destination
- 51  * @return {vec4} dest if specified, v otherwise
- 52  * @private
- 53  */
- 54 var SceneJS_math_negateVector4 = function(v, dest) {
- 55     if (!dest) {
- 56         dest = v;
- 57     }
- 58     dest[0] = -v[0];
- 59     dest[1] = -v[1];
- 60     dest[2] = -v[2];
- 61     dest[3] = -v[3];
- 62 
- 63     return dest;
- 64 };
- 65 
- 66 /**
- 67  * @param u vec4
- 68  * @param v vec4
- 69  * @param dest vec4 - optional destination
- 70  * @return {vec4} dest if specified, u otherwise
- 71  * @private
- 72  */
- 73 var SceneJS_math_addVec4 = function(u, v, dest) {
- 74     if (!dest) {
- 75         dest = u;
- 76     }
- 77 
- 78     dest[0] = u[0] + v[0];
- 79     dest[1] = u[1] + v[1];
- 80     dest[2] = u[2] + v[2];
- 81     dest[3] = u[3] + v[3];
- 82 
- 83     return dest;
- 84 };
- 85 
- 86 
- 87 /**
- 88  * @param v vec4
- 89  * @param s scalar
- 90  * @param dest vec4 - optional destination
- 91  * @return {vec4} dest if specified, v otherwise
- 92  * @private
- 93  */
- 94 var SceneJS_math_addVec4s = function(v, s, dest) {
- 95     if (!dest) {
- 96         dest = v;
- 97     }
- 98 
- 99     dest[0] = v[0] + s;
-100     dest[1] = v[1] + s;
-101     dest[2] = v[2] + s;
-102     dest[3] = v[3] + s;
-103 
-104     return dest;
-105 };
-106 
-107 /**
-108  * @param u vec3
-109  * @param v vec3
-110  * @param dest vec3 - optional destination
-111  * @return {vec3} dest if specified, u otherwise
-112  * @private
-113  */
-114 var SceneJS_math_addVec3 = function(u, v, dest) {
-115     if (!dest) {
-116         dest = u;
-117     }
-118 
-119     dest[0] = u[0] + v[0];
-120     dest[1] = u[1] + v[1];
-121     dest[2] = u[2] + v[2];
-122 
-123     return dest;
-124 };
-125 
-126 /**
-127  * @param v vec3
-128  * @param s scalar
-129  * @param dest vec3 - optional destination
-130  * @return {vec3} dest if specified, v otherwise
-131  * @private
-132  */
-133 var SceneJS_math_addVec3s = function(v, s, dest) {
-134     if (!dest) {
-135         dest = v;
-136     }
-137 
-138     dest[0] = v[0] + s;
-139     dest[1] = v[1] + s;
-140     dest[2] = v[2] + s;
-141 
-142     return dest;
-143 };
-144 
-145 /** @private */
-146 var SceneJS_math_addScalarVec4 = function(s, v, dest) {
-147     return SceneJS_math_addVec4s(v, s, dest);
-148 };
-149 
-150 /**
-151  * @param u vec4
-152  * @param v vec4
-153  * @param dest vec4 - optional destination
-154  * @return {vec4} dest if specified, u otherwise
-155  * @private
-156  */
-157 var SceneJS_math_subVec4 = function(u, v, dest) {
-158     if (!dest) {
-159         dest = u;
-160     }
-161 
-162     dest[0] = u[0] - v[0];
-163     dest[1] = u[1] - v[1];
-164     dest[2] = u[2] - v[2];
-165     dest[3] = u[3] - v[3];
-166 
-167     return dest;
-168 };
-169 
-170 /**
-171  * @param u vec3
-172  * @param v vec3
-173  * @param dest vec3 - optional destination
-174  * @return {vec3} dest if specified, v otherwise
-175  * @private
-176  */
-177 var SceneJS_math_subVec3 = function(u, v, dest) {
-178     if (!dest) {
-179         dest = u;
-180     }
-181 
-182     dest[0] = u[0] - v[0];
-183     dest[1] = u[1] - v[1];
-184     dest[2] = u[2] - v[2];
-185 
-186     return dest;
-187 };
-188 
-189 var SceneJS_math_lerpVec3 = function(t, t1, t2, p1, p2) {
-190     var f2 = (t - t1) / (t2 - t1);
-191     var f1 = 1.0 - f2;
-192     return  {
-193         x: p1.x * f1 + p2.x * f2,
-194         y: p1.y * f1 + p2.y * f2,
-195         z: p1.z * f1 + p2.z * f2
-196     };
-197 };
-198 
-199 
-200 /**
-201  * @param u vec2
-202  * @param v vec2
-203  * @param dest vec2 - optional destination
-204  * @return {vec2} dest if specified, u otherwise
-205  * @private
-206  */
-207 var SceneJS_math_subVec2 = function(u, v, dest) {
-208     if (!dest) {
-209         dest = u;
-210     }
-211 
-212     dest[0] = u[0] - v[0];
-213     dest[1] = u[1] - v[1];
-214 
-215     return dest;
-216 };
-217 
-218 /**
-219  * @param v vec4
-220  * @param s scalar
-221  * @param dest vec4 - optional destination
-222  * @return {vec4} dest if specified, v otherwise
-223  * @private
-224  */
-225 var SceneJS_math_subVec4Scalar = function(v, s, dest) {
-226     if (!dest) {
-227         dest = v;
-228     }
-229 
-230     dest[0] = v[0] - s;
-231     dest[1] = v[1] - s;
-232     dest[2] = v[2] - s;
-233     dest[3] = v[3] - s;
-234 
-235     return dest;
-236 };
-237 
-238 /**
-239  * @param v vec4
-240  * @param s scalar
-241  * @param dest vec4 - optional destination
-242  * @return {vec4} dest if specified, v otherwise
-243  * @private
-244  */
-245 var SceneJS_math_subScalarVec4 = function(v, s, dest) {
-246     if (!dest) {
-247         dest = v;
-248     }
-249 
-250     dest[0] = s - v[0];
-251     dest[1] = s - v[1];
-252     dest[2] = s - v[2];
-253     dest[3] = s - v[3];
-254 
-255     return dest;
-256 };
-257 
-258 /**
-259  * @param u vec4
-260  * @param v vec4
-261  * @param dest vec4 - optional destination
-262  * @return {vec4} dest if specified, u otherwise
-263  * @private
-264  */
-265 var SceneJS_math_mulVec4 = function(u, v, dest) {
-266     if (!dest) {
-267         dest = u;
-268     }
-269 
-270     dest[0] = u[0] * v[0];
-271     dest[1] = u[1] * v[1];
-272     dest[2] = u[2] * v[2];
-273     dest[3] = u[3] * v[3];
-274 
-275     return dest;
-276 };
-277 
-278 /**
-279  * @param v vec4
-280  * @param s scalar
-281  * @param dest vec4 - optional destination
-282  * @return {vec4} dest if specified, v otherwise
-283  * @private
-284  */
-285 var SceneJS_math_mulVec4Scalar = function(v, s, dest) {
-286     if (!dest) {
-287         dest = v;
-288     }
-289 
-290     dest[0] = v[0] * s;
-291     dest[1] = v[1] * s;
-292     dest[2] = v[2] * s;
-293     dest[3] = v[3] * s;
-294 
-295     return dest;
-296 };
-297 
-298 
-299 /**
-300  * @param v vec3
-301  * @param s scalar
-302  * @param dest vec3 - optional destination
-303  * @return {vec3} dest if specified, v otherwise
-304  * @private
-305  */
-306 var SceneJS_math_mulVec3Scalar = function(v, s, dest) {
-307     if (!dest) {
-308         dest = v;
-309     }
-310 
-311     dest[0] = v[0] * s;
-312     dest[1] = v[1] * s;
-313     dest[2] = v[2] * s;
-314 
-315     return dest;
-316 };
-317 
-318 /**
-319  * @param v vec2
-320  * @param s scalar
-321  * @param dest vec2 - optional destination
-322  * @return {vec2} dest if specified, v otherwise
-323  * @private
-324  */
-325 var SceneJS_math_mulVec2Scalar = function(v, s, dest) {
-326     if (!dest) {
-327         dest = v;
-328     }
-329 
-330     dest[0] = v[0] * s;
-331     dest[1] = v[1] * s;
-332 
-333     return dest;
-334 };
-335 
-336 
-337 /**
-338  * @param u vec4
-339  * @param v vec4
-340  * @param dest vec4 - optional destination
-341  * @return {vec4} dest if specified, u otherwise
-342  * @private
-343  */
-344 var SceneJS_math_divVec4 = function(u, v, dest) {
-345     if (!dest) {
-346         dest = u;
-347     }
-348 
-349     dest[0] = u[0] / v[0];
-350     dest[1] = u[1] / v[1];
-351     dest[2] = u[2] / v[2];
-352     dest[3] = u[3] / v[3];
-353 
-354     return dest;
-355 };
-356 
-357 /**
-358  * @param v vec3
-359  * @param s scalar
-360  * @param dest vec3 - optional destination
-361  * @return {vec3} dest if specified, v otherwise
-362  * @private
-363  */
-364 var SceneJS_math_divScalarVec3 = function(s, v, dest) {
-365     if (!dest) {
-366         dest = v;
-367     }
-368 
-369     dest[0] = s / v[0];
-370     dest[1] = s / v[1];
-371     dest[2] = s / v[2];
-372 
-373     return dest;
-374 };
-375 
-376 /**
-377  * @param v vec3
-378  * @param s scalar
-379  * @param dest vec3 - optional destination
-380  * @return {vec3} dest if specified, v otherwise
-381  * @private
-382  */
-383 var SceneJS_math_divVec3s = function(v, s, dest) {
-384     if (!dest) {
-385         dest = v;
-386     }
-387 
-388     dest[0] = v[0] / s;
-389     dest[1] = v[1] / s;
-390     dest[2] = v[2] / s;
-391 
-392     return dest;
-393 };
-394 
-395 /**
-396  * @param v vec4
-397  * @param s scalar
-398  * @param dest vec4 - optional destination
-399  * @return {vec4} dest if specified, v otherwise
-400  * @private
-401  */
-402 var SceneJS_math_divVec4s = function(v, s, dest) {
-403     if (!dest) {
-404         dest = v;
-405     }
-406 
-407     dest[0] = v[0] / s;
-408     dest[1] = v[1] / s;
-409     dest[2] = v[2] / s;
-410     dest[3] = v[3] / s;
-411 
-412     return dest;
-413 };
-414 
-415 
-416 /**
-417  * @param s scalar
-418  * @param v vec4
-419  * @param dest vec4 - optional destination
-420  * @return {vec4} dest if specified, v otherwise
-421  * @private
-422  */
-423 var SceneJS_math_divScalarVec4 = function(s, v, dest) {
-424     if (!dest) {
-425         dest = v;
-426     }
-427 
-428     dest[0] = s / v[0];
-429     dest[1] = s / v[1];
-430     dest[2] = s / v[2];
-431     dest[3] = s / v[3];
-432 
-433     return dest;
-434 };
-435 
-436 
-437 /** @private */
-438 var SceneJS_math_dotVector4 = function(u, v) {
-439     return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2] + u[3] * v[3]);
-440 };
-441 
-442 /** @private */
-443 var SceneJS_math_cross3Vec4 = function(u, v) {
-444     var u0 = u[0], u1 = u[1], u2 = u[2];
-445     var v0 = v[0], v1 = v[1], v2 = v[2];
-446     return [
-447         u1 * v2 - u2 * v1,
-448         u2 * v0 - u0 * v2,
-449         u0 * v1 - u1 * v0,
-450         0.0];
-451 };
-452 
-453 /**
-454  * @param u vec3
-455  * @param v vec3
-456  * @param dest vec3 - optional destination
-457  * @return {vec3} dest if specified, u otherwise
-458  * @private
-459  */
-460 var SceneJS_math_cross3Vec3 = function(u, v, dest) {
-461     if (!dest) {
-462         dest = u;
-463     }
-464 
-465     var x = u[0], y = u[1], z = u[2];
-466     var x2 = v[0], y2 = v[1], z2 = v[2];
-467 
-468     dest[0] = y * z2 - z * y2;
-469     dest[1] = z * x2 - x * z2;
-470     dest[2] = x * y2 - y * x2;
-471 
-472     return dest;
-473 };
-474 
-475 /** @private */
-476 var SceneJS_math_sqLenVec4 = function(v) {
-477     return SceneJS_math_dotVector4(v, v);
-478 };
-479 
-480 /** @private */
-481 var SceneJS_math_lenVec4 = function(v) {
-482     return Math.sqrt(SceneJS_math_sqLenVec4(v));
-483 };
-484 
-485 /** @private */
-486 var SceneJS_math_dotVector3 = function(u, v) {
-487     return (u[0] * v[0] + u[1] * v[1] + u[2] * v[2]);
-488 };
-489 
-490 /** @private */
-491 var SceneJS_math_dotVector2 = function(u, v) {
-492     return (u[0] * v[0] + u[1] * v[1]);
-493 };
-494 
-495 /** @private */
-496 var SceneJS_math_sqLenVec3 = function(v) {
-497     return SceneJS_math_dotVector3(v, v);
-498 };
-499 
-500 /** @private */
-501 var SceneJS_math_sqLenVec2 = function(v) {
-502     return SceneJS_math_dotVector2(v, v);
-503 };
-504 
-505 /** @private */
-506 var SceneJS_math_lenVec3 = function(v) {
-507     return Math.sqrt(SceneJS_math_sqLenVec3(v));
-508 };
-509 
-510 /** @private */
-511 var SceneJS_math_lenVec2 = function(v) {
-512     return Math.sqrt(SceneJS_math_sqLenVec2(v));
-513 };
-514 
-515 /**
-516  * @param v vec3
-517  * @param dest vec3 - optional destination
-518  * @return {vec3} dest if specified, v otherwise
-519  * @private
-520  */
-521 var SceneJS_math_rcpVec3 = function(v, dest) {
-522     return SceneJS_math_divScalarVec3(1.0, v, dest);
-523 };
-524 
-525 /**
-526  * @param v vec4
-527  * @param dest vec4 - optional destination
-528  * @return {vec4} dest if specified, v otherwise
-529  * @private
-530  */
-531 var SceneJS_math_normalizeVec4 = function(v, dest) {
-532     var f = 1.0 / SceneJS_math_lenVec4(v);
-533     return SceneJS_math_mulVec4Scalar(v, f, dest);
-534 };
-535 
-536 /** @private */
-537 var SceneJS_math_normalizeVec3 = function(v, dest) {
-538     var f = 1.0 / SceneJS_math_lenVec3(v);
-539     return SceneJS_math_mulVec3Scalar(v, f, dest);
-540 };
-541 
-542 // @private
-543 var SceneJS_math_normalizeVec2 = function(v, dest) {
-544     var f = 1.0 / SceneJS_math_lenVec2(v);
-545     return SceneJS_math_mulVec2Scalar(v, f, dest);
-546 };
-547 
-548 /** @private */
-549 var SceneJS_math_mat4 = function() {
-550     return new Array(16);
-551 };
-552 
-553 /** @private */
-554 var SceneJS_math_dupMat4 = function(m) {
-555     return m.slice(0, 16);
-556 };
-557 
-558 /** @private */
-559 var SceneJS_math_getCellMat4 = function(m, row, col) {
-560     return m[row + col * 4];
-561 };
-562 
-563 /** @private */
-564 var SceneJS_math_setCellMat4 = function(m, row, col, s) {
-565     m[row + col * 4] = s;
-566 };
-567 
-568 /** @private */
-569 var SceneJS_math_getRowMat4 = function(m, r) {
-570     return [m[r], m[r + 4], m[r + 8], m[r + 12]];
-571 };
-572 
-573 /** @private */
-574 var SceneJS_math_setRowMat4 = function(m, r, v) {
-575     m[r] = v[0];
-576     m[r + 4] = v[1];
-577     m[r + 8] = v[2];
-578     m[r + 12] = v[3];
-579 };
-580 
-581 /** @private */
-582 var SceneJS_math_setRowMat4c = function(m, r, x, y, z, w) {
-583     SceneJS_math_setRowMat4(m, r, [x,y,z,w]);
-584 };
-585 
-586 /** @private */
-587 var SceneJS_math_setRowMat4s = function(m, r, s) {
-588     SceneJS_math_setRowMat4c(m, r, s, s, s, s);
-589 };
-590 
-591 /** @private */
-592 var SceneJS_math_getColMat4 = function(m, c) {
-593     var i = c * 4;
-594     return [m[i], m[i + 1],m[i + 2],m[i + 3]];
-595 };
-596 
-597 /** @private */
-598 var SceneJS_math_setColMat4v = function(m, c, v) {
-599     var i = c * 4;
-600     m[i] = v[0];
-601     m[i + 1] = v[1];
-602     m[i + 2] = v[2];
-603     m[i + 3] = v[3];
-604 };
-605 
-606 /** @private */
-607 var SceneJS_math_setColMat4c = function(m, c, x, y, z, w) {
-608     SceneJS_math_setColMat4v(m, c, [x,y,z,w]);
-609 };
-610 
-611 /** @private */
-612 var SceneJS_math_setColMat4Scalar = function(m, c, s) {
-613     SceneJS_math_setColMat4c(m, c, s, s, s, s);
-614 };
-615 
-616 /** @private */
-617 var SceneJS_math_mat4To3 = function(m) {
-618     return [
-619         m[0],m[1],m[2],
-620         m[4],m[5],m[6],
-621         m[8],m[9],m[10]
-622     ];
-623 };
-624 
-625 /** @private */
-626 var SceneJS_math_m4s = function(s) {
-627     return [
-628         s,s,s,s,
-629         s,s,s,s,
-630         s,s,s,s,
-631         s,s,s,s
-632     ];
-633 };
-634 
-635 /** @private */
-636 var SceneJS_math_setMat4ToZeroes = function() {
-637     return SceneJS_math_m4s(0.0);
-638 };
-639 
-640 /** @private */
-641 var SceneJS_math_setMat4ToOnes = function() {
-642     return SceneJS_math_m4s(1.0);
-643 };
-644 
-645 /** @private */
-646 var SceneJS_math_diagonalMat4v = function(v) {
-647     return [
-648         v[0], 0.0, 0.0, 0.0,
-649         0.0,v[1], 0.0, 0.0,
-650         0.0, 0.0, v[2],0.0,
-651         0.0, 0.0, 0.0, v[3]
-652     ];
-653 };
-654 
-655 /** @private */
-656 var SceneJS_math_diagonalMat4c = function(x, y, z, w) {
-657     return SceneJS_math_diagonalMat4v([x,y,z,w]);
-658 };
-659 
-660 /** @private */
-661 var SceneJS_math_diagonalMat4s = function(s) {
-662     return SceneJS_math_diagonalMat4c(s, s, s, s);
-663 };
-664 
-665 /** @private */
-666 var SceneJS_math_identityMat4 = function() {
-667     return SceneJS_math_diagonalMat4v([1.0,1.0,1.0,1.0]);
-668 };
-669 
-670 /** @private */
-671 var SceneJS_math_isIdentityMat4 = function(m) {
-672     if (m[0] !== 1.0 || m[1] !== 0.0 || m[2] !== 0.0 || m[3] !== 0.0 ||
-673         m[4] !== 0.0 || m[5] !== 1.0 || m[6] !== 0.0 || m[7] !== 0.0 ||
-674         m[8] !== 0.0 || m[9] !== 0.0 || m[10] !== 1.0 || m[11] !== 0.0 ||
-675         m[12] !== 0.0 || m[13] !== 0.0 || m[14] !== 0.0 || m[15] !== 1.0)
-676     {
-677         return false;
-678     }
-679 
-680     return true;
-681 };
-682 
-683 /**
-684  * @param m mat4
-685  * @param dest mat4 - optional destination
-686  * @return {mat4} dest if specified, m otherwise
-687  * @private
-688  */
-689 var SceneJS_math_negateMat4 = function(m, dest) {
-690     if (!dest) {
-691         dest = m;
-692     }
-693 
-694     dest[0] = -m[0];
-695     dest[1] = -m[1];
-696     dest[2] = -m[2];
-697     dest[3] = -m[3];
-698     dest[4] = -m[4];
-699     dest[5] = -m[5];
-700     dest[6] = -m[6];
-701     dest[7] = -m[7];
-702     dest[8] = -m[8];
-703     dest[9] = -m[9];
-704     dest[10] = -m[10];
-705     dest[11] = -m[11];
-706     dest[12] = -m[12];
-707     dest[13] = -m[13];
-708     dest[14] = -m[14];
-709     dest[15] = -m[15];
-710 
-711     return dest;
-712 };
-713 
-714 /**
-715  * @param a mat4
-716  * @param b mat4
-717  * @param dest mat4 - optional destination
-718  * @return {mat4} dest if specified, a otherwise
-719  * @private
-720  */
-721 var SceneJS_math_addMat4 = function(a, b, dest) {
-722     if (!dest) {
-723         dest = a;
-724     }
-725 
-726     dest[0] = a[0] + b[0];
-727     dest[1] = a[1] + b[1];
-728     dest[2] = a[2] + b[2];
-729     dest[3] = a[3] + b[3];
-730     dest[4] = a[4] + b[4];
-731     dest[5] = a[5] + b[5];
-732     dest[6] = a[6] + b[6];
-733     dest[7] = a[7] + b[7];
-734     dest[8] = a[8] + b[8];
-735     dest[9] = a[9] + b[9];
-736     dest[10] = a[10] + b[10];
-737     dest[11] = a[11] + b[11];
-738     dest[12] = a[12] + b[12];
-739     dest[13] = a[13] + b[13];
-740     dest[14] = a[14] + b[14];
-741     dest[15] = a[15] + b[15];
-742 
-743     return dest;
-744 };
-745 
-746 /**
-747  * @param m mat4
-748  * @param s scalar
-749  * @param dest mat4 - optional destination
-750  * @return {mat4} dest if specified, m otherwise
-751  * @private
-752  */
-753 var SceneJS_math_addMat4Scalar = function(m, s, dest) {
-754     if (!dest) {
-755         dest = m;
-756     }
-757 
-758     dest[0] = m[0] + s;
-759     dest[1] = m[1] + s;
-760     dest[2] = m[2] + s;
-761     dest[3] = m[3] + s;
-762     dest[4] = m[4] + s;
-763     dest[5] = m[5] + s;
-764     dest[6] = m[6] + s;
-765     dest[7] = m[7] + s;
-766     dest[8] = m[8] + s;
-767     dest[9] = m[9] + s;
-768     dest[10] = m[10] + s;
-769     dest[11] = m[11] + s;
-770     dest[12] = m[12] + s;
-771     dest[13] = m[13] + s;
-772     dest[14] = m[14] + s;
-773     dest[15] = m[15] + s;
-774 
-775     return dest;
-776 };
-777 
-778 /** @private */
-779 var SceneJS_math_addScalarMat4 = function(s, m, dest) {
-780     return SceneJS_math_addMat4Scalar(m, s, dest);
-781 };
-782 
-783 /**
-784  * @param a mat4
-785  * @param b mat4
-786  * @param dest mat4 - optional destination
-787  * @return {mat4} dest if specified, a otherwise
-788  * @private
-789  */
-790 var SceneJS_math_subMat4 = function(a, b, dest) {
-791     if (!dest) {
-792         dest = a;
-793     }
-794 
-795     dest[0] = a[0] - b[0];
-796     dest[1] = a[1] - b[1];
-797     dest[2] = a[2] - b[2];
-798     dest[3] = a[3] - b[3];
-799     dest[4] = a[4] - b[4];
-800     dest[5] = a[5] - b[5];
-801     dest[6] = a[6] - b[6];
-802     dest[7] = a[7] - b[7];
-803     dest[8] = a[8] - b[8];
-804     dest[9] = a[9] - b[9];
-805     dest[10] = a[10] - b[10];
-806     dest[11] = a[11] - b[11];
-807     dest[12] = a[12] - b[12];
-808     dest[13] = a[13] - b[13];
-809     dest[14] = a[14] - b[14];
-810     dest[15] = a[15] - b[15];
-811 
-812     return dest;
-813 };
-814 
-815 /**
-816  * @param m mat4
-817  * @param s scalar
-818  * @param dest mat4 - optional destination
-819  * @return {mat4} dest if specified, m otherwise
-820  * @private
-821  */
-822 var SceneJS_math_subMat4Scalar = function(m, s, dest) {
-823     if (!dest) {
-824         dest = m;
-825     }
-826 
-827     dest[0] = m[0] - s;
-828     dest[1] = m[1] - s;
-829     dest[2] = m[2] - s;
-830     dest[3] = m[3] - s;
-831     dest[4] = m[4] - s;
-832     dest[5] = m[5] - s;
-833     dest[6] = m[6] - s;
-834     dest[7] = m[7] - s;
-835     dest[8] = m[8] - s;
-836     dest[9] = m[9] - s;
-837     dest[10] = m[10] - s;
-838     dest[11] = m[11] - s;
-839     dest[12] = m[12] - s;
-840     dest[13] = m[13] - s;
-841     dest[14] = m[14] - s;
-842     dest[15] = m[15] - s;
-843 
-844     return dest;
-845 };
-846 
-847 /**
-848  * @param s scalar
-849  * @param m mat4
-850  * @param dest mat4 - optional destination
-851  * @return {mat4} dest if specified, m otherwise
-852  * @private
-853  */
-854 var SceneJS_math_subScalarMat4 = function(s, m, dest) {
-855     if (!dest) {
-856         dest = m;
-857     }
-858 
-859     dest[0] = s - m[0];
-860     dest[1] = s - m[1];
-861     dest[2] = s - m[2];
-862     dest[3] = s - m[3];
-863     dest[4] = s - m[4];
-864     dest[5] = s - m[5];
-865     dest[6] = s - m[6];
-866     dest[7] = s - m[7];
-867     dest[8] = s - m[8];
-868     dest[9] = s - m[9];
-869     dest[10] = s - m[10];
-870     dest[11] = s - m[11];
-871     dest[12] = s - m[12];
-872     dest[13] = s - m[13];
-873     dest[14] = s - m[14];
-874     dest[15] = s - m[15];
-875 
-876     return dest;
-877 };
-878 
-879 /**
-880  * @param a mat4
-881  * @param b mat4
-882  * @param dest mat4 - optional destination
-883  * @return {mat4} dest if specified, a otherwise
-884  * @private
-885  */
-886 var SceneJS_math_mulMat4 = function(a, b, dest) {
-887     if (!dest) {
-888         dest = a;
-889     }
-890 
-891     // Cache the matrix values (makes for huge speed increases!)
-892     var a00 = a[0], a01 = a[1], a02 = a[2], a03 = a[3];
-893     var a10 = a[4], a11 = a[5], a12 = a[6], a13 = a[7];
-894     var a20 = a[8], a21 = a[9], a22 = a[10], a23 = a[11];
-895     var a30 = a[12], a31 = a[13], a32 = a[14], a33 = a[15];
-896 
-897     var b00 = b[0], b01 = b[1], b02 = b[2], b03 = b[3];
-898     var b10 = b[4], b11 = b[5], b12 = b[6], b13 = b[7];
-899     var b20 = b[8], b21 = b[9], b22 = b[10], b23 = b[11];
-900     var b30 = b[12], b31 = b[13], b32 = b[14], b33 = b[15];
-901 
-902     dest[0] = b00 * a00 + b01 * a10 + b02 * a20 + b03 * a30;
-903     dest[1] = b00 * a01 + b01 * a11 + b02 * a21 + b03 * a31;
-904     dest[2] = b00 * a02 + b01 * a12 + b02 * a22 + b03 * a32;
-905     dest[3] = b00 * a03 + b01 * a13 + b02 * a23 + b03 * a33;
-906     dest[4] = b10 * a00 + b11 * a10 + b12 * a20 + b13 * a30;
-907     dest[5] = b10 * a01 + b11 * a11 + b12 * a21 + b13 * a31;
-908     dest[6] = b10 * a02 + b11 * a12 + b12 * a22 + b13 * a32;
-909     dest[7] = b10 * a03 + b11 * a13 + b12 * a23 + b13 * a33;
-910     dest[8] = b20 * a00 + b21 * a10 + b22 * a20 + b23 * a30;
-911     dest[9] = b20 * a01 + b21 * a11 + b22 * a21 + b23 * a31;
-912     dest[10] = b20 * a02 + b21 * a12 + b22 * a22 + b23 * a32;
-913     dest[11] = b20 * a03 + b21 * a13 + b22 * a23 + b23 * a33;
-914     dest[12] = b30 * a00 + b31 * a10 + b32 * a20 + b33 * a30;
-915     dest[13] = b30 * a01 + b31 * a11 + b32 * a21 + b33 * a31;
-916     dest[14] = b30 * a02 + b31 * a12 + b32 * a22 + b33 * a32;
-917     dest[15] = b30 * a03 + b31 * a13 + b32 * a23 + b33 * a33;
-918 
-919     return dest;
-920 };
-921 
-922 /**
-923  * @param m mat4
-924  * @param s scalar
-925  * @param dest mat4 - optional destination
-926  * @return {mat4} dest if specified, m otherwise
-927  * @private
-928  */
-929 var SceneJS_math_mulMat4s = function(m, s, dest)
-930 {
-931     if (!dest) {
-932         dest = m;
-933     }
-934 
-935     dest[0] = m[0] * s;
-936     dest[1] = m[1] * s;
-937     dest[2] = m[2] * s;
-938     dest[3] = m[3] * s;
-939     dest[4] = m[4] * s;
-940     dest[5] = m[5] * s;
-941     dest[6] = m[6] * s;
-942     dest[7] = m[7] * s;
-943     dest[8] = m[8] * s;
-944     dest[9] = m[9] * s;
-945     dest[10] = m[10] * s;
-946     dest[11] = m[11] * s;
-947     dest[12] = m[12] * s;
-948     dest[13] = m[13] * s;
-949     dest[14] = m[14] * s;
-950     dest[15] = m[15] * s;
-951 
-952     return dest;
-953 };
-954 
-955 /**
-956  * @param m mat4
-957  * @param v vec4
-958  * @return {vec4}
-959  * @private
-960  */
-961 var SceneJS_math_mulMat4v4 = function(m, v) {
-962     var v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
-963 
-964     return [
-965         m[0] * v0 + m[4] * v1 + m[8] * v2 + m[12] * v3,
-966         m[1] * v0 + m[5] * v1 + m[9] * v2 + m[13] * v3,
-967         m[2] * v0 + m[6] * v1 + m[10] * v2 + m[14] * v3,
-968         m[3] * v0 + m[7] * v1 + m[11] * v2 + m[15] * v3
-969     ];
-970 };
-971 
-972 /**
-973  * @param mat mat4
-974  * @param dest mat4 - optional destination
-975  * @return {mat4} dest if specified, mat otherwise
-976  * @private
-977  */
-978 var SceneJS_math_transposeMat4 = function(mat, dest) {
-979     // If we are transposing ourselves we can skip a few steps but have to cache some values
-980     var m4 = mat[4], m14 = mat[14], m8 = mat[8];
-981     var m13 = mat[13], m12 = mat[12], m9 = mat[9];
-982     if (!dest || mat == dest) {
-983         var a01 = mat[1], a02 = mat[2], a03 = mat[3];
-984         var a12 = mat[6], a13 = mat[7];
-985         var a23 = mat[11];
-986 
-987         mat[1] = m4;
-988         mat[2] = m8;
-989         mat[3] = m12;
-990         mat[4] = a01;
-991         mat[6] = m9;
-992         mat[7] = m13;
-993         mat[8] = a02;
-994         mat[9] = a12;
-995         mat[11] = m14;
-996         mat[12] = a03;
-997         mat[13] = a13;
-998         mat[14] = a23;
-999         return mat;
-1000     }
-1001 
-1002     dest[0] = mat[0];
-1003     dest[1] = m4;
-1004     dest[2] = m8;
-1005     dest[3] = m12;
-1006     dest[4] = mat[1];
-1007     dest[5] = mat[5];
-1008     dest[6] = m9;
-1009     dest[7] = m13;
-1010     dest[8] = mat[2];
-1011     dest[9] = mat[6];
-1012     dest[10] = mat[10];
-1013     dest[11] = m14;
-1014     dest[12] = mat[3];
-1015     dest[13] = mat[7];
-1016     dest[14] = mat[11];
-1017     dest[15] = mat[15];
-1018     return dest;
-1019 };
-1020 
-1021 /** @private */
-1022 var SceneJS_math_determinantMat4 = function(mat) {
-1023     // Cache the matrix values (makes for huge speed increases!)
-1024     var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
-1025     var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
-1026     var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
-1027     var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
-1028 
-1029     return a30 * a21 * a12 * a03 - a20 * a31 * a12 * a03 - a30 * a11 * a22 * a03 + a10 * a31 * a22 * a03 +
-1030            a20 * a11 * a32 * a03 - a10 * a21 * a32 * a03 - a30 * a21 * a02 * a13 + a20 * a31 * a02 * a13 +
-1031            a30 * a01 * a22 * a13 - a00 * a31 * a22 * a13 - a20 * a01 * a32 * a13 + a00 * a21 * a32 * a13 +
-1032            a30 * a11 * a02 * a23 - a10 * a31 * a02 * a23 - a30 * a01 * a12 * a23 + a00 * a31 * a12 * a23 +
-1033            a10 * a01 * a32 * a23 - a00 * a11 * a32 * a23 - a20 * a11 * a02 * a33 + a10 * a21 * a02 * a33 +
-1034            a20 * a01 * a12 * a33 - a00 * a21 * a12 * a33 - a10 * a01 * a22 * a33 + a00 * a11 * a22 * a33;
-1035 };
-1036 
-1037 /**
-1038  * @param mat mat4
-1039  * @param dest mat4 - optional destination
-1040  * @return {mat4} dest if specified, mat otherwise
-1041  * @private
-1042  */
-1043 var SceneJS_math_inverseMat4 = function(mat, dest) {
-1044     if (!dest) {
-1045         dest = mat;
-1046     }
-1047 
-1048     // Cache the matrix values (makes for huge speed increases!)
-1049     var a00 = mat[0], a01 = mat[1], a02 = mat[2], a03 = mat[3];
-1050     var a10 = mat[4], a11 = mat[5], a12 = mat[6], a13 = mat[7];
-1051     var a20 = mat[8], a21 = mat[9], a22 = mat[10], a23 = mat[11];
-1052     var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15];
-1053 
-1054     var b00 = a00 * a11 - a01 * a10;
-1055     var b01 = a00 * a12 - a02 * a10;
-1056     var b02 = a00 * a13 - a03 * a10;
-1057     var b03 = a01 * a12 - a02 * a11;
-1058     var b04 = a01 * a13 - a03 * a11;
-1059     var b05 = a02 * a13 - a03 * a12;
-1060     var b06 = a20 * a31 - a21 * a30;
-1061     var b07 = a20 * a32 - a22 * a30;
-1062     var b08 = a20 * a33 - a23 * a30;
-1063     var b09 = a21 * a32 - a22 * a31;
-1064     var b10 = a21 * a33 - a23 * a31;
-1065     var b11 = a22 * a33 - a23 * a32;
-1066 
-1067     // Calculate the determinant (inlined to avoid double-caching)
-1068     var invDet = 1 / (b00 * b11 - b01 * b10 + b02 * b09 + b03 * b08 - b04 * b07 + b05 * b06);
-1069 
-1070     dest[0] = (a11 * b11 - a12 * b10 + a13 * b09) * invDet;
-1071     dest[1] = (-a01 * b11 + a02 * b10 - a03 * b09) * invDet;
-1072     dest[2] = (a31 * b05 - a32 * b04 + a33 * b03) * invDet;
-1073     dest[3] = (-a21 * b05 + a22 * b04 - a23 * b03) * invDet;
-1074     dest[4] = (-a10 * b11 + a12 * b08 - a13 * b07) * invDet;
-1075     dest[5] = (a00 * b11 - a02 * b08 + a03 * b07) * invDet;
-1076     dest[6] = (-a30 * b05 + a32 * b02 - a33 * b01) * invDet;
-1077     dest[7] = (a20 * b05 - a22 * b02 + a23 * b01) * invDet;
-1078     dest[8] = (a10 * b10 - a11 * b08 + a13 * b06) * invDet;
-1079     dest[9] = (-a00 * b10 + a01 * b08 - a03 * b06) * invDet;
-1080     dest[10] = (a30 * b04 - a31 * b02 + a33 * b00) * invDet;
-1081     dest[11] = (-a20 * b04 + a21 * b02 - a23 * b00) * invDet;
-1082     dest[12] = (-a10 * b09 + a11 * b07 - a12 * b06) * invDet;
-1083     dest[13] = (a00 * b09 - a01 * b07 + a02 * b06) * invDet;
-1084     dest[14] = (-a30 * b03 + a31 * b01 - a32 * b00) * invDet;
-1085     dest[15] = (a20 * b03 - a21 * b01 + a22 * b00) * invDet;
-1086 
-1087     return dest;
-1088 };
-1089 
-1090 /** @private */
-1091 var SceneJS_math_traceMat4 = function(m) {
-1092     return (m[0] + m[5] + m[10] + m[15]);
-1093 };
-1094 
-1095 /** @private */
-1096 var SceneJS_math_translationMat4v = function(v) {
-1097     var m = SceneJS_math_identityMat4();
-1098     m[12] = v[0];
-1099     m[13] = v[1];
-1100     m[14] = v[2];
-1101     return m;
-1102 };
-1103 
-1104 /** @private */
-1105 var SceneJS_math_translationMat4c = function(x, y, z) {
-1106     return SceneJS_math_translationMat4v([x,y,z]);
-1107 };
-1108 
-1109 /** @private */
-1110 var SceneJS_math_translationMat4s = function(s) {
-1111     return SceneJS_math_translationMat4c(s, s, s);
-1112 };
-1113 
-1114 /** @private */
-1115 var SceneJS_math_rotationMat4v = function(anglerad, axis) {
-1116     var ax = SceneJS_math_normalizeVec4([axis[0],axis[1],axis[2],0.0]);
-1117     var s = Math.sin(anglerad);
-1118     var c = Math.cos(anglerad);
-1119     var q = 1.0 - c;
-1120 
-1121     var x = ax[0];
-1122     var y = ax[1];
-1123     var z = ax[2];
-1124 
-1125     var xy,yz,zx,xs,ys,zs;
-1126 
-1127     //xx = x * x; used once
-1128     //yy = y * y; used once
-1129     //zz = z * z; used once
-1130     xy = x * y;
-1131     yz = y * z;
-1132     zx = z * x;
-1133     xs = x * s;
-1134     ys = y * s;
-1135     zs = z * s;
-1136 
-1137     var m = SceneJS_math_mat4();
-1138 
-1139     m[0] = (q * x * x) + c;
-1140     m[1] = (q * xy) + zs;
-1141     m[2] = (q * zx) - ys;
-1142     m[3] = 0.0;
-1143 
-1144     m[4] = (q * xy) - zs;
-1145     m[5] = (q * y * y) + c;
-1146     m[6] = (q * yz) + xs;
-1147     m[7] = 0.0;
-1148 
-1149     m[8] = (q * zx) + ys;
-1150     m[9] = (q * yz) - xs;
-1151     m[10] = (q * z * z) + c;
-1152     m[11] = 0.0;
-1153 
-1154     m[12] = 0.0;
-1155     m[13] = 0.0;
-1156     m[14] = 0.0;
-1157     m[15] = 1.0;
-1158 
-1159     return m;
-1160 };
-1161 
-1162 /** @private */
-1163 var SceneJS_math_rotationMat4c = function(anglerad, x, y, z) {
-1164     return SceneJS_math_rotationMat4v(anglerad, [x,y,z]);
-1165 };
-1166 
-1167 /** @private */
-1168 var SceneJS_math_scalingMat4v = function(v) {
-1169     var m = SceneJS_math_identityMat4();
-1170     m[0] = v[0];
-1171     m[5] = v[1];
-1172     m[10] = v[2];
-1173     return m;
-1174 };
-1175 
-1176 /** @private */
-1177 var SceneJS_math_scalingMat4c = function(x, y, z) {
-1178     return SceneJS_math_scalingMat4v([x,y,z]);
-1179 };
-1180 
-1181 /** @private */
-1182 var SceneJS_math_scalingMat4s = function(s) {
-1183     return SceneJS_math_scalingMat4c(s, s, s);
-1184 };
-1185 
-1186 /**
-1187  * Default lookat properties - eye at 0,0,1, looking at 0,0,0, up vector pointing up Y-axis
-1188  */
-1189 var SceneJS_math_LOOKAT_OBJ = {
-1190     eye:    {x: 0, y:0, z:1.0 },
-1191     look:   {x:0, y:0, z:0.0 },
-1192     up:     {x:0, y:1, z:0.0 }
-1193 };
-1194 
-1195 /**
-1196  * Default lookat properties in array form - eye at 0,0,1, looking at 0,0,0, up vector pointing up Y-axis
-1197  */
-1198 var SceneJS_math_LOOKAT_ARRAYS = {
-1199     eye:    [0, 0, 1.0],
-1200     look:   [0, 0, 0.0 ],
-1201     up:     [0, 1, 0.0 ]
-1202 };
-1203 
-1204 /**
-1205  * Default orthographic projection properties
-1206  */
-1207 var SceneJS_math_ORTHO_OBJ = {
-1208     left: -1.0,
-1209     right: 1.0,
-1210     bottom: -1.0,
-1211     near: 0.1,
-1212     top: 1.0,
-1213     far: 5000.0
-1214 };
-1215 
-1216 /**
-1217  * @param pos vec3 position of the viewer
-1218  * @param target vec3 point the viewer is looking at
-1219  * @param up vec3 pointing "up"
-1220  * @param dest mat4 Optional, mat4 frustum matrix will be written into
-1221  *
-1222  * @return {mat4} dest if specified, a new mat4 otherwise
-1223  */
-1224 var SceneJS_math_lookAtMat4v = function(pos, target, up, dest) {
-1225     if (!dest) {
-1226         dest = SceneJS_math_mat4();
-1227     }
-1228 
-1229     var posx = pos[0],
-1230             posy = pos[1],
-1231             posz = pos[2],
-1232             upx = up[0],
-1233             upy = up[1],
-1234             upz = up[2],
-1235             targetx = target[0],
-1236             targety = target[1],
-1237             targetz = target[2];
-1238 
-1239     if (posx == targetx && posy == targety && posz == targetz) {
-1240         return SceneJS_math_identityMat4();
-1241     }
-1242 
-1243     var z0,z1,z2,x0,x1,x2,y0,y1,y2,len;
-1244 
-1245     //vec3.direction(eye, center, z);
-1246     z0 = posx - targetx;
-1247     z1 = posy - targety;
-1248     z2 = posz - targetz;
-1249 
-1250     // normalize (no check needed for 0 because of early return)
-1251     len = 1 / Math.sqrt(z0 * z0 + z1 * z1 + z2 * z2);
-1252     z0 *= len;
-1253     z1 *= len;
-1254     z2 *= len;
-1255 
-1256     //vec3.normalize(vec3.cross(up, z, x));
-1257     x0 = upy * z2 - upz * z1;
-1258     x1 = upz * z0 - upx * z2;
-1259     x2 = upx * z1 - upy * z0;
-1260     len = Math.sqrt(x0 * x0 + x1 * x1 + x2 * x2);
-1261     if (!len) {
-1262         x0 = 0;
-1263         x1 = 0;
-1264         x2 = 0;
-1265     } else {
-1266         len = 1 / len;
-1267         x0 *= len;
-1268         x1 *= len;
-1269         x2 *= len;
-1270     }
-1271 
-1272     //vec3.normalize(vec3.cross(z, x, y));
-1273     y0 = z1 * x2 - z2 * x1;
-1274     y1 = z2 * x0 - z0 * x2;
-1275     y2 = z0 * x1 - z1 * x0;
-1276 
-1277     len = Math.sqrt(y0 * y0 + y1 * y1 + y2 * y2);
-1278     if (!len) {
-1279         y0 = 0;
-1280         y1 = 0;
-1281         y2 = 0;
-1282     } else {
-1283         len = 1 / len;
-1284         y0 *= len;
-1285         y1 *= len;
-1286         y2 *= len;
-1287     }
-1288 
-1289     dest[0] = x0;
-1290     dest[1] = y0;
-1291     dest[2] = z0;
-1292     dest[3] = 0;
-1293     dest[4] = x1;
-1294     dest[5] = y1;
-1295     dest[6] = z1;
-1296     dest[7] = 0;
-1297     dest[8] = x2;
-1298     dest[9] = y2;
-1299     dest[10] = z2;
-1300     dest[11] = 0;
-1301     dest[12] = -(x0 * posx + x1 * posy + x2 * posz);
-1302     dest[13] = -(y0 * posx + y1 * posy + y2 * posz);
-1303     dest[14] = -(z0 * posx + z1 * posy + z2 * posz);
-1304     dest[15] = 1;
-1305 
-1306     return dest;
-1307 };
-1308 
-1309 /** @private */
-1310 var SceneJS_math_lookAtMat4c = function(posx, posy, posz, targetx, targety, targetz, upx, upy, upz) {
-1311     return SceneJS_math_lookAtMat4v([posx,posy,posz], [targetx,targety,targetz], [upx,upy,upz]);
-1312 };
-1313 
-1314 /** @private */
-1315 var SceneJS_math_orthoMat4c = function(left, right, bottom, top, near, far, dest) {
-1316     if (!dest) {
-1317         dest = SceneJS_math_mat4();
-1318     }
-1319     var rl = (right - left);
-1320     var tb = (top - bottom);
-1321     var fn = (far - near);
-1322 
-1323     dest[0] = 2.0 / rl;
-1324     dest[1] = 0.0;
-1325     dest[2] = 0.0;
-1326     dest[3] = 0.0;
-1327 
-1328     dest[4] = 0.0;
-1329     dest[5] = 2.0 / tb;
-1330     dest[6] = 0.0;
-1331     dest[7] = 0.0;
-1332 
-1333     dest[8] = 0.0;
-1334     dest[9] = 0.0;
-1335     dest[10] = -2.0 / fn;
-1336     dest[11] = 0.0;
-1337 
-1338     dest[12] = -(left + right) / rl;
-1339     dest[13] = -(top + bottom) / tb;
-1340     dest[14] = -(far + near) / fn;
-1341     dest[15] = 1.0;
-1342 
-1343     return dest;
-1344 };
-1345 
-1346 /** @private */
-1347 var SceneJS_math_frustumMat4v = function(fmin, fmax) {
-1348     var fmin4 = [fmin[0],fmin[1],fmin[2],0.0];
-1349     var fmax4 = [fmax[0],fmax[1],fmax[2],0.0];
-1350     var vsum = SceneJS_math_mat4();
-1351     SceneJS_math_addVec4(fmax4, fmin4, vsum);
-1352     var vdif = SceneJS_math_mat4();
-1353     SceneJS_math_subVec4(fmax4, fmin4, vdif);
-1354     var t = 2.0 * fmin4[2];
-1355 
-1356     var m = SceneJS_math_mat4();
-1357     var vdif0 = vdif[0], vdif1 = vdif[1], vdif2 = vdif[2];
-1358 
-1359     m[0] = t / vdif0;
-1360     m[1] = 0.0;
-1361     m[2] = 0.0;
-1362     m[3] = 0.0;
-1363 
-1364     m[4] = 0.0;
-1365     m[5] = t / vdif1;
-1366     m[6] = 0.0;
-1367     m[7] = 0.0;
-1368 
-1369     m[8] = vsum[0] / vdif0;
-1370     m[9] = vsum[1] / vdif1;
-1371     m[10] = -vsum[2] / vdif2;
-1372     m[11] = -1.0;
-1373 
-1374     m[12] = 0.0;
-1375     m[13] = 0.0;
-1376     m[14] = -t * fmax4[2] / vdif2;
-1377     m[15] = 0.0;
-1378 
-1379     return m;
-1380 };
-1381 
-1382 /** @private */
-1383 var SceneJS_math_frustumMatrix4 = function(left, right, bottom, top, near, far, dest) {
-1384     if (!dest) {
-1385         dest = SceneJS_math_mat4();
-1386     }
-1387     var rl = (right - left);
-1388     var tb = (top - bottom);
-1389     var fn = (far - near);
-1390     dest[0] = (near * 2) / rl;
-1391     dest[1] = 0;
-1392     dest[2] = 0;
-1393     dest[3] = 0;
-1394     dest[4] = 0;
-1395     dest[5] = (near * 2) / tb;
-1396     dest[6] = 0;
-1397     dest[7] = 0;
-1398     dest[8] = (right + left) / rl;
-1399     dest[9] = (top + bottom) / tb;
-1400     dest[10] = -(far + near) / fn;
-1401     dest[11] = -1;
-1402     dest[12] = 0;
-1403     dest[13] = 0;
-1404     dest[14] = -(far * near * 2) / fn;
-1405     dest[15] = 0;
-1406     return dest;
-1407 };
-1408 
-1409 
-1410 /** @private */
-1411 var SceneJS_math_perspectiveMatrix4 = function(fovyrad, aspectratio, znear, zfar) {
-1412     var pmin = [];
-1413     var pmax = [];
-1414 
-1415     pmin[2] = znear;
-1416     pmax[2] = zfar;
-1417 
-1418     pmax[1] = pmin[2] * Math.tan(fovyrad / 2.0);
-1419     pmin[1] = -pmax[1];
-1420 
-1421     pmax[0] = pmax[1] * aspectratio;
-1422     pmin[0] = -pmax[0];
-1423 
-1424     return SceneJS_math_frustumMat4v(pmin, pmax);
-1425 };
-1426 
-1427 /** @private */
-1428 var SceneJS_math_transformPoint3 = function(m, p) {
-1429     var p0 = p[0], p1 = p[1], p2 = p[2];
-1430     return [
-1431         (m[0] * p0) + (m[4] * p1) + (m[8] * p2) + m[12],
-1432         (m[1] * p0) + (m[5] * p1) + (m[9] * p2) + m[13],
-1433         (m[2] * p0) + (m[6] * p1) + (m[10] * p2) + m[14],
-1434         (m[3] * p0) + (m[7] * p1) + (m[11] * p2) + m[15]
-1435     ];
-1436 };
-1437 
-1438 
-1439 /** @private */
-1440 var SceneJS_math_transformPoints3 = function(m, points) {
-1441     var result = new Array(points.length);
-1442     var len = points.length;
-1443     var p0, p1, p2;
-1444     var pi;
-1445 
-1446     // cache values
-1447     var m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3];
-1448     var m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7];
-1449     var m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11];
-1450     var m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15];
-1451 
-1452     for (var i = 0; i < len; ++i) {
-1453         // cache values
-1454         pi = points[i];
-1455         p0 = pi[0];
-1456         p1 = pi[1];
-1457         p2 = pi[2];
-1458 
-1459         result[i] = [
-1460             (m0 * p0) + (m4 * p1) + (m8 * p2) + m12,
-1461             (m1 * p0) + (m5 * p1) + (m9 * p2) + m13,
-1462             (m2 * p0) + (m6 * p1) + (m10 * p2) + m14,
-1463             (m3 * p0) + (m7 * p1) + (m11 * p2) + m15
-1464         ];
-1465     }
-1466 
-1467     return result;
-1468 };
-1469 
-1470 /** @private */
-1471 var SceneJS_math_transformVector3 = function(m, v) {
-1472     var v0 = v[0], v1 = v[1], v2 = v[2];
-1473     return [
-1474         (m[0] * v0) + (m[4] * v1) + (m[8] * v2),
-1475         (m[1] * v0) + (m[5] * v1) + (m[9] * v2),
-1476         (m[2] * v0) + (m[6] * v1) + (m[10] * v2)
-1477     ];
-1478 };
-1479 
-1480 var SceneJS_math_transformVector4 = function(m, v) {
-1481     var v0 = v[0], v1 = v[1], v2 = v[2], v3 = v[3];
-1482     return [
-1483         m[ 0] * v0 + m[ 4] * v1 + m[ 8] * v2 + m[12] * v3,
-1484         m[ 1] * v0 + m[ 5] * v1 + m[ 9] * v2 + m[13] * v3,
-1485         m[ 2] * v0 + m[ 6] * v1 + m[10] * v2 + m[14] * v3,
-1486         m[ 3] * v0 + m[ 7] * v1 + m[11] * v2 + m[15] * v3
-1487     ];
-1488 };
-1489 
-1490 /** @private */
-1491 var SceneJS_math_projectVec4 = function(v) {
-1492     var f = 1.0 / v[3];
-1493     return [v[0] * f, v[1] * f, v[2] * f, 1.0];
-1494 };
-1495 
-1496 
-1497 /** @private */
-1498 var SceneJS_math_Plane3 = function (normal, offset, normalize) {
-1499     this.normal = [0.0, 0.0, 1.0 ];
-1500 
-1501     this.offset = 0.0;
-1502     if (normal && offset) {
-1503         var normal0 = normal[0], normal1 = normal[1], normal2 = normal[2];
-1504         this.offset = offset;
-1505 
-1506         if (normalize) {
-1507             var s = Math.sqrt(
-1508                     normal0 * normal0 +
-1509                     normal1 * normal1 +
-1510                     normal2 * normal2
-1511                     );
-1512             if (s > 0.0) {
-1513                 s = 1.0 / s;
-1514                 this.normal[0] = normal0 * s;
-1515                 this.normal[1] = normal1 * s;
-1516                 this.normal[2] = normal2 * s;
-1517                 this.offset *= s;
-1518             }
-1519         }
-1520     }
-1521 };
-1522 
-1523 /** @private */
-1524 var SceneJS_math_MAX_DOUBLE = Number.POSITIVE_INFINITY;
-1525 /** @private */
-1526 var SceneJS_math_MIN_DOUBLE = Number.NEGATIVE_INFINITY;
-1527 
-1528 /** @private
-1529  *
-1530  */
-1531 var SceneJS_math_Box3 = function(min, max) {
-1532     this.min = min || [ SceneJS_math_MAX_DOUBLE,SceneJS_math_MAX_DOUBLE,SceneJS_math_MAX_DOUBLE ];
-1533     this.max = max || [ SceneJS_math_MIN_DOUBLE,SceneJS_math_MIN_DOUBLE,SceneJS_math_MIN_DOUBLE ];
-1534 
-1535     /** @private */
-1536     this.init = function(min, max) {
-1537         this.min[0] = min[0];
-1538         this.min[1] = min[1];
-1539         this.min[2] = min[2];
-1540         this.max[0] = max[0];
-1541         this.max[1] = max[1];
-1542         this.max[2] = max[2];
-1543         return this;
-1544     };
-1545 
-1546     /** @private */
-1547     this.fromPoints = function(points) {
-1548         var pointsLength = points.length;
-1549 
-1550         for (var i = 0; i < pointsLength; ++i) {
-1551             var points_i3 = points[i][3];
-1552             var pDiv0 = points[i][0] / points_i3;
-1553             var pDiv1 = points[i][1] / points_i3;
-1554             var pDiv2 = points[i][2] / points_i3;
-1555 
-1556             if (pDiv0 < this.min[0]) {
-1557                 this.min[0] = pDiv0;
-1558             }
-1559             if (pDiv1 < this.min[1]) {
-1560                 this.min[1] = pDiv1;
-1561             }
-1562             if (pDiv2 < this.min[2]) {
-1563                 this.min[2] = pDiv2;
-1564             }
-1565 
-1566             if (pDiv0 > this.max[0]) {
-1567                 this.max[0] = pDiv0;
-1568             }
-1569             if (pDiv1 > this.max[1]) {
-1570                 this.max[1] = pDiv1;
-1571             }
-1572             if (pDiv2 > this.max[2]) {
-1573                 this.max[2] = pDiv2;
-1574             }
-1575         }
-1576         return this;
-1577     };
-1578 
-1579     /** @private */
-1580     this.isEmpty = function() {
-1581         return (
-1582                 (this.min[0] >= this.max[0]) &&
-1583                 (this.min[1] >= this.max[1]) &&
-1584                 (this.min[2] >= this.max[2])
-1585                 );
-1586     };
-1587 
-1588     /** @private */
-1589     this.getCenter = function() {
-1590         return [
-1591             (this.max[0] + this.min[0]) / 2.0,
-1592             (this.max[1] + this.min[1]) / 2.0,
-1593             (this.max[2] + this.min[2]) / 2.0
-1594         ];
-1595     };
-1596 
-1597     /** @private */
-1598     this.getSize = function() {
-1599         return [
-1600             (this.max[0] - this.min[0]),
-1601             (this.max[1] - this.min[1]),
-1602             (this.max[2] - this.min[2])
-1603         ];
-1604     };
-1605 
-1606     /** @private */
-1607     this.getFacesAreas = function() {
-1608         var s = this.size;
-1609         return [
-1610             (s[1] * s[2]),
-1611             (s[0] * s[2]),
-1612             (s[0] * s[1])
-1613         ];
-1614     };
-1615 
-1616     /** @private */
-1617     this.getSurfaceArea = function() {
-1618         var a = this.getFacesAreas();
-1619         return ((a[0] + a[1] + a[2]) * 2.0);
-1620     };
-1621 
-1622     /** @private */
-1623     this.getVolume = function() {
-1624         var s = this.size;
-1625         return (s[0] * s[1] * s[2]);
-1626     };
-1627 
-1628     /** @private */
-1629     this.getOffset = function(half_delta) {
-1630         this.min[0] -= half_delta;
-1631         this.min[1] -= half_delta;
-1632         this.min[2] -= half_delta;
-1633         this.max[0] += half_delta;
-1634         this.max[1] += half_delta;
-1635         this.max[2] += half_delta;
-1636         return this;
-1637     };
-1638 };
-1639 
-1640 /** @private
-1641  *
-1642  * @param min
-1643  * @param max
-1644  */
-1645 var SceneJS_math_AxisBox3 = function(min, max) {
-1646     var min0 = min[0], min1 = min[1], min2 = min[2];
-1647     var max0 = max[0], max1 = max[1], max2 = max[2];
-1648 
-1649     this.verts = [
-1650         [min0, min1, min2],
-1651         [max0, min1, min2],
-1652         [max0, max1, min2],
-1653         [min0, max1, min2],
-1654 
-1655         [min0, min1, max2],
-1656         [max0, min1, max2],
-1657         [max0, max1, max2],
-1658         [min0, max1, max2]
-1659     ];
-1660 
-1661     /** @private */
-1662     this.toBox3 = function() {
-1663         var box = new SceneJS_math_Box3();
-1664         for (var i = 0; i < 8; ++i) {
-1665             var v = this.verts[i];
-1666             for (var j = 0; j < 3; ++j) {
-1667                 if (v[j] < box.min[j]) {
-1668                     box.min[j] = v[j];
-1669                 }
-1670                 if (v[j] > box.max[j]) {
-1671                     box.max[j] = v[j];
-1672                 }
-1673             }
-1674         }
-1675     };
-1676 };
-1677 
-1678 /** @private
-1679  *
-1680  * @param center
-1681  * @param radius
-1682  */
-1683 var SceneJS_math_Sphere3 = function(center, radius) {
-1684     this.center = [center[0], center[1], center[2] ];
-1685     this.radius = radius;
-1686 
-1687     /** @private */
-1688     this.isEmpty = function() {
-1689         return (this.radius === 0.0);
-1690     };
-1691 
-1692     /** @private */
-1693     this.surfaceArea = function() {
-1694         return (4.0 * Math.PI * this.radius * this.radius);
-1695     };
-1696 
-1697     /** @private */
-1698     this.getVolume = function() {
-1699         var thisRadius = this.radius;
-1700         return ((4.0 / 3.0) * Math.PI * thisRadius * thisRadius * thisRadius);
-1701     };
-1702 };
-1703 
-1704 /** Creates billboard matrix from given view matrix
-1705  * @private
-1706  */
-1707 var SceneJS_math_billboardMat = function(viewMatrix) {
-1708     var rotVec = [
-1709         SceneJS_math_getColMat4(viewMatrix, 0),
-1710         SceneJS_math_getColMat4(viewMatrix, 1),
-1711         SceneJS_math_getColMat4(viewMatrix, 2)
-1712     ];
-1713 
-1714     var scaleVec = [
-1715         SceneJS_math_lenVec4(rotVec[0]),
-1716         SceneJS_math_lenVec4(rotVec[1]),
-1717         SceneJS_math_lenVec4(rotVec[2])
-1718     ];
-1719 
-1720     var scaleVecRcp = SceneJS_math_mat4();
-1721     SceneJS_math_rcpVec3(scaleVec, scaleVecRcp);
-1722     var sMat = SceneJS_math_scalingMat4v(scaleVec);
-1723     //var sMatInv = SceneJS_math_scalingMat4v(scaleVecRcp);
-1724 
-1725     SceneJS_math_mulVec4Scalar(rotVec[0], scaleVecRcp[0]);
-1726     SceneJS_math_mulVec4Scalar(rotVec[1], scaleVecRcp[1]);
-1727     SceneJS_math_mulVec4Scalar(rotVec[2], scaleVecRcp[2]);
-1728 
-1729     var rotMatInverse = SceneJS_math_identityMat4();
-1730 
-1731     SceneJS_math_setRowMat4(rotMatInverse, 0, rotVec[0]);
-1732     SceneJS_math_setRowMat4(rotMatInverse, 1, rotVec[1]);
-1733     SceneJS_math_setRowMat4(rotMatInverse, 2, rotVec[2]);
-1734 
-1735     //return rotMatInverse;
-1736     //return SceneJS_math_mulMat4(sMatInv, SceneJS_math_mulMat4(rotMatInverse, sMat));
-1737     return SceneJS_math_mulMat4(rotMatInverse, sMat);
-1738     // return SceneJS_math_mulMat4(sMat, SceneJS_math_mulMat4(rotMatInverse, sMat));
-1739     //return SceneJS_math_mulMat4(sMatInv, SceneJS_math_mulMat4(rotMatInverse, sMat));
-1740 };
-1741 
-1742 /** @private */
-1743 var SceneJS_math_FrustumPlane = function(nx, ny, nz, offset) {
-1744     var s = 1.0 / Math.sqrt(nx * nx + ny * ny + nz * nz);
-1745     this.normal = [nx * s, ny * s, nz * s];
-1746     this.offset = offset * s;
-1747     this.testVertex = [
-1748         (this.normal[0] >= 0.0) ? (1) : (0),
-1749         (this.normal[1] >= 0.0) ? (1) : (0),
-1750         (this.normal[2] >= 0.0) ? (1) : (0)];
-1751 };
-1752 
-1753 /** @private */
-1754 var SceneJS_math_OUTSIDE_FRUSTUM = 3;
-1755 /** @private */
-1756 var SceneJS_math_INTERSECT_FRUSTUM = 4;
-1757 /** @private */
-1758 var SceneJS_math_INSIDE_FRUSTUM = 5;
-1759 
-1760 /** @private */
-1761 var SceneJS_math_Frustum = function(viewMatrix, projectionMatrix, viewport) {
-1762     var m = SceneJS_math_mat4();
-1763     SceneJS_math_mulMat4(projectionMatrix, viewMatrix, m);
-1764 
-1765     // cache m indexes
-1766     var m0 = m[0], m1 = m[1], m2 = m[2], m3 = m[3];
-1767     var m4 = m[4], m5 = m[5], m6 = m[6], m7 = m[7];
-1768     var m8 = m[8], m9 = m[9], m10 = m[10], m11 = m[11];
-1769     var m12 = m[12], m13 = m[13], m14 = m[14], m15 = m[15];
-1770 
-1771     //var q = [ m[3], m[7], m[11] ]; just reuse m indexes instead of making new var
-1772     var planes = [
-1773         new SceneJS_math_FrustumPlane(m3 - m0, m7 - m4, m11 - m8, m15 - m12),
-1774         new SceneJS_math_FrustumPlane(m3 + m0, m7 + m4, m11 + m8, m15 + m12),
-1775         new SceneJS_math_FrustumPlane(m3 - m1, m7 - m5, m11 - m9, m15 - m13),
-1776         new SceneJS_math_FrustumPlane(m3 + m1, m7 + m5, m11 + m9, m15 + m13),
-1777         new SceneJS_math_FrustumPlane(m3 - m2, m7 - m6, m11 - m10, m15 - m14),
-1778         new SceneJS_math_FrustumPlane(m3 + m2, m7 + m6, m11 + m10, m15 + m14)
-1779     ];
-1780 
-1781     /* Resources for LOD
-1782      */
-1783     var rotVec = [
-1784         SceneJS_math_getColMat4(viewMatrix, 0),
-1785         SceneJS_math_getColMat4(viewMatrix, 1),
-1786         SceneJS_math_getColMat4(viewMatrix, 2)
-1787     ];
-1788 
-1789     var scaleVec = [
-1790         SceneJS_math_lenVec4(rotVec[0]),
-1791         SceneJS_math_lenVec4(rotVec[1]),
-1792         SceneJS_math_lenVec4(rotVec[2])
-1793     ];
-1794 
-1795     var scaleVecRcp = SceneJS_math_rcpVec3(scaleVec);
-1796     var sMat = SceneJS_math_scalingMat4v(scaleVec);
-1797     var sMatInv = SceneJS_math_scalingMat4v(scaleVecRcp);
-1798 
-1799     SceneJS_math_mulVec4Scalar(rotVec[0], scaleVecRcp[0]);
-1800     SceneJS_math_mulVec4Scalar(rotVec[1], scaleVecRcp[1]);
-1801     SceneJS_math_mulVec4Scalar(rotVec[2], scaleVecRcp[2]);
-1802 
-1803     var rotMatInverse = SceneJS_math_identityMat4();
-1804 
-1805     SceneJS_math_setRowMat4(rotMatInverse, 0, rotVec[0]);
-1806     SceneJS_math_setRowMat4(rotMatInverse, 1, rotVec[1]);
-1807     SceneJS_math_setRowMat4(rotMatInverse, 2, rotVec[2]);
-1808 
-1809     if (!this.matrix) {
-1810         this.matrix = SceneJS_math_mat4();
-1811     }
-1812     SceneJS_math_mulMat4(projectionMatrix, viewMatrix, this.matrix);
-1813     if (!this.billboardMatrix) {
-1814         this.billboardMatrix = SceneJS_math_mat4();
-1815     }
-1816     SceneJS_math_mulMat4(sMatInv, SceneJS_math_mulMat4(rotMatInverse, sMat), this.billboardMatrix);
-1817     this.viewport = viewport.slice(0, 4);
-1818 
-1819     /** @private */
-1820     this.textAxisBoxIntersection = function(box) {
-1821         var ret = SceneJS_math_INSIDE_FRUSTUM;
-1822         var bminmax = [ box.min, box.max ];
-1823         var plane = null;
-1824 
-1825         for (var i = 0; i < 6; ++i) {
-1826             plane = planes[i];
-1827             if (((plane.normal[0] * bminmax[plane.testVertex[0]][0]) +
-1828                  (plane.normal[1] * bminmax[plane.testVertex[1]][1]) +
-1829                  (plane.normal[2] * bminmax[plane.testVertex[2]][2]) +
-1830                  (plane.offset)) < 0.0) {
-1831                 return SceneJS_math_OUTSIDE_FRUSTUM;
-1832             }
-1833             if (((plane.normal[0] * bminmax[1 - plane.testVertex[0]][0]) +
-1834                  (plane.normal[1] * bminmax[1 - plane.testVertex[1]][1]) +
-1835                  (plane.normal[2] * bminmax[1 - plane.testVertex[2]][2]) +
-1836                  (plane.offset)) < 0.0) {
-1837                 ret = SceneJS_math_INTERSECT_FRUSTUM;
-1838             }
-1839         }
-1840         return ret;
-1841     };
-1842 
-1843     /** @private */
-1844     this.getProjectedSize = function(box) {
-1845         var diagVec = SceneJS_math_mat4();
-1846         SceneJS_math_subVec3(box.max, box.min, diagVec);
-1847 
-1848         var diagSize = SceneJS_math_lenVec3(diagVec);
-1849 
-1850         var size = Math.abs(diagSize);
-1851 
-1852         var p0 = [
-1853             (box.min[0] + box.max[0]) * 0.5,
-1854             (box.min[1] + box.max[1]) * 0.5,
-1855             (box.min[2] + box.max[2]) * 0.5,
-1856             0.0];
-1857 
-1858         var halfSize = size * 0.5;
-1859         var p1 = [ -halfSize, 0.0, 0.0, 1.0 ];
-1860         var p2 = [  halfSize, 0.0, 0.0, 1.0 ];
-1861 
-1862         p1 = SceneJS_math_mulMat4v4(this.billboardMatrix, p1);
-1863         p1 = SceneJS_math_addVec4(p1, p0);
-1864         p1 = SceneJS_math_projectVec4(SceneJS_math_mulMat4v4(this.matrix, p1));
-1865 
-1866         p2 = SceneJS_math_mulMat4v4(this.billboardMatrix, p2);
-1867         p2 = SceneJS_math_addVec4(p2, p0);
-1868         p2 = SceneJS_math_projectVec4(SceneJS_math_mulMat4v4(this.matrix, p2));
-1869 
-1870         return viewport[2] * Math.abs(p2[0] - p1[0]);
-1871     };
-1872 
-1873 
-1874     this.getProjectedState = function(modelCoords) {
-1875         var viewCoords = SceneJS_math_transformPoints3(this.matrix, modelCoords);
-1876 
-1877         //var canvasBox = {
-1878         //    min: [10000000, 10000000 ],
-1879         //    max: [-10000000, -10000000]
-1880         //};
-1881         // separate variables instead of indexing an array
-1882         var canvasBoxMin0 = 10000000, canvasBoxMin1 = 10000000;
-1883         var canvasBoxMax0 = -10000000, canvasBoxMax1 = -10000000;
-1884 
-1885         var v, x, y;
-1886 
-1887         var arrLen = viewCoords.length;
-1888         for (var i = 0; i < arrLen; ++i) {
-1889             v = SceneJS_math_projectVec4(viewCoords[i]);
-1890             x = v[0];
-1891             y = v[1];
-1892 
-1893             if (x < -0.5) {
-1894                 x = -0.5;
-1895             }
-1896 
-1897             if (y < -0.5) {
-1898                 y = -0.5;
-1899             }
-1900 
-1901             if (x > 0.5) {
-1902                 x = 0.5;
-1903             }
-1904 
-1905             if (y > 0.5) {
-1906                 y = 0.5;
-1907             }
-1908 
-1909 
-1910             if (x < canvasBoxMin0) {
-1911                 canvasBoxMin0 = x;
-1912             }
-1913             if (y < canvasBoxMin1) {
-1914                 canvasBoxMin1 = y;
-1915             }
-1916 
-1917             if (x > canvasBoxMax0) {
-1918                 canvasBoxMax0 = x;
-1919             }
-1920             if (y > canvasBoxMax1) {
-1921                 canvasBoxMax1 = y;
-1922             }
-1923         }
-1924 
-1925         canvasBoxMin0 += 0.5;
-1926         canvasBoxMin1 += 0.5;
-1927         canvasBoxMax0 += 0.5;
-1928         canvasBoxMax1 += 0.5;
-1929 
-1930         // cache viewport indexes
-1931         var viewport2 = viewport[2], viewport3 = viewport[3];
-1932 
-1933         canvasBoxMin0 = (canvasBoxMin0 * (viewport2 + 15));
-1934         canvasBoxMin1 = (canvasBoxMin1 * (viewport3 + 15));
-1935         canvasBoxMax0 = (canvasBoxMax0 * (viewport2 + 15));
-1936         canvasBoxMax1 = (canvasBoxMax1 * (viewport3 + 15));
-1937 
-1938         var diagCanvasBoxVec = SceneJS_math_mat4();
-1939         SceneJS_math_subVec2([canvasBoxMax0, canvasBoxMax1],
-1940                 [canvasBoxMin0, canvasBoxMin1],
-1941                 diagCanvasBoxVec);
-1942         var diagCanvasBoxSize = SceneJS_math_lenVec2(diagCanvasBoxVec);
-1943 
-1944         if (canvasBoxMin0 < 0) {
-1945             canvasBoxMin0 = 0;
-1946         }
-1947         if (canvasBoxMax0 > viewport2) {
-1948             canvasBoxMax0 = viewport2;
-1949         }
-1950 
-1951         if (canvasBoxMin1 < 0) {
-1952             canvasBoxMin1 = 0;
-1953         }
-1954         if (canvasBoxMax1 > viewport3) {
-1955             canvasBoxMax1 = viewport3;
-1956         }
-1957         return {
-1958             canvasBox:  {
-1959                 min: [canvasBoxMin0, canvasBoxMin1 ],
-1960                 max: [canvasBoxMax0, canvasBoxMax1 ]
-1961             },
-1962             canvasSize: diagCanvasBoxSize
-1963         };
-1964     };
-1965 };
-1966 
-1967 var SceneJS_math_identityQuaternion = function() {
-1968     return [ 0.0, 0.0, 0.0, 1.0 ];
-1969 };
-1970 
-1971 var SceneJS_math_angleAxisQuaternion = function(x, y, z, degrees) {
-1972     var angleRad = (degrees / 180.0) * Math.PI;
-1973     var halfAngle = angleRad / 2.0;
-1974     var fsin = Math.sin(halfAngle);
-1975     return [
-1976         fsin * x,
-1977         fsin * y,
-1978         fsin * z,
-1979         Math.cos(halfAngle)
-1980     ];
-1981 };
-1982 
-1983 var SceneJS_math_mulQuaternions = function(p, q) {
-1984     var p0 = p[0], p1 = p[1], p2 = p[2], p3 = p[3];
-1985     var q0 = q[0], q1 = q[1], q2 = q[2], q3 = q[3];
-1986     return [
-1987         p3 * q0 + p0 * q3 + p1 * q2 - p2 * q1,
-1988         p3 * q1 + p1 * q3 + p2 * q0 - p0 * q2,
-1989         p3 * q2 + p2 * q3 + p0 * q1 - p1 * q0,
-1990         p3 * q3 - p0 * q0 - p1 * q1 - p2 * q2
-1991     ];
-1992 };
-1993 
-1994 var SceneJS_math_newMat4FromQuaternion = function(q) {
-1995     var q0 = q[0], q1 = q[1], q2 = q[2], q3 = q[3];
-1996     var tx = 2.0 * q0;
-1997     var ty = 2.0 * q1;
-1998     var tz = 2.0 * q2;
-1999     var twx = tx * q3;
-2000     var twy = ty * q3;
-2001     var twz = tz * q3;
-2002     var txx = tx * q0;
-2003     var txy = ty * q0;
-2004     var txz = tz * q0;
-2005     var tyy = ty * q1;
-2006     var tyz = tz * q1;
-2007     var tzz = tz * q2;
-2008     var m = SceneJS_math_identityMat4();
-2009     SceneJS_math_setCellMat4(m, 0, 0, 1.0 - (tyy + tzz));
-2010     SceneJS_math_setCellMat4(m, 0, 1, txy - twz);
-2011     SceneJS_math_setCellMat4(m, 0, 2, txz + twy);
-2012     SceneJS_math_setCellMat4(m, 1, 0, txy + twz);
-2013     SceneJS_math_setCellMat4(m, 1, 1, 1.0 - (txx + tzz));
-2014     SceneJS_math_setCellMat4(m, 1, 2, tyz - twx);
-2015     SceneJS_math_setCellMat4(m, 2, 0, txz - twy);
-2016     SceneJS_math_setCellMat4(m, 2, 1, tyz + twx);
-2017     SceneJS_math_setCellMat4(m, 2, 2, 1.0 - (txx + tyy));
-2018     return m;
-2019 };
-2020 
-2021 
-2022 //var SceneJS_math_slerp(t, q1, q2) {
-2023 //    var result = SceneJS_math_identityQuaternion();
-2024 //    var cosHalfAngle = q1[3] * q2[3] + q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2];
-2025 //    if (Math.abs(cosHalfAngle) >= 1) {
-2026 //        return [ q1[0],q1[1], q1[2], q1[3] ];
-2027 //    } else {
-2028 //        var halfAngle = Math.acos(cosHalfAngle);
-2029 //        var sinHalfAngle = Math.sqrt(1 - cosHalfAngle * cosHalfAngle);
-2030 //        if (Math.abs(sinHalfAngle) < 0.001) {
-2031 //            return [
-2032 //                q1[0] * 0.5 + q2[0] * 0.5,
-2033 //                q1[1] * 0.5 + q2[1] * 0.5,
-2034 //                q1[2] * 0.5 + q2[2] * 0.5,
-2035 //                q1[3] * 0.5 + q2[3] * 0.5
-2036 //            ];
-2037 //        } else {
-2038 //            var a = Math.sin((1 - t) * halfAngle) / sinHalfAngle;
-2039 //            var b = Math.sin(t * halfAngle) / sinHalfAngle;
-2040 //            return [
-2041 //                q1[0] * a + q2[0] * b,
-2042 //                q1[1] * a + q2[1] * b,
-2043 //                q1[2] * a + q2[2] * b,
-2044 //                q1[3] * a + q2[3] * b
-2045 //            ];
-2046 //        }
-2047 //    }
-2048 //}
-2049 
-2050 var SceneJS_math_slerp = function(t, q1, q2) {
-2051     //var result = SceneJS_math_identityQuaternion();
-2052     var q13 = q1[3] * 0.0174532925;
-2053     var q23 = q2[3] * 0.0174532925;
-2054     var cosHalfAngle = q13 * q23 + q1[0] * q2[0] + q1[1] * q2[1] + q1[2] * q2[2];
-2055     if (Math.abs(cosHalfAngle) >= 1) {
-2056         return [ q1[0],q1[1], q1[2], q1[3] ];
-2057     } else {
-2058         var halfAngle = Math.acos(cosHalfAngle);
-2059         var sinHalfAngle = Math.sqrt(1 - cosHalfAngle * cosHalfAngle);
-2060         if (Math.abs(sinHalfAngle) < 0.001) {
-2061             return [
-2062                 q1[0] * 0.5 + q2[0] * 0.5,
-2063                 q1[1] * 0.5 + q2[1] * 0.5,
-2064                 q1[2] * 0.5 + q2[2] * 0.5,
-2065                 q1[3] * 0.5 + q2[3] * 0.5
-2066             ];
-2067         } else {
-2068             var a = Math.sin((1 - t) * halfAngle) / sinHalfAngle;
-2069             var b = Math.sin(t * halfAngle) / sinHalfAngle;
-2070             return [
-2071                 q1[0] * a + q2[0] * b,
-2072                 q1[1] * a + q2[1] * b,
-2073                 q1[2] * a + q2[2] * b,
-2074                 (q13 * a + q23 * b) * 57.295779579
-2075             ];
-2076         }
-2077     }
-2078 };
-2079 
-2080 var SceneJS_math_normalizeQuaternion = function(q) {
-2081     var len = SceneJS_math_lenVec4([q[0], q[1], q[2], q[3]]);
-2082     return [ q[0] / len, q[1] / len, q[2] / len, q[3] / len ];
-2083 };
-2084 
-2085 var SceneJS_math_conjugateQuaternion = function(q) {
-2086     return[-q[0],-q[1],-q[2],q[3]];
-2087 };
-2088 
-2089 var SceneJS_math_angleAxisFromQuaternion = function(q) {
-2090     q = SceneJS_math_normalizeQuaternion(q);
-2091     var q3 = q[3];
-2092     var angle = 2 * Math.acos(q3);
-2093     var s = Math.sqrt(1 - q3 * q3);
-2094     if (s < 0.001) { // test to avoid divide by zero, s is always positive due to sqrt
-2095         return {
-2096             x : q[0],
-2097             y : q[1],
-2098             z : q[2],
-2099             angle: angle * 57.295779579
-2100         };
-2101     } else {
-2102         return {
-2103             x : q[0] / s,
-2104             y : q[1] / s,
-2105             z : q[2] / s,
-2106             angle: angle * 57.295779579
-2107         };
-2108     }
-2109 };
-2110 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_plugins.js.html b/docs/symbols/src/src_core_plugins.js.html deleted file mode 100644 index 8fe56b88..00000000 --- a/docs/symbols/src/src_core_plugins.js.html +++ /dev/null @@ -1,74 +0,0 @@ -
  1 /**
-  2  * SceneJS plugin registry
-  3  */
-  4 SceneJS.Plugins = new (function () {
-  5 
-  6     this._nodePlugins = {};
-  7 
-  8     /**
-  9      * Installs a plugin into SceneJS
- 10      */
- 11     this.addPlugin = function (nodeType, pluginType, plugin) {
- 12         var plugins = this._nodePlugins[nodeType] || (this._nodePlugins[nodeType] = {});
- 13         plugins[pluginType] = plugin;
- 14     };
- 15 
- 16     /**
- 17      * Tests if given plugin is installed
- 18      */
- 19     this.hasPlugin = function (nodeType, pluginType) {
- 20         var plugins = this._nodePlugins[nodeType];
- 21         return (plugins && !!plugins[pluginType]);
- 22     };
- 23 
- 24     /**
- 25      * Returns installed plugin of given type and ID
- 26      */
- 27     this.getPlugin = function (nodeType, pluginType, ok) {
- 28         var plugins = this._nodePlugins[nodeType];
- 29         if (plugins) {
- 30             var plugin = plugins[pluginType];
- 31             if (plugin) {
- 32                 ok(plugin);
- 33             }
- 34         }
- 35         // lazy-load
- 36         var self = this;
- 37         var pluginPath = SceneJS_debugModule.configs.pluginPath;
- 38         if (!pluginPath) {
- 39             throw "no pluginPath config"; // Build script error - should create this config
- 40         }
- 41         loadScript(pluginPath + "/" + nodeType + "/" + pluginType + ".js",
- 42             function () {
- 43                 ok(self._nodePlugins[nodeType][pluginType]);
- 44             });
- 45     };
- 46 
- 47     function loadScript(url, ok) {
- 48         var script = document.createElement("script");
- 49         script.type = "text/javascript";
- 50         if (script.readyState) {  //IE
- 51             script.onreadystatechange = function () {
- 52                 if (script.readyState == "loaded" ||
- 53                     script.readyState == "complete") {
- 54                     script.onreadystatechange = null;
- 55                     ok();
- 56                 }
- 57             };
- 58         } else {  //Others
- 59             script.onload = function () {
- 60                 ok();
- 61             };
- 62         }
- 63         script.src = url;
- 64         document.getElementsByTagName("head")[0].appendChild(script);
- 65     }
- 66 
- 67 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_camera.js.html b/docs/symbols/src/src_core_scene_camera.js.html deleted file mode 100644 index c227c914..00000000 --- a/docs/symbols/src/src_core_scene_camera.js.html +++ /dev/null @@ -1,170 +0,0 @@ -
  1 (function () {
-  2 
-  3     // The default state core singleton for {@link SceneJS.Camera} nodes
-  4     var defaultCore = {
-  5 
-  6         type:"camera",
-  7 
-  8         stateId:SceneJS._baseStateId++,
-  9 
- 10         // Default perspective projection matrix
- 11         mat:SceneJS_math_perspectiveMatrix4(
- 12             45, // fovy
- 13             1, // aspect
- 14             0.1, // near
- 15             5000), // far
- 16 
- 17         //Default optical attributes for perspective projection
- 18         optics:{
- 19             type:"perspective",
- 20             fovy:45.0,
- 21             aspect:1.0,
- 22             near:0.1,
- 23             far:5000.0
- 24         }
- 25     };
- 26 
- 27     var coreStack = [];
- 28     var stackLen = 0;
- 29 
- 30     // Set default core on the display at the start of each new scene compilation
- 31     SceneJS_events.addListener(
- 32         SceneJS_events.SCENE_COMPILING,
- 33         function (params) {
- 34             params.engine.display.projTransform = defaultCore;
- 35             stackLen = 0;
- 36         });
- 37 
- 38     /**
- 39      * @class Scene graph node which defines the projection transform to apply to the {@link SceneJS.Geometry} nodes in its subgraph
- 40      * @extends SceneJS.Node
- 41      */
- 42     SceneJS.Camera = SceneJS_NodeFactory.createNodeType("camera");
- 43 
- 44     SceneJS.Camera.prototype._init = function (params) {
- 45         if (this._core.useCount == 1) {
- 46             this.setOptics(params.optics); // Can be undefined
- 47         }
- 48     };
- 49 
- 50     SceneJS.Camera.prototype.setOptics = function (optics) {
- 51         var core = this._core;
- 52         if (!optics) {
- 53             core.optics = {
- 54                 type:type,
- 55                 fovy:60.0,
- 56                 aspect:1.0,
- 57                 near:0.1,
- 58                 far:5000.0
- 59             };
- 60         } else {
- 61             var type = optics.type || core.optics.type;
- 62             if (type == "ortho") {
- 63                 core.optics = SceneJS._applyIf(SceneJS_math_ORTHO_OBJ, {
- 64                     type:type,
- 65                     left:optics.left,
- 66                     bottom:optics.bottom,
- 67                     near:optics.near,
- 68                     right:optics.right,
- 69                     top:optics.top,
- 70                     far:optics.far
- 71                 });
- 72             } else if (type == "frustum") {
- 73                 core.optics = {
- 74                     type:type,
- 75                     left:optics.left || -1.0,
- 76                     bottom:optics.bottom || -1.0,
- 77                     near:optics.near || 0.1,
- 78                     right:optics.right || 1.00,
- 79                     top:optics.top || 1.0,
- 80                     far:optics.far || 5000.0
- 81                 };
- 82             } else if (type == "perspective") {
- 83                 core.optics = {
- 84                     type:type,
- 85                     fovy:optics.fovy || 60.0,
- 86                     aspect:optics.aspect == undefined ? 1.0 : optics.aspect,
- 87                     near:optics.near || 0.1,
- 88                     far:optics.far || 5000.0
- 89                 };
- 90             } else if (!optics.type) {
- 91                 throw SceneJS_error.fatalError(
- 92                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
- 93                     "SceneJS.Camera configuration invalid: optics type not specified - " +
- 94                         "supported types are 'perspective', 'frustum' and 'ortho'");
- 95             } else {
- 96                 throw SceneJS_error.fatalError(
- 97                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
- 98                     "SceneJS.Camera configuration invalid: optics type not supported - " +
- 99                         "supported types are 'perspective', 'frustum' and 'ortho'");
-100             }
-101         }
-102         this._rebuild();
-103         this._engine.display.imageDirty = true;
-104     };
-105 
-106     SceneJS.Camera.prototype._rebuild = function () {
-107         var optics = this._core.optics;
-108         if (optics.type == "ortho") {
-109             this._core.matrix = SceneJS_math_orthoMat4c(
-110                 optics.left,
-111                 optics.right,
-112                 optics.bottom,
-113                 optics.top,
-114                 optics.near,
-115                 optics.far);
-116 
-117         } else if (optics.type == "frustum") {
-118             this._core.matrix = SceneJS_math_frustumMatrix4(
-119                 optics.left,
-120                 optics.right,
-121                 optics.bottom,
-122                 optics.top,
-123                 optics.near,
-124                 optics.far);
-125 
-126         } else if (optics.type == "perspective") {
-127             this._core.matrix = SceneJS_math_perspectiveMatrix4(
-128                 optics.fovy * Math.PI / 180.0,
-129                 optics.aspect,
-130                 optics.near,
-131                 optics.far);
-132         }
-133         if (!this._core.mat) {
-134             this._core.mat = new Float32Array(this._core.matrix);
-135         } else {
-136             this._core.mat.set(this._core.matrix);
-137         }
-138     };
-139 
-140     SceneJS.Camera.prototype.getOptics = function () {
-141         var optics = {};
-142         for (var key in this._core.optics) {
-143             if (this._core.optics.hasOwnProperty(key)) {
-144                 optics[key] = this._core.optics[key];
-145             }
-146         }
-147         return optics;
-148     };
-149 
-150     SceneJS.Camera.prototype.getMatrix = function () {
-151         return this._core.matrix.slice(0);
-152     };
-153 
-154     /**
-155      * Compiles this camera node, setting this node's state core on the display, compiling sub-nodes,
-156      * then restoring the previous camera state core back onto the display on exit.
-157      */
-158     SceneJS.Camera.prototype._compile = function () {
-159         this._engine.display.projTransform = coreStack[stackLen++] = this._core;
-160         this._compileNodes();
-161         this._engine.display.projTransform = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
-162     };
-163 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_clips.js.html b/docs/symbols/src/src_core_scene_clips.js.html deleted file mode 100644 index ac1d1a2d..00000000 --- a/docs/symbols/src/src_core_scene_clips.js.html +++ /dev/null @@ -1,105 +0,0 @@ -
  1 (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.Clips} nodes
-  5      */
-  6     var defaultCore = {
-  7         type: "clips",
-  8         stateId: SceneJS._baseStateId++,
-  9         empty: true,        
- 10         hash: "",
- 11         clips : []
- 12     };
- 13 
- 14     var coreStack = [];
- 15     var stackLen = 0;
- 16 
- 17     SceneJS_events.addListener(
- 18             SceneJS_events.SCENE_COMPILING,
- 19             function(params) {
- 20                 params.engine.display.clips = defaultCore;
- 21                 stackLen = 0;
- 22             });
- 23 
- 24     /**
- 25      * @class Scene graph node which defines one or more arbitrarily-aligned clip planes to clip the {@link SceneJS.Geometry} nodes in its subgraph
- 26      * @extends SceneJS.Node
- 27      */
- 28     SceneJS.Clips = SceneJS_NodeFactory.createNodeType("clips");
- 29 
- 30     SceneJS.Clips.prototype._init = function(params) {
- 31 
- 32         if (this._core.useCount == 1) { // This node defines the resource
- 33 
- 34             var clips = params.clips;
- 35 
- 36             if (!clips) {
- 37                 throw SceneJS_error.fatalError(
- 38                         SceneJS.errors.NODE_CONFIG_EXPECTED,
- 39                         "clips node attribute missing : 'clips'");
- 40             }
- 41 
- 42             this._core.clips = this._core.clips || [];
- 43 
- 44             for (var i = 0, len = clips.length; i < len; i++) {
- 45                 this._setClip(i, clips[i]);
- 46             }
- 47         }
- 48     };
- 49 
- 50     SceneJS.Clips.prototype.setClips = function(clips) {
- 51         var indexNum;
- 52         for (var index in clips) {
- 53             if (clips.hasOwnProperty(index)) {
- 54                 if (index != undefined || index != null) {
- 55                     indexNum = parseInt(index);
- 56                     if (indexNum < 0 || indexNum >= this._core.clips.length) {
- 57                         throw SceneJS_error.fatalError(
- 58                                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
- 59                                 "Invalid argument to set 'clips': index out of range (" + this._core.clips.length + " clips defined)");
- 60                     }
- 61                     this._setClip(indexNum, clips[index] || {});
- 62                 }
- 63             }
- 64         }
- 65         this._engine.display.imageDirty = true;
- 66     };
- 67 
- 68     SceneJS.Clips.prototype._setClip = function(index, cfg) {
- 69 
- 70         var clip = this._core.clips[index] || (this._core.clips[index] = {});
- 71 
- 72         clip.normalAndDist = [cfg.x || 0,  cfg.y || 0, cfg.z || 0, cfg.dist || 0];
- 73 
- 74         var mode = cfg.mode || clip.mode || "disabled";
- 75 
- 76         if (mode != "inside" && mode != "outside" && mode != "disabled") {
- 77             throw SceneJS_error.fatalError(
- 78                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
- 79                     "clips node invalid value for property 'mode': should be 'inside' or 'outside' or 'disabled'");
- 80         }
- 81         clip.mode = mode;
- 82 
- 83         this._core.hash = null;
- 84     };
- 85 
- 86     SceneJS.Clips.prototype._compile = function() {
- 87 
- 88         if (!this._core.hash) {
- 89             this._core.hash = this._core.clips.length;
- 90         }
- 91 
- 92         this._engine.display.clips = coreStack[stackLen++] = this._core;
- 93         this._compileNodes();
- 94         this._engine.display.clips = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
- 95     };
- 96 
- 97 
- 98 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_core.js.html b/docs/symbols/src/src_core_scene_core.js.html deleted file mode 100644 index 938bde40..00000000 --- a/docs/symbols/src/src_core_scene_core.js.html +++ /dev/null @@ -1,50 +0,0 @@ -
  1 /**
-  2  * @class Holds state for one or more {@link SceneJS.Node}s.
-  3  *
-  4  * <p>Each {@link SceneJS.Node} has a state core to hold its state, and the core may be shared by other
-  5  * {@link SceneJS.Nodes}s of the same type.</p>
-  6  *
-  7  * <p>The state held by core is rendered by a {@link SceneJS_Chunk}  
-  8  *
-  9  * @private
- 10  */
- 11 var SceneJS_Core = function(type) {
- 12 
- 13     /**
- 14      * The state core type, which will be the same value as the type property on the {@link SceneJS.Node}s that use the core
- 15      * @type String
- 16      * @see SceneJS.Node#type
- 17      */
- 18     this.type = type;
- 19 
- 20     /**
- 21      * The state core ID, unique within the scene. This ID may be either a string assigned by the application layer via
- 22      * scene node configs, or a number that is automatically generated by the {@link SceneJS_CoreFactory} managing
- 23      * this core instance.
- 24      * @type String|Number
- 25      */
- 26     this.coreId = null;
- 27 
- 28     /**
- 29      * Uniquely identifies this state core within a {@link SceneJS_Display}.
- 30      *
- 31      * This ID is used by a {@link SceneJS_Display} to reduce redundant state changes when rendering a sequence of cores, 
- 32      * where as a {@link SceneJS_Display} renders a frame it avoids applying consecutive cores that have the
- 33      * same value for this ID.
- 34      *
- 35      * @type Number
- 36      */
- 37     this.stateId = null;
- 38 
- 39     /**
- 40      * Count of {@link SceneJS.Node} instances this core holds state for
- 41      */
- 42     this.useCount = 0;
- 43 };
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_coreFactory.js.html b/docs/symbols/src/src_core_scene_coreFactory.js.html deleted file mode 100644 index 82555f8f..00000000 --- a/docs/symbols/src/src_core_scene_coreFactory.js.html +++ /dev/null @@ -1,162 +0,0 @@ -
  1 /**
-  2  * @class Manages creation, recycle and destruction of {@link SceneJS_Core} instances
-  3  * @private
-  4  */
-  5 var SceneJS_CoreFactory = function () {
-  6 
-  7     this._stateMap = new SceneJS_Map(null, SceneJS._baseStateId);  // For creating unique state IDs for cores
-  8 
-  9     this._cores = {}; // Map of cores for each type
- 10 };
- 11 
- 12 /**
- 13  * State core classes provided by this factory
- 14  * @type {SceneJS.Core}
- 15  */
- 16 SceneJS_CoreFactory.coreTypes = {};    // Supported core classes, installed by #createCoreType
- 17 
- 18 /**
- 19  * Creates a core class for instantiation by this factory
- 20  * @param {String} type Name of type, eg. "camera"
- 21  * @param {Node} [superType] Class of super type - SceneJS.Node by default
- 22  * @returns The new node class
- 23  */
- 24 SceneJS_CoreFactory.createCoreType = function (type, superType) {
- 25     //
- 26     //    var supa = SceneJS_CoreFactory.coreTypes[superType];
- 27     //
- 28     //    if (!supa) {
- 29     //        supa = SceneJS.Core; // Super class is Core by default
- 30     //    }
- 31     //
- 32     //    var nodeType = function() { // Create the class
- 33     //        supa.apply(this, arguments);
- 34     //        this.type = type;
- 35     //    };
- 36     //
- 37     //    nodeType.prototype = new supa();            // Inherit from base class
- 38     //    nodeType.prototype.constructor = nodeType;
- 39     //
- 40     //    SceneJS_CoreFactory.nodeTypes[type] = nodeType;
- 41     //
- 42     //    return nodeType;
- 43 };
- 44 
- 45 SceneJS_CoreFactory.addCoreBuilder = function (type, factory) {
- 46 
- 47 };
- 48 
- 49 /* HACK - allows different types of node to have same type of core, eg. "rotate" and "translate" nodes can both have an "xform" core    
- 50  */
- 51 SceneJS_CoreFactory.coreAliases = {
- 52     "rotate":"xform",
- 53     "translate":"xform",
- 54     "scale":"xform",
- 55     "matrix":"xform",
- 56     "xform":"xform"
- 57 };
- 58 
- 59 /**
- 60  * Gets a core of the given type from this factory. Reuses any existing existing core of the same type and ID.
- 61  *
- 62  * The caller (a scene node) will then augment the core with type-specific attributes and methods.
- 63  *
- 64  * @param {String} type Type name of core, e.g. "material", "texture"
- 65  * @param {String} coreId ID for the core, unique among all cores of the given type within this factory
- 66  * @returns {Core} The core
- 67  */
- 68 SceneJS_CoreFactory.prototype.getCore = function (type, coreId) {
- 69 
- 70     /* HACK - allows different types of node to have same type of core, eg. "rotate" and "translate" nodes can both have an "xform" core    
- 71      */
- 72     var alias = SceneJS_CoreFactory.coreAliases[type];
- 73     if (alias) {
- 74         type = alias;
- 75     }
- 76 
- 77     var cores = this._cores[type];
- 78 
- 79     if (!cores) {
- 80         cores = this._cores[type] = {};
- 81     }
- 82 
- 83     var core;
- 84 
- 85     if (coreId) { // Attempt to reuse a core
- 86 
- 87         core = cores[coreId];
- 88 
- 89         if (core) {
- 90             core.useCount++;
- 91             return core;
- 92         }
- 93     }
- 94 
- 95     core = new SceneJS_Core(type);
- 96     core.useCount = 1;  // One user so far
- 97 
- 98     core.stateId = this._stateMap.addItem(core);
- 99     core.coreId = (coreId != undefined && coreId != null) ? coreId : core.stateId; // Use state ID as core ID by default
-100 
-101     cores[core.coreId] = core;
-102 
-103     return core;
-104 };
-105 
-106 /**
-107  * Releases a state core back to this factory, destroying it if the core's use count is then zero.
-108  * @param {Core} core Core to release
-109  */
-110 SceneJS_CoreFactory.prototype.putCore = function (core) {
-111 
-112     if (core.useCount == 0) {
-113         return; // In case of excess puts
-114     }
-115 
-116     if (--core.useCount <= 0) {                    // Release shared core if use count now zero
-117 
-118         var cores = this._cores[core.type];
-119 
-120         cores[core.coreId] = null;
-121 
-122         this._stateMap.removeItem(core.stateId);  // Release state ID for reuse
-123     }
-124 };
-125 
-126 /**
-127  * Reallocates WebGL resources for cores within this factory
-128  */
-129 SceneJS_CoreFactory.prototype.webglRestored = function () {
-130 
-131     var cores;
-132     var core;
-133 
-134     for (var type in this._cores) {
-135         if (this._cores.hasOwnProperty(type)) {
-136 
-137             cores = this._cores[type];
-138 
-139             if (cores) {
-140 
-141                 for (var coreId in cores) {
-142                     if (cores.hasOwnProperty(coreId)) {
-143 
-144                         core = cores[coreId];
-145 
-146                         if (core.webglRestored) { // Method augmented on core by user
-147                             core.webglRestored();
-148                         }
-149                     }
-150                 }
-151             }
-152         }
-153     }
-154 };
-155 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_flags.js.html b/docs/symbols/src/src_core_scene_flags.js.html deleted file mode 100644 index 05a1dbc3..00000000 --- a/docs/symbols/src/src_core_scene_flags.js.html +++ /dev/null @@ -1,287 +0,0 @@ -
  1 (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.Flags} nodes
-  5      */
-  6     var defaultCore = {
-  7 
-  8         stateId: SceneJS._baseStateId++,
-  9         type: "flags",
- 10 
- 11         picking : true,             // Picking enabled
- 12         clipping : true,            // User-defined clipping enabled
- 13         enabled : true,             // Node not culled from traversal
- 14         transparent: false,         // Node transparent - works in conjunction with matarial alpha properties
- 15         backfaces: true,            // Show backfaces
- 16         frontface: "ccw",           // Default vertex winding for front face
- 17         backfaceLighting: true,     // Shading enabled for backfaces
- 18         backfaceTexturing: true,    // Texturing enabled for backfaces
- 19         specular: true,             // Specular lighting enabled
- 20         ambient: true               // Ambient lighting enabled
- 21     };
- 22 
- 23     var coreStack = [];
- 24     var stackLen = 0;
- 25 
- 26     SceneJS_events.addListener(
- 27             SceneJS_events.SCENE_COMPILING,
- 28             function(params) {
- 29                 params.engine.display.flags = defaultCore;
- 30                 stackLen = 0;
- 31             });
- 32 
- 33     /**
- 34      * @class Scene graph node which sets rendering mode flags for its subgraph
- 35      * @extends SceneJS.Node
- 36      */
- 37     SceneJS.Flags = SceneJS_NodeFactory.createNodeType("flags");
- 38 
- 39     SceneJS.Flags.prototype._init = function(params) {
- 40 
- 41         if (this._core.useCount == 1) {         // This node is first to reference the state core, so sets it up
- 42 
- 43             this._core.picking = true;           // Picking enabled
- 44             this._core.clipping = true;          // User-defined clipping enabled
- 45             this._core.enabled = true;           // Node not culled from traversal
- 46             this._core.transparent = false;      // Node transparent - works in conjunction with matarial alpha properties
- 47             this._core.backfaces = true;         // Show backfaces
- 48             this._core.frontface = "ccw";        // Default vertex winding for front face
- 49             this._core.backfaceLighting = true;  // Shading enabled for backfaces
- 50             this._core.backfaceTexturing = true; // Texturing enabled for backfaces
- 51             this._core.specular = true;          // Specular lighting enabled by default
- 52             this._core.ambient = true;           // Ambient lighting enabled by default
- 53 
- 54             if (params.flags) {                 // 'flags' property is actually optional in the node definition
- 55                 this.setFlags(params.flags);
- 56             }
- 57         }
- 58     };
- 59 
- 60     SceneJS.Flags.prototype.setFlags = function(flags) {
- 61 
- 62         var core = this._core;
- 63 
- 64         if (flags.picking != undefined) {
- 65             core.picking = !!flags.picking;
- 66             this._engine.display.drawListDirty = true;
- 67         }
- 68 
- 69         if (flags.clipping != undefined) {
- 70             core.clipping = !!flags.clipping;
- 71             this._engine.display.imageDirty = true;
- 72         }
- 73 
- 74         if (flags.enabled != undefined) {
- 75             core.enabled = !!flags.enabled;
- 76             this._engine.display.drawListDirty = true;
- 77         }
- 78 
- 79         if (flags.transparent != undefined) {
- 80             core.transparent = !!flags.transparent;
- 81             this._engine.display.drawListDirty = true;
- 82         }
- 83 
- 84         if (flags.backfaces != undefined) {
- 85             core.backfaces = !!flags.backfaces;
- 86             this._engine.display.imageDirty = true;
- 87         }
- 88 
- 89         if (flags.frontface != undefined) {
- 90             core.frontface = !!flags.frontface;
- 91             this._engine.display.imageDirty = true;
- 92         }
- 93 
- 94         if (flags.backfaceLighting != undefined) {
- 95             core.backfaceLighting = !!flags.backfaceLighting;
- 96             this._engine.display.imageDirty = true;
- 97         }
- 98 
- 99         if (flags.backfaceTexturing != undefined) {
-100             core.backfaceTexturing = !!flags.backfaceTexturing;
-101             this._engine.display.imageDirty = true;
-102         }
-103 
-104         if (flags.specular != undefined) {
-105             core.specular = !!flags.specular;
-106             this._engine.display.imageDirty = true;
-107         }
-108 
-109         if (flags.ambient != undefined) {
-110             core.ambient = !!flags.ambient;
-111             this._engine.display.imageDirty = true;
-112         }
-113 
-114         return this;
-115     };
-116 
-117     SceneJS.Flags.prototype.addFlags = function(flags) {
-118         return this.setFlags(flags);
-119         //        var core = this._core;
-120         //        if (flags.picking != undefined) core.picking = flags.picking;
-121         //        if (flags.clipping != undefined) core.clipping = flags.clipping;
-122         //        if (flags.enabled != undefined) core.enabled = flags.enabled;
-123         //        if (flags.transparent != undefined) core.transparent = flags.transparent;
-124         //        if (flags.backfaces != undefined) core.backfaces = flags.backfaces;
-125         //        if (flags.frontface != undefined) core.frontface = flags.frontface;
-126         //        if (flags.backfaceLighting != undefined) core.backfaceLighting = flags.backfaceLighting;
-127         //        if (flags.backfaceTexturing != undefined) core.backfaceTexturing = flags.backfaceTexturing;
-128         //        return this;
-129     };
-130 
-131     SceneJS.Flags.prototype.getFlags = function() {
-132         var core = this._core;
-133         return {
-134             picking : core.picking,
-135             clipping : core.clipping,
-136             enabled : core.enabled,
-137             transparent: core.transparent,
-138             backfaces: core.backfaces,
-139             frontface: core.frontface,
-140             specular: core.specular,
-141             ambient: core.ambient
-142         };
-143     };
-144 
-145     SceneJS.Flags.prototype.setPicking = function(picking) {
-146         picking = !!picking;
-147         if (this._core.picking != picking) {
-148             this._core.picking = picking;
-149             this._engine.display.drawListDirty = true;
-150         }
-151         return this;
-152     };
-153 
-154     SceneJS.Flags.prototype.getPicking = function() {
-155         return this._core.picking;
-156     };
-157 
-158     SceneJS.Flags.prototype.setClipping = function(clipping) {
-159         clipping = !!clipping;
-160         if (this._core.clipping != clipping) {
-161             this._core.clipping = clipping;
-162             this._engine.display.imageDirty = true;
-163         }
-164         return this;
-165     };
-166 
-167     SceneJS.Flags.prototype.getClipping = function() {
-168         return this._core.clipping;
-169     };
-170 
-171     SceneJS.Flags.prototype.setEnabled = function(enabled) {
-172         enabled = !!enabled;
-173         if (this._core.enabled != enabled) {
-174             this._core.enabled = enabled;
-175             this._engine.display.drawListDirty = true;
-176         }
-177         return this;
-178     };
-179 
-180     SceneJS.Flags.prototype.getEnabled = function() {
-181         return this._core.enabled;
-182     };
-183 
-184     SceneJS.Flags.prototype.setTransparent = function(transparent) {
-185         transparent = !!transparent;
-186         if (this._core.transparent != transparent) {
-187             this._core.transparent = transparent;
-188             this._engine.display.drawListDirty = true;
-189         }
-190         return this;
-191     };
-192 
-193     SceneJS.Flags.prototype.getTransparent = function() {
-194         return this._core.transparent;
-195     };
-196 
-197     SceneJS.Flags.prototype.setBackfaces = function(backfaces) {
-198         backfaces = !!backfaces;
-199         if (this._core.backfaces != backfaces) {
-200             this._core.backfaces = backfaces;
-201             this._engine.display.imageDirty = true;
-202         }
-203         return this;
-204     };
-205 
-206     SceneJS.Flags.prototype.getBackfaces = function() {
-207         return this._core.backfaces;
-208     };
-209 
-210     SceneJS.Flags.prototype.setFrontface = function(frontface) {
-211         if (this._core.frontface != frontface) {
-212             this._core.frontface = frontface;
-213             this._engine.display.imageDirty = true;
-214         }
-215         return this;
-216     };
-217 
-218     SceneJS.Flags.prototype.getFrontface = function() {
-219         return this._core.frontface;
-220     };
-221 
-222     SceneJS.Flags.prototype.setBackfaceLighting = function(backfaceLighting) {
-223         backfaceLighting = !!backfaceLighting;
-224         if (this._core.backfaceLighting != backfaceLighting) {
-225             this._core.backfaceLighting = backfaceLighting;
-226             this._engine.display.imageDirty = true;
-227         }
-228         return this;
-229     };
-230 
-231     SceneJS.Flags.prototype.getBackfaceLighting = function() {
-232         return this._core.backfaceLighting;
-233     };
-234 
-235     SceneJS.Flags.prototype.setBackfaceTexturing = function(backfaceTexturing) {
-236         backfaceTexturing = !!backfaceTexturing;
-237         if (this._core.backfaceTexturing != backfaceTexturing) {
-238             this._core.backfaceTexturing = backfaceTexturing;
-239             this._engine.display.imageDirty = true;
-240         }
-241         return this;
-242     };
-243 
-244     SceneJS.Flags.prototype.getBackfaceTexturing = function() {
-245         return this._core.backfaceTexturing;
-246     };
-247 
-248     SceneJS.Flags.prototype.setAmbient = function(ambient) {
-249         ambient = !!ambient;
-250         if (this._core.ambient != ambient) {
-251             this._core.ambient = ambient;
-252             this._engine.display.imageDirty = true;
-253         }
-254         return this;
-255     };
-256 
-257     SceneJS.Flags.prototype.getAmbient = function() {
-258         return this._core.ambient;
-259     };
-260 
-261     SceneJS.Flags.prototype.setAmbient = function(ambient) {
-262         ambient = !!ambient;
-263         if (this._core.ambient != ambient) {
-264             this._core.ambient = ambient;
-265             this._engine.display.imageDirty = true;
-266         }
-267         return this;
-268     };
-269 
-270     SceneJS.Flags.prototype.getAmbient = function() {
-271         return this._core.ambient;
-272     };
-273 
-274     SceneJS.Flags.prototype._compile = function() {
-275         this._engine.display.flags = coreStack[stackLen++] = this._core;
-276         this._compileNodes();
-277         this._engine.display.flags = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
-278     };
-279 
-280 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_framebuf.js.html b/docs/symbols/src/src_core_scene_framebuf.js.html deleted file mode 100644 index 65b92f00..00000000 --- a/docs/symbols/src/src_core_scene_framebuf.js.html +++ /dev/null @@ -1,208 +0,0 @@ -
  1 new (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.Framebuf} nodes
-  5      */
-  6     var defaultCore = {
-  7 
-  8         type: "framebuf",
-  9         stateId: SceneJS._baseStateId++,
- 10         empty: true,
- 11 
- 12         framebuf: null
- 13     };
- 14 
- 15     var nodeCoreMap = {}; // Map of framebuf nodes to cores, for reallocation on WebGL context restore
- 16 
- 17     var coreStack = [];
- 18     var stackLen = 0;
- 19 
- 20     SceneJS_events.addListener(
- 21             SceneJS_events.SCENE_COMPILING,
- 22             function(params) {
- 23                 params.engine.display.framebuf = defaultCore;
- 24                 stackLen = 0;
- 25             });
- 26 
- 27     SceneJS_events.addListener(// Reallocate VBOs when context restored after loss
- 28             SceneJS_events.WEBGL_CONTEXT_RESTORED,
- 29             function() {
- 30 
- 31                 var node;
- 32 
- 33                 for (var nodeId in nodeCoreMap) {
- 34                     if (nodeCoreMap.hasOwnProperty(nodeId)) {
- 35 
- 36                         node = nodeCoreMap[nodeId];
- 37 
- 38                         if (!node._core._loading) {
- 39                             node._buildNodeCore();
- 40                         }
- 41                     }
- 42                 }
- 43             });
- 44 
- 45     SceneJS_events.addListener(
- 46             SceneJS_events.SCENE_DESTROYED,
- 47             function(params) {
- 48                 //     sceneBufs[params.sceneId] = null;
- 49             });
- 50 
- 51     /**
- 52      * @class Scene graph node which sets up a frame buffer to which the {@link SceneJS.Geometry} nodes in its subgraph will be rendered.
- 53      * The frame buffer may be referenced as an image source by successive {@link SceneJS.Texture} nodes.
- 54      * @extends SceneJS.Node
- 55      */
- 56     SceneJS.Framebuf = SceneJS_NodeFactory.createNodeType("framebuf");
- 57 
- 58     SceneJS.Framebuf.prototype._init = function() {
- 59 
- 60         nodeCoreMap[this._core.coreId] = this; // Register for core rebuild on WEBGL_CONTEXT_RESTORED
- 61 
- 62         this._buildNodeCore();
- 63     };
- 64 
- 65     SceneJS.Framebuf.prototype._buildNodeCore = function() {
- 66 
- 67         var canvas = this._engine.canvas;
- 68         var gl = canvas.gl;
- 69         var width = canvas.canvas.width;
- 70         var height = canvas.canvas.height;
- 71 
- 72         var framebuf = gl.createFramebuffer();
- 73         var renderbuf = gl.createRenderbuffer();
- 74         var texture = gl.createTexture() ;
- 75 
- 76         var rendered = false;
- 77 
- 78         if (!this._core) {
- 79             this._core = {};
- 80         }
- 81 
- 82         gl.bindFramebuffer(gl.FRAMEBUFFER, framebuf);
- 83 
- 84         gl.bindTexture(gl.TEXTURE_2D, texture);
- 85         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
- 86         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
- 87         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
- 88         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
- 89 
- 90         try {
- 91             // Do it the way the spec requires
- 92             gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
- 93         } catch (exception) {
- 94             // Workaround for what appears to be a Minefield bug.
- 95             var textureStorage = new WebGLUnsignedByteArray(width * height * 4);
- 96             gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureStorage);
- 97         }
- 98         gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuf);
- 99         gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
-100         gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
-101         gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, renderbuf);
-102         gl.bindTexture(gl.TEXTURE_2D, null);
-103         gl.bindRenderbuffer(gl.RENDERBUFFER, null);
-104         gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-105 
-106         /* Verify framebuffer is OK
-107          */
-108         gl.bindFramebuffer(gl.FRAMEBUFFER, framebuf);
-109 
-110         if (!gl.isFramebuffer(framebuf)) {
-111             throw SceneJS_error.fatalError("Invalid framebuffer");
-112         }
-113 
-114         var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
-115 
-116         gl.bindRenderbuffer(gl.RENDERBUFFER, null);
-117         gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-118 
-119         switch (status) {
-120             case gl.FRAMEBUFFER_COMPLETE:
-121                 break;
-122             case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-123                 throw SceneJS_error.fatalError("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
-124             case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-125                 throw SceneJS_error.fatalError("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
-126             case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
-127                 throw SceneJS_error.fatalError("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
-128             case gl.FRAMEBUFFER_UNSUPPORTED:
-129                 throw SceneJS_error.fatalError("Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED");
-130             default:
-131                 throw SceneJS_error.fatalError("Incomplete framebuffer: " + status);
-132         }
-133 
-134         this._core.framebuf = {
-135 
-136             id: this.id, // TODO: maybe unused?
-137 
-138             /** Binds the image buffer as target for subsequent geometry renders
-139              */
-140             bind: function() {
-141              //   gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuf);
-142                 gl.bindFramebuffer(gl.FRAMEBUFFER, framebuf);
-143                 gl.clearColor(0.0, 0.0, 0.0, 1.0);
-144                 gl.clearDepth(1.0);
-145                 gl.enable(gl.DEPTH_TEST);
-146                 gl.disable(gl.CULL_FACE);
-147                 gl.depthRange(0, 1);
-148                 gl.disable(gl.SCISSOR_TEST);
-149                 //  gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-150                 gl.disable(gl.BLEND);
-151             },
-152 
-153             /** Unbinds image buffer, the default buffer then becomes the rendering target
-154              */
-155             unbind:function() {
-156                 gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-157                // gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-158                 gl.bindRenderbuffer(gl.RENDERBUFFER, renderbuf);
-159                 rendered = true;
-160             },
-161 
-162             /** Returns true if this texture has been rendered
-163              */
-164             isRendered: function() {
-165                 return rendered;
-166             },
-167 
-168             /** Gets the texture from this image buffer
-169              */
-170             getTexture: function() {
-171 
-172                 return {
-173 
-174                     bind: function(unit) {
-175                         gl.activeTexture(gl["TEXTURE" + unit]);
-176                         gl.bindTexture(gl.TEXTURE_2D, texture);
-177                     },
-178 
-179                     unbind : function(unit) {
-180                         gl.activeTexture(gl["TEXTURE" + unit]);
-181                         gl.bindTexture(gl.TEXTURE_2D, null);
-182                     }
-183                 };
-184             }
-185         };
-186     };
-187 
-188     SceneJS.Framebuf.prototype._compile = function() {
-189         this._engine.display.framebuf = coreStack[stackLen++] = this._core;
-190         this._compileNodes();
-191         this._engine.display.framebuf = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
-192     };
-193 
-194     SceneJS.Framebuf.prototype._destroy = function() {
-195         if (this._core) {
-196             //destroyFrameBuffer(this._buf);
-197         }
-198     };
-199 
-200 
-201 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_geometry.js.html b/docs/symbols/src/src_core_scene_geometry.js.html deleted file mode 100644 index 8d70c7de..00000000 --- a/docs/symbols/src/src_core_scene_geometry.js.html +++ /dev/null @@ -1,695 +0,0 @@ -
  1 new (function () {
-  2 
-  3     var coreStack = [];
-  4     var stackLen = 0;
-  5 
-  6     SceneJS_events.addListener(
-  7         SceneJS_events.SCENE_COMPILING,
-  8         function () {
-  9             stackLen = 0;
- 10         });
- 11 
- 12     /**
- 13      * @class Scene graph node that defines geometry.
- 14      * @extends SceneJS.Node
- 15      * When this node is at a leaf, it defines a scene object which inherits the state set up by all the nodes above it
- 16      * on the path up to the root. These nodes can be nested, so that child geometries inherit arrays
- 17      * defined by parent geometries.
- 18      */
- 19     SceneJS.Geometry = SceneJS_NodeFactory.createNodeType("geometry");
- 20 
- 21     SceneJS.Geometry.prototype._init = function (params) {
- 22 
- 23         if (this._core.useCount == 1) { // This node defines the core
- 24 
- 25             var options = {
- 26                 origin:params.origin,
- 27                 scale:params.scale
- 28             };
- 29 
- 30             var self = this;
- 31 
- 32             this._sourceConfigs = null;
- 33             this._source = null;
- 34 
- 35             if (params.plugin) {
- 36                 this._sourceConfigs = SceneJS._apply({ type:params.plugin }, params);
- 37             } else if (params.source) {
- 38                 this._sourceConfigs = params.source;
- 39             }
- 40 
- 41             if (this._sourceConfigs) {
- 42 
- 43                 /*---------------------------------------------------------------------------------------------------
- 44                  * Build node core (possibly asynchronously) using a factory object
- 45                  *--------------------------------------------------------------------------------------------------*/
- 46 
- 47                 if (!this._sourceConfigs.type) {
- 48                     throw SceneJS_error.fatalError(
- 49                         SceneJS.errors.ILLEGAL_NODE_CONFIG,
- 50                         "geometry config expected: source.type");
- 51                 }
- 52 
- 53                 SceneJS.Plugins.getPlugin(
- 54                     "geometry",
- 55                     this._sourceConfigs.type,
- 56                     function (plugin) {
- 57 
- 58                         if (!plugin.getSource) {
- 59                             throw SceneJS_error.fatalError(
- 60                                 SceneJS.errors.PLUGIN_INVALID,
- 61                                 "geometry: 'getSource' method missing on plugin for geometry source type '" + this._sourceConfigs.type + "'.");
- 62                         }
- 63 
- 64                         self._source = plugin.getSource();
- 65 
- 66                         if (!self._source.onUpdate) {
- 67                             throw SceneJS_error.fatalError(
- 68                                 SceneJS.errors.PLUGIN_INVALID,
- 69                                 "geometry: 'onUpdate' method missing on plugin for geometry source type '" + this._sourceConfigs.type + "'");
- 70                         }
- 71 
- 72                         self._source.onCreate(// Get notification when source creates the geometry
- 73                             function (data) { // Data contains both typed arrays and primitive name
- 74 
- 75                                 if (options) { // HACK - should apply this on GPU
- 76                                     data.positions = data.positions
- 77                                         ? new Float32Array((options.scale || options.origin)
- 78                                         ? self._applyOptions(data.positions, options)
- 79                                         : data.positions) : undefined;
- 80                                 }
- 81 
- 82                                 self._initNodeCore(data);
- 83 
- 84                                 SceneJS.Geometry._buildNodeCore(self._engine.canvas.gl, self._core);
- 85 
- 86                                 self._core._loading = false;
- 87                                 self._fireEvent("loaded");
- 88 
- 89                                 self._engine.display.imageDirty = true;
- 90 
- 91                                 self._engine.branchDirty(self); // TODO
- 92                             });
- 93 
- 94                         if (self._source.onUpdate) {
- 95                             self._source.onUpdate(// Reload core arrays from factory updates to the geometry
- 96                                 function (data) {
- 97 
- 98                                     var core = self._core;
- 99 
-100                                     if (data.positions && core.vertexBuf) {
-101 
-102 //                                    if (data.positions.length > core.vertexBuf.length) {
-103 //                                        alert("too long");
-104 //                                    }
-105 
-106                                         core.vertexBuf.bind();
-107                                         core.vertexBuf.setData(data.positions, data.positionsOffset || 0);
-108 
-109                                         if (data.positions.length > core.arrays.positions.length) {
-110                                             core.arrays.positions = data.positions;
-111 
-112                                         } else {
-113                                             core.arrays.positions.set(data.positions, data.positionsOffset || 0);
-114                                         }
-115                                     }
-116 
-117                                     if (data.normals && core.normalBuf) {
-118 
-119                                         core.normalBuf.bind();
-120                                         core.normalBuf.setData(data.normals, data.normalsOffset || 0);
-121 
-122                                         if (data.normals.length > core.arrays.normals.length) {
-123                                             core.arrays.normals = data.normals;
-124 
-125                                         } else {
-126                                             core.arrays.normals.set(data.normals, data.normalsOffset || 0);
-127                                         }
-128                                     }
-129 
-130                                     if (data.uv && core.uvBuf) {
-131 
-132                                         core.uvBuf.bind();
-133                                         core.uvBuf.setData(data.uv, data.uvOffset || 0);
-134 
-135                                         if (data.uv.length > core.arrays.uv.length) {
-136                                             core.arrays.uv = data.uv;
-137 
-138                                         } else {
-139                                             core.arrays.uv.set(data.uv, data.uvOffset || 0);
-140                                         }
-141                                     }
-142 
-143                                     if (data.uv2 && core.uvBuf2) {
-144 
-145                                         core.uvBuf2.bind();
-146                                         core.uvBuf2.setData(data.uv2, data.uv2Offset || 0);
-147 
-148                                         if (data.uv2.length > core.arrays.uv2.length) {
-149                                             core.arrays.uv2 = data.uv2;
-150 
-151                                         } else {
-152                                             core.arrays.uv2.set(data.uv2, data.uv2Offset || 0);
-153                                         }
-154                                     }
-155 
-156                                     if (data.colors && core.colorBuf) {
-157 
-158                                         if (data.colors.length > core.arrays.colors.length) {
-159                                             core.arrays.colors = data.colors;
-160 
-161                                         } else {
-162                                             core.arrays.colors.set(data.colors, data.colorsOffset || 0);
-163                                         }
-164 
-165                                         core.colorBuf.bind();
-166                                         core.colorBuf.setData(data.colors, data.colorsOffset || 0);
-167                                     }
-168 
-169                                     if (data.indices && core.indexBuf) {
-170 
-171                                         if (data.indices.length > core.arrays.indices.length) {
-172                                             core.arrays.indices = data.indices;
-173 
-174                                         } else {
-175                                             core.arrays.indices.set(data.indices, data.indicesOffset || 0);
-176                                         }
-177 
-178                                         core.indexBuf.bind();
-179                                         core.indexBuf.setData(data.indices, data.indicesOffset || 0);
-180 
-181                                         for (var i = 0; i < data.indices.length; i++) {
-182                                             var idx = data.indices[i];
-183                                             if (idx < 0 || idx >= core.arrays.positions.length) {
-184                                                 alert("out of range ");
-185                                             }
-186                                             if (core.arrays.normals && (idx < 0 || idx >= core.arrays.normals.length)) {
-187                                                 alert("out of range ");
-188                                             }
-189                                             if (core.arrays.uv && (idx < 0 || idx >= core.arrays.uv.length)) {
-190                                                 alert("out of range ");
-191                                             }
-192                                             if (core.arrays.uv2 && (idx < 0 || idx >= core.arrays.uv2.length)) {
-193                                                 alert("out of range ");
-194                                             }
-195                                             if (core.arrays.colors && (idx < 0 || idx >= core.arrays.colors.length)) {
-196                                                 alert("out of range ");
-197                                             }
-198                                         }
-199                                     }
-200 
-201                                     self._engine.display.imageDirty = true;
-202                                 });
-203                         }
-204 
-205                         self._core._loading = true;
-206 
-207                         self._fireEvent("loading");
-208 
-209                         self._source.setConfigs(self._sourceConfigs);
-210                     });
-211 
-212             } else {
-213 
-214                 // Build node core from JSON arrays and primitive name given in node properties
-215 
-216                 this._initNodeCore(params, options);
-217 
-218                 SceneJS.Geometry._buildNodeCore(this._engine.canvas.gl, this._core);
-219             }
-220 
-221             this._core.webglRestored = function () {
-222                 SceneJS.Geometry._buildNodeCore(self._engine.canvas.gl, self._core);
-223             };
-224 
-225         }
-226     };
-227 
-228     /**
-229      * Convert JSON arrays into typed arrays,
-230      * apply optional baked Model-space transforms to positions
-231      */
-232     SceneJS.Geometry.prototype._initNodeCore = function (data, options) {
-233 
-234         options = options || {};
-235 
-236         this._core.primitive = this._getPrimitiveType(data.primitive || "triangles");
-237 
-238         this._core.arrays = {
-239             positions:data.positions
-240                 ? new Float32Array((options.scale || options.origin)
-241                 ? this._applyOptions(data.positions, options)
-242                 : data.positions) : undefined,
-243 
-244             normals:data.normals ? new Float32Array(data.normals) : undefined,
-245             uv:data.uv ? new Float32Array(data.uv) : undefined,
-246             uv2:data.uv2 ? new Float32Array(data.uv2) : undefined,
-247             colors:data.colors ? new Float32Array(data.colors) : undefined,
-248             indices:data.indices ? new Uint16Array(data.indices) : undefined
-249         };
-250     };
-251 
-252     /**
-253      * Returns WebGL constant for primitive name
-254      */
-255     SceneJS.Geometry.prototype._getPrimitiveType = function (primitive) {
-256 
-257         var gl = this._engine.canvas.gl;
-258 
-259         switch (primitive) {
-260 
-261             case "points":
-262                 return gl.POINTS;
-263 
-264             case "lines":
-265                 return gl.LINES;
-266 
-267             case "line-loop":
-268                 return gl.LINE_LOOP;
-269 
-270             case "line-strip":
-271                 return gl.LINE_STRIP;
-272 
-273             case "triangles":
-274                 return gl.TRIANGLES;
-275 
-276             case "triangle-strip":
-277                 return gl.TRIANGLE_STRIP;
-278 
-279             case "triangle-fan":
-280                 return gl.TRIANGLE_FAN;
-281 
-282             default:
-283                 throw SceneJS_error.fatalError(
-284                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
-285                     "geometry primitive unsupported: '" +
-286                         primitive +
-287                         "' - supported types are: 'points', 'lines', 'line-loop', " +
-288                         "'line-strip', 'triangles', 'triangle-strip' and 'triangle-fan'");
-289         }
-290     };
-291 
-292     /**
-293      * Apply baked Model-space transformations to give position array
-294      */
-295     SceneJS.Geometry.prototype._applyOptions = function (positions, options) {
-296 
-297         var positions2 = positions.slice ? positions.slice(0) : new Float32Array(positions);  // HACK
-298 
-299         if (options.scale) {
-300 
-301             var scaleX = options.scale.x != undefined ? options.scale.x : 1.0;
-302             var scaleY = options.scale.y != undefined ? options.scale.y : 1.0;
-303             var scaleZ = options.scale.z != undefined ? options.scale.z : 1.0;
-304 
-305             for (var i = 0, len = positions2.length; i < len; i += 3) {
-306                 positions2[i    ] *= scaleX;
-307                 positions2[i + 1] *= scaleY;
-308                 positions2[i + 2] *= scaleZ;
-309             }
-310         }
-311 
-312         if (options.origin) {
-313 
-314             var originX = options.origin.x != undefined ? options.origin.x : 0.0;
-315             var originY = options.origin.y != undefined ? options.origin.y : 0.0;
-316             var originZ = options.origin.z != undefined ? options.origin.z : 0.0;
-317 
-318             for (var i = 0, len = positions2.length; i < len; i += 3) {
-319                 positions2[i    ] -= originX;
-320                 positions2[i + 1] -= originY;
-321                 positions2[i + 2] -= originZ;
-322             }
-323         }
-324 
-325         return positions2;
-326     };
-327 
-328     /**
-329      * Allocates WebGL buffers for geometry arrays
-330      *
-331      * In addition to initially allocating those, this is called to reallocate them after
-332      * WebGL context is regained after being lost.
-333      */
-334     SceneJS.Geometry._buildNodeCore = function (gl, core) {
-335 
-336         var usage = gl.STATIC_DRAW; //var usage = (!arrays.fixed) ? gl.STREAM_DRAW : gl.STATIC_DRAW;
-337 
-338         try { // TODO: Modify usage flags in accordance with how often geometry is evicted
-339 
-340             var arrays = core.arrays;
-341 
-342             if (arrays.positions) {
-343                 core.vertexBuf = new SceneJS_webgl_ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.positions, arrays.positions.length, 3, usage);
-344             }
-345 
-346             if (arrays.normals) {
-347                 core.normalBuf = new SceneJS_webgl_ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.normals, arrays.normals.length, 3, usage);
-348             }
-349 
-350             if (arrays.uv) {
-351                 core.uvBuf = new SceneJS_webgl_ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.uv, arrays.uv.length, 2, usage);
-352             }
-353 
-354             if (arrays.uv2) {
-355                 core.uvBuf2 = new SceneJS_webgl_ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.uv2, arrays.uv2.length, 2, usage);
-356             }
-357 
-358             if (arrays.colors) {
-359                 core.colorBuf = new SceneJS_webgl_ArrayBuffer(gl, gl.ARRAY_BUFFER, arrays.colors, arrays.colors.length, 4, usage);
-360             }
-361 
-362             if (arrays.indices) {
-363                 core.indexBuf = new SceneJS_webgl_ArrayBuffer(gl, gl.ELEMENT_ARRAY_BUFFER, arrays.indices, arrays.indices.length, 1, usage);
-364             }
-365 
-366         } catch (e) { // Allocation failure - delete whatever buffers got allocated
-367 
-368             if (core.vertexBuf) {
-369                 core.vertexBuf.destroy();
-370                 core.vertexBuf = null;
-371             }
-372 
-373             if (core.normalBuf) {
-374                 core.normalBuf.destroy();
-375                 core.normalBuf = null;
-376             }
-377 
-378             if (core.uvBuf) {
-379                 core.uvBuf.destroy();
-380                 core.uvBuf = null;
-381             }
-382 
-383             if (core.uvBuf2) {
-384                 core.uvBuf2.destroy();
-385                 core.uvBuf2 = null;
-386             }
-387 
-388             if (core.colorBuf) {
-389                 core.colorBuf.destroy();
-390                 core.colorBuf = null;
-391             }
-392 
-393             if (core.indexBuf) {
-394                 core.indexBuf.destroy();
-395                 core.indexBuf = null;
-396             }
-397 
-398             throw SceneJS_error.fatalError(
-399                 SceneJS.errors.ERROR,
-400                 "Failed to allocate geometry: " + e);
-401         }
-402     };
-403 
-404     SceneJS.Geometry.prototype._updateArray = function (array, items, offset) {
-405 
-406         var arrayLen = array.length;
-407         var itemsLen = items.length;
-408 
-409         if (itemsLen + offset > arrayLen) {
-410             itemsLen -= (itemsLen + offset) - arrayLen;
-411         }
-412 
-413         for (var i = offset, j = 0; j < itemsLen; i++, j++) {
-414             array[i] = items[j];
-415         }
-416 
-417     };
-418 
-419     SceneJS.Geometry.prototype.setSource = function (sourceConfigs) {
-420         this._sourceConfigs = sourceConfigs;
-421         var source = this._source;
-422         if (source) {
-423             source.setConfigs(sourceConfigs);
-424         }
-425     };
-426 
-427     SceneJS.Geometry.prototype.getSource = function () {
-428         return this._sourceConfigs || {};
-429     };
-430 
-431     SceneJS.Geometry.prototype.setPositions = function (data) {
-432         if (data.positions && this._core.vertexBuf) {
-433             var core = this._core;
-434             core.vertexBuf.bind();
-435             core.vertexBuf.setData(new Float32Array(data.positions), data.positionsOffset || 0);
-436             core.arrays.positions.set(data.positions, data.positionsOffset || 0);
-437             this._engine.display.imageDirty = true;
-438         }
-439     };
-440 
-441     SceneJS.Geometry.prototype.getPositions = function () {
-442         return this._core.arrays ? this._core.arrays.positions : null;
-443     };
-444 
-445     SceneJS.Geometry.prototype.setNormals = function (data) {
-446         if (data.normals && this._core.normalBuf) {
-447             var core = this._core;
-448             core.normalBuf.bind();
-449             core.normalBuf.setData(new Float32Array(data.normals), data.normalsOffset || 0);
-450             core.arrays.normals.set(data.normals, data.normalsOffset || 0);
-451             this._engine.display.imageDirty = true;
-452         }
-453     };
-454 
-455     SceneJS.Geometry.prototype.getNormals = function () {
-456         return this._core.arrays ? this._core.arrays.normals : null;
-457     };
-458 
-459     SceneJS.Geometry.prototype.setColors = function (data) {
-460         if (data.colors && this._core.colorBuf) {
-461             var core = this._core;
-462             core.colorBuf.bind();
-463             core.colorBuf.setData(new Float32Array(data.colors), data.colorsOffset || 0);
-464             core.arrays.colors.set(data.colors, data.colorsOffset || 0);
-465             this._engine.display.imageDirty = true;
-466         }
-467     };
-468 
-469     SceneJS.Geometry.prototype.getColors = function () {
-470         return this._core.arrays ? this._core.arrays.colors : null;
-471     };
-472 
-473     SceneJS.Geometry.prototype.getIndices = function () {
-474         return this._core.arrays ? this._core.arrays.indices : null;
-475     };
-476 
-477     SceneJS.Geometry.prototype.setUV = function (data) {
-478         if (data.uv && this._core.colorBuf) {
-479             var core = this._core;
-480             core.colorBuf.bind();
-481             core.colorBuf.setData(new Float32Array(data.uv), data.uvOffset || 0);
-482             core.arrays.uv.set(data.uv, data.uvOffset || 0);
-483             this._engine.display.imageDirty = true;
-484         }
-485     };
-486 
-487     SceneJS.Geometry.prototype.getUV = function () {
-488         return this._core.arrays ? this._core.arrays.uv : null;
-489     };
-490 
-491     SceneJS.Geometry.prototype.setUV2 = function (data) {
-492         if (data.uv2 && this._core.colorBuf) {
-493             var core = this._core;
-494             core.colorBuf.bind();
-495             core.colorBuf.setData(new Float32Array(data.uv2), data.uv2Offset || 0);
-496             core.arrays.uv2.set(data.uv2, data.uv2Offset || 0);
-497             this._engine.display.imageDirty = true;
-498         }
-499     };
-500 
-501     SceneJS.Geometry.prototype.getUV2 = function () {
-502         return this._core.arrays ? this._core.arrays.uv2 : null;
-503     };
-504 
-505     SceneJS.Geometry.prototype.getPrimitive = function () {
-506         return this.primitive;
-507     };
-508 
-509     SceneJS.Geometry.prototype.getBoundary = function () {
-510         if (this._boundary) {
-511             return this._boundary;
-512         }
-513 
-514         var arrays = this._core.arrays;
-515 
-516         if (!arrays) {
-517             return null;
-518         }
-519 
-520         var positions = arrays.positions;
-521 
-522         if (!positions) {
-523             return null;
-524         }
-525 
-526         this._boundary = {
-527             xmin:SceneJS_math_MAX_DOUBLE,
-528             ymin:SceneJS_math_MAX_DOUBLE,
-529             zmin:SceneJS_math_MAX_DOUBLE,
-530             xmax:SceneJS_math_MIN_DOUBLE,
-531             ymax:SceneJS_math_MIN_DOUBLE,
-532             zmax:SceneJS_math_MIN_DOUBLE
-533         };
-534 
-535         var x, y, z;
-536 
-537         for (var i = 0, len = positions.length - 2; i < len; i += 3) {
-538 
-539             x = positions[i];
-540             y = positions[i + 1];
-541             z = positions[i + 2];
-542 
-543             if (x < this._boundary.xmin) {
-544                 this._boundary.xmin = x;
-545             }
-546             if (y < this._boundary.ymin) {
-547                 this._boundary.ymin = y;
-548             }
-549             if (z < this._boundary.zmin) {
-550                 this._boundary.zmin = z;
-551             }
-552             if (x > this._boundary.xmax) {
-553                 this._boundary.xmax = x;
-554             }
-555             if (y > this._boundary.ymax) {
-556                 this._boundary.ymax = y;
-557             }
-558             if (z > this._boundary.zmax) {
-559                 this._boundary.zmax = z;
-560             }
-561         }
-562 
-563         return this._boundary;
-564     };
-565 
-566     SceneJS.Geometry.prototype._compile = function () {
-567 
-568         if (this._core._loading) {
-569             this._compileNodes();
-570             return;
-571         }
-572 
-573         var core = this._core;
-574 
-575         if (!core.vertexBuf) {
-576 
-577             /* SceneJS.Geometry has no vertex buffer - it must be therefore be indexing a vertex/uv buffers defined
-578              * by a higher Geometry, as part of a composite geometry:
-579              *
-580              * It must therefore inherit the vertex buffer, along with UV coord buffers.
-581              *
-582              * We'll leave it to the render state graph traversal to ensure that the
-583              * vertex and UV buffers are not needlessly rebound for this geometry.
-584              */
-585             core = this._inheritVBOs(core);
-586         }
-587 
-588         if (core.indexBuf) { // Can only render when we have indices
-589 
-590             core.hash = ([                           // Safe to build geometry hash here - geometry is immutable
-591                 core.normalBuf ? "t" : "f",
-592                 core.uvBuf ? "t" : "f",
-593                 core.uvBuf2 ? "t" : "f",
-594                 core.colorBuf ? "t" : "f",
-595                 core.primitive
-596             ]).join("");
-597 
-598             core.stateId = this._core.stateId;
-599             core.type = "geometry";
-600 
-601             this._engine.display.geometry = coreStack[stackLen++] = core;
-602 
-603             SceneJS_events.fireEvent(SceneJS_events.OBJECT_COMPILING, { // Pull in state updates from scenes nodes
-604                 display:this._engine.display
-605             });
-606 
-607             this._engine.display.buildObject(this.id); // Use node ID since we may inherit from many cores
-608 
-609         } else {
-610             coreStack[stackLen++] = this._core;
-611         }
-612 
-613         this._compileNodes();
-614 
-615         stackLen--;
-616     };
-617 
-618     SceneJS.Geometry.prototype._inheritVBOs = function (core) {
-619 
-620         var core2 = {
-621             primitive:core.primitive,
-622             boundary:core.boundary,
-623             normalBuf:core.normalBuf,
-624             uvBuf:core.uvBuf,
-625             uvBuf2:core.uvBuf2,
-626             colorBuf:core.colorBuf,
-627             indexBuf:core.indexBuf
-628         };
-629 
-630         for (var i = stackLen - 1; i >= 0; i--) {
-631             if (coreStack[i].vertexBuf) {
-632                 core2.vertexBuf = coreStack[i].vertexBuf;
-633                 core2.boundary = coreStack[i].boundary;
-634                 core2.normalBuf = coreStack[i].normalBuf;
-635                 core2.uvBuf = coreStack[i].uvBuf;           // Vertex and UVs are a package
-636                 core2.uvBuf2 = coreStack[i].uvBuf2;
-637                 core2.colorBuf = coreStack[i].colorBuf;
-638                 return core2;
-639             }
-640         }
-641 
-642         return core2;
-643     };
-644 
-645     SceneJS.Geometry.prototype._destroy = function () {
-646 
-647         this._engine.display.removeObject(this.id);
-648 
-649         /* Destroy core if no other references
-650          */
-651         if (this._core.useCount == 1) {
-652 
-653             this._destroyNodeCore();
-654 
-655             if (this._source) {
-656                 this._source.destroy();
-657             }
-658         }
-659     };
-660 
-661     SceneJS.Geometry.prototype._destroyNodeCore = function () {
-662 
-663         if (document.getElementById(this._engine.canvas.canvasId)) { // Context won't exist if canvas has disappeared
-664 
-665             var core = this._core;
-666 
-667             if (core.vertexBuf) {
-668                 core.vertexBuf.destroy();
-669             }
-670             if (core.normalBuf) {
-671                 core.normalBuf.destroy();
-672             }
-673             if (core.uvBuf) {
-674                 core.uvBuf.destroy();
-675             }
-676             if (core.uvBuf2) {
-677                 core.uvBuf2.destroy();
-678             }
-679             if (core.colorBuf) {
-680                 core.colorBuf.destroy();
-681             }
-682             if (core.indexBuf) {
-683                 core.indexBuf.destroy();
-684             }
-685         }
-686     };
-687 
-688 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_layer.js.html b/docs/symbols/src/src_core_scene_layer.js.html deleted file mode 100644 index 91994569..00000000 --- a/docs/symbols/src/src_core_scene_layer.js.html +++ /dev/null @@ -1,75 +0,0 @@ -
  1 (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.Layer} nodes
-  5      */
-  6     var defaultCore = {
-  7         type: "layer",
-  8         stateId: SceneJS._baseStateId++,
-  9         priority: 0,
- 10         enabled: true
- 11     };
- 12 
- 13     var coreStack = [];
- 14     var stackLen = 0;
- 15 
- 16     SceneJS_events.addListener(
- 17             SceneJS_events.SCENE_COMPILING,
- 18             function(params) {
- 19                 params.engine.display.layer = defaultCore;
- 20                 stackLen = 0;
- 21             });
- 22 
- 23     /**
- 24      * @class Scene graph node which assigns the {@link SceneJS.Geometry}s within its subgraph to a prioritised render bin
- 25      * @extends SceneJS.Node
- 26      */
- 27     SceneJS.Layer = SceneJS_NodeFactory.createNodeType("layer");
- 28 
- 29     SceneJS.Layer.prototype._init = function(params) {
- 30         if (this._core.useCount == 1) { // This node defines the resource
- 31             this._core.priority = params.priority || 0;
- 32             this._core.enabled = params.enabled !== false;
- 33         }
- 34     };
- 35 
- 36     SceneJS.Layer.prototype.setPriority = function(priority) {
- 37         priority = priority || 0;
- 38         if (this._core.priority != priority) {
- 39             this._core.priority = priority;
- 40             this._engine.display.stateOrderDirty = true;
- 41         }
- 42     };
- 43 
- 44     SceneJS.Layer.prototype.getPriority = function() {
- 45         return this._core.priority;
- 46     };
- 47 
- 48     SceneJS.Layer.prototype.setEnabled = function(enabled) {
- 49         enabled = !!enabled;
- 50         if (this._core.enabled != enabled) {
- 51             this._core.enabled = enabled;
- 52             this._engine.display.drawListDirty = true;
- 53         }
- 54     };
- 55 
- 56     SceneJS.Layer.prototype.getEnabled = function() {
- 57         return this._core.enabled;
- 58     };
- 59 
- 60     SceneJS.Layer.prototype._compile = function() {
- 61         this._engine.display.layer = coreStack[stackLen++] = this._core;
- 62         this._compileNodes();
- 63         this._engine.display.layer = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
- 64     };
- 65 
- 66 })();
- 67 
- 68 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_library.js.html b/docs/symbols/src/src_core_scene_library.js.html deleted file mode 100644 index 5348c2c3..00000000 --- a/docs/symbols/src/src_core_scene_library.js.html +++ /dev/null @@ -1,16 +0,0 @@ -
  1 /**
-  2  * @class Scene graph node which assigns nodes in its subgraph to a library
-  3  * @extends SceneJS.Node
-  4  */
-  5 SceneJS.Library = SceneJS_NodeFactory.createNodeType("library");
-  6 SceneJS.Library.prototype._compile = function() { // Bypass child nodes
-  7 };
-  8 
-  9 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_lights.js.html b/docs/symbols/src/src_core_scene_lights.js.html deleted file mode 100644 index c96aebe6..00000000 --- a/docs/symbols/src/src_core_scene_lights.js.html +++ /dev/null @@ -1,181 +0,0 @@ -
  1 (function () {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.Lights} nodes
-  5      */
-  6     var defaultCore = {
-  7         type:"lights",
-  8         stateId:SceneJS._baseStateId++,
-  9         hash:null,
- 10         empty:false,
- 11         lights:[
- 12             {
- 13                 mode:"ambient",
- 14                 color:[0.6, 0.6, 0.6], // Core has arrays for WebGL loading
- 15                 diffuse:true,
- 16                 specular:false
- 17             },
- 18             {
- 19                 mode:"dir",
- 20                 color:[1.0, 1.0, 1.0 ],
- 21                 diffuse:true,
- 22                 specular:true,
- 23                 dir:[0.5, -1.0, -0.6 ]
- 24             },
- 25             {
- 26                 mode:"dir",
- 27                 color:[1.0, 1.0, 1.0 ],
- 28                 diffuse:true,
- 29                 specular:true,
- 30                 dir:[-1.0, 0.0, 0.0 ]
- 31             }
- 32         ]
- 33     };
- 34 
- 35     makeHash(defaultCore);
- 36 
- 37     function makeHash(core) {
- 38         if (core.lights && core.lights.length > 0) {
- 39             var lights = core.lights;
- 40             var parts = [];
- 41             var light;
- 42             for (var i = 0, len = lights.length; i < len; i++) {
- 43                 light = lights[i];
- 44                 parts.push(light.mode);
- 45                 if (light.specular) {
- 46                     parts.push("s");
- 47                 }
- 48                 if (light.diffuse) {
- 49                     parts.push("d");
- 50                 }
- 51                 parts.push((light.space == "world") ? "w" : "v");
- 52             }
- 53             core.hash = parts.join("");
- 54 
- 55         } else {
- 56             core.hash = "";
- 57         }
- 58     }
- 59 
- 60     var coreStack = [];
- 61     var stackLen = 0;
- 62 
- 63     SceneJS_events.addListener(
- 64         SceneJS_events.SCENE_COMPILING,
- 65         function (params) {
- 66             params.engine.display.lights = defaultCore;
- 67             stackLen = 0;
- 68         });
- 69 
- 70     /**
- 71      * @class Scene graph node which defines light sources to illuminate the {@link SceneJS.Geometry}s within its subgraph
- 72      * @extends SceneJS.Node
- 73      */
- 74     SceneJS.Lights = SceneJS_NodeFactory.createNodeType("lights");
- 75 
- 76     SceneJS.Lights.prototype._init = function (params) {
- 77 
- 78         if (this._core.useCount == 1) { // This node defines the resource
- 79 
- 80             var lights = params.lights;
- 81 
- 82             if (!lights) {
- 83                 throw SceneJS_error.fatalError(
- 84                     SceneJS.errors.NODE_CONFIG_EXPECTED,
- 85                     "lights node attribute missing : 'lights'");
- 86             }
- 87 
- 88             this._core.lights = this._core.lights || [];
- 89 
- 90             for (var i = 0, len = lights.length; i < len; i++) {
- 91                 this._setLight(i, lights[i]);
- 92             }
- 93         }
- 94     };
- 95 
- 96     SceneJS.Lights.prototype.setLights = function (lights) {
- 97         var indexNum;
- 98         for (var index in lights) {
- 99             if (lights.hasOwnProperty(index)) {
-100                 if (index != undefined || index != null) {
-101                     indexNum = parseInt(index);
-102                     if (indexNum < 0 || indexNum >= this._core.lights.length) {
-103                         throw SceneJS_error.fatalError(
-104                             SceneJS.errors.ILLEGAL_NODE_CONFIG,
-105                             "Invalid argument to set 'lights': index out of range (" + this._core.lights.length + " lights defined)");
-106                     }
-107                     this._setLight(indexNum, lights[index] || {});
-108                 }
-109             }
-110         }
-111         this._engine.display.imageDirty = true;
-112     };
-113 
-114     SceneJS.Lights.prototype._setLight = function (index, cfg) {
-115 
-116         var light = this._core.lights[index] || (this._core.lights[index] = []);
-117 
-118         var mode = cfg.mode || "dir";
-119         if (mode != "dir" && mode != "point" && mode != "ambient") {
-120             throw SceneJS_error.fatalError(
-121                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-122                 "Light mode not supported - should be 'dir' or 'point' or 'ambient'");
-123         }
-124 
-125         var pos = cfg.pos;
-126         var dir = cfg.dir;
-127 
-128         var color = cfg.color;
-129         light.color = [
-130             color.r != undefined ? color.r : 1.0,
-131             color.g != undefined ? color.g : 1.0,
-132             color.b != undefined ? color.b : 1.0
-133         ];
-134 
-135         // Ambient lights hardwired to contribute to diffuse lighting
-136         light.mode = mode;
-137         light.diffuse = (mode == "ambient") ? true : ((cfg.diffuse != undefined) ? cfg.diffuse : true);
-138         light.specular = (mode == "ambient") ? false : ((cfg.specular != undefined) ? cfg.specular : true);
-139         light.pos = cfg.pos ? [ pos.x || 0, pos.y || 0, pos.z || 0 ] : undefined;
-140         light.dir = cfg.dir ? [dir.x || 0, dir.y || 0, dir.z || 0] : undefined;
-141         light.constantAttenuation = (cfg.constantAttenuation != undefined) ? cfg.constantAttenuation : 1.0;
-142         light.linearAttenuation = (cfg.linearAttenuation || 0.0);
-143         light.quadraticAttenuation = (cfg.quadraticAttenuation || 0.0);
-144 
-145         var space = cfg.space;
-146 
-147         if (!space) {
-148 
-149             space = "world";
-150 
-151         } else if (space != "view" && space != "world") {
-152 
-153             throw SceneJS_error.fatalError(
-154                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-155                 "lights node invalid value for property 'space': '" + space + "' - should be 'view' or 'world'");
-156         }
-157 
-158         light.space = space;
-159 
-160         this._core.hash = null;
-161     };
-162 
-163     SceneJS.Lights.prototype._compile = function () {
-164 
-165         if (!this._core.hash) {
-166             makeHash(this._core);
-167         }
-168 
-169         this._engine.display.lights = coreStack[stackLen++] = this._core;
-170         this._compileNodes();
-171         this._engine.display.lights = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
-172     };
-173 
-174 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_lookAt.js.html b/docs/symbols/src/src_core_scene_lookAt.js.html deleted file mode 100644 index c6878112..00000000 --- a/docs/symbols/src/src_core_scene_lookAt.js.html +++ /dev/null @@ -1,394 +0,0 @@ -
  1 (function() {
-  2 
-  3     var defaultMatrix = SceneJS_math_identityMat4();
-  4     var defaultMat = new Float32Array(defaultMatrix);
-  5 
-  6     var normalMat = SceneJS_math_transposeMat4(
-  7             SceneJS_math_inverseMat4(
-  8                     SceneJS_math_identityMat4(),
-  9                     SceneJS_math_mat4()));
- 10     var defaultNormalMat = new Float32Array(normalMat);
- 11 
- 12     /**
- 13      * The default state core singleton for {@link SceneJS.LookAt} nodes
- 14      */
- 15     var defaultCore = {
- 16         type: "lookAt",
- 17         stateId: SceneJS._baseStateId++,
- 18         matrix: defaultMatrix,
- 19         mat : defaultMat,
- 20         normalMatrix: normalMat,
- 21         normalMat : defaultNormalMat,
- 22         lookAt: SceneJS_math_LOOKAT_ARRAYS
- 23     };
- 24 
- 25     var coreStack = [];
- 26     var stackLen = 0;
- 27 
- 28     SceneJS_events.addListener(
- 29             SceneJS_events.SCENE_COMPILING,
- 30             function(params) {
- 31                 params.engine.display.viewTransform = defaultCore;
- 32                 stackLen = 0;
- 33             });
- 34 
- 35     /**
- 36      * @class Scene graph node which defines the viewing transform for the {@link SceneJS.Geometry}s within its subgraph
- 37      * @extends SceneJS.Node
- 38      */
- 39     SceneJS.Lookat = SceneJS_NodeFactory.createNodeType("lookAt");
- 40 
- 41     SceneJS.Lookat.prototype._init = function(params) {
- 42 
- 43         this._mat = null;
- 44 
- 45         this._xf = {
- 46             type: "lookat"
- 47         };
- 48 
- 49         if (this._core.useCount == 1) { // This node is the resource definer
- 50 
- 51             this._core.eyeX = 0;
- 52             this._core.eyeY = 0;
- 53             this._core.eyeZ = 1.0;
- 54 
- 55             this._core.lookX = 0;
- 56             this._core.lookY = 0;
- 57             this._core.lookZ = 0;
- 58 
- 59             this._core.upX = 0;
- 60             this._core.upY = 1;
- 61             this._core.upZ = 0;
- 62 
- 63             if (!params.eye && !params.look && !params.up) {
- 64                 this.setEye({x: 0, y: 0, z: 1.0 });
- 65                 this.setLook({x: 0, y: 0, z: 0 });
- 66                 this.setUp({x: 0, y: 1.0, z: 0 });
- 67             } else {
- 68                 this.setEye(params.eye);
- 69                 this.setLook(params.look);
- 70                 this.setUp(params.up);
- 71             }
- 72 
- 73             var core = this._core;
- 74 
- 75             this._core.rebuild = function() {
- 76 
- 77                 core.matrix = SceneJS_math_lookAtMat4c(
- 78                         core.eyeX, core.eyeY, core.eyeZ,
- 79                         core.lookX, core.lookY, core.lookZ,
- 80                         core.upX, core.upY, core.upZ);
- 81 
- 82                 core.lookAt = {
- 83                     eye: [core.eyeX, core.eyeY, core.eyeZ ],
- 84                     look: [core.lookX, core.lookY, core.lookZ ],
- 85                     up:  [core.upX, core.upY, core.upZ ]
- 86                 };
- 87 
- 88                 if (!core.mat) { // Lazy-create arrays
- 89                     core.mat = new Float32Array(core.matrix);
- 90                     core.normalMat = new Float32Array(
- 91                             SceneJS_math_transposeMat4(SceneJS_math_inverseMat4(core.matrix, SceneJS_math_mat4())));
- 92 
- 93                 } else { // Insert into arrays
- 94                     core.mat.set(core.matrix);
- 95                     core.normalMat.set(SceneJS_math_transposeMat4(SceneJS_math_inverseMat4(core.matrix, SceneJS_math_mat4())));
- 96                 }
- 97 
- 98                 core.dirty = false;
- 99             };
-100 
-101             this._core.dirty = true;
-102         }
-103     };
-104 
-105     SceneJS.Lookat.prototype.setEye = function(eye) {
-106 
-107         eye = eye || {};
-108 
-109         if (eye.x != undefined && eye.x != null) {
-110             this._core.eyeX = eye.x;
-111         }
-112 
-113         if (eye.y != undefined && eye.y != null) {
-114             this._core.eyeY = eye.y;
-115         }
-116 
-117         if (eye.z != undefined && eye.z != null) {
-118             this._core.eyeZ = eye.z;
-119         }
-120 
-121         this._core.dirty = true;
-122         this._engine.display.imageDirty = true;
-123 
-124         return this;
-125     };
-126 
-127     SceneJS.Lookat.prototype.incEye = function(eye) {
-128         eye = eye || {};
-129         this._core.eyeX += (eye.x != undefined && eye.x != null) ? eye.x : 0;
-130         this._core.eyeY += (eye.y != undefined && eye.y != null) ? eye.y : 0;
-131         this._core.eyeZ += (eye.z != undefined && eye.z != null) ? eye.z : 0;
-132         this._core.dirty = true;
-133         this._engine.display.imageDirty = true;
-134         return this;
-135     };
-136 
-137     SceneJS.Lookat.prototype.setEyeX = function(x) {
-138         this._core.eyeX = x || 0;
-139         this._core.dirty = true;
-140         this._engine.display.imageDirty = true;
-141         return this;
-142     };
-143 
-144     SceneJS.Lookat.prototype.setEyeY = function(y) {
-145         this._core.eyeY = y || 0;
-146         this._core.dirty = true;
-147         this._engine.display.imageDirty = true;
-148         return this;
-149     };
-150 
-151     SceneJS.Lookat.prototype.setEyeZ = function(z) {
-152         this._core.eyeZ = z || 0;
-153         this._core.dirty = true;
-154         this._engine.display.imageDirty = true;
-155         return this;
-156     };
-157 
-158     SceneJS.Lookat.prototype.incEyeX = function(x) {
-159         this._core.eyeX += x;
-160         this._core.dirty = true;
-161         this._engine.display.imageDirty = true;
-162         return this;
-163     };
-164 
-165     SceneJS.Lookat.prototype.incEyeY = function(y) {
-166         this._core.eyeY += y;
-167         this._core.dirty = true;
-168         this._engine.display.imageDirty = true;
-169         return this;
-170     };
-171 
-172     SceneJS.Lookat.prototype.incEyeZ = function(z) {
-173         this._core.eyeZ += z;
-174         this._core.dirty = true;
-175         this._engine.display.imageDirty = true;
-176         return this;
-177     };
-178 
-179     SceneJS.Lookat.prototype.getEye = function() {
-180         return {
-181             x: this._core.eyeX,
-182             y: this._core.eyeY,
-183             z: this._core.eyeZ
-184         };
-185     };
-186 
-187     SceneJS.Lookat.prototype.setLook = function(look) {
-188         look = look || {};
-189 
-190         if (look.x != undefined && look.x != null) {
-191             this._core.lookX = look.x;
-192         }
-193 
-194         if (look.y != undefined && look.y != null) {
-195             this._core.lookY = look.y;
-196         }
-197 
-198         if (look.z != undefined && look.z != null) {
-199             this._core.lookZ = look.z;
-200         }
-201 
-202         this._core.dirty = true;
-203         this._engine.display.imageDirty = true;
-204         return this;
-205     };
-206 
-207     SceneJS.Lookat.prototype.incLook = function(look) {
-208         look = look || {};
-209         this._core.lookX += (look.x != undefined && look.x != null) ? look.x : 0;
-210         this._core.lookY += (look.y != undefined && look.y != null) ? look.y : 0;
-211         this._core.lookZ += (look.z != undefined && look.z != null) ? look.z : 0;
-212         this._core.dirty = true;
-213         this._engine.display.imageDirty = true;
-214         return this;
-215     };
-216 
-217     SceneJS.Lookat.prototype.setLookX = function(x) {
-218         this._core.lookX = x || 0;
-219         this._core.dirty = true;
-220         this._engine.display.imageDirty = true;
-221         return this;
-222     };
-223 
-224     SceneJS.Lookat.prototype.setLookY = function(y) {
-225         this._core.lookY = y || 0;
-226         this._core.dirty = true;
-227         this._engine.display.imageDirty = true;
-228         return this;
-229     };
-230 
-231     SceneJS.Lookat.prototype.setLookZ = function(z) {
-232         this._core.lookZ = z || 0;
-233         this._core.dirty = true;
-234         this._engine.display.imageDirty = true;
-235         return this;
-236     };
-237 
-238     SceneJS.Lookat.prototype.incLookX = function(x) {
-239         this._core.lookX += x;
-240         this._core.dirty = true;
-241         this._engine.display.imageDirty = true;
-242         return this;
-243     };
-244 
-245     SceneJS.Lookat.prototype.incLookY = function(y) {
-246         this._core.lookY += y;
-247         this._core.dirty = true;
-248         this._engine.display.imageDirty = true;
-249         return this;
-250     };
-251 
-252     SceneJS.Lookat.prototype.incLookZ = function(z) {
-253         this._core.lookZ += z;
-254         this._core.dirty = true;
-255         this._engine.display.imageDirty = true;
-256         return this;
-257     };
-258 
-259     SceneJS.Lookat.prototype.getLook = function() {
-260         return {
-261             x: this._core.lookX,
-262             y: this._core.lookY,
-263             z: this._core.lookZ
-264         };
-265     };
-266 
-267     SceneJS.Lookat.prototype.setUp = function(up) {
-268         up = up || {};
-269 
-270         if (up.x != undefined && up.x != null) {
-271             this._core.upX = up.x;
-272         }
-273 
-274         if (up.y != undefined && up.y != null) {
-275             this._core.upY = up.y;
-276         }
-277 
-278         if (up.z != undefined && up.z != null) {
-279             this._core.upZ = up.z;
-280         }
-281 
-282         this._core.dirty = true;
-283         this._engine.display.imageDirty = true;
-284 
-285         return this;
-286     };
-287 
-288     SceneJS.Lookat.prototype.incUp = function(up) {
-289         up = up || {};
-290         this._core.upX += (up.x != undefined && up.x != null) ? up.x : 0;
-291         this._core.upY += (up.y != undefined && up.y != null) ? up.y : 0;
-292         this._core.upZ += (up.z != undefined && up.z != null) ? up.z : 0;
-293         this._core.dirty = true;
-294         this._engine.display.imageDirty = true;
-295         return this;
-296     };
-297 
-298     SceneJS.Lookat.prototype.setUpX = function(x) {
-299         this._core.upX = x || 0;
-300         this._core.dirty = true;
-301         this._engine.display.imageDirty = true;
-302         return this;
-303     };
-304 
-305     SceneJS.Lookat.prototype.setUpY = function(y) {
-306         this._core.upY = y || 0;
-307         this._core.dirty = true;
-308         this._engine.display.imageDirty = true;
-309         return this;
-310     };
-311 
-312     SceneJS.Lookat.prototype.setUpZ = function(z) {
-313         this._core.upZ = z || 0;
-314         this._core.dirty = true;
-315         this._engine.display.imageDirty = true;
-316         return this;
-317     };
-318 
-319     SceneJS.Lookat.prototype.incUpX = function(x) {
-320         this._core.upX += x;
-321         this._core.dirty = true;
-322         this._engine.display.imageDirty = true;
-323         return this;
-324     };
-325 
-326     SceneJS.Lookat.prototype.incUpY = function(y) {
-327         this._core.upY += y;
-328         this._core.dirty = true;
-329         this._engine.display.imageDirty = true;
-330         return this;
-331     };
-332 
-333     SceneJS.Lookat.prototype.incUpZ = function(z) {
-334         this._core.upZ += z;
-335         this._core.dirty = true;
-336         this._engine.display.imageDirty = true;
-337         return this;
-338     };
-339 
-340     SceneJS.Lookat.prototype.getUp = function() {
-341         return {
-342             x: this._core.upX,
-343             y: this._core.upY,
-344             z: this._core.upZ
-345         };
-346     };
-347 
-348     /**
-349      * Returns a copy of the matrix as a 1D array of 16 elements
-350      * @returns {Number[16]}
-351      */
-352     SceneJS.Lookat.prototype.getMatrix = function() {
-353 
-354         if (this._core.dirty) {
-355             this._core.rebuild();
-356         }
-357 
-358         return  this._mat.slice(0);
-359     };
-360 
-361     SceneJS.Lookat.prototype.getAttributes = function() {
-362         return {
-363             look: {
-364                 x: this._core.lookX,
-365                 y: this._core.lookY,
-366                 z: this._core.lookZ
-367             },
-368             eye: {
-369                 x: this._core.eyeX,
-370                 y: this._core.eyeY,
-371                 z: this._core.eyeZ
-372             },
-373             up: {
-374                 x: this._core.upX,
-375                 y: this._core.upY,
-376                 z: this._core.upZ
-377             }
-378         };
-379     };
-380 
-381     SceneJS.Lookat.prototype._compile = function() {
-382         this._engine.display.viewTransform = coreStack[stackLen++] = this._core;
-383         this._compileNodes();
-384         this._engine.display.viewTransform = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
-385     };
-386 
-387 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_material.js.html b/docs/symbols/src/src_core_scene_material.js.html deleted file mode 100644 index 91061eb0..00000000 --- a/docs/symbols/src/src_core_scene_material.js.html +++ /dev/null @@ -1,149 +0,0 @@ -
  1 /*
-  2 
-  3  TODO: material system from virtualworldframework:
-  4 
-  5  "color":
-  6  "ambient":
-  7  "specColor":
-  8  "shininess":
-  9  "reflect":
- 10  "specular":
- 11  "emit":
- 12  "alpha":
- 13  "binaryAlpha":
- 14  */
- 15 new (function() {
- 16 
- 17     /**
- 18      * The default state core singleton for {@link SceneJS.Material} nodes
- 19      */
- 20     var defaultCore = {
- 21         type: "material",
- 22         stateId: SceneJS._baseStateId++,
- 23         baseColor :  [ 1.0, 1.0, 1.0 ],
- 24         specularColor :  [ 1.0,  1.0,  1.0 ],
- 25         specular : 0.4,
- 26         shine :  20.0,
- 27         alpha :  1.0,
- 28         emit :  0.0
- 29     };
- 30 
- 31     var coreStack = [];
- 32     var stackLen = 0;
- 33 
- 34     SceneJS_events.addListener(
- 35             SceneJS_events.SCENE_COMPILING,
- 36             function(params) {
- 37                 params.engine.display.material = defaultCore;
- 38                 stackLen = 0;
- 39             });
- 40 
- 41     /**
- 42      * @class Scene graph node which defines surface material properties for the {@link SceneJS.Geometry}s within its subgraph
- 43      * @extends SceneJS.Node
- 44      */
- 45     SceneJS.Material = SceneJS_NodeFactory.createNodeType("material");
- 46 
- 47     SceneJS.Material.prototype._init = function(params) {
- 48         if (this._core.useCount == 1) {
- 49             this.setBaseColor(params.baseColor);
- 50             this.setSpecularColor(params.specularColor);
- 51             this.setSpecular(params.specular);
- 52             this.setShine(params.shine);
- 53             this.setEmit(params.emit);
- 54             this.setAlpha(params.alpha);
- 55         }
- 56     };
- 57 
- 58     SceneJS.Material.prototype.setBaseColor = function(color) {
- 59         var defaultBaseColor = defaultCore.baseColor;
- 60         this._core.baseColor = color ? [
- 61             color.r != undefined && color.r != null ? color.r : defaultBaseColor[0],
- 62             color.g != undefined && color.g != null ? color.g : defaultBaseColor[1],
- 63             color.b != undefined && color.b != null ? color.b : defaultBaseColor[2]
- 64         ] : defaultCore.baseColor;
- 65         this._engine.display.imageDirty = true;
- 66         return this;
- 67     };
- 68 
- 69     SceneJS.Material.prototype.getBaseColor = function() {
- 70         return {
- 71             r: this._core.baseColor[0],
- 72             g: this._core.baseColor[1],
- 73             b: this._core.baseColor[2]
- 74         };
- 75     };
- 76 
- 77     SceneJS.Material.prototype.setSpecularColor = function(color) {
- 78         var defaultSpecularColor = defaultCore.specularColor;
- 79         this._core.specularColor = color ? [
- 80             color.r != undefined && color.r != null ? color.r : defaultSpecularColor[0],
- 81             color.g != undefined && color.g != null ? color.g : defaultSpecularColor[1],
- 82             color.b != undefined && color.b != null ? color.b : defaultSpecularColor[2]
- 83         ] : defaultCore.specularColor;
- 84         this._engine.display.imageDirty = true;
- 85         return this;
- 86     };
- 87 
- 88     SceneJS.Material.prototype.getSpecularColor = function() {
- 89         return {
- 90             r: this._core.specularColor[0],
- 91             g: this._core.specularColor[1],
- 92             b: this._core.specularColor[2]
- 93         };
- 94     };
- 95 
- 96     SceneJS.Material.prototype.setSpecular = function(specular) {
- 97         this._core.specular = (specular != undefined && specular != null) ? specular : defaultCore.specular;
- 98         this._engine.display.imageDirty = true;
- 99         return this;
-100     };
-101 
-102     SceneJS.Material.prototype.getSpecular = function() {
-103         return this._core.specular;
-104     };
-105 
-106     SceneJS.Material.prototype.setShine = function(shine) {
-107         this._core.shine = (shine != undefined && shine != null) ? shine : defaultCore.shine;
-108         this._engine.display.imageDirty = true;
-109         return this;
-110     };
-111 
-112     SceneJS.Material.prototype.getShine = function() {
-113         return this._core.shine;
-114     };
-115 
-116     SceneJS.Material.prototype.setEmit = function(emit) {
-117         this._core.emit = (emit != undefined && emit != null) ? emit : defaultCore.emit;
-118         this._engine.display.imageDirty = true;
-119         return this;
-120     };
-121 
-122     SceneJS.Material.prototype.getEmit = function() {
-123         return this._core.emit;
-124     };
-125 
-126     SceneJS.Material.prototype.setAlpha = function(alpha) {
-127         this._core.alpha = (alpha != undefined && alpha != null) ? alpha : defaultCore.alpha;
-128         this._engine.display.imageDirty = true;
-129         return this;
-130     };
-131 
-132     SceneJS.Material.prototype.getAlpha = function() {
-133         return this._core.alpha;
-134     };
-135 
-136     SceneJS.Material.prototype._compile = function() {
-137         this._engine.display.material = coreStack[stackLen++] = this._core;
-138         this._compileNodes();
-139         this._engine.display.material = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
-140     };
-141 
-142 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_matrix.js.html b/docs/symbols/src/src_core_scene_matrix.js.html deleted file mode 100644 index b736784d..00000000 --- a/docs/symbols/src/src_core_scene_matrix.js.html +++ /dev/null @@ -1,93 +0,0 @@ -
  1 
-  2 /**
-  3  * @class Scene graph node which defines a modelling transform matrix to apply to the objects in its subgraph
-  4  * @extends SceneJS.Node
-  5  */
-  6 SceneJS.Matrix = SceneJS_NodeFactory.createNodeType("matrix");
-  7 
-  8 SceneJS.Matrix.prototype._init = function(params) {
-  9 
- 10     if (this._core.useCount == 1) { // This node is the resource definer
- 11 
- 12         SceneJS_modelXFormStack.buildCore(this._core);
- 13 
- 14         this.setElements(params.elements);
- 15     }
- 16 };
- 17 
- 18 /**
- 19  * Get Model matrix
- 20  * @return {*}
- 21  */
- 22 SceneJS.Matrix.prototype.getModelMatrix = function() {
- 23     if (this._core.dirty) {
- 24         this._core.build();
- 25     }
- 26     return this._core.matrix;
- 27 };
- 28 
- 29 /**
- 30  * Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next
- 31  * tranform (scale, matrix, translate etc) node on the path to the scene root.
- 32  * @return {*}
- 33  */
- 34 SceneJS.Matrix.prototype.getWorldMatrix = function() {
- 35     if (this._core.dirty) {
- 36         this._core.build();
- 37     }
- 38     return Array.apply( [], this._core.mat);
- 39 };
- 40 
- 41 /**
- 42  * Sets the matrix elements
- 43  * @type {Function}
- 44  */
- 45 SceneJS.Matrix.prototype.setMatrix = function(elements) {
- 46 
- 47     elements = elements || SceneJS_math_identityMat4();
- 48 
- 49     if (elements.length != 16) {
- 50         throw SceneJS_error.fatalError(
- 51                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
- 52                 "SceneJS.Matrix elements should number 16");
- 53     }
- 54 
- 55     var core = this._core;
- 56 
- 57     if (!core.matrix) {
- 58         core.matrix = elements;
- 59 
- 60     } else {
- 61 
- 62         for (var i = 0; i < 16; i++) {
- 63             core.matrix[i] = elements[i];
- 64         }
- 65     }
- 66 
- 67     core.setDirty();
- 68 
- 69     this._engine.display.imageDirty = true;
- 70 
- 71     return this;
- 72 };
- 73 
- 74 /**
- 75  * Sets the matrix elements
- 76  * @deprecated
- 77  * @type {Function}
- 78  */
- 79 SceneJS.Matrix.prototype.setElements = SceneJS.Matrix.prototype.setMatrix;
- 80 
- 81 SceneJS.Matrix.prototype._compile = function() {
- 82     SceneJS_modelXFormStack.push(this._core);
- 83     this._compileNodes();
- 84     SceneJS_modelXFormStack.pop();
- 85 };
- 86 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_modelXFormStack.js.html b/docs/symbols/src/src_core_scene_modelXFormStack.js.html deleted file mode 100644 index cc4096b6..00000000 --- a/docs/symbols/src/src_core_scene_modelXFormStack.js.html +++ /dev/null @@ -1,223 +0,0 @@ -
  1 /**
-  2  * Provides a model transform stack in front of the renderer.
-  3  * Nodes peek push and pop to the stack, while the renderer peeks at
-  4  * the transform on the top of the stack whenever it builds a renderer node.
-  5  *
-  6  */
-  7 var SceneJS_modelXFormStack = new (function () {
-  8 
-  9     var defaultMatrix = SceneJS_math_identityMat4();
- 10     var defaultMat = new Float32Array(defaultMatrix);
- 11 
- 12     var defaultNormalMatrix = SceneJS_math_transposeMat4(
- 13         SceneJS_math_inverseMat4(
- 14             SceneJS_math_identityMat4(),
- 15             SceneJS_math_mat4()));
- 16     var defaultNormalMat = new Float32Array(defaultNormalMatrix);
- 17 
- 18     var defaultCore = {
- 19         type:"xform",
- 20         stateId:SceneJS._baseStateId++,
- 21 
- 22         matrix:defaultMatrix,
- 23         mat:defaultMat,
- 24 
- 25         normalMatrix:defaultNormalMatrix,
- 26         normalMat:defaultNormalMat,
- 27 
- 28         parent:null, // Parent transform core
- 29         cores:[], // Child transform cores
- 30         numCores:0, // Number of child transform cores
- 31         dirty:false, // Does this subtree need matrices rebuilt
- 32         matrixDirty:false
- 33     };
- 34 
- 35     var transformStack = [];
- 36     var stackLen = 0;
- 37 
- 38     this.top = defaultCore;
- 39 
- 40     var dirty;
- 41 
- 42     var self = this;
- 43 
- 44     SceneJS_events.addListener(
- 45         SceneJS_events.SCENE_COMPILING,
- 46         function () {
- 47             stackLen = 0;
- 48             self.top = defaultCore;
- 49             dirty = true;
- 50         });
- 51 
- 52     SceneJS_events.addListener(
- 53         SceneJS_events.OBJECT_COMPILING,
- 54         function (params) {
- 55 
- 56             if (dirty) {
- 57 
- 58                 if (stackLen > 0) {
- 59 
- 60                     params.display.modelTransform = transformStack[stackLen - 1];
- 61 
- 62                 } else {
- 63 
- 64                     params.display.modelTransform = defaultCore;
- 65                 }
- 66 
- 67                 dirty = false;
- 68             }
- 69         });
- 70 
- 71     /**
- 72      * Creates a fresh transformation core
- 73      * @param core
- 74      */
- 75     this.buildCore = function (core) {
- 76 
- 77         /*
- 78          * Transform tree node properties
- 79          */
- 80         core.parent = null;         // Parent transform core
- 81         core.cores = [];            // Child transform cores
- 82         core.numCores = 0;          // Number of child transform cores
- 83         core.matrixDirty = false;
- 84 
- 85         core.matrix = SceneJS_math_identityMat4();
- 86 
- 87         core.mat = new Float32Array(core.matrix);
- 88         core.normalMat = new Float32Array(
- 89             SceneJS_math_transposeMat4(
- 90                 SceneJS_math_inverseMat4(core.matrix, SceneJS_math_mat4())));
- 91 
- 92         core.dirty = false;         // Does this subtree need matrices rebuilt
- 93 
- 94         core.setDirty = function () {
- 95 
- 96             core.matrixDirty = true;
- 97 
- 98             if (core.dirty) {
- 99                 // return;
-100             }
-101 
-102             setDirty(core);
-103         };
-104 
-105         /**
-106          * Recursively flag this subtree of transforms cores as dirty,
-107          * ie. needing their matrices rebuilt.
-108          */
-109         function setDirty(core) {
-110 
-111             core.dirty = true;
-112             core.matrixDirty = true;
-113 
-114             for (var i = 0, len = core.numCores; i < len; i++) {
-115                 setDirty(core.cores[i]);
-116             }
-117         }
-118 
-119         /**
-120          * Pre-multiply matrices at cores on path up to root into matrix at this core
-121          */
-122         core.build = function () {
-123 
-124             if (core.matrixDirty) {
-125                 if (core.buildMatrix) { // Matrix might be explicit property on some transform node types
-126                     core.buildMatrix();
-127                 }
-128                 core.matrixDirty = false;
-129             }
-130 
-131             var parent = core.parent;
-132 
-133             var matrix;
-134 
-135             if (parent) {
-136 
-137                 matrix = core.matrix.slice(0);
-138 
-139                 while (parent) {
-140 
-141                     if (parent.matrixDirty) {
-142 
-143                         if (parent.buildMatrix) { // Matrix might be explicit property on some transform node types
-144                             parent.buildMatrix();
-145                         }
-146                         parent.mat.set(parent.matrix);
-147                         parent.normalMat.set(
-148                             SceneJS_math_transposeMat4(
-149                                 SceneJS_math_inverseMat4(parent.matrix, SceneJS_math_mat4())));
-150 
-151                         parent.matrixDirty = false;
-152                     }
-153 
-154                     SceneJS_math_mulMat4(parent.matrix, matrix, matrix);
-155 
-156                     if (!parent.dirty) {
-157                         //   break;
-158                     }
-159 
-160                     //  parent.dirty = false;
-161 
-162                     parent = parent.parent;
-163                 }
-164 
-165             } else {
-166 
-167                 matrix = core.matrix;
-168             }
-169 
-170             //            if (!core.mat) {
-171             //
-172             //                core.mat = new Float32Array(matrix);
-173             //
-174             //                core.normalMat = new Float32Array(
-175             //                        SceneJS_math_transposeMat4(
-176             //                                SceneJS_math_inverseMat4(matrix, SceneJS_math_mat4())));
-177             //            } else {
-178 
-179             core.mat.set(matrix);
-180 
-181             core.normalMat.set(
-182                 SceneJS_math_transposeMat4(
-183                     SceneJS_math_inverseMat4(matrix, SceneJS_math_mat4())));
-184             //}
-185 
-186             core.dirty = false;
-187         };
-188     };
-189 
-190     this.push = function (core) {
-191 
-192         transformStack[stackLen++] = core;
-193 
-194         core.parent = this.top;
-195         core.dirty = true;
-196 
-197         if (this.top) {
-198             this.top.cores[this.top.numCores++] = core;
-199         }
-200 
-201         core.numCores = 0;
-202 
-203         this.top = core;
-204 
-205         dirty = true;
-206     };
-207 
-208     this.pop = function () {
-209 
-210         this.top = (--stackLen > 0) ? transformStack[stackLen - 1] : defaultCore;
-211 
-212         dirty = true;
-213     };
-214 
-215 })();
-216 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_morphGeometry.js.html b/docs/symbols/src/src_core_scene_morphGeometry.js.html deleted file mode 100644 index c5345297..00000000 --- a/docs/symbols/src/src_core_scene_morphGeometry.js.html +++ /dev/null @@ -1,390 +0,0 @@ -
  1 new (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.MorphGeometry} nodes
-  5      */
-  6     var defaultCore = {
-  7         type: "morphGeometry",
-  8         stateId: SceneJS._baseStateId++,
-  9         hash: "",
- 10         //         empty: true,
- 11         morph: null
- 12     };
- 13 
- 14     var coreStack = [];
- 15     var stackLen = 0;
- 16 
- 17     SceneJS_events.addListener(
- 18             SceneJS_events.SCENE_COMPILING,
- 19             function(params) {
- 20                 params.engine.display.morphGeometry = defaultCore;
- 21                 stackLen = 0;
- 22             });
- 23 
- 24     /**
- 25      * @class Scene graph node which defines morphing behaviour for the {@link SceneJS.Geometry}s within its subgraph
- 26      * @extends SceneJS.Node
- 27      */
- 28     SceneJS.MorphGeometry = SceneJS_NodeFactory.createNodeType("morphGeometry");
- 29 
- 30     SceneJS.MorphGeometry.prototype._init = function(params) {
- 31 
- 32         if (this._core.useCount == 1) { // This node defines the resource
- 33 
- 34             this._sourceConfigs = params.source;
- 35             this._source = null;
- 36 
- 37             if (params.source) {
- 38 
- 39                 /*---------------------------------------------------------------------------------------------------
- 40                  * Build node core (possibly asynchronously) using a factory object
- 41                  *--------------------------------------------------------------------------------------------------*/
- 42 
- 43                 if (!params.source.type) {
- 44                     throw SceneJS_error.fatalError(
- 45                             SceneJS.errors.ILLEGAL_NODE_CONFIG,
- 46                             "morphGeometry config expected: source.type");
- 47                 }
- 48 
- 49                 var sourceService = SceneJS.Plugins.getPlugin(SceneJS.Plugins.MORPH_GEO_SOURCE_PLUGIN, this._sourceConfigs.type);
- 50 
- 51                 if (!sourceService) {
- 52                     throw SceneJS_error.fatalError(
- 53                             SceneJS.errors.PLUGIN_INVALID,
- 54                             "morphGeometry: no support for source type '" + this._sourceConfigs.type + "' - need to include plugin for this source type, " +
- 55                             "or install a custom source service with SceneJS.Plugins.addPlugin(SceneJS.Plugins.MORPH_GEO_SOURCE_PLUGIN, '" + this._sourceConfigs.type + "', <your service>).");
- 56                 }
- 57 
- 58                 if (!sourceService.getSource) {
- 59                     throw SceneJS_error.fatalError(
- 60                             SceneJS.errors.PLUGIN_INVALID,
- 61                             "morphGeometry: 'getSource' method not found on MorphGeoFactoryService (SceneJS.Plugins.MORPH_GEO_SOURCE_PLUGIN)");
- 62                 }
- 63 
- 64                 this._source = sourceService.getSource();
- 65 
- 66                 if (!this._source.onUpdate) {
- 67                     throw SceneJS_error.fatalError(
- 68                             SceneJS.errors.PLUGIN_INVALID,
- 69                             "morphGeometry: 'onUpdate' method not found on source provided by plugin type '" + params.source.type + "'");
- 70                 }
- 71 
- 72                 var self = this;
- 73 
- 74                 this._source.onCreate(// Get notification when factory creates the morph
- 75                         function(data) {
- 76 
- 77                             self._buildNodeCore(data);
- 78 
- 79                             self._core._loading = false;
- 80                             self._fireEvent("loaded");
- 81 
- 82                             self._engine.branchDirty(this); // TODO
- 83                         });
- 84 
- 85                 if (this._source.onUpdate) {
- 86                     this._source.onUpdate(// Reload factory updates to the morph
- 87                             function(data) {
- 88 
- 89                                 if (data.targets) {
- 90 
- 91                                     var dataTargets = data.targets;
- 92                                     var dataTarget;
- 93                                     var index;
- 94                                     var morphTargets = self._core.targets;
- 95                                     var morphTarget;
- 96 
- 97                                     for (var i = 0, len = dataTargets.length; i < len; i++) {
- 98                                         dataTarget = dataTargets[i];
- 99                                         index = dataTarget.targetIndex;
-100                                         morphTarget = morphTargets[index];
-101 
-102                                         if (dataTarget.positions && morphTarget.vertexBuf) {
-103                                             morphTarget.vertexBuf.bind();
-104                                             morphTarget.vertexBuf.setData(dataTarget.positions, 0);
-105                                         }
-106                                     }
-107                                 }
-108 
-109                                 // TODO: factory can update factor?
-110                                 // this.setFactor(params.factor);
-111 
-112                                 self._display.imageDirty = true;
-113                             });
-114                 }
-115 
-116                 this._core._loading = true;
-117 
-118                 this._fireEvent("loading");
-119 
-120                 this._source.setConfigs(this._sourceConfigs);
-121 
-122             } else if (params.create instanceof Function) {
-123 
-124                 /*---------------------------------------------------------------------------------------------------
-125                  * Build node core from JSON arrays and primitive name returned by factory function
-126                  *--------------------------------------------------------------------------------------------------*/
-127 
-128                 this._buildNodeCore(params.create());
-129 
-130             } else {
-131 
-132                 /*---------------------------------------------------------------------------------------------------
-133                  * Build node core from JSON arrays and primitive name given in node properties
-134                  *--------------------------------------------------------------------------------------------------*/
-135 
-136                 this._buildNodeCore(params);
-137             }
-138 
-139             this._core.webglRestored = function() {
-140                 //self._buildNodeCore(self._engine.canvas.gl, self._core);
-141             };
-142 
-143             this.setFactor(params.factor);
-144         }
-145 
-146         // TODO: factor shared on cores?
-147         this._core.factor = params.factor || 0;
-148         this._core.clamp = !!params.clamp;
-149     };
-150 
-151     SceneJS.MorphGeometry.prototype._buildNodeCore = function(data) {
-152 
-153         var targetsData = data.targets || [];
-154         if (targetsData.length < 2) {
-155             throw SceneJS_error.fatalError(
-156                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
-157                     "morphGeometry node should have at least two targets");
-158         }
-159 
-160         var keysData = data.keys || [];
-161         if (keysData.length != targetsData.length) {
-162             throw SceneJS_error.fatalError(
-163                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
-164                     "morphGeometry node mismatch in number of keys and targets");
-165         }
-166 
-167         var core = this._core;
-168         var gl = this._engine.canvas.gl;
-169         var usage = gl.STATIC_DRAW; //var usage = (!arrays.fixed) ? gl.STREAM_DRAW : gl.STATIC_DRAW;
-170 
-171         core.keys = keysData;
-172         core.targets = [];
-173         core.key1 = 0;
-174         core.key2 = 1;
-175 
-176         /* First target's arrays are defaults for where not given on previous and subsequent targets.
-177          * When target does have array, subsequent targets without array inherit it.
-178          */
-179 
-180         var positions;
-181         var normals;
-182         var uv;
-183         var uv2;
-184 
-185         var targetData;
-186 
-187         for (var i = 0, len = targetsData.length; i < len; i++) {
-188             targetData = targetsData[i];
-189             if (!positions && targetData.positions) {
-190                 positions = targetData.positions;
-191             }
-192             if (!normals && targetData.normals) {
-193                 normals = targetData.normals;
-194             }
-195             if (!uv && targetData.uv) {
-196                 uv = targetData.uv;
-197             }
-198             if (!uv2 && targetData.uv2) {
-199                 uv2 = targetData.uv2;
-200             }
-201         }
-202 
-203         try {
-204             var target;
-205             var arry;
-206 
-207             for (var i = 0, len = targetsData.length; i < len; i++) {
-208                 targetData = targetsData[i];
-209                 target = {};
-210 
-211                 arry = targetData.positions || positions;
-212                 if (arry) {
-213                     target.vertexBuf = new SceneJS_webgl_ArrayBuffer(gl, gl.ARRAY_BUFFER,
-214                             (typeof arry == "Float32Array") ? arry : new Float32Array(arry),
-215                             arry.length, 3, usage);
-216                     positions = arry;
-217                 }
-218 
-219                 arry = targetData.normals || normals;
-220                 if (arry) {
-221                     target.normalBuf = new SceneJS_webgl_ArrayBuffer(gl, gl.ARRAY_BUFFER,
-222                             (typeof arry == "Float32Array") ? arry : new Float32Array(arry),
-223                             arry.length,
-224                             3, usage);
-225                     normals = arry;
-226                 }
-227 
-228                 arry = targetData.uv || uv;
-229                 if (arry) {
-230                     target.uvBuf = new SceneJS_webgl_ArrayBuffer(gl, gl.ARRAY_BUFFER,
-231                             (typeof arry == "Float32Array") ? arry : new Float32Array(arry),
-232                             arry.length, 2, usage);
-233                     uv = arry;
-234                 }
-235 
-236                 arry = targetData.uv2 || uv2;
-237                 if (arry) {
-238                     target.uvBuf2 = new SceneJS_webgl_ArrayBuffer(gl, gl.ARRAY_BUFFER,
-239                             (typeof arry == "Float32Array") ? arry : new Float32Array(arry),
-240                             arry.length, 2, usage);
-241                     uv2 = arry;
-242                 }
-243 
-244                 core.targets.push(target);  // We'll iterate this to destroy targets when we recover from error
-245             }
-246 
-247         } catch (e) {
-248 
-249             /* Allocation failure - deallocate target VBOs
-250              */
-251             for (var i = 0, len = core.targets.length; i < len; i++) {
-252 
-253                 target = core.targets[i];
-254 
-255                 if (target.vertexBuf) {
-256                     target.vertexBuf.destroy();
-257                 }
-258                 if (target.normalBuf) {
-259                     target.normalBuf.destroy();
-260                 }
-261                 if (target.uvBuf) {
-262                     target.uvBuf.destroy();
-263                 }
-264                 if (target.uvBuf2) {
-265                     target.uvBuf2.destroy();
-266                 }
-267             }
-268 
-269             throw SceneJS_error.fatalError(
-270                     SceneJS.errors.ERROR,
-271                     "Failed to allocate VBO(s) for morphGeometry: " + e);
-272         }
-273     };
-274 
-275     SceneJS.MorphGeometry.prototype.setSource = function(sourceConfigs) {
-276         this._sourceConfigs = sourceConfigs;
-277         var source = this._source;
-278         if (source) {
-279             source.setConfigs(sourceConfigs);
-280         }
-281     };
-282 
-283     SceneJS.MorphGeometry.prototype.getSource = function() {
-284         return this._sourceConfigs;
-285     };
-286 
-287     SceneJS.MorphGeometry.prototype.setFactor = function(factor) {
-288         factor = factor || 0.0;
-289 
-290         var core = this._core;
-291 
-292         var keys = core.keys;
-293         var key1 = core.key1;
-294         var key2 = core.key2;
-295 
-296         if (factor < keys[0]) {
-297             key1 = 0;
-298             key2 = 1;
-299 
-300         } else if (factor > keys[keys.length - 1]) {
-301             key1 = keys.length - 2;
-302             key2 = key1 + 1;
-303 
-304         } else {
-305             while (keys[key1] > factor) {
-306                 key1--;
-307                 key2--;
-308             }
-309             while (keys[key2] < factor) {
-310                 key1++;
-311                 key2++;
-312             }
-313         }
-314 
-315         /* Normalise factor to range [0.0..1.0] for the target frame
-316          */
-317         core.factor = (factor - keys[key1]) / (keys[key2] - keys[key1]);
-318         core.key1 = key1;
-319         core.key2 = key2;
-320 
-321         this._engine.display.imageDirty = true;
-322     };
-323 
-324     SceneJS.MorphGeometry.prototype.getFactor = function() {
-325         return this._core.factor;
-326     };
-327 
-328     SceneJS.MorphGeometry.prototype._compile = function() {
-329 
-330         if (!this._core.hash) {
-331             this._makeHash();
-332         }
-333 
-334         this._engine.display.morphGeometry = coreStack[stackLen++] = this._core;
-335         this._compileNodes();
-336         this._engine.display.morphGeometry = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
-337     };
-338 
-339     SceneJS.MorphGeometry.prototype._makeHash = function() {
-340         var core = this._core;
-341         if (core.targets.length > 0) {
-342             var target0 = core.targets[0];  // All targets have same arrays
-343             var t = "t";
-344             var f = "f";
-345             core.hash = ([
-346                 target0.vertexBuf ? t : f,
-347                 target0.normalBuf ? t : f,
-348                 target0.uvBuf ? t : f,
-349                 target0.uvBuf2 ? t : f
-350             ]).join("");
-351         } else {
-352             core.hash = "";
-353         }
-354     };
-355 
-356     SceneJS.MorphGeometry.prototype._destroy = function() {
-357         if (this._core.useCount == 1) { // Destroy core if no other references
-358             if (document.getElementById(this._engine.canvas.canvasId)) { // Context won't exist if canvas has disappeared
-359                 var core = this._core;
-360                 var target;
-361                 for (var i = 0, len = core.targets.length; i < len; i++) {
-362                     target = core.targets[i];
-363                     if (target.vertexBuf) {
-364                         target.vertexBuf.destroy();
-365                     }
-366                     if (target.normalBuf) {
-367                         target.normalBuf.destroy();
-368                     }
-369                     if (target.uvBuf) {
-370                         target.uvBuf.destroy();
-371                     }
-372                     if (target.uvBuf2) {
-373                         target.uvBuf2.destroy();
-374                     }
-375                 }
-376             }
-377             if (this._source) {
-378                 this._source.destroy();
-379             }
-380         }
-381     };
-382 
-383 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_name.js.html b/docs/symbols/src/src_core_scene_name.js.html deleted file mode 100644 index 48c9ca1a..00000000 --- a/docs/symbols/src/src_core_scene_name.js.html +++ /dev/null @@ -1,55 +0,0 @@ -
  1 (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.Name} nodes
-  5      */
-  6     var defaultCore = {
-  7         type: "name",
-  8         stateId: SceneJS._baseStateId++,
-  9         name: null
- 10     };
- 11 
- 12     var coreStack = [];
- 13     var stackLen = 0;
- 14 
- 15     SceneJS_events.addListener(
- 16             SceneJS_events.SCENE_COMPILING,
- 17             function(params) {
- 18                 params.engine.display.name = defaultCore;
- 19                 stackLen = 0;
- 20             });
- 21 
- 22     /**
- 23      * @class Scene graph node which assigns a pick name to the {@link SceneJS.Geometry} nodes in its subgraph.
- 24      * @extends SceneJS.Node
- 25      */
- 26     SceneJS.Name = SceneJS_NodeFactory.createNodeType("name");
- 27 
- 28     SceneJS.Name.prototype._init = function(params) {
- 29         if (this._core.useCount == 1) {
- 30             this.setName(params.name);
- 31         }
- 32     };
- 33 
- 34     SceneJS.Name.prototype.setName = function(name) {
- 35         this._core.name = name || "unnamed";
- 36         this._engine.display.imageDirty = true;
- 37     };
- 38 
- 39     SceneJS.Name.prototype.getName = function() {
- 40         return this._core.name;
- 41     };
- 42 
- 43     SceneJS.Name.prototype._compile = function() {
- 44         this._engine.display.name = coreStack[stackLen++] = this._core;
- 45         this._compileNodes();
- 46         this._engine.display.name = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
- 47     };
- 48 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_node.js.html b/docs/symbols/src/src_core_scene_node.js.html deleted file mode 100644 index c6a0fa64..00000000 --- a/docs/symbols/src/src_core_scene_node.js.html +++ /dev/null @@ -1,1161 +0,0 @@ -
  1 /**
-  2  * @class The basic scene graph node type
-  3  */
-  4 SceneJS.Node = function() {
-  5 };
-  6 
-  7 /**
-  8  * @class Basic scene graph node
-  9  */
- 10 SceneJS.Node.prototype.constructor = SceneJS.Node;
- 11 
- 12 /**
- 13  * Called by SceneJS_Engine after it has instantiated the node
- 14  *
- 15  * @param {SceneJS_Engine} engine The engine which will manage this node
- 16  * @param {SceneJS_Core} core The core which will hold state for this node, may be shared with other nodes of the same type
- 17  * @param cfg Configuration for this node
- 18  * @param {String} cfg.id ID for the node, unique among all nodes in the scene
- 19  * @param {String} cfg.type type Type of this node (eg. "material", "texture" etc)
- 20  * @param {Object} cfg.data Optional arbitrary JSON object to attach to node
- 21  * @param {String} nodeId Optional ID for node
- 22  */
- 23 SceneJS.Node.prototype._construct = function(engine, core, cfg, nodeId) {
- 24 
- 25     /**
- 26      * Engine that manages this node
- 27      * @type SceneJS_Engine
- 28      */
- 29     this._engine = engine;
- 30 
- 31     /**
- 32      * The core which holds state for this node, may be shared with other nodes of the same type
- 33      * @type SceneJS_Core
- 34      */
- 35     this._core = core;
- 36 
- 37     /**
- 38      * ID of this node, unique within its scene. The ID is a string if it was defined by the application
- 39      * via the node's JSON configuration, otherwise it is a number if it was left to SceneJS to automatically create.
- 40      * @type String|Number
- 41      */
- 42     this.id = cfg.id || cfg.nodeId || nodeId;
- 43 
- 44     /**
- 45      * Type of this node (eg. "material", "texture" etc)
- 46      * @type String
- 47      */
- 48     this.type = cfg.type || "node";
- 49 
- 50     /**
- 51      * Optional arbitrary JSON object attached to this node
- 52      * @type JSON
- 53      */
- 54     this.data = cfg.data;
- 55 
- 56     /**
- 57      * Parent node
- 58      * @type SceneJS.Node
- 59      */
- 60     this.parent = null;
- 61 
- 62     /**
- 63      * Child nodes
- 64      * @type SceneJS.Node[]
- 65      */
- 66     this.nodes = [];
- 67 
- 68     /**
- 69      *
- 70      */
- 71     this._listeners = {};
- 72 
- 73     /**
- 74      *
- 75      */
- 76     this._numListeners = 0; // Useful for quick check whether node observes any events
- 77 
- 78     /**
- 79      *
- 80      */
- 81     this.dirty = false;
- 82 
- 83     /**
- 84      *
- 85      */
- 86     this.branchDirty = false;
- 87 
- 88     if (this._init) {
- 89         this._init(cfg);
- 90     }
- 91 };
- 92 
- 93 
- 94 /**
- 95  * Returns this node's {@link SceneJS.Scene}
- 96  */
- 97 SceneJS.Node.prototype.getScene = function() {
- 98     return this._engine.scene;
- 99 };
-100 
-101 
-102 /**
-103  * Returns the ID of this node's core
-104  */
-105 SceneJS.Node.prototype.getCoreId = function() {
-106     return this._core.coreId;
-107 };
-108 
-109 /**
-110  * Get the node's ID
-111  *
-112  */
-113 SceneJS.Node.prototype.getID = function() {
-114     return this.id;
-115 };
-116 
-117 /**
-118  * Alias for getID
-119  *  @function
-120  */
-121 SceneJS.Node.prototype.getId = function() {
-122     return this.id;
-123 };
-124 
-125 /**
-126  * Alias for getID
-127  *  @function
-128  */
-129 SceneJS.Node.prototype.getNodeId = function() {
-130     return this.id;
-131 };
-132 
-133 
-134 /**
-135  * Returns the node's type. For the Node base class, it is "node", overridden in sub-classes.
-136  */
-137 SceneJS.Node.prototype.getType = function() {
-138     return this.type;
-139 };
-140 
-141 /**
-142  * Returns the data object attached to this node.
-143  */
-144 SceneJS.Node.prototype.getData = function() {
-145     return this.data;
-146 };
-147 
-148 /**
-149  * Sets a data object on this node.
-150  */
-151 SceneJS.Node.prototype.setData = function(data) {
-152     this.data = data;
-153     return this;
-154 };
-155 
-156 /**
-157  * Returns the number of child nodes
-158  */
-159 SceneJS.Node.prototype.getNumNodes = function() {
-160     return this.nodes.length;
-161 };
-162 
-163 /** Returns child nodes
-164  * @returns {Array} Child nodes
-165  */
-166 SceneJS.Node.prototype.getNodes = function() {
-167     return this.nodes.slice(0);
-168 };
-169 
-170 /** Returns child node at given index. Returns null if no node at that index.
-171  * @param {Number} index The child index
-172  * @returns {Node} Child node, or null if not found
-173  */
-174 SceneJS.Node.prototype.getNodeAt = function(index) {
-175     if (index < 0 || index >= this.nodes.length) {
-176         return null;
-177     }
-178     return this.nodes[index];
-179 };
-180 
-181 /** Returns first child node. Returns null if no child nodes.
-182  * @returns {Node} First child node, or null if not found
-183  */
-184 SceneJS.Node.prototype.getFirstNode = function() {
-185     if (this.nodes.length == 0) {
-186         return null;
-187     }
-188     return this.nodes[0];
-189 };
-190 
-191 /** Returns last child node. Returns null if no child nodes.
-192  * @returns {Node} Last child node, or null if not found
-193  */
-194 SceneJS.Node.prototype.getLastNode = function() {
-195     if (this.nodes.length == 0) {
-196         return null;
-197     }
-198     return this.nodes[this.nodes.length - 1];
-199 };
-200 
-201 /** Returns child node with the given ID.
-202  * Returns null if no such child node found.
-203  */
-204 SceneJS.Node.prototype.getNode = function(id) {
-205     for (var i = 0; i < this.nodes.length; i++) {
-206         if (this.nodes[i].id == id) {
-207             return this.nodes[i];
-208         }
-209     }
-210     return null;
-211 };
-212 
-213 /** Disconnects the child node at the given index from its parent node
-214  * @param {int} index Child node index
-215  * @returns {Node} The disconnected child node if located, else null
-216  */
-217 SceneJS.Node.prototype.disconnectNodeAt = function(index) {
-218     var r = this.nodes.splice(index, 1);
-219     if (r.length > 0) {
-220         r[0].parent = null;
-221         this._engine.display.objectListDirty = true;
-222         return r[0];
-223     } else {
-224         return null;
-225     }
-226 };
-227 
-228 /** Disconnects the child node from its parent, given as a node object
-229  * @param {String | Node} id The target child node, or its ID
-230  * @returns {Node} The removed child node if located
-231  */
-232 SceneJS.Node.prototype.disconnect = function() {
-233     if (this.parent) {
-234         for (var i = 0; i < this.parent.nodes.length; i++) {
-235             if (this.parent.nodes[i] === this) {
-236                 return this.parent.disconnectNodeAt(i);
-237             }
-238         }
-239     }
-240     return null;
-241 };
-242 
-243 /** Removes the child node at the given index
-244  * @param {int} index Child node index
-245  */
-246 SceneJS.Node.prototype.removeNodeAt = function(index) {
-247     var child = this.disconnectNodeAt(index);
-248     if (child) {
-249         child.destroy();
-250         this._engine.display.objectListDirty = true;
-251     }
-252 };
-253 
-254 /** Removes the child node, given as either a node object or an ID string.
-255  * @param {String | Node} id The target child node, or its ID
-256  * @returns {Node} The removed child node if located
-257  */
-258 SceneJS.Node.prototype.removeNode = function(node) {
-259 
-260     if (!node) {
-261         throw SceneJS_error.fatalError(
-262                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-263                 "Node#removeNode - node argument undefined");
-264     }
-265 
-266     if (!node._compile) {
-267         if (typeof node == "string") {
-268             var gotNode = this._engine.nodes.items[node];
-269             if (!gotNode) {
-270                 throw SceneJS_error.fatalError(
-271                         SceneJS.errors.NODE_NOT_FOUND,
-272                         "Node#removeNode - node not found anywhere: '" + node + "'");
-273             }
-274             node = gotNode;
-275         }
-276     }
-277 
-278     if (node._compile) { //  instance of node
-279         for (var i = 0; i < this.nodes.length; i++) {
-280             if (this.nodes[i] === node) {
-281                 var removedNode = this.removeNodeAt(i);
-282                 this._engine.display.objectListDirty = true;
-283                 return removedNode;
-284             }
-285         }
-286     }
-287 
-288     throw SceneJS_error.fatalError(
-289             SceneJS.errors.NODE_NOT_FOUND,
-290             "Node#removeNode - child node not found: " + (node._compile ? ": " + node.id : node));
-291 };
-292 
-293 /** Disconnects all child nodes from their parent node and returns them in an array.
-294  */
-295 SceneJS.Node.prototype.disconnectNodes = function() {
-296 
-297     var len = this.nodes.length;
-298 
-299     for (var i = 0; i < len; i++) {  // Unlink nodes from this
-300         this.nodes[i].parent = null;
-301     }
-302 
-303     var nodes = this.nodes;
-304 
-305     this.nodes = [];
-306 
-307     this._engine.display.objectListDirty = true;
-308 
-309     return nodes;
-310 };
-311 
-312 /** Removes all child nodes and returns them in an array.
-313  */
-314 SceneJS.Node.prototype.removeNodes = function() {
-315     var nodes = this.disconnectNodes();
-316     for (var i = 0; i < nodes.length; i++) {
-317         this.nodes[i].destroy();
-318         this._engine.display.objectListDirty = true;
-319     }
-320 };
-321 
-322 /** Destroys this node and moves children up to parent, inserting them where this node resided.
-323  */
-324 SceneJS.Node.prototype.splice = function() {
-325 
-326     var i, len;
-327 
-328     if (this.parent == null) {
-329         return null;
-330     }
-331     var parent = this.parent;
-332     var nodes = this.disconnectNodes();
-333     for (i = 0,len = nodes.length; i < len; i++) {  // Link this node's nodes to new parent
-334         nodes[i].parent = this.parent;
-335     }
-336     for (i = 0,len = parent.nodes.length; i < len; i++) { // Replace node on parent's nodes with this node's nodes
-337         if (parent.nodes[i] === this) {
-338 
-339             parent.nodes.splice.apply(parent.nodes, [i, 1].concat(nodes));
-340 
-341             this.nodes = [];
-342             this.parent = null;
-343 
-344             this.destroy();
-345 
-346             this._engine.branchDirty(parent);
-347 
-348             return parent;
-349         }
-350     }
-351 };
-352 
-353 /** Appends multiple child nodes
-354  */
-355 SceneJS.Node.prototype.addNodes = function(nodes) {
-356 
-357     if (!nodes) {
-358         throw SceneJS_error.fatalError(
-359                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-360                 "Node#addNodes - nodes argument is undefined");
-361     }
-362 
-363     var node;
-364     var result = [];
-365 
-366     for (var i = nodes.length - 1; i >= 0; i--) {
-367 
-368         node = this.addNode(nodes[i]);
-369 
-370         result[i] = node;
-371 
-372         this._engine.branchDirty(node); // Schedule compilation of new node
-373     }
-374 
-375     return result;
-376 };
-377 
-378 /** Appends a child node
-379  */
-380 SceneJS.Node.prototype.addNode = function(node) {
-381 
-382     if (!node) {
-383         throw SceneJS_error.fatalError(
-384                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-385                 "Node#addNode - node argument is undefined");
-386     }
-387 
-388     if (!node._compile) {
-389         if (typeof node == "string") {
-390             var gotNode = this._engine.nodes.items[node];
-391             if (!gotNode) {
-392                 throw SceneJS_error.fatalError(
-393                         SceneJS.errors.ILLEGAL_NODE_CONFIG,
-394                         "Node#addNode - node not found: '" + node + "'");
-395             }
-396             node = gotNode;
-397         } else {
-398             node = this._engine.createNode(node);
-399         }
-400     }
-401 
-402     if (!node._compile) {
-403         throw SceneJS_error.fatalError(
-404                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-405                 "Node#addNode - node argument is not a Node or subclass");
-406     }
-407 
-408     if (node.parent != null) {
-409         throw SceneJS_error.fatalError(
-410                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-411                 "Node#addNode - node argument is still attached to another parent");
-412     }
-413 
-414     this.nodes.push(node);
-415 
-416     node.parent = this;
-417 
-418     this._engine.branchDirty(node);
-419 
-420     return node;
-421 };
-422 
-423 /** Inserts a subgraph into child nodes
-424  * @param {Node} node Child node
-425  * @param {int} i Index for new child node
-426  * @return {Node} The child node
-427  */
-428 SceneJS.Node.prototype.insertNode = function(node, i) {
-429 
-430     if (!node) {
-431         throw SceneJS_error.fatalError(
-432                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-433                 "Node#insertNode - node argument is undefined");
-434     }
-435 
-436     if (!node._compile) {
-437         node = this._engine.createNode(node);
-438     }
-439 
-440     if (!node._compile) {
-441         throw SceneJS_error.fatalError(
-442                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-443                 "Node#insertNode - node argument is not a Node or subclass!");
-444     }
-445 
-446     if (node.parent != null) {
-447         throw SceneJS_error.fatalError(
-448                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-449                 "Node#insertNode - node argument is still attached to another parent!");
-450     }
-451 
-452     if (i == undefined || i == null) {
-453 
-454         /* Insert node above nodes when no index given
-455          */
-456         var nodes = this.disconnectNodes();
-457 
-458         /* Move nodes to right-most leaf of inserted graph
-459          */
-460         var leaf = node;
-461         while (leaf.getNumNodes() > 0) {
-462             leaf = leaf.getLastNode();
-463         }
-464 
-465         leaf.addNodes(nodes);
-466 
-467         this.addNode(node);
-468 
-469     } else if (i < 0) {
-470 
-471         throw SceneJS_error.fatalError(
-472                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-473                 "Node#insertNode - node index out of range: -1");
-474 
-475     } else if (i >= this.nodes.length) {
-476         this.nodes.push(node);
-477 
-478     } else {
-479         this.nodes.splice(i, 0, node);
-480     }
-481 
-482     node.parent = this;
-483     return node;
-484 };
-485 
-486 /** Calls the given function on each node in the subgraph rooted by this node, including this node.
-487  * The callback takes each node as it's sole argument and traversal stops as soon as the function returns
-488  * true and returns the node.
-489  * @param {function(Node)} func The function
-490  */
-491 SceneJS.Node.prototype.mapNodes = function(func) {
-492     if (func(this)) {
-493         return this;
-494     }
-495     var result;
-496     for (var i = 0; i < this.nodes.length; i++) {
-497         result = this.nodes[i].mapNodes(func);
-498         if (result) {
-499             return result;
-500         }
-501     }
-502     return null;
-503 };
-504 
-505 /**
-506  * Registers a listener for a given event on this node. If the event type
-507  * is not supported by this node type, then the listener will never be called.
-508  * <p><b>Example:</b>
-509  * <pre><code>
-510  * var node = new Node();
-511  *
-512  * node.addListener(
-513  *
-514  *              // eventName
-515  *              "some-event",
-516  *
-517  *              // handler
-518  *              function(node,      // Node we are listening to
-519  *                       params) {  // Whatever params accompany the event type
-520  *
-521  *                     // ...
-522  *              }
-523  * );
-524  *
-525  *
-526  * </code></pre>
-527  *
-528  * @param {String} eventName One of the event types supported by this node
-529  * @param {Function} fn - Handler function that be called as specified
-530  * @param options - Optional options for the handler as specified
-531  * @return {Node} this
-532  */
-533 SceneJS.Node.prototype.addListener = function(eventName, fn, options) {
-534     var list = this._listeners[eventName];
-535     if (!list) {
-536         list = [];
-537         this._listeners[eventName] = list;
-538     }
-539     list.push({
-540         eventName : eventName,
-541         fn: fn,
-542         options : options || {}
-543     });
-544     this._numListeners++;
-545     return this;
-546 };
-547 
-548 /**
-549  * Fires an event at this node, immediately calling listeners registered for the event
-550  */
-551 SceneJS.Node.prototype._fireEvent = function(eventName, params, options) {
-552     var list = this._listeners[eventName];
-553     if (list) {
-554         if (!params) {
-555             params = {};
-556         }
-557         var event = {
-558             name: eventName,
-559             params : params,
-560             options: options || {}
-561         };
-562         var listener;
-563         for (var i = 0, len = list.length; i < len; i++) {
-564             listener = list[i];
-565             if (listener.options.scope) {
-566                 listener.fn.call(listener.options.scope, event);
-567             } else {
-568                 listener.fn.call(this, event);
-569             }
-570         }
-571     }
-572 };
-573 
-574 /**
-575  * Removes a handler that is registered for the given event on this node.
-576  * Does nothing if no such handler registered.
-577  */
-578 SceneJS.Node.prototype.removeListener = function(eventName, fn) {
-579     var list = this._listeners[eventName];
-580     if (!list) {
-581         return null;
-582     }
-583     for (var i = 0; i < list.length; i++) {
-584         if (list[i].fn == fn) {
-585             list.splice(i, 1);
-586             return fn;
-587         }
-588     }
-589     this._numListeners--;
-590     return null;
-591 };
-592 
-593 /**
-594  * Returns true if this node has any listeners for the given event
-595  */
-596 SceneJS.Node.prototype.hasListener = function(eventName) {
-597     return this._listeners[eventName];
-598 };
-599 
-600 /**
-601  * Returns true if this node has any listeners at all.
-602  */
-603 SceneJS.Node.prototype.hasListeners = function() {
-604     return (this._numListeners > 0);
-605 };
-606 
-607 /** Removes all listeners registered on this node.
-608  */
-609 SceneJS.Node.prototype.removeListeners = function() {
-610     this._listeners = {};
-611     this._numListeners = 0;
-612     return this;
-613 };
-614 
-615 /** Returns the parent node
-616  */
-617 SceneJS.Node.prototype.getParent = function() {
-618     return this.parent;
-619 };
-620 
-621 /**
-622  * Iterates over parent nodes on the path from the selected node to the root, executing a function
-623  * for each.
-624  * If the function returns true at any node, then traversal stops and a selector is
-625  * returned for that node.
-626  * @param {Function(node, index)} fn Function to execute on each instance node
-627  * @return {Object} Selector for selected node, if any
-628  */
-629 SceneJS.Node.prototype.eachParent = function(fn) {
-630 
-631     if (!fn) {
-632         throw "SceneJS.Node.eachParent param 'fn' is null or undefined";
-633     }
-634 
-635     var count = 0;
-636     var node = this;
-637 
-638     while (node.parent) {
-639         if (fn.call(node.parent, count++) === true) {
-640             return node.parent;
-641         }
-642         node = node.parent;
-643     }
-644 
-645     return null;
-646 };
-647 
-648 /** Returns true if a child node matching given ID or index exists on this node
-649  * @param {Number|String} node Child node index or ID
-650  */
-651 SceneJS.Node.prototype.hasNode = function(node) {
-652 
-653     if (node === null || node === undefined) {
-654         throw "SceneJS.Node.hasNode param 'node' is null or undefined";
-655     }
-656 
-657     var type = typeof node;
-658     var nodeGot;
-659 
-660     if (type == "number") {
-661         nodeGot = this.getNodeAt(node);
-662 
-663     } else if (type == "string") {
-664         nodeGot = this.getNode(node);
-665 
-666     } else {
-667         throw "SceneJS.Node.hasNode param 'node' should be either an index number or an ID string";
-668     }
-669 
-670     return (nodeGot != undefined && nodeGot != null);
-671 };
-672 
-673 /** Selects a child node matching given ID or index
-674  * @param {Number|String} node Child node index or ID
-675  */
-676 SceneJS.Node.prototype.node = function(node) {
-677 
-678     if (node === null || node === undefined) {
-679         throw "SceneJS.Node.node param 'node' is null or undefined";
-680     }
-681 
-682     var type = typeof node;
-683     var nodeGot;
-684 
-685     if (type == "number") {
-686         nodeGot = this.getNodeAt(node);
-687 
-688     } else if (type == "string") {
-689         nodeGot = this.getNode(node);
-690 
-691     } else {
-692         throw "SceneJS.Node.node param 'node' should be either an index number or an ID string";
-693     }
-694 
-695     if (!nodeGot) {
-696         throw "SceneJS.Node.node - node not found: '" + node + "'";
-697     }
-698 
-699     return nodeGot;
-700 };
-701 
-702 /**
-703  * Iterates over sub-nodes of the selected node, executing a function
-704  * for each. With the optional options object we can configure is depth-first or breadth-first order.
-705  * If neither, then only the child nodes are iterated.
-706  * If the function returns true at any node, then traversal stops and a selector is
-707  * returned for that node.
-708  * @param {Function(index, node)} fn Function to execute on each child node
-709  * @return {Object} Selector for selected node, if any
-710  */
-711 SceneJS.Node.prototype.eachNode = function(fn, options) {
-712 
-713     if (!fn) {
-714         throw "SceneJS.Node.eachNode param 'fn' is null or undefined";
-715     }
-716 
-717     if (typeof fn != "function") {
-718         throw "SceneJS.Node.eachNode param 'fn' should be a function";
-719     }
-720 
-721     var stoppedNode;
-722     options = options || {};
-723     var count = 0;
-724 
-725     if (options.andSelf) {
-726         if (fn.call(this, count++) === true) {
-727             return this;
-728         }
-729     }
-730 
-731     if (!options.depthFirst && !options.breadthFirst) {
-732         stoppedNode = this._iterateEachNode(fn, this, count);
-733 
-734     } else if (options.depthFirst) {
-735         stoppedNode = this._iterateEachNodeDepthFirst(fn, this, count, false); // Not below root yet
-736 
-737     } else {
-738         // TODO: breadth-first
-739     }
-740 
-741     if (stoppedNode) {
-742         return stoppedNode;
-743     }
-744 
-745     return undefined; // IDE happy now
-746 };
-747 
-748 SceneJS.Node.prototype.numNodes = function() {
-749     return this.nodes.length;
-750 };
-751 
-752 SceneJS.Node.prototype._iterateEachNode = function(fn, node, count) {
-753 
-754     var len = node.nodes.length;
-755     var child;
-756 
-757     for (var i = 0; i < len; i++) {
-758         child = node.nodes[i];
-759 
-760         if (fn.call(child, count++) === true) {
-761             return child;
-762         }
-763     }
-764 
-765     return null;
-766 };
-767 
-768 SceneJS.Node.prototype._iterateEachNodeDepthFirst = function(fn, node, count, belowRoot) {
-769 
-770     if (belowRoot) {
-771 
-772         /* Visit this node - if we are below root, because entry point visits the root
-773          */
-774         if (fn.call(node, count++) === true) {
-775             return node;
-776         }
-777     }
-778 
-779     belowRoot = true;
-780 
-781     /* Iterate nodes
-782      */
-783     var len = node.nodes.length;
-784     var child;
-785     for (var i = 0; i < len; i++) {
-786         child = this._iterateEachNodeDepthFirst(fn, node.nodes[i], count, belowRoot);
-787         if (child) {
-788             return child;
-789         }
-790     }
-791 
-792     return null;
-793 };
-794 
-795 /** Returns either all child or all sub-nodes of the given type, depending on whether search is recursive or not.
-796  */
-797 SceneJS.Node.prototype.findNodesByType = function(type, recursive) {
-798     return this._findNodesByType(type, [], recursive);
-799 };
-800 
-801 SceneJS.Node.prototype._findNodesByType = function(type, list, recursive) {
-802     var i;
-803     for (i = 0; i < this.nodes; i++) {
-804         var node = this.nodes[i];
-805         if (node.type == type) {
-806             list.add(node);
-807         }
-808     }
-809     if (recursive) {
-810         for (i = 0; i < this.nodes; i++) {
-811             this.nodes[i]._findNodesByType(type, list, recursive);
-812         }
-813     }
-814     return list;
-815 };
-816 
-817 /** Finds the first node on path up to root whose type equals that given
-818  */
-819 SceneJS.Node.prototype.findParentByType = function(type) {
-820     var parent = this.parent;
-821     while (parent && parent.type != type) {
-822         parent = parent.parent;
-823     }
-824     return parent;
-825 };
-826 
-827 
-828 /**
-829  * Given a map of name-value pairs, calls a getter method for each name,
-830  * feeding into it the corresponding value.
-831  *
-832  * @param attr
-833  * @param value
-834  * @return {*}
-835  */
-836 SceneJS.Node.prototype.set = function(attr, value) {
-837 
-838     if (typeof attr == "object") { // Attribute map - recurse for each attribute
-839         for (var subAttr in attr) {
-840             if (attr.hasOwnProperty(subAttr)) {
-841                 this.set(subAttr, attr[subAttr]);
-842             }
-843         }
-844         return;
-845     }
-846 
-847     if (this._set) {
-848         var method = this._set[attr];
-849         if (method) {
-850             return method.call(this, value);
-851         }
-852     }
-853 
-854     return this._createAccessor("set", attr, value);
-855 };
-856 
-857 SceneJS.Node.prototype.get = function(attr) {
-858 
-859     if (this._get) {
-860         var method = this._get[attr];
-861         if (method) {
-862             return method.call(this);
-863         }
-864     }
-865 
-866     return this._createAccessor("get", attr);
-867 };
-868 
-869 SceneJS.Node.prototype.add = function(attr, value) {
-870 
-871     if (typeof attr == "object") { // Attribute map - recurse for each attribute
-872         for (var subAttr in attr) {
-873             if (attr.hasOwnProperty(subAttr)) {
-874                 this.add(subAttr, attr[subAttr]);
-875             }
-876         }
-877         return;
-878     }
-879 
-880     if (this._add) {
-881         var method = this._add[attr];
-882         if (method) {
-883             return method.call(this, value);
-884         }
-885     }
-886 
-887     return this._createAccessor("add", attr, value);
-888 };
-889 
-890 SceneJS.Node.prototype.inc = function(attr, value) {
-891 
-892     if (typeof attr == "object") { // Attribute map - recurse for each attribute
-893         for (var subAttr in attr) {
-894             if (attr.hasOwnProperty(subAttr)) {
-895                 this.inc(subAttr, attr[subAttr]);
-896             }
-897         }
-898         return;
-899     }
-900 
-901     if (this._inc) {
-902         var method = this._inc[attr];
-903         if (method) {
-904             return method.call(this, value);
-905         }
-906     }
-907 
-908     return this._createAccessor("inc", attr, value);
-909 };
-910 
-911 SceneJS.Node.prototype.insert = function(attr, value) {
-912 
-913     if (typeof attr == "object") { // Attribute map - recurse for each attribute
-914         for (var subAttr in attr) {
-915             if (attr.hasOwnProperty(subAttr)) {
-916                 this.insert(subAttr, attr[subAttr]);
-917             }
-918         }
-919         return;
-920     }
-921 
-922     if (this._set) {
-923         var method = this._set[attr];
-924         if (method) {
-925             return method.call(this, value);
-926         }
-927     }
-928 
-929     return this._createAccessor("insert", attr, value);
-930 };
-931 
-932 SceneJS.Node.prototype.remove = function(attr, value) {
-933 
-934     if (typeof attr == "object") { // Attribute map - recurse for each attribute
-935         for (var subAttr in attr) {
-936             if (attr.hasOwnProperty(subAttr)) {
-937                 this.remove(subAttr, attr[subAttr]);
-938             }
-939         }
-940         return;
-941     }
-942 
-943     if (this._remove) {
-944         var method = this._remove[attr];
-945         if (method) {
-946             return method.call(this, value);
-947         }
-948     }
-949 
-950     return this._createAccessor("remove", attr, value);
-951 };
-952 
-953 SceneJS.Node.prototype._createAccessor = function(op, attr, value) {
-954 
-955     var methodName = op + attr.substr(0, 1).toUpperCase() + attr.substr(1);
-956 
-957     var method = this[methodName];
-958 
-959     if (!method) {
-960         throw "Method not found on node: '" + methodName + "'";
-961     }
-962 
-963     //var proto = (this.type == "node") ? SceneJS.Node.prototype : this._engine.nodeTypes[this.type].prototype;
-964 
-965     var proto = this.__proto__;
-966 
-967     var accessors;
-968     switch (op) {
-969         case "set":
-970             accessors = (proto._set || (proto._set = {}));
-971             break;
-972 
-973         case "get":
-974             accessors = (proto._get || (proto._get = {}));
-975             break;
-976 
-977         case "inc":
-978             accessors = (proto._inc || (proto._inc = {}));
-979             break;
-980 
-981         case "add":
-982             accessors = (proto._add || (proto._add = {}));
-983             break;
-984 
-985         case "insert":
-986             accessors = (proto._insert || (proto._insert = {}));
-987             break;
-988 
-989         case "remove":
-990             accessors = (proto._remove || (proto._remove = {}));
-991             break;
-992     }
-993 
-994     accessors[attr] = method;
-995 
-996     return method.call(this, value); // value can be undefined
-997 };
-998 
-999 /** Binds a listener to an event on the selected node
-1000  *
-1001  * @param {String} name Event name
-1002  * @param {Function} handler Event handler
-1003  */
-1004 SceneJS.Node.prototype.bind = function(name, handler) {
-1005 
-1006     if (!name) {
-1007         throw "SceneJS.Node.bind param 'name' null or undefined";
-1008     }
-1009 
-1010     if (typeof name != "string") {
-1011         throw "SceneJS.Node.bind param 'name' should be a string";
-1012     }
-1013 
-1014     if (!handler) {
-1015         throw "SceneJS.Node.bind param 'handler' null or undefined";
-1016     }
-1017 
-1018     if (typeof handler != "function") {
-1019         throw "SceneJS.Node.bind param 'handler' should be a function";
-1020     }
-1021 
-1022     this.addListener(name, handler, { scope: this });
-1023 
-1024     this._engine.branchDirty(this);
-1025 
-1026     return this;
-1027 };
-1028 
-1029 /** Unbinds a listener for an event on the selected node
-1030  *
-1031  * @param {String} name Event name
-1032  * @param {Function} handler Event handler
-1033  */
-1034 SceneJS.Node.prototype.unbind = function(name, handler) {
-1035     if (!name) {
-1036         throw "SceneJS.Node.bind param 'name' null or undefined";
-1037     }
-1038     if (typeof name != "string") {
-1039         throw "SceneJS.Node.bind param 'name' should be a string";
-1040     }
-1041     if (!handler) {
-1042         throw "SceneJS.Node.bind param 'handler' null or undefined";
-1043     }
-1044     if (typeof handler != "function") {
-1045         throw "SceneJS.Node.bind param 'handler' should be a function";
-1046     }
-1047 
-1048     this.removeListener(name, handler);
-1049 
-1050     this._engine.branchDirty(this);
-1051 
-1052     return this;
-1053 };
-1054 
-1055 /**
-1056  * Returns an object containing the attributes that were given when creating the node. Obviously, the map will have
-1057  * the current values, plus any attributes that were later added through set/add methods on the node
-1058  *
-1059  */
-1060 SceneJS.Node.prototype.getJSON = function() {
-1061     return this;
-1062 };
-1063 
-1064 
-1065 SceneJS.Node.prototype._compile = function() {
-1066     this._compileNodes();
-1067 };
-1068 
-1069 SceneJS.Node.prototype._compileNodes = function() {
-1070 
-1071     var renderListeners = this._listeners["rendered"];
-1072 
-1073     if (renderListeners) {
-1074         SceneJS_nodeEventsModule.preVisitNode(this);
-1075     }
-1076 
-1077     var child;
-1078 
-1079     for (var i = 0, len = this.nodes.length; i < len; i++) {
-1080 
-1081         child = this.nodes[i];
-1082 
-1083         child.branchDirty = child.branchDirty || this.branchDirty; // Compile subnodes if scene branch dirty
-1084 
-1085         if (child.dirty || child.branchDirty || this._engine.sceneDirty) {  // Compile nodes that are flagged dirty
-1086 
-1087             child._compile();
-1088 
-1089             child.dirty = false;
-1090             child.branchDirty = false;
-1091         }
-1092     }
-1093 
-1094     if (renderListeners) {
-1095         SceneJS_nodeEventsModule.postVisitNode(this);
-1096     }
-1097 };
-1098 
-1099 
-1100 /**
-1101  * Destroys this node. It is marked for destruction; when the next scene traversal begins (or the current one ends)
-1102  * it will be destroyed and removed from it's parent.
-1103  */
-1104 SceneJS.Node.prototype.destroy = function() {
-1105 
-1106     if (!this.destroyed) {
-1107 
-1108         if (this.parent) {
-1109 
-1110             /* Remove from parent's child node list
-1111              */
-1112             for (var i = 0; i < this.nodes.length; i++) {
-1113                 if (this.parent.nodes[i].id === this.id) {
-1114                     this.parent.nodes.splice(i, 1);
-1115                     break;
-1116                 }
-1117             }
-1118         }
-1119 
-1120         /* Recusrsively destroy child nodes without
-1121          * bothering to remove them from their parents
-1122          */
-1123         this._destroyTree();
-1124 
-1125         /* Need object list recompilation on display
-1126          */
-1127         this._engine.display.objectListDirty = true;
-1128     }
-1129 
-1130     return this;
-1131 };
-1132 
-1133 SceneJS.Node.prototype._destroyTree = function() {
-1134 
-1135     this.destroyed = true;
-1136 
-1137     this._engine.destroyNode(this); // Release node object
-1138 
-1139     for (var i = 0, len = this.nodes.length; i < len; i++) {
-1140         this.nodes[i]._destroyTree();
-1141     }
-1142 };
-1143 
-1144 /**
-1145  * Performs the actual destruction of this node, calling the node's optional template destroy method
-1146  */
-1147 SceneJS.Node.prototype._doDestroy = function() {
-1148 
-1149     if (this._destroy) {  // Call destruction handler for each node subclass
-1150         this._destroy();
-1151     }
-1152 
-1153     return this;
-1154 };
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_nodeEvents.js.html b/docs/symbols/src/src_core_scene_nodeEvents.js.html deleted file mode 100644 index e1566adc..00000000 --- a/docs/symbols/src/src_core_scene_nodeEvents.js.html +++ /dev/null @@ -1,87 +0,0 @@ -
  1 /**
-  2  * Manages scene node event listeners
-  3  * @private
-  4  */
-  5 var SceneJS_nodeEventsModule = new (function() {
-  6 
-  7     var idStack = [];
-  8     var listenerStack = [];
-  9     var stackLen = 0;
- 10     var dirty;
- 11 
- 12     var defaultCore = {
- 13         type: "listeners",
- 14         stateId: SceneJS._baseStateId++,
- 15         empty: true,
- 16         listeners:  []
- 17     };
- 18 
- 19     SceneJS_events.addListener(
- 20             SceneJS_events.SCENE_COMPILING,
- 21             function() {
- 22                 stackLen = 0;
- 23                 dirty = true;
- 24             });
- 25 
- 26     SceneJS_events.addListener(
- 27             SceneJS_events.OBJECT_COMPILING,
- 28             function(params) {
- 29 
- 30                 if (dirty) {
- 31 
- 32                     if (stackLen > 0) {
- 33 
- 34                         var core = {
- 35                             type: "listeners",
- 36                             stateId: idStack[stackLen - 1],
- 37                             listeners: listenerStack.slice(0, stackLen)
- 38                         };
- 39 
- 40                         params.display.renderListeners = core;
- 41 
- 42                     } else {
- 43 
- 44                         params.display.renderListeners = defaultCore;
- 45                     }
- 46 
- 47                     dirty = false;
- 48                 }
- 49             });
- 50 
- 51     this.preVisitNode = function(node) {
- 52 
- 53         var listeners = node._listeners["rendered"];
- 54 
- 55         if (listeners && listeners.length > 0) {
- 56             idStack[stackLen] = node.id;
- 57 
- 58             var fn = node.__fireRenderedEvent;
- 59             if (!fn) {
- 60                 fn = node.__fireRenderedEvent = function (params) {
- 61                     node._fireEvent("rendered", params);
- 62                 };
- 63             }
- 64 
- 65             listenerStack[stackLen] = fn;
- 66             stackLen++;
- 67             dirty = true;
- 68         }
- 69     };
- 70 
- 71     this.postVisitNode = function(node) {
- 72         if (node.id == idStack[stackLen - 1]) {
- 73             stackLen--;
- 74             dirty = true;
- 75         }
- 76     };
- 77 
- 78 })();
- 79 
- 80 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_nodeFactory.js.html b/docs/symbols/src/src_core_scene_nodeFactory.js.html deleted file mode 100644 index d633a135..00000000 --- a/docs/symbols/src/src_core_scene_nodeFactory.js.html +++ /dev/null @@ -1,91 +0,0 @@ -
  1 /**
-  2  * @class Manages creation, recycle and destruction of {@link SceneJS.Node} instances
-  3  * @private
-  4  */
-  5 var SceneJS_NodeFactory = function() {
-  6 
-  7     this.nodes = new SceneJS_Map({});
-  8 };
-  9 
- 10 /**
- 11  * Scene graph node classes provided by the SceneJS_NodeFactory class
- 12  *
- 13  * @type {[SceneJS.Node]}
- 14  */
- 15 SceneJS_NodeFactory.nodeTypes = {};    // Supported node classes, installed by #createNodeType
- 16 
- 17 /**
- 18  * Creates a node class for instantiation by this factory
- 19  *
- 20  * @param {String} nodeTypeName Name of type, eg. "rotate"
- 21  * @param {String} coreTypeName Optional name of core type for the node, eg. "xform" - defaults to type name of node
- 22  * @returns The new node class
- 23  */
- 24 SceneJS_NodeFactory.createNodeType = function(nodeTypeName, coreTypeName) {
- 25 
- 26     var nodeType = function() { // Create the class
- 27         SceneJS.Node.apply(this, arguments);
- 28         this.type = nodeTypeName;
- 29     };
- 30 
- 31     nodeType.prototype = new SceneJS.Node();            // Inherit from base class
- 32     nodeType.prototype.constructor = nodeType;
- 33 
- 34     SceneJS_NodeFactory.nodeTypes[nodeTypeName] = nodeType;
- 35 
- 36     return nodeType;
- 37 };
- 38 
- 39 /**
- 40  *
- 41  */
- 42 SceneJS_NodeFactory.prototype.getNode = function(engine, json, core) {
- 43 
- 44     json.type = json.type || "node"; // Nodes are SceneJS.Node type by default
- 45 
- 46     var nodeType;
- 47 
- 48     if (json.type == "node") {
- 49 
- 50         nodeType = SceneJS.Node;
- 51 
- 52     } else {
- 53 
- 54         nodeType = SceneJS_NodeFactory.nodeTypes[json.type];
- 55 
- 56         if (!nodeType) {
- 57             throw SceneJS_error.fatalError("node type not supported: '" + json.type + "'");
- 58         }
- 59     }
- 60 
- 61     var node = new nodeType();
- 62 
- 63     var id = json.id || json.nodeId; // 'id' and 'nodeId' are aliases
- 64 
- 65     if (id) {
- 66         this.nodes.addItem(id, node);
- 67 
- 68     } else {
- 69         id = this.nodes.addItem(node);
- 70     }
- 71 
- 72     node._construct(engine, core, json, id); // Instantiate node
- 73 
- 74     return node;
- 75 };
- 76 
- 77 /**
- 78  * Releases a node back to this factory
- 79  */
- 80 SceneJS_NodeFactory.prototype.putNode = function(node) {
- 81 
- 82     this.nodes.removeItem(node.id);
- 83 };
- 84 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_renderer.js.html b/docs/symbols/src/src_core_scene_renderer.js.html deleted file mode 100644 index d5774432..00000000 --- a/docs/symbols/src/src_core_scene_renderer.js.html +++ /dev/null @@ -1,787 +0,0 @@ -
  1 new (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.Renderer} nodes
-  5      */
-  6     var defaultCore = {
-  7         type: "renderer",
-  8         stateId: SceneJS._baseStateId++,
-  9         props: null
- 10     };
- 11 
- 12     var canvas;         // Currently active canvas
- 13     var coreStack = [];
- 14     var stackLen = 0;
- 15 
- 16     SceneJS_events.addListener(
- 17             SceneJS_events.SCENE_COMPILING,
- 18             function(params) {
- 19 
- 20                 canvas = params.engine.canvas;
- 21 
- 22 //                // TODO: Below is a HACK
- 23 //
- 24 //                defaultCore.props = createProps({  // Dont set props - just define for restoring to on props pop
- 25 //                    clear: {
- 26 //                        depth : true,
- 27 //                        color : true
- 28 //                    },
- 29 //                    // clearColor: {r: 0, g : 0, b : 0 },
- 30 //                    clearDepth: 1.0,
- 31 //                    enableDepthTest:true,
- 32 //                    enableCullFace: false,
- 33 //                    frontFace: "ccw",
- 34 //                    cullFace: "back",
- 35 //                    depthFunc: "less",
- 36 //                    depthRange: {
- 37 //                        zNear: 0,
- 38 //                        zFar: 1
- 39 //                    },
- 40 //                    enableScissorTest: false,
- 41 //                    viewport:{
- 42 //                        x : 1,
- 43 //                        y : 1,
- 44 //                        width: canvas.canvas.width,
- 45 //                        height: canvas.canvas.height
- 46 //                    },
- 47 //                    enableClip: undefined,
- 48 //                    enableBlend: false,
- 49 //                    blendFunc: {
- 50 //                        sfactor: "srcAlpha",
- 51 //                        dfactor: "one"
- 52 //                    }
- 53 //                });
- 54 
- 55                 stackLen = 0;
- 56 
- 57                 params.engine.display.renderer = coreStack[stackLen++] = defaultCore;
- 58             });
- 59 
- 60     function createProps(props) {
- 61 
- 62         var restore;
- 63         if (stackLen > 0) {  // can't restore when no previous props set
- 64             restore = {};
- 65             for (var name in props) {
- 66                 if (props.hasOwnProperty(name)) {
- 67                     if (!(props[name] == undefined)) {
- 68                         restore[name] = getSuperProperty(name);
- 69                     }
- 70                 }
- 71             }
- 72         }
- 73 
- 74         processProps(props.props);
- 75 
- 76         return {
- 77 
- 78             props: props,
- 79 
- 80             setProps: function(gl) {
- 81                 setProperties(gl, props);
- 82             },
- 83 
- 84             restoreProps : function(gl) {
- 85                 if (restore) {
- 86                     restoreProperties(gl, restore);
- 87                 }
- 88             }
- 89         };
- 90     }
- 91 
- 92     var getSuperProperty = function(name) {
- 93         var props;
- 94         var prop;
- 95         for (var i = stackLen - 1; i >= 0; i--) {
- 96             props = coreStack[i].props;
- 97             prop = props[name];
- 98             if (prop != undefined && prop != null) {
- 99                 return props[name];
-100             }
-101         }
-102         return null; // Cause default to be set
-103     };
-104 
-105     function processProps(props) {
-106         var prop;
-107         for (var name in props) {
-108             if (props.hasOwnProperty(name)) {
-109                 prop = props[name];
-110                 if (prop != undefined && prop != null) {
-111                     if (glModeSetters[name]) {
-112                         props[name] = glModeSetters[name](null, prop);
-113                     } else if (glStateSetters[name]) {
-114                         props[name] = glStateSetters[name](null, prop);
-115                     }
-116                 }
-117             }
-118         }
-119     }
-120 
-121     var setProperties = function(gl, props) {
-122 
-123         for (var key in props) {        // Set order-insensitive properties (modes)
-124             if (props.hasOwnProperty(key)) {
-125                 var setter = glModeSetters[key];
-126                 if (setter) {
-127                     setter(gl, props[key]);
-128                 }
-129             }
-130         }
-131 
-132         if (props.viewport) {           // Set order-sensitive properties (states)
-133             glStateSetters.viewport(gl, props.viewport);
-134         }
-135 
-136         if (props.scissor) {
-137             glStateSetters.clear(gl, props.scissor);
-138         }
-139 
-140         if (props.clear) {
-141             glStateSetters.clear(gl, props.clear);
-142         }
-143     };
-144 
-145     /**
-146      * Restores previous renderer properties, except for clear - that's the reason we
-147      * have a seperate set and restore semantic - we don't want to keep clearing the buffer.
-148      */
-149     var restoreProperties = function(gl, props) {
-150 
-151         var value;
-152 
-153         for (var key in props) {            // Set order-insensitive properties (modes)
-154             if (props.hasOwnProperty(key)) {
-155                 value = props[key];
-156                 if (value != undefined && value != null) {
-157                     var setter = glModeSetters[key];
-158                     if (setter) {
-159                         setter(gl, value);
-160                     }
-161                 }
-162             }
-163         }
-164 
-165         if (props.viewport) {               //  Set order-sensitive properties (states)
-166             glStateSetters.viewport(gl, props.viewport);
-167         }
-168 
-169         if (props.scissor) {
-170             glStateSetters.clear(gl, props.scissor);
-171         }
-172     };
-173 
-174 
-175     /**
-176      * Maps renderer node properties to WebGL gl enums
-177      * @private
-178      */
-179     var glEnum = function(gl, name) {
-180         if (!name) {
-181             throw SceneJS_error.fatalError(
-182                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
-183                     "Null SceneJS.State node config: \"" + name + "\"");
-184         }
-185         var result = SceneJS_webgl_enumMap[name];
-186         if (!result) {
-187             throw SceneJS_error.fatalError(
-188                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
-189                     "Unrecognised SceneJS.State node config value: \"" + name + "\"");
-190         }
-191         var value = gl[result];
-192         if (!value) {
-193             throw SceneJS_error.fatalError(
-194                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
-195                     "This browser's WebGL does not support renderer node config value: \"" + name + "\"");
-196         }
-197         return value;
-198     };
-199 
-200 
-201     /**
-202      * Order-insensitive functions that set WebGL modes ie. not actually causing an
-203      * immediate change.
-204      *
-205      * These map to renderer properties and are called in whatever order their
-206      * property is found on the renderer config.
-207      *
-208      * Each of these wrap a state-setter function on the WebGL gl. Each function
-209      * also uses the glEnum map to convert its renderer node property argument to the
-210      * WebGL enum constant required by its wrapped function.
-211      *
-212      * When called with undefined/null gl, will condition and return the value given
-213      * ie. set it to default if value is undefined. When called with a gl, will
-214      * set the value on the gl using the wrapped function.
-215      *
-216      * @private
-217      */
-218     var glModeSetters = {
-219 
-220         enableBlend: function(gl, flag) {
-221             if (!gl) {
-222                 if (flag == null || flag == undefined) {
-223                     flag = false;
-224                 }
-225                 return flag;
-226             }
-227             if (flag) {
-228                 gl.enable(gl.BLEND);
-229             } else {
-230                 gl.disable(gl.BLEND);
-231             }
-232         },
-233 
-234         blendColor: function(gl, color) {
-235             if (!gl) {
-236                 color = color || {};
-237                 return {
-238                     r: color.r || 0,
-239                     g: color.g || 0,
-240                     b: color.b || 0,
-241                     a: (color.a == undefined || color.a == null) ? 1 : color.a
-242                 };
-243             }
-244             gl.blendColor(color.r, color.g, color.b, color.a);
-245         },
-246 
-247         blendEquation: function(gl, eqn) {
-248             if (!gl) {
-249                 return eqn || "funcAdd";
-250             }
-251             gl.blendEquation(gl, glEnum(gl, eqn));
-252         },
-253 
-254         /** Sets the RGB blend equation and the alpha blend equation separately
-255          */
-256         blendEquationSeparate: function(gl, eqn) {
-257             if (!gl) {
-258                 eqn = eqn || {};
-259                 return {
-260                     rgb : eqn.rgb || "funcAdd",
-261                     alpha : eqn.alpha || "funcAdd"
-262                 };
-263             }
-264             gl.blendEquation(glEnum(gl, eqn.rgb), glEnum(gl, eqn.alpha));
-265         },
-266 
-267         blendFunc: function(gl, funcs) {
-268             if (!gl) {
-269                 funcs = funcs || {};
-270                 return  {
-271                     sfactor : funcs.sfactor || "srcAlpha",
-272                     dfactor : funcs.dfactor || "oneMinusSrcAlpha"
-273                 };
-274             }
-275             gl.blendFunc(glEnum(gl, funcs.sfactor || "srcAlpha"), glEnum(gl, funcs.dfactor || "oneMinusSrcAlpha"));
-276         },
-277 
-278         blendFuncSeparate: function(gl, func) {
-279             if (!gl) {
-280                 func = func || {};
-281                 return {
-282                     srcRGB : func.srcRGB || "zero",
-283                     dstRGB : func.dstRGB || "zero",
-284                     srcAlpha : func.srcAlpha || "zero",
-285                     dstAlpha :  func.dstAlpha || "zero"
-286                 };
-287             }
-288             gl.blendFuncSeparate(
-289                     glEnum(gl, func.srcRGB || "zero"),
-290                     glEnum(gl, func.dstRGB || "zero"),
-291                     glEnum(gl, func.srcAlpha || "zero"),
-292                     glEnum(gl, func.dstAlpha || "zero"));
-293         },
-294 
-295         clearColor: function(gl, color) {
-296             if (!gl) {
-297                 color = color || {};
-298                 return {
-299                     r : color.r || 0,
-300                     g : color.g || 0,
-301                     b : color.b || 0,
-302                     a : (color.a == undefined || color.a == null) ? 1 : color.a
-303                 };
-304             }
-305             gl.clearColor(color.r, color.g, color.b, color.a);
-306         },
-307 
-308         clearDepth: function(gl, depth) {
-309             if (!gl) {
-310                 return (depth == null || depth == undefined) ? 1 : depth;
-311             }
-312             gl.clearDepth(depth);
-313         },
-314 
-315         clearStencil: function(gl, clearValue) {
-316             if (!gl) {
-317                 return  clearValue || 0;
-318             }
-319             gl.clearStencil(clearValue);
-320         },
-321 
-322         colorMask: function(gl, color) {
-323             if (!gl) {
-324                 color = color || {};
-325                 return {
-326                     r : color.r || 0,
-327                     g : color.g || 0,
-328                     b : color.b || 0,
-329                     a : (color.a == undefined || color.a == null) ? 1 : color.a
-330                 };
-331 
-332             }
-333             gl.colorMask(color.r, color.g, color.b, color.a);
-334         },
-335 
-336         enableCullFace: function(gl, flag) {
-337             if (!gl) {
-338                 return flag;
-339             }
-340             if (flag) {
-341                 gl.enable(gl.CULL_FACE);
-342             } else {
-343                 gl.disable(gl.CULL_FACE);
-344             }
-345         },
-346 
-347         cullFace: function(gl, mode) {
-348             if (!gl) {
-349                 return mode || "back";
-350             }
-351             gl.cullFace(glEnum(gl, mode));
-352         },
-353 
-354         enableDepthTest: function(gl, flag) {
-355             if (!gl) {
-356                 if (flag == null || flag == undefined) {
-357                     flag = true;
-358                 }
-359                 return flag;
-360             }
-361             if (flag) {
-362                 gl.enable(gl.DEPTH_TEST);
-363             } else {
-364                 gl.disable(gl.DEPTH_TEST);
-365             }
-366         },
-367 
-368         depthFunc: function(gl, func) {
-369             if (!gl) {
-370                 return func || "less";
-371             }
-372             gl.depthFunc(glEnum(gl, func));
-373         },
-374 
-375         enableDepthMask: function(gl, flag) {
-376             if (!gl) {
-377                 if (flag == null || flag == undefined) {
-378                     flag = true;
-379                 }
-380                 return flag;
-381             }
-382             gl.depthMask(flag);
-383         },
-384 
-385         depthRange: function(gl, range) {
-386             if (!gl) {
-387                 range = range || {};
-388                 return {
-389                     zNear : (range.zNear == undefined || range.zNear == null) ? 0 : range.zNear,
-390                     zFar : (range.zFar == undefined || range.zFar == null) ? 1 : range.zFar
-391                 };
-392             }
-393             gl.depthRange(range.zNear, range.zFar);
-394         } ,
-395 
-396         frontFace: function(gl, mode) {
-397             if (!gl) {
-398                 return mode || "ccw";
-399             }
-400             gl.frontFace(glEnum(gl, mode));
-401         },
-402 
-403         lineWidth: function(gl, width) {
-404             if (!gl) {
-405                 return width || 1;
-406             }
-407             gl.lineWidth(width);
-408         },
-409 
-410         enableScissorTest: function(gl, flag) {
-411             if (!gl) {
-412                 return flag;
-413             }
-414             if (flag) {
-415                 gl.enable(gl.SCISSOR_TEST);
-416             } else {
-417                 flag = false;
-418                 gl.disable(gl.SCISSOR_TEST);
-419             }
-420         }
-421     };
-422 
-423     /**
-424      * Order-sensitive functions that immediately effect WebGL state change.
-425      *
-426      * These map to renderer properties and are called in a particular order since they
-427      * affect one another.
-428      *
-429      * Each of these wrap a state-setter function on the WebGL gl. Each function
-430      * also uses the glEnum map to convert its renderer node property argument to the
-431      * WebGL enum constant required by its wrapped function.
-432      *
-433      * @private
-434      */
-435     var glStateSetters = {
-436 
-437         /** Set viewport on the given gl
-438          */
-439         viewport: function(gl, v) {
-440             if (!gl) {
-441                 v = v || {};
-442                 return {
-443                     x : v.x || 1,
-444                     y : v.y || 1,
-445                     width: v.width || canvas.canvas.width,
-446                     height: v.height || canvas.canvas.height
-447                 };
-448             }
-449             gl.viewport(v.x, v.y, v.width, v.height);
-450         },
-451 
-452         /** Sets scissor region on the given gl
-453          */
-454         scissor: function(gl, s) {
-455             if (!gl) {
-456                 s = s || {};
-457                 return {
-458                     x : s.x || 0,
-459                     y : s.y || 0,
-460                     width: s.width || 1.0,
-461                     height: s.height || 1.0
-462                 };
-463             }
-464             gl.scissor(s.x, s.y, s.width, s.height);
-465         },
-466 
-467         /** Clears buffers on the given gl as specified in mask
-468          */
-469         clear:function(gl, mask) {
-470             if (!gl) {
-471                 mask = mask || {};
-472                 return mask;
-473             }
-474             var m;
-475             if (mask.color) {
-476                 m = gl.COLOR_BUFFER_BIT;
-477             }
-478             if (mask.depth) {
-479                 m = m | gl.DEPTH_BUFFER_BIT;
-480             }
-481             if (mask.stencil) {
-482                 m = m | gl.STENCIL_BUFFER_BIT;
-483             }
-484             if (m) {
-485                 //    gl.clear(m);
-486             }
-487         }
-488     };
-489 
-490     SceneJS.Renderer = SceneJS_NodeFactory.createNodeType("renderer");
-491 
-492     SceneJS.Renderer.prototype._init = function(params) {
-493         if (this._core.useCount == 1) { // This node defines the resource
-494             for (var key in params) {
-495                 if (params.hasOwnProperty(key)) {
-496                     this._core[key] = params[key];
-497                 }
-498             }
-499             this._core.dirty = true;
-500         }
-501     };
-502 
-503     SceneJS.Renderer.prototype.setViewport = function(viewport) {
-504         this._core.viewport = viewport ? {
-505             x : viewport.x || 1,
-506             y : viewport.y || 1,
-507             width: viewport.width || 1000,
-508             height: viewport.height || 1000
-509         } : undefined;
-510         this._core.dirty = true;
-511     };
-512 
-513     SceneJS.Renderer.prototype.getViewport = function() {
-514         return this._core.viewport ? {
-515             x : this._core.viewport.x,
-516             y : this._core.viewport.y,
-517             width: this._core.viewport.width,
-518             height: this._core.viewport.height
-519         } : undefined;
-520     };
-521 
-522     SceneJS.Renderer.prototype.setScissor = function(scissor) {
-523         this._core.scissor = scissor ? {
-524             x : scissor.x || 1,
-525             y : scissor.y || 1,
-526             width: scissor.width || 1000,
-527             height: scissor.height || 1000
-528         } : undefined;
-529         this._core.dirty = true;
-530     };
-531 
-532     SceneJS.Renderer.prototype.getScissor = function() {
-533         return this._core.scissor ? {
-534             x : this._core.scissor.x,
-535             y : this._core.scissor.y,
-536             width: this._core.scissor.width,
-537             height: this._core.scissor.height
-538         } : undefined;
-539     };
-540 
-541     SceneJS.Renderer.prototype.setClear = function(clear) {
-542         this._core.clear = clear ? {
-543             r : clear.r || 0,
-544             g : clear.g || 0,
-545             b : clear.b || 0
-546         } : undefined;
-547         this._core.dirty = true;
-548     };
-549 
-550     SceneJS.Renderer.prototype.getClear = function() {
-551         return this._core.clear ? {
-552             r : this._core.clear.r,
-553             g : this._core.clear.g,
-554             b : this._core.clear.b
-555         } : null;
-556     };
-557 
-558     SceneJS.Renderer.prototype.setEnableBlend = function(enableBlend) {
-559         this._core.enableBlend = enableBlend;
-560         this._core.dirty = true;
-561     };
-562 
-563     SceneJS.Renderer.prototype.getEnableBlend = function() {
-564         return this._core.enableBlend;
-565     };
-566 
-567     SceneJS.Renderer.prototype.setBlendColor = function(color) {
-568         this._core.blendColor = color ? {
-569             r : color.r || 0,
-570             g : color.g || 0,
-571             b : color.b || 0,
-572             a : (color.a == undefined || color.a == null) ? 1 : color.a
-573         } : undefined;
-574         this._core.dirty = true;
-575     };
-576 
-577     SceneJS.Renderer.prototype.getBlendColor = function() {
-578         return this._core.blendColor ? {
-579             r : this._core.blendColor.r,
-580             g : this._core.blendColor.g,
-581             b : this._core.blendColor.b,
-582             a : this._core.blendColor.a
-583         } : undefined;
-584     };
-585 
-586     SceneJS.Renderer.prototype.setBlendEquation = function(eqn) {
-587         this._core.blendEquation = eqn;
-588         this._core.dirty = true;
-589     };
-590 
-591     SceneJS.Renderer.prototype.getBlendEquation = function() {
-592         return this._core.blendEquation;
-593     };
-594 
-595     SceneJS.Renderer.prototype.setBlendEquationSeparate = function(eqn) {
-596         this._core.blendEquationSeparate = eqn ? {
-597             rgb : eqn.rgb || "funcAdd",
-598             alpha : eqn.alpha || "funcAdd"
-599         } : undefined;
-600         this._core.dirty = true;
-601     };
-602 
-603     SceneJS.Renderer.prototype.getBlendEquationSeparate = function() {
-604         return this._core.blendEquationSeparate ? {
-605             rgb : this._core.rgb,
-606             alpha : this._core.alpha
-607         } : undefined;
-608     };
-609 
-610     SceneJS.Renderer.prototype.setBlendFunc = function(funcs) {
-611         this._core.blendFunc = funcs ? {
-612             sfactor : funcs.sfactor || "srcAlpha",
-613             dfactor : funcs.dfactor || "one"
-614         } : undefined;
-615         this._core.dirty = true;
-616     };
-617 
-618     SceneJS.Renderer.prototype.getBlendFunc = function() {
-619         return this._core.blendFunc ? {
-620             sfactor : this._core.sfactor,
-621             dfactor : this._core.dfactor
-622         } : undefined;
-623     };
-624 
-625     SceneJS.Renderer.prototype.setBlendFuncSeparate = function(eqn) {
-626         this._core.blendFuncSeparate = eqn ? {
-627             srcRGB : eqn.srcRGB || "zero",
-628             dstRGB : eqn.dstRGB || "zero",
-629             srcAlpha : eqn.srcAlpha || "zero",
-630             dstAlpha : eqn.dstAlpha || "zero"
-631         } : undefined;
-632         this._core.dirty = true;
-633     };
-634 
-635     SceneJS.Renderer.prototype.getBlendFuncSeparate = function() {
-636         return this._core.blendFuncSeparate ? {
-637             srcRGB : this._core.blendFuncSeparate.srcRGB,
-638             dstRGB : this._core.blendFuncSeparate.dstRGB,
-639             srcAlpha : this._core.blendFuncSeparate.srcAlpha,
-640             dstAlpha : this._core.blendFuncSeparate.dstAlpha
-641         } : undefined;
-642     };
-643 
-644     SceneJS.Renderer.prototype.setEnableCullFace = function(enableCullFace) {
-645         this._core.enableCullFace = enableCullFace;
-646         this._core.dirty = true;
-647     };
-648 
-649     SceneJS.Renderer.prototype.getEnableCullFace = function() {
-650         return this._core.enableCullFace;
-651     };
-652 
-653 
-654     SceneJS.Renderer.prototype.setCullFace = function(cullFace) {
-655         this._core.cullFace = cullFace;
-656         this._core.dirty = true;
-657     };
-658 
-659     SceneJS.Renderer.prototype.getCullFace = function() {
-660         return this._core.cullFace;
-661     };
-662 
-663     SceneJS.Renderer.prototype.setEnableDepthTest = function(enableDepthTest) {
-664         this._core.enableDepthTest = enableDepthTest;
-665         this._core.dirty = true;
-666     };
-667 
-668     SceneJS.Renderer.prototype.getEnableDepthTest = function() {
-669         return this._core.enableDepthTest;
-670     };
-671 
-672     SceneJS.Renderer.prototype.setDepthFunc = function(depthFunc) {
-673         this._core.depthFunc = depthFunc;
-674         this._core.dirty = true;
-675     };
-676 
-677     SceneJS.Renderer.prototype.getDepthFunc = function() {
-678         return this._core.depthFunc;
-679     };
-680 
-681     SceneJS.Renderer.prototype.setEnableDepthMask = function(enableDepthMask) {
-682         this._core.enableDepthMask = enableDepthMask;
-683         this._core.dirty = true;
-684     };
-685 
-686     SceneJS.Renderer.prototype.getEnableDepthMask = function() {
-687         return this._core.enableDepthMask;
-688     };
-689 
-690     SceneJS.Renderer.prototype.setClearDepth = function(clearDepth) {
-691         this._core.clearDepth = clearDepth;
-692         this._core.dirty = true;
-693     };
-694 
-695     SceneJS.Renderer.prototype.getClearDepth = function() {
-696         return this._core.clearDepth;
-697     };
-698 
-699     SceneJS.Renderer.prototype.setDepthRange = function(range) {
-700         this._core.depthRange = range ? {
-701             zNear : (range.zNear == undefined || range.zNear == null) ? 0 : range.zNear,
-702             zFar : (range.zFar == undefined || range.zFar == null) ? 1 : range.zFar
-703         } : undefined;
-704         this._core.dirty = true;
-705     };
-706 
-707     SceneJS.Renderer.prototype.getDepthRange = function() {
-708         return this._core.depthRange ? {
-709             zNear : this._core.depthRange.zNear,
-710             zFar : this._core.depthRange.zFar
-711         } : undefined;
-712     };
-713 
-714     SceneJS.Renderer.prototype.setFrontFace = function(frontFace) {
-715         this._core.frontFace = frontFace;
-716         this._core.dirty = true;
-717     };
-718 
-719     SceneJS.Renderer.prototype.getFrontFace = function() {
-720         return this._core.frontFace;
-721     };
-722 
-723     SceneJS.Renderer.prototype.setLineWidth = function(lineWidth) {
-724         this._core.lineWidth = lineWidth;
-725         this._core.dirty = true;
-726     };
-727 
-728     SceneJS.Renderer.prototype.getLineWidth = function() {
-729         return this._core.lineWidth;
-730     };
-731 
-732     SceneJS.Renderer.prototype.setEnableScissorTest = function(enableScissorTest) {
-733         this._core.enableScissorTest = enableScissorTest;
-734         this._core.dirty = true;
-735     };
-736 
-737     SceneJS.Renderer.prototype.getEnableScissorTest = function() {
-738         return this._core.enableScissorTest;
-739     };
-740 
-741     SceneJS.Renderer.prototype.setClearStencil = function(clearStencil) {
-742         this._core.clearStencil = clearStencil;
-743         this._core.dirty = true;
-744     };
-745 
-746     SceneJS.Renderer.prototype.getClearStencil = function() {
-747         return this._core.clearStencil;
-748     };
-749 
-750     SceneJS.Renderer.prototype.setColorMask = function(color) {
-751         this._core.colorMask = color ? {
-752             r : color.r || 0,
-753             g : color.g || 0,
-754             b : color.b || 0,
-755             a : (color.a == undefined || color.a == null) ? 1 : color.a
-756         } : undefined;
-757         this._core.dirty = true;
-758     };
-759 
-760     SceneJS.Renderer.prototype.getColorMask = function() {
-761         return this._core.colorMask ? {
-762             r : this._core.colorMask.r,
-763             g : this._core.colorMask.g,
-764             b : this._core.colorMask.b,
-765             a : this._core.colorMask.a
-766         } : undefined;
-767     };
-768 
-769     SceneJS.Renderer.prototype._compile = function() {
-770 
-771 //        if (this._core.dirty) {
-772 //            this._core.props = createProps(this._core);
-773 //            this._core.dirty = false;
-774 //        }
-775 //
-776 //        this._engine.display.renderer = coreStack[stackLen++] = this._core;
-777         this._compileNodes();
-778         //this._engine.display.renderer = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
-779     };
-780 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_rotate.js.html b/docs/symbols/src/src_core_scene_rotate.js.html deleted file mode 100644 index da2eeb48..00000000 --- a/docs/symbols/src/src_core_scene_rotate.js.html +++ /dev/null @@ -1,156 +0,0 @@ -
  1 /**
-  2  * @class Scene graph node which defines a rotation modelling transform to apply to the objects in its subgraph
-  3  * @extends SceneJS.Node
-  4  */
-  5 SceneJS.Rotate = SceneJS_NodeFactory.createNodeType("rotate");
-  6 
-  7 SceneJS.Rotate.prototype._init = function(params) {
-  8 
-  9     if (this._core.useCount == 1) { // This node is the resource definer
- 10 
- 11         SceneJS_modelXFormStack.buildCore(this._core);
- 12         
- 13         this.setMultOrder(params.multOrder);
- 14 
- 15         this.setAngle(params.angle);
- 16 
- 17         this.setXYZ({
- 18             x: params.x,
- 19             y: params.y,
- 20             z: params.z
- 21         });
- 22 
- 23         var core = this._core;
- 24 
- 25         this._core.buildMatrix = function() {
- 26             core.matrix = SceneJS_math_rotationMat4v(core.angle * Math.PI / 180.0, [core.x, core.y, core.z]);
- 27         };
- 28     }
- 29 };
- 30 
- 31 /**
- 32  * Get Model matrix
- 33  * @return {*}
- 34  */
- 35 SceneJS.Rotate.prototype.getModelMatrix = function() {
- 36     if (this._core.dirty) {
- 37         this._core.build();
- 38     }
- 39     return this._core.matrix;
- 40 };
- 41 
- 42 /**
- 43  * Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next
- 44  * tranform (scale, rotate, translate etc) node on the path to the scene root.
- 45  * @return {*}
- 46  */
- 47 SceneJS.Rotate.prototype.getWorldMatrix = function() {
- 48     if (this._core.dirty) {
- 49         this._core.build();
- 50     }
- 51     return Array.apply( [], this._core.mat);
- 52 };
- 53 
- 54 /**
- 55  * Sets the multiplication order of this node's transform matrix with respect to the parent modeling transform
- 56  * in the scene graph.
- 57  *
- 58  * @param {String} multOrder Mulplication order - "post" and "pre"
- 59  */
- 60 SceneJS.Rotate.prototype.setMultOrder = function(multOrder) {
- 61 
- 62     multOrder = multOrder || "post";
- 63 
- 64     if (multOrder != "post" && multOrder != "pre") {
- 65 
- 66         throw SceneJS_error.fatalError(
- 67                 SceneJS.errors.NODE_CONFIG_EXPECTED,
- 68                 "Illegal multOrder for rotate node - '" + multOrder + "' should be 'pre' or 'post'");
- 69     }
- 70 
- 71     this._core.multOrder = multOrder;
- 72 
- 73     this._core.setDirty();
- 74     this._engine.display.imageDirty = true;
- 75 };
- 76 
- 77 SceneJS.Rotate.prototype.setAngle = function(angle) {
- 78     this._core.angle = angle || 0;
- 79     this._core.setDirty();
- 80     this._engine.display.imageDirty = true;
- 81 };
- 82 
- 83 SceneJS.Rotate.prototype.getAngle = function() {
- 84     return this._core.angle;
- 85 };
- 86 
- 87 SceneJS.Rotate.prototype.setXYZ = function(xyz) {
- 88 
- 89     xyz = xyz || {};
- 90 
- 91     this._core.x = xyz.x || 0;
- 92     this._core.y = xyz.y || 0;
- 93     this._core.z = xyz.z || 0;
- 94 
- 95     this._core.setDirty();
- 96 
- 97     this._engine.display.imageDirty = true;
- 98 };
- 99 
-100 SceneJS.Rotate.prototype.getXYZ = function() {
-101     return {
-102         x: this._core.x,
-103         y: this._core.y,
-104         z: this._core.z
-105     };
-106 };
-107 
-108 SceneJS.Rotate.prototype.setX = function(x) {
-109     this._core.x = x;
-110     this._core.setDirty();
-111     this._engine.display.imageDirty = true;
-112 };
-113 
-114 SceneJS.Rotate.prototype.getX = function() {
-115     return this._core.x;
-116 };
-117 
-118 SceneJS.Rotate.prototype.setY = function(y) {
-119     this._core.y = y;
-120     this._core.setDirty();
-121     this._engine.display.imageDirty = true;
-122 };
-123 
-124 SceneJS.Rotate.prototype.getY = function() {
-125     return this._core.y;
-126 };
-127 
-128 SceneJS.Rotate.prototype.setZ = function(z) {
-129     this._core.z = z;
-130     this._core.setDirty();
-131     this._engine.display.imageDirty = true;
-132 };
-133 
-134 SceneJS.Rotate.prototype.getZ = function() {
-135     return this._core.z;
-136 };
-137 
-138 SceneJS.Rotate.prototype.incAngle = function(angle) {
-139     this._core.angle += angle;
-140     this._core.setDirty();
-141     this._engine.display.imageDirty = true;
-142 };
-143 
-144 SceneJS.Rotate.prototype._compile = function() {
-145     SceneJS_modelXFormStack.push(this._core);
-146     this._compileNodes();
-147     SceneJS_modelXFormStack.pop();
-148 };
-149 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_scale.js.html b/docs/symbols/src/src_core_scene_scale.js.html deleted file mode 100644 index 6a0ee033..00000000 --- a/docs/symbols/src/src_core_scene_scale.js.html +++ /dev/null @@ -1,160 +0,0 @@ -
  1 /**
-  2  * @class Scene graph node which defines a rotation modelling transform to apply to the objects in its subgraph
-  3  * @extends SceneJS.Node
-  4  */
-  5 SceneJS.Scale = SceneJS_NodeFactory.createNodeType("scale");
-  6 
-  7 SceneJS.Scale.prototype._init = function(params) {
-  8 
-  9     if (this._core.useCount == 1) { // This node is the resource definer
- 10 
- 11         SceneJS_modelXFormStack.buildCore(this._core);
- 12 
- 13         this.setMultOrder(params.multOrder);
- 14 
- 15         this.setXYZ({
- 16             x: params.x,
- 17             y: params.y,
- 18             z: params.z
- 19         });
- 20 
- 21         var core = this._core;
- 22 
- 23         this._core.buildMatrix = function() {
- 24             core.matrix = SceneJS_math_scalingMat4v([core.x, core.y, core.z]);
- 25         };
- 26     }
- 27 };
- 28 
- 29 /**
- 30  * Get Model matrix
- 31  * @return {*}
- 32  */
- 33 SceneJS.Scale.prototype.getModelMatrix = function() {
- 34     if (this._core.dirty) {
- 35         this._core.build();
- 36     }
- 37     return this._core.matrix;
- 38 };
- 39 
- 40 /**
- 41  * Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next
- 42  * tranform (scale, scale, translate etc) node on the path to the scene root.
- 43  * @return {*}
- 44  */
- 45 SceneJS.Scale.prototype.getWorldMatrix = function() {
- 46     if (this._core.dirty) {
- 47         this._core.build();
- 48     }
- 49     return Array.apply( [], this._core.mat);
- 50 };
- 51 
- 52 
- 53 /**
- 54  * Sets the multiplication order of this node's transform matrix with respect to the parent modeling transform
- 55  * in the scene graph.
- 56  *
- 57  * @param {String} multOrder Mulplication order - "post" and "pre"
- 58  */
- 59 SceneJS.Scale.prototype.setMultOrder = function(multOrder) {
- 60 
- 61     multOrder = multOrder || "post";
- 62 
- 63     if (multOrder != "post" && multOrder != "pre") {
- 64 
- 65         throw SceneJS_error.fatalError(
- 66                 SceneJS.errors.NODE_CONFIG_EXPECTED,
- 67                 "Illegal multOrder for scale node - '" + multOrder + "' should be 'pre' or 'post'");
- 68     }
- 69 
- 70     this._core.multOrder = multOrder;
- 71 
- 72     this._core.setDirty();
- 73     this._engine.display.imageDirty = true;
- 74 };
- 75 
- 76 SceneJS.Scale.prototype.getAngle = function() {
- 77     return this._core.angle;
- 78 };
- 79 
- 80 SceneJS.Scale.prototype.setXYZ = function(xyz) {
- 81 
- 82     xyz = xyz || {};
- 83 
- 84     this._core.x = xyz.x || 0;
- 85     this._core.y = xyz.y || 0;
- 86     this._core.z = xyz.z || 0;
- 87 
- 88     this._core.setDirty();
- 89 
- 90     this._engine.display.imageDirty = true;
- 91 };
- 92 
- 93 SceneJS.Scale.prototype.getXYZ = function() {
- 94     return {
- 95         x: this._core.x,
- 96         y: this._core.y,
- 97         z: this._core.z
- 98     };
- 99 };
-100 
-101 SceneJS.Scale.prototype.setX = function(x) {
-102     this._core.x = x;
-103     this._core.setDirty();
-104     this._engine.display.imageDirty = true;
-105 };
-106 
-107 SceneJS.Scale.prototype.getX = function() {
-108     return this._core.x;
-109 };
-110 
-111 SceneJS.Scale.prototype.setY = function(y) {
-112     this._core.y = y;
-113     this._core.setDirty();
-114     this._engine.display.imageDirty = true;
-115 };
-116 
-117 SceneJS.Scale.prototype.getY = function() {
-118     return this._core.y;
-119 };
-120 
-121 SceneJS.Scale.prototype.setZ = function(z) {
-122     this._core.z = z;
-123     this._core.setDirty();
-124     this._engine.display.imageDirty = true;
-125 };
-126 
-127 SceneJS.Scale.prototype.getZ = function() {
-128     return this._core.z;
-129 };
-130 
-131 SceneJS.Scale.prototype.incX = function(x) {
-132     this._core.x += x;
-133     this._core.setDirty();
-134     this._engine.display.imageDirty = true;
-135 };
-136 
-137 SceneJS.Scale.prototype.incY = function(y) {
-138     this._core.y += y;
-139     this._core.matrixDirty = true;
-140 };
-141 
-142 SceneJS.Scale.prototype.incZ = function(z) {
-143     this._core.z += z;
-144     this._core.setDirty();
-145     this._engine.display.imageDirty = true;
-146 };
-147 
-148 SceneJS.Scale.prototype._compile = function() {
-149     SceneJS_modelXFormStack.push(this._core);
-150     this._compileNodes();
-151     SceneJS_modelXFormStack.pop();
-152 };
-153 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_scene.js.html b/docs/symbols/src/src_core_scene_scene.js.html deleted file mode 100644 index 0556d344..00000000 --- a/docs/symbols/src/src_core_scene_scene.js.html +++ /dev/null @@ -1,228 +0,0 @@ -
  1 /**
-  2  * @class The root node of a scenegraph
-  3  * @extends SceneJS.Node
-  4  *
-  5  */
-  6 
-  7 SceneJS.Scene = SceneJS_NodeFactory.createNodeType("scene");
-  8 
-  9 SceneJS.Scene.prototype._init = function(params) {
- 10 
- 11     if (params.tagMask) {
- 12         this.setTagMask(params.tagMask);
- 13     }
- 14 
- 15     this._tagSelector = null;
- 16 };
- 17 
- 18 /**
- 19  * Subscribes to an event on this scene
- 20  *
- 21  * @param {String} type Event type
- 22  * @param {Function} callback Callback that will be called with the event parameters
- 23  * @return {String} handle Handle to the subcription
- 24  */
- 25 SceneJS.Scene.prototype.onEvent = function(type, callback) {
- 26     return this._engine.events.onEvent(type, callback);
- 27 };
- 28 
- 29 /**
- 30  * Unsubscribes to an event previously subscribed to on scene
- 31  *
- 32  * @param {String} handle Subscription handle
- 33  */
- 34 SceneJS.Scene.prototype.unEvent = function(handle) {
- 35     this._engine.events.unEvent(handle);
- 36 };
- 37 
- 38 /**
- 39  * Simulate a lost WebGL context for testing purposes.
- 40  * Only works if the simulateWebGLLost was given as an option to {@link SceneJS.createScene}.
- 41  */
- 42 SceneJS.Scene.prototype.loseWebGLContext = function() {
- 43     this._engine.loseWebGLContext();
- 44 };
- 45 
- 46 
- 47 /**
- 48  * Returns the HTML canvas for this scene
- 49  * @return {HTMLCanvas} The canvas
- 50  */
- 51 SceneJS.Scene.prototype.getCanvas = function() {
- 52     return this._engine.canvas.canvas;
- 53 };
- 54 
- 55 /**
- 56  * Returns the WebGL context for this scene
- 57  */
- 58 SceneJS.Scene.prototype.getGL = function() {
- 59     return this._engine.canvas.gl;
- 60 };
- 61 
- 62 /** Returns the Z-buffer depth in bits of the webgl context that this scene is to bound to.
- 63  */
- 64 SceneJS.Scene.prototype.getZBufferDepth = function() {
- 65 
- 66     var gl = this._engine.canvas.gl;
- 67 
- 68     return gl.getParameter(gl.DEPTH_BITS);
- 69 };
- 70 
- 71 /**
- 72  * Sets a regular expression to select which of the scene subgraphs that are rooted by {@link SceneJS.Tag} nodes are included in scene renders
- 73  * @param {String} tagMask Regular expression string to match on the tag attributes of {@link SceneJS.Tag} nodes
- 74  * @see #getTagMask
- 75  * @see SceneJS.Tag
- 76  */
- 77 SceneJS.Scene.prototype.setTagMask = function(tagMask) {
- 78 
- 79     if (!this._tagSelector) {
- 80         this._tagSelector = {};
- 81     }
- 82 
- 83     this._tagSelector.mask = tagMask;
- 84     this._tagSelector.regex = tagMask ? new RegExp(tagMask) : null;
- 85 
- 86     this._engine.display.selectTags(this._tagSelector);
- 87 };
- 88 
- 89 /**
- 90  * Gets the regular expression which will select which of the scene subgraphs that are rooted by {@link SceneJS.Tag} nodes are included in scene renders
- 91  * @see #setTagMask
- 92  * @see SceneJS.Tag
- 93  * @returns {String} Regular expression string that will be matched on the tag attributes of {@link SceneJS.Tag} nodes
- 94  */
- 95 SceneJS.Scene.prototype.getTagMask = function() {
- 96     return this._tagSelector ? this._tagSelector.mask : null;
- 97 };
- 98 
- 99 /**
-100  * Render a single frame if new frame pending, or force a new frame
-101  * Returns true if frame rendered
-102  */
-103 SceneJS.Scene.prototype.renderFrame = function(params) {
-104     return this._engine.renderFrame(params);
-105 };
-106 
-107 /**
-108  * Starts the render loop for this scene
-109  */
-110 SceneJS.Scene.prototype.start = function(params) {
-111     this._engine.start(params);
-112 };
-113 
-114 /**
-115  * Pauses/unpauses current render loop that was started with {@link #start}. After this, {@link #isRunning} will return false.
-116  * @param {Boolean} doPause Indicates whether to pause or unpause the render loop
-117  */
-118 SceneJS.Scene.prototype.pause = function(doPause) {
-119     this._engine.pause(doPause);
-120 };
-121 
-122 /**
-123  * Returns true if the scene's render loop is currently running.
-124  * @returns {Boolean} True when scene render loop is running
-125  */
-126 SceneJS.Scene.prototype.isRunning = function() {
-127     return this._engine.running;
-128 };
-129 
-130 /**
-131  * Picks whatever geometry will be rendered at the given canvas coordinates.
-132  */
-133 SceneJS.Scene.prototype.pick = function(canvasX, canvasY, options) {
-134     return this._engine.pick(canvasX, canvasY, options);
-135 };
-136 
-137 /**                                  p
-138  * Scene node's destroy handler, called by {@link SceneJS_node#destroy}
-139  * @private
-140  */
-141 SceneJS.Scene.prototype.destroy = function() {
-142 
-143     if (!this.destroyed) {
-144 
-145         delete SceneJS._engines[this.id];  // HACK: circular dependency
-146         SceneJS._engineIds.removeItem(this.id); // HACK: circular dependency
-147 
-148         this.destroyed = true;
-149     }
-150 };
-151 
-152 /**
-153  * Returns true if scene active, ie. not destroyed. A destroyed scene becomes active again
-154  * when you render it.
-155  */
-156 SceneJS.Scene.prototype.isActive = function() {
-157     return !this._engine.destroyed;
-158 };
-159 
-160 /**
-161  * Stops current render loop that was started with {@link #start}. After this, {@link #isRunning} will return false.
-162  */
-163 SceneJS.Scene.prototype.stop = function() {
-164     this._engine.stop();
-165 };
-166 
-167 /** Determines if node exists in this scene
-168  */
-169 SceneJS.Scene.prototype.containsNode = function(nodeId) {
-170     return !!this._engine.findNode(nodeId);
-171 };
-172 
-173 /**
-174  * Finds nodes in this scene that have nodes IDs matching the given regular expression
-175  *
-176  * @param {String} nodeIdRegex Regular expression to match on node IDs
-177  * @return {[SceneJS.Node]} Array of nodes whose IDs match the given regex
-178  */
-179 SceneJS.Scene.prototype.findNodes = function(nodeIdRegex) {
-180     return this._engine.findNodes(nodeIdRegex);
-181 };
-182 
-183 /**
-184  * Finds the node with the given ID in this scene
-185  * @deprecated
-186  * @return {SceneJS.Node} The node if found, else null
-187  */
-188 SceneJS.Scene.prototype.findNode = function(nodeId) {
-189     return this._engine.findNode(nodeId);
-190 };
-191 
-192 /**
-193  * @function Finds the node with the given ID in this scene
-194  * @return {SceneJS.Node} The node if found, else null
-195  */
-196 SceneJS.Scene.prototype.getNode  = function(nodeId) {
-197     return this._engine.findNode(nodeId);
-198 };
-199 
-200 /**
-201  * Returns the current status of this scene.
-202  *
-203  * When the scene has been destroyed, the returned status will be a map like this:
-204  *
-205  * {
-206  *      destroyed: true
-207  * }
-208  *
-209  * Otherwise, the status will be:
-210  *
-211  * {
-212  *      numTasks: Number // Number of asset loads (eg. texture, geometry stream etc.) currently in progress
-213  * }
-214  *
-215  */
-216 SceneJS.Scene.prototype.getStatus = function() {
-217     return (this._engine.destroyed)
-218             ? { destroyed: true }
-219             : SceneJS._shallowClone(SceneJS_sceneStatusModule.sceneStatus[this.id]);
-220 };
-221 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_shader.js.html b/docs/symbols/src/src_core_scene_shader.js.html deleted file mode 100644 index 344b4a23..00000000 --- a/docs/symbols/src/src_core_scene_shader.js.html +++ /dev/null @@ -1,201 +0,0 @@ -
  1 new (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.Shader} nodes
-  5      */
-  6     var defaultCore = {
-  7         type: "shader",
-  8         stateId: SceneJS._baseStateId++,
-  9         hash: "",
- 10         empty: true,
- 11         shader : {}
- 12     };
- 13 
- 14     var idStack = [];
- 15     var shaderVertexCodeStack = [];
- 16     var shaderVertexHooksStack = [];
- 17     var shaderFragmentCodeStack = [];
- 18     var shaderFragmentHooksStack = [];
- 19     var shaderParamsStack = [];
- 20 
- 21     var stackLen = 0;
- 22 
- 23     var dirty = true;
- 24 
- 25     SceneJS_events.addListener(
- 26             SceneJS_events.SCENE_COMPILING,
- 27             function(params) {
- 28 
- 29                 params.engine.display.shader = defaultCore;
- 30 
- 31                 stackLen = 0;
- 32 
- 33                 dirty = true;
- 34             });
- 35 
- 36     SceneJS_events.addListener(
- 37             SceneJS_events.OBJECT_COMPILING,
- 38             function(params) {
- 39                 if (dirty) {
- 40 
- 41                     if (stackLen > 0) {
- 42 
- 43                         var core = {
- 44                             type: "shader",
- 45                             stateId: idStack[stackLen - 1],
- 46                             hash: idStack.slice(0, stackLen).join("."),
- 47 
- 48                             shaders: {
- 49                                 fragment: {
- 50                                     code: shaderFragmentCodeStack.slice(0, stackLen).join("\n"),
- 51                                     hooks: combineMapStack(shaderFragmentHooksStack)
- 52                                 },
- 53                                 vertex: {
- 54                                     code: shaderVertexCodeStack.slice(0, stackLen).join("\n"),
- 55                                     hooks: combineMapStack(shaderVertexHooksStack)
- 56                                 }
- 57                             },
- 58 
- 59                             paramsStack: shaderParamsStack.slice(0, stackLen)
- 60                         };
- 61 
- 62                         params.display.shader = core;
- 63 
- 64                     } else {
- 65 
- 66                         params.display.shader = defaultCore;
- 67                     }
- 68 
- 69                     dirty = false;
- 70                 }
- 71             });
- 72 
- 73     function combineMapStack(maps) {
- 74         var map1;
- 75         var map2 = {};
- 76         var name;
- 77         for (var i = 0; i < stackLen; i++) {
- 78             map1 = maps[i];
- 79             for (name in map1) {
- 80                 if (map1.hasOwnProperty(name)) {
- 81                     map2[name] = map1[name];
- 82                 }
- 83             }
- 84         }
- 85         return map2;
- 86     }
- 87 
- 88     function pushHooks(hooks, hookStacks) {
- 89         var stack;
- 90         for (var key in hooks) {
- 91             if (hooks.hasOwnProperty(key)) {
- 92                 stack = hookStacks[key];
- 93                 if (!stack) {
- 94                     stack = hookStacks[key] = [];
- 95                 }
- 96                 stack.push(hooks[key]);
- 97             }
- 98         }
- 99     }
-100 
-101     SceneJS.Shader = SceneJS_NodeFactory.createNodeType("shader");
-102 
-103     SceneJS.Shader.prototype._init = function(params) {
-104         if (this._core.useCount == 1) { // This node is the resource definer
-105             this._setShaders(params.shaders);
-106             this.setParams(params.params);
-107         }
-108     };
-109 
-110     SceneJS.Shader.prototype._setShaders = function(shaders) {
-111         shaders = shaders || [];
-112         this._core.shaders = {};
-113         var shader;
-114 
-115         for (var i = 0, len = shaders.length; i < len; i++) {
-116             shader = shaders[i];
-117 
-118             if (!shader.stage) {
-119                 throw SceneJS_error.fatalError(
-120                         SceneJS.errors.ILLEGAL_NODE_CONFIG,
-121                         "shader 'stage' attribute expected");
-122             }
-123 
-124             var code;
-125             if (shader.code) {
-126                 if (SceneJS._isArray(shader.code)) {
-127                     code = shader.code.join("");
-128                 } else {
-129                     code = shader.code;
-130                 }
-131             }
-132 
-133             this._core.shaders[shader.stage] = {
-134                 code: code,
-135                 hooks: shader.hooks
-136             };
-137         }
-138     };
-139 
-140     SceneJS.Shader.prototype.setParams = function(params) {
-141         params = params || {};
-142         var coreParams = this._core.params;
-143         if (!coreParams) {
-144             coreParams = this._core.params = {};
-145         }
-146         for (var name in params) {
-147             if (params.hasOwnProperty(name)) {
-148                 coreParams[name] = params[name];
-149             }
-150         }
-151         this._engine.display.imageDirty = true;
-152     };
-153 
-154     SceneJS.Shader.prototype.getParams = function() {
-155         var coreParams = this._core.params;
-156         if (!coreParams) {
-157             return {};
-158         }
-159         var params = {};
-160         for (var name in coreParams) {
-161             if (coreParams.hasOwnProperty(name)) {
-162                 params[name] = coreParams[name];
-163             }
-164         }
-165         return params;
-166     };
-167 
-168     SceneJS.Shader.prototype._compile = function() {
-169 
-170         idStack[stackLen] = this._core.coreId; // Draw list node tied to core, not node
-171 
-172         var shaders = this._core.shaders;
-173 
-174         var fragment = shaders.fragment || {};
-175         var vertex = shaders.vertex || {};
-176 
-177         shaderFragmentCodeStack[stackLen] = fragment.code || "";
-178         shaderFragmentHooksStack[stackLen] = fragment.hooks || {};
-179 
-180         shaderVertexCodeStack[stackLen] = vertex.code || "";
-181         shaderVertexHooksStack[stackLen] = vertex.hooks || {};
-182 
-183         shaderParamsStack[stackLen] = this._core.params || {};
-184 
-185         stackLen++;
-186         dirty = true;
-187 
-188         this._compileNodes();
-189 
-190         stackLen--;
-191         dirty = true;
-192     };
-193 
-194 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_shaderParams.js.html b/docs/symbols/src/src_core_scene_shaderParams.js.html deleted file mode 100644 index dae64c0f..00000000 --- a/docs/symbols/src/src_core_scene_shaderParams.js.html +++ /dev/null @@ -1,104 +0,0 @@ -
  1 new (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.ShaderParams} nodes
-  5      */
-  6     var defaultCore = {
-  7         type: "shaderParams",
-  8         stateId: SceneJS._baseStateId++,
-  9         empty: true
- 10     };
- 11 
- 12     var idStack = [];
- 13     var shaderParamsStack = [];
- 14     var stackLen = 0;
- 15     var dirty;
- 16 
- 17     SceneJS_events.addListener(
- 18             SceneJS_events.SCENE_COMPILING,
- 19             function(params) {
- 20 
- 21                 params.engine.display.shaderParams = defaultCore;
- 22 
- 23                 stackLen = 0;
- 24                 dirty = true;
- 25             });
- 26 
- 27     SceneJS_events.addListener(
- 28             SceneJS_events.OBJECT_COMPILING,
- 29             function(params) {
- 30                 if (dirty) {
- 31 
- 32                     if (stackLen > 0) {
- 33                         var core = {
- 34                             type: "shaderParams",
- 35                             stateId: idStack[stackLen - 1],
- 36                             paramsStack: shaderParamsStack.slice(0, stackLen)
- 37                         };
- 38                         params.display.shaderParams = core;
- 39 
- 40                     } else {
- 41                         params.display.shaderParams = defaultCore;
- 42                     }
- 43 
- 44                     dirty = false;
- 45                 }
- 46             });
- 47 
- 48     SceneJS.ShaderParams = SceneJS_NodeFactory.createNodeType("shaderParams");
- 49 
- 50     SceneJS.ShaderParams.prototype._init = function(params) {
- 51         if (this._core.useCount == 1) { // This node is the resource definer
- 52             this.setParams(params.params);
- 53         }
- 54     };
- 55 
- 56     SceneJS.ShaderParams.prototype.setParams = function(params) {
- 57         params = params || {};
- 58         var core = this._core;
- 59         if (!core.params) {
- 60             core.params = {};
- 61         }
- 62         for (var name in params) {
- 63             if (params.hasOwnProperty(name)) {
- 64                 core.params[name] = params[name];
- 65             }
- 66         }
- 67         this._engine.display.imageDirty = true;
- 68     };
- 69 
- 70     SceneJS.ShaderParams.prototype.getParams = function() {
- 71         var coreParams = this._core.params;
- 72         if (!coreParams) {
- 73             return {};
- 74         }
- 75         var params = {};
- 76         for (var name in coreParams) {
- 77             if (coreParams.hasOwnProperty(name)) {
- 78                 params[name] = coreParams[name];
- 79             }
- 80         }
- 81         return params;
- 82     };
- 83 
- 84     SceneJS.ShaderParams.prototype._compile = function() {
- 85 
- 86         idStack[stackLen] = this._core.coreId; // Tie draw list state to core, not to scene node
- 87         shaderParamsStack[stackLen] = this._core.params;
- 88         stackLen++;
- 89         dirty = true;
- 90 
- 91         this._compileNodes();
- 92 
- 93         stackLen--;
- 94         dirty = true;
- 95     };
- 96 
- 97 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_tag.js.html b/docs/symbols/src/src_core_scene_tag.js.html deleted file mode 100644 index 059b8f6e..00000000 --- a/docs/symbols/src/src_core_scene_tag.js.html +++ /dev/null @@ -1,67 +0,0 @@ -
  1 (function() {
-  2 
-  3     /**
-  4      * The default state core singleton for {@link SceneJS.Tag} nodes
-  5      */
-  6     var defaultCore = {
-  7         type: "tag",
-  8         stateId: SceneJS._baseStateId++,
-  9         tag : null
- 10     };
- 11 
- 12     var coreStack = [];
- 13     var stackLen = 0;
- 14 
- 15     SceneJS_events.addListener(
- 16             SceneJS_events.SCENE_COMPILING,
- 17             function(params) {
- 18                 params.engine.display.tag = defaultCore;
- 19                 stackLen = 0;
- 20             });
- 21 
- 22     /**
- 23      * @class Scene graph node which assigns a symbolic tag name to the {@link SceneJS.Geometry} nodes in its subgraph.
- 24      * The subgraph can then be included or excluded from scene rendering using {@link SceneJS.Scene#setTagMask}.
- 25      * @extends SceneJS.Node
- 26      */
- 27     SceneJS.Tag = SceneJS_NodeFactory.createNodeType("tag");
- 28 
- 29     SceneJS.Tag.prototype._init = function(params) {
- 30         if (this._core.useCount == 1) { // This node defines the resource
- 31             if (!params.tag) {
- 32                 throw SceneJS_error.fatalError(
- 33                         SceneJS.errors.NODE_CONFIG_EXPECTED,
- 34                         "tag node attribute missing : 'tag'");
- 35             }
- 36             this.setTag(params.tag);
- 37         }
- 38     };
- 39 
- 40     SceneJS.Tag.prototype.setTag = function(tag) {
- 41 
- 42         var core = this._core;
- 43 
- 44         core.tag = tag;
- 45         core.pattern = null;    // To be recomputed
- 46         core.matched = false;   // To be rematched
- 47 
- 48         this._engine.display.drawListDirty = true;
- 49     };
- 50 
- 51     SceneJS.Tag.prototype.getTag = function() {
- 52         return this._core.tag;
- 53     };
- 54 
- 55     SceneJS.Tag.prototype._compile = function() {
- 56         this._engine.display.tag = coreStack[stackLen++] = this._core;
- 57         this._compileNodes();
- 58         this._engine.display.tag = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
- 59     };
- 60 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_texture.js.html b/docs/symbols/src/src_core_scene_texture.js.html deleted file mode 100644 index 6a311cbc..00000000 --- a/docs/symbols/src/src_core_scene_texture.js.html +++ /dev/null @@ -1,507 +0,0 @@ -
  1 /**
-  2  * @class Scene graph node which defines textures to apply to the objects in its subgraph
-  3  * @extends SceneJS.Node
-  4  */
-  5 new (function () {
-  6 
-  7     /**
-  8      * The default state core singleton for {@link SceneJS.Texture} nodes
-  9      */
- 10     var defaultCore = {
- 11         type:"texture",
- 12         stateId:SceneJS._baseStateId++,
- 13         empty:true,
- 14         hash:""
- 15     };
- 16 
- 17     var coreStack = [];
- 18     var stackLen = 0;
- 19 
- 20     SceneJS_events.addListener(
- 21         SceneJS_events.SCENE_COMPILING,
- 22         function (params) {
- 23             params.engine.display.texture = defaultCore;
- 24             stackLen = 0;
- 25         });
- 26 
- 27     /**
- 28      * @class Scene graph node which defines one or more textures to apply to the {@link SceneJS.Geometry} nodes in its subgraph
- 29      * @extends SceneJS.Node
- 30      */
- 31     SceneJS.Texture = SceneJS_NodeFactory.createNodeType("texture");
- 32 
- 33     SceneJS.Texture.prototype._init = function (params) {
- 34 
- 35         if (this._core.useCount == 1) { // This node is the resource definer
- 36 
- 37             this._core.layers = [];
- 38             this._core.params = {};
- 39 
- 40             var waitForLoad = !!params.waitForLoad;
- 41 
- 42             if (!params.layers) {
- 43                 throw SceneJS_error.fatalError(
- 44                     SceneJS.errors.NODE_CONFIG_EXPECTED,
- 45                     "texture layers missing");
- 46             }
- 47 
- 48             if (!SceneJS._isArray(params.layers)) {
- 49                 throw SceneJS_error.fatalError(
- 50                     SceneJS.errors.NODE_CONFIG_EXPECTED,
- 51                     "texture layers should be an array");
- 52             }
- 53 
- 54             var layerParams;
- 55             var gl = this._engine.canvas.gl;
- 56 
- 57             for (var i = 0; i < params.layers.length; i++) {
- 58 
- 59                 layerParams = params.layers[i];
- 60 
- 61                 if (!layerParams.source && !layerParams.uri && !layerParams.src && !layerParams.framebuf && !layerParams.video) {
- 62 
- 63                     throw SceneJS_error.fatalError(
- 64                         SceneJS.errors.NODE_CONFIG_EXPECTED,
- 65                         "texture layer " + i + "  has no uri, src, source, framebuf, video or canvasId specified");
- 66                 }
- 67 
- 68                 if (layerParams.applyFrom) {
- 69 
- 70                     if (layerParams.applyFrom != "uv" &&
- 71                         layerParams.applyFrom != "uv2" &&
- 72                         layerParams.applyFrom != "normal" &&
- 73                         layerParams.applyFrom != "geometry") {
- 74 
- 75                         throw SceneJS_error.fatalError(
- 76                             SceneJS.errors.NODE_CONFIG_EXPECTED,
- 77                             "texture layer " + i + "  applyFrom value is unsupported - " +
- 78                                 "should be either 'uv', 'uv2', 'normal' or 'geometry'");
- 79                     }
- 80                 }
- 81 
- 82                 if (layerParams.applyTo) {
- 83 
- 84                     if (layerParams.applyTo != "baseColor" && // Colour map
- 85                         layerParams.applyTo != "specular" && // Specular map
- 86                         layerParams.applyTo != "emit" && // Emission map
- 87                         layerParams.applyTo != "alpha" && // Alpha map
- 88                         layerParams.applyTo != "normals") {
- 89 
- 90                         throw SceneJS_error.fatalError(
- 91                             SceneJS.errors.NODE_CONFIG_EXPECTED,
- 92                             "texture layer " + i + " applyTo value is unsupported - " +
- 93                                 "should be either 'baseColor', 'specular' or 'normals'");
- 94                     }
- 95                 }
- 96 
- 97                 if (layerParams.blendMode) {
- 98 
- 99                     if (layerParams.blendMode != "add" && layerParams.blendMode != "multiply") {
-100 
-101                         throw SceneJS_error.fatalError(
-102                             SceneJS.errors.NODE_CONFIG_EXPECTED,
-103                             "texture layer " + i + " blendMode value is unsupported - " +
-104                                 "should be either 'add' or 'multiply'");
-105                     }
-106                 }
-107 
-108                 var layer = SceneJS._apply(layerParams, {
-109                     waitForLoad:waitForLoad,
-110                     texture:null,
-111                     applyFrom:layerParams.applyFrom || "uv",
-112                     applyTo:layerParams.applyTo || "baseColor",
-113                     blendMode:layerParams.blendMode || "multiply",
-114                     blendFactor:(layerParams.blendFactor != undefined && layerParams.blendFactor != null) ? layerParams.blendFactor : 1.0,
-115                     translate:{ x:0, y:0},
-116                     scale:{ x:1, y:1 },
-117                     rotate:{ z:0.0 }
-118                 });
-119 
-120                 this._core.layers.push(layer);
-121 
-122                 this._setLayerTransform(layerParams, layer);
-123 
-124                 if (layer.framebuf) { // Create from a framebuf node preceeding this texture in the scene graph
-125 
-126                     var targetNode = this._engine.findNode(layer.framebuf);
-127 
-128                     if (targetNode && targetNode.type == "framebuf") {
-129                         layer.texture = targetNode._core.framebuf.getTexture(); // TODO: what happens when the framebuf is destroyed?
-130                     }
-131 
-132                 } else { // Create from texture node's layer configs
-133                     this._loadLayerTexture(gl, layer);
-134                 }
-135             }
-136 
-137             var self = this;
-138 
-139             /**
-140              * WebGL restored handler - rebuilds the texture layers
-141              */
-142             this._core.webglRestored = function () {
-143 
-144                 var layers = self._core.layers;
-145                 var gl = self._engine.canvas.gl;
-146 
-147                 for (var i = 0, len = layers.length; i < len; i++) {
-148                     self._loadLayerTexture(gl, layers[i]);
-149                 }
-150             };
-151         }
-152     };
-153 
-154     SceneJS.Texture.prototype._loadLayerTexture = function (gl, layer) {
-155 
-156         SceneJS_sceneStatusModule.nodeLoading(this);
-157 
-158         this._engine.nodeLoading(this);
-159 
-160         this._fireEvent("loading");
-161 
-162         var self = this;
-163 
-164         var sourceConfigs = layer.source;
-165 
-166         if (sourceConfigs) {
-167 
-168             if (!sourceConfigs.type) {
-169                 throw SceneJS_error.fatalError(
-170                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
-171                     "texture layer config expected: source.type");
-172             }
-173 
-174             SceneJS.Plugins.getPlugin(
-175                 "texture",
-176                 sourceConfigs.type,
-177                 function (plugin) {
-178 
-179                     if (!plugin.getSource) {
-180                         throw SceneJS_error.fatalError(
-181                             SceneJS.errors.PLUGIN_INVALID,
-182                             "texture: 'getSource' method missing on plugin for texture source type '" + sourceConfigs.type + "'.");
-183                     }
-184 
-185                     var source = plugin.getSource({ gl:gl });
-186 
-187                     if (!source.onUpdate) {
-188                         throw SceneJS_error.fatalError(
-189                             SceneJS.errors.PLUGIN_INVALID,
-190                             "texture: 'onUpdate' method missing on plugin for texture source type '" + sourceConfigs.type + "'");
-191                     }
-192 
-193                     source.onUpdate(// Get notification whenever source updates the texture
-194                         (function () {
-195                             var loaded = false;
-196                             return function () {
-197                                 if (!loaded) { // Texture first initialised - create layer
-198                                     loaded = true;
-199                                     self._setLayerTexture(gl, layer, source.getTexture());
-200 
-201                                 } else { // Texture updated - layer already has the handle to it, so just signal a redraw
-202                                     self._engine.display.imageDirty = true;
-203                                 }
-204                             };
-205                         })());
-206 
-207                     source.setConfigs(sourceConfigs); // Configure the source, which may cause it to update the texture
-208 
-209                     layer._source = source;
-210                 });
-211 
-212         } else {
-213 
-214             /* Load from URL
-215              */
-216             var image = new Image();
-217 
-218             image.onload = function () {
-219                 var texture = gl.createTexture();
-220                 gl.bindTexture(gl.TEXTURE_2D, texture);
-221                 gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, self._ensureImageSizePowerOfTwo(image));
-222                 self._setLayerTexture(gl, layer, texture);
-223             };
-224 
-225             image.crossOrigin = "";
-226             image.src = layer.uri || layer.src;
-227         }
-228     };
-229 
-230     SceneJS.Texture.prototype._ensureImageSizePowerOfTwo = function (image) {
-231 
-232         if (!this._isPowerOfTwo(image.width) || !this._isPowerOfTwo(image.height)) {
-233 
-234             var canvas = document.createElement("canvas");
-235             canvas.width = this._nextHighestPowerOfTwo(image.width);
-236             canvas.height = this._nextHighestPowerOfTwo(image.height);
-237 
-238             var ctx = canvas.getContext("2d");
-239 
-240             ctx.drawImage(image,
-241                 0, 0, image.width, image.height,
-242                 0, 0, canvas.width, canvas.height);
-243 
-244             image = canvas;
-245             image.crossOrigin = "";
-246         }
-247         return image;
-248     };
-249 
-250     SceneJS.Texture.prototype._isPowerOfTwo = function (x) {
-251         return (x & (x - 1)) == 0;
-252     };
-253 
-254     SceneJS.Texture.prototype._nextHighestPowerOfTwo = function (x) {
-255         --x;
-256         for (var i = 1; i < 32; i <<= 1) {
-257             x = x | x >> i;
-258         }
-259         return x + 1;
-260     };
-261 
-262     SceneJS.Texture.prototype._setLayerTexture = function (gl, layer, texture) {
-263 
-264         layer.texture = new SceneJS_webgl_Texture2D(gl, {
-265             texture:texture, // WebGL texture object
-266             minFilter:this._getGLOption("minFilter", gl, layer, gl.LINEAR_MIPMAP_NEAREST),
-267             magFilter:this._getGLOption("magFilter", gl, layer, gl.LINEAR),
-268             wrapS:this._getGLOption("wrapS", gl, layer, gl.CLAMP_TO_EDGE),
-269             wrapT:this._getGLOption("wrapT", gl, layer, gl.CLAMP_TO_EDGE),
-270             isDepth:this._getOption(layer.isDepth, false),
-271             depthMode:this._getGLOption("depthMode", gl, layer, gl.LUMINANCE),
-272             depthCompareMode:this._getGLOption("depthCompareMode", gl, layer, gl.COMPARE_R_TO_TEXTURE),
-273             depthCompareFunc:this._getGLOption("depthCompareFunc", gl, layer, gl.LEQUAL),
-274             flipY:this._getOption(layer.flipY, true),
-275             width:this._getOption(layer.width, 1),
-276             height:this._getOption(layer.height, 1),
-277             internalFormat:this._getGLOption("internalFormat", gl, layer, gl.LEQUAL),
-278             sourceFormat:this._getGLOption("sourceType", gl, layer, gl.ALPHA),
-279             sourceType:this._getGLOption("sourceType", gl, layer, gl.UNSIGNED_BYTE),
-280             update:null
-281         });
-282 
-283         SceneJS_sceneStatusModule.nodeLoaded(this);
-284 
-285         this._engine.nodeLoaded(this);
-286 
-287         this._fireEvent("loaded");
-288 
-289         if (this.destroyed) { // Node was destroyed while loading
-290             layer.texture.destroy();
-291         }
-292 
-293         this._engine.display.imageDirty = true;
-294     };
-295 
-296     SceneJS.Texture.prototype._getGLOption = function (name, gl, layer, defaultVal) {
-297         var value = layer[name];
-298         if (value == undefined) {
-299             return defaultVal;
-300         }
-301         var glName = SceneJS_webgl_enumMap[value];
-302         if (glName == undefined) {
-303             throw SceneJS_error.fatalError(
-304                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-305                 "Unrecognised value for texture node property '" + name + "' value: '" + value + "'");
-306         }
-307         var glValue = gl[glName];
-308         //                if (!glValue) {
-309         //                    throw new SceneJS.errors.WebGLUnsupportedNodeConfigException(
-310         //                            "This browser's WebGL does not support value of SceneJS.texture node property '" + name + "' value: '" + value + "'");
-311         //                }
-312         return glValue;
-313     };
-314 
-315     SceneJS.Texture.prototype._getOption = function (value, defaultVal) {
-316         return (value == undefined) ? defaultVal : value;
-317     };
-318 
-319     /**
-320      * Set some writeable properties on a layer
-321      */
-322     SceneJS.Texture.prototype.setLayer = function (cfg) {
-323 
-324         if (cfg.index == undefined || cfg.index == null) {
-325             throw SceneJS_error.fatalError(
-326                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-327                 "Invalid texture set layer argument: index null or undefined");
-328         }
-329 
-330         if (cfg.index < 0 || cfg.index >= this._core.layers.length) {
-331             throw SceneJS_error.fatalError(
-332                 SceneJS.errors.ILLEGAL_NODE_CONFIG,
-333                 "Invalid texture set layer argument: index out of range (" + this._core.layers.length + " layers defined)");
-334         }
-335 
-336         this._setLayer(parseInt(cfg.index), cfg);
-337 
-338         this._engine.display.imageDirty = true;
-339     };
-340 
-341     /**
-342      * Set some writeable properties on multiple layers
-343      */
-344     SceneJS.Texture.prototype.setLayers = function (layers) {
-345         var indexNum;
-346         for (var index in layers) {
-347             if (layers.hasOwnProperty(index)) {
-348                 if (index != undefined || index != null) {
-349                     indexNum = parseInt(index);
-350                     if (indexNum < 0 || indexNum >= this._core.layers.length) {
-351                         throw SceneJS_error.fatalError(
-352                             SceneJS.errors.ILLEGAL_NODE_CONFIG,
-353                             "Invalid texture set layer argument: index out of range (" + this._core.layers.length + " layers defined)");
-354                     }
-355                     this._setLayer(indexNum, layers[index] || {});
-356                 }
-357             }
-358         }
-359         this._engine.display.imageDirty = true;
-360     };
-361 
-362     SceneJS.Texture.prototype._setLayer = function (index, cfg) {
-363 
-364         cfg = cfg || {};
-365 
-366         var layer = this._core.layers[index];
-367 
-368         if (cfg.blendFactor != undefined && cfg.blendFactor != null) {
-369             layer.blendFactor = cfg.blendFactor;
-370         }
-371 
-372         if (cfg.source) {
-373             var source = layer._source;
-374             if (source) {
-375                 source.setConfigs(cfg.source);
-376             }
-377         }
-378 
-379         if (cfg.translate || cfg.rotate || cfg.scale) {
-380             this._setLayerTransform(cfg, layer);
-381         }
-382     };
-383 
-384     SceneJS.Texture.prototype._setLayerTransform = function (cfg, layer) {
-385 
-386         var matrix;
-387         var t;
-388 
-389         if (cfg.translate) {
-390             var translate = cfg.translate;
-391             if (translate.x != undefined) {
-392                 layer.translate.x = translate.x;
-393             }
-394             if (translate.y != undefined) {
-395                 layer.translate.y = translate.y;
-396             }
-397             matrix = SceneJS_math_translationMat4v([ translate.x || 0, translate.y || 0, 0]);
-398         }
-399 
-400         if (cfg.scale) {
-401             var scale = cfg.scale;
-402             if (scale.x != undefined) {
-403                 layer.scale.x = scale.x;
-404             }
-405             if (scale.y != undefined) {
-406                 layer.scale.y = scale.y;
-407             }
-408             t = SceneJS_math_scalingMat4v([ scale.x || 1, scale.y || 1, 1]);
-409             matrix = matrix ? SceneJS_math_mulMat4(matrix, t) : t;
-410         }
-411 
-412         if (cfg.rotate) {
-413             var rotate = cfg.rotate;
-414             if (rotate.z != undefined) {
-415                 layer.rotate.z = rotate.z || 0;
-416             }
-417             t = SceneJS_math_rotationMat4v(rotate.z * 0.0174532925, [0, 0, 1]);
-418             matrix = matrix ? SceneJS_math_mulMat4(matrix, t) : t;
-419         }
-420 
-421         if (matrix) {
-422             layer.matrix = matrix;
-423             if (!layer.matrixAsArray) {
-424                 layer.matrixAsArray = new Float32Array(layer.matrix);
-425             } else {
-426                 layer.matrixAsArray.set(layer.matrix);
-427             }
-428 
-429             layer.matrixAsArray = new Float32Array(layer.matrix); // TODO - reinsert into array
-430         }
-431     };
-432 
-433     SceneJS.Texture.prototype._compile = function () {
-434 
-435         if (!this._core.hash) {
-436             this._makeHash();
-437         }
-438 
-439         this._engine.display.texture = coreStack[stackLen++] = this._core;
-440         this._compileNodes();
-441         this._engine.display.texture = (--stackLen > 0) ? coreStack[stackLen - 1] : defaultCore;
-442     };
-443 
-444     SceneJS.Texture.prototype._makeHash = function () {
-445 
-446         var core = this._core;
-447         var hash;
-448 
-449         if (core.layers && core.layers.length > 0) {
-450 
-451             var layers = core.layers;
-452             var hashParts = [];
-453             var texLayer;
-454 
-455             for (var i = 0, len = layers.length; i < len; i++) {
-456 
-457                 texLayer = layers[i];
-458 
-459                 hashParts.push("/");
-460                 hashParts.push(texLayer.applyFrom);
-461                 hashParts.push("/");
-462                 hashParts.push(texLayer.applyTo);
-463                 hashParts.push("/");
-464                 hashParts.push(texLayer.blendMode);
-465 
-466                 if (texLayer.matrix) {
-467                     hashParts.push("/anim");
-468                 }
-469             }
-470 
-471             hash = hashParts.join("");
-472 
-473         } else {
-474             hash = "";
-475         }
-476 
-477         if (core.hash != hash) {
-478             core.hash = hash;
-479         }
-480     };
-481 
-482     SceneJS.Texture.prototype._destroy = function () {
-483         if (this._core.useCount == 1) { // Last resource user
-484             var layers = this._core.layers;
-485             var layer;
-486             var source;
-487             for (var i = 0, len = layers.length; i < len; i++) {
-488                 layer = layers[i];
-489                 if (layer.texture) {
-490                     layer.texture.destroy();
-491                 }
-492                 source = layer._source;
-493                 if (source && source.destroy) {
-494                     source.destroy();
-495                 }
-496             }
-497         }
-498     };
-499 
-500 })();
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_translate.js.html b/docs/symbols/src/src_core_scene_translate.js.html deleted file mode 100644 index 094e53f1..00000000 --- a/docs/symbols/src/src_core_scene_translate.js.html +++ /dev/null @@ -1,166 +0,0 @@ -
  1 /**
-  2  * @class Scene graph node which defines a translation modelling transform to apply to the objects in its subgraph
-  3  * @extends SceneJS.Node
-  4  */
-  5 SceneJS.Translate = SceneJS_NodeFactory.createNodeType("translate");
-  6 
-  7 SceneJS.Translate.prototype._init = function(params) {
-  8 
-  9     if (this._core.useCount == 1) { // This node is the resource definer
- 10 
- 11         SceneJS_modelXFormStack.buildCore(this._core);
- 12         
- 13         this.setMultOrder(params.multOrder);
- 14 
- 15         this.setXYZ({
- 16             x: params.x,
- 17             y: params.y,
- 18             z: params.z
- 19         });
- 20 
- 21         var core = this._core;
- 22 
- 23         this._core.buildMatrix = function() {
- 24             core.matrix = SceneJS_math_translationMat4v([core.x, core.y, core.z], core.matrix);
- 25         };
- 26     }
- 27 };
- 28 
- 29 /**
- 30  * Get Model matrix
- 31  * @return {*}
- 32  */
- 33 SceneJS.Translate.prototype.getModelMatrix = function() {
- 34     if (this._core.dirty) {
- 35         this._core.build();
- 36     }
- 37     return this._core.matrix;
- 38 };
- 39 
- 40 /**
- 41  * Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next
- 42  * tranform (scale, translate, translate etc) node on the path to the scene root.
- 43  * @return {*}
- 44  */
- 45 SceneJS.Translate.prototype.getWorldMatrix = function() {
- 46     if (this._core.dirty) {
- 47         this._core.build();
- 48     }
- 49     return Array.apply( [], this._core.mat);
- 50 };
- 51 
- 52 
- 53 /**
- 54  * Sets the multiplication order of this node's transform matrix with respect to the parent modeling transform
- 55  * in the scene graph.
- 56  *
- 57  * @param {String} multOrder Mulplication order - "post" and "pre"
- 58  */
- 59 SceneJS.Translate.prototype.setMultOrder = function(multOrder) {
- 60 
- 61     multOrder = multOrder || "post";
- 62 
- 63     if (multOrder != "post" && multOrder != "pre") {
- 64 
- 65         throw SceneJS_error.fatalError(
- 66                 SceneJS.errors.NODE_CONFIG_EXPECTED,
- 67                 "Illegal multOrder for translate node - '" + multOrder + "' should be 'pre' or 'post'");
- 68     }
- 69 
- 70     this._core.multOrder = multOrder;
- 71 
- 72     this._core.setDirty();
- 73 
- 74     this._engine.display.imageDirty = true;
- 75 };
- 76 
- 77 SceneJS.Translate.prototype.setXYZ = function(xyz) {
- 78 
- 79     xyz = xyz || {};
- 80 
- 81     this._core.x = xyz.x || 0;
- 82     this._core.y = xyz.y || 0;
- 83     this._core.z = xyz.z || 0;
- 84 
- 85     this._core.setDirty();
- 86 
- 87     this._engine.display.imageDirty = true;
- 88 
- 89     return this;
- 90 };
- 91 
- 92 SceneJS.Translate.prototype.getXYZ = function() {
- 93     return {
- 94         x: this._core.x,
- 95         y: this._core.y,
- 96         z: this._core.z
- 97     };
- 98 };
- 99 
-100 SceneJS.Translate.prototype.setX = function(x) {
-101     this._core.x = x;
-102     this._core.setDirty();
-103     this._engine.display.imageDirty = true;
-104     return this;
-105 };
-106 
-107 SceneJS.Translate.prototype.getX = function() {
-108     return this._core.x;
-109 };
-110 
-111 SceneJS.Translate.prototype.setY = function(y) {
-112     this._core.y = y;
-113     this._core.setDirty();
-114     this._engine.display.imageDirty = true;
-115     return this;
-116 };
-117 
-118 SceneJS.Translate.prototype.getY = function() {
-119     return this._core.y;
-120 };
-121 
-122 SceneJS.Translate.prototype.setZ = function(z) {
-123     this._core.z = z;
-124     this._core.setDirty();
-125     this._engine.display.imageDirty = true;
-126     return this;
-127 };
-128 
-129 SceneJS.Translate.prototype.getZ = function() {
-130     return this._core.z;
-131 };
-132 
-133 SceneJS.Translate.prototype.incX = function(x) {
-134     this._core.x += x;
-135     this._core.setDirty();
-136     this._engine.display.imageDirty = true;
-137     return this;
-138 };
-139 
-140 SceneJS.Translate.prototype.incY = function(y) {
-141     this._core.y += y;
-142     this._core.setDirty();
-143     this._engine.display.imageDirty = true;
-144     return this;
-145 };
-146 
-147 SceneJS.Translate.prototype.incZ = function(z) {
-148     this._core.z += z;
-149     this._core.setDirty();
-150     this._engine.display.imageDirty = true;
-151     return this;
-152 };
-153 
-154 SceneJS.Translate.prototype._compile = function() {
-155     SceneJS_modelXFormStack.push(this._core);
-156     this._compileNodes();
-157     SceneJS_modelXFormStack.pop();
-158 };
-159 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scene_xform.js.html b/docs/symbols/src/src_core_scene_xform.js.html deleted file mode 100644 index 53b79cbb..00000000 --- a/docs/symbols/src/src_core_scene_xform.js.html +++ /dev/null @@ -1,88 +0,0 @@ -
  1 /**
-  2  * @class Scene graph node which defines the modelling transform to apply to the objects in its subgraph
-  3  * @extends SceneJS.Node
-  4  */
-  5 SceneJS.XForm = SceneJS_NodeFactory.createNodeType("xform");
-  6 
-  7 SceneJS.XForm.prototype._init = function (params) {
-  8 
-  9     if (this._core.useCount == 1) { // This node is the resource definer
- 10 
- 11         SceneJS_modelXFormStack.buildCore(this._core);
- 12 
- 13         this.setElements(params.elements);
- 14     }
- 15 };
- 16 
- 17 /**
- 18  * Get Model matrix
- 19  * @return {*}
- 20  */
- 21 SceneJS.XForm.prototype.getModelMatrix = function() {
- 22     if (this._core.dirty) {
- 23         this._core.build();
- 24     }
- 25     return this._core.matrix;
- 26 };
- 27 
- 28 /**
- 29  * Get World matrix. That's the multiplication of this node's Model matrix by the World matrix of the the next
- 30  * tranform (scale, XForm, translate etc) node on the path to the scene root.
- 31  * @return {*}
- 32  */
- 33 SceneJS.XForm.prototype.getWorldMatrix = function() {
- 34     if (this._core.dirty) {
- 35         this._core.build();
- 36     }
- 37     return Array.apply( [], this._core.mat);
- 38 };
- 39 
- 40 
- 41 SceneJS.XForm.prototype.setElements = function (elements) {
- 42 
- 43     elements = elements || SceneJS_math_identityMat4();
- 44 
- 45     if (elements.length != 16) {
- 46         throw SceneJS_error.fatalError(
- 47             SceneJS.errors.ILLEGAL_NODE_CONFIG,
- 48             "SceneJS.XForm elements should number 16");
- 49     }
- 50 
- 51     var core = this._core;
- 52 
- 53     if (!core.matrix) {
- 54         core.matrix = elements;
- 55 
- 56     } else {
- 57 
- 58         for (var i = 0; i < 16; i++) {
- 59             core.matrix[i] = elements[i];
- 60         }
- 61     }
- 62 
- 63 //    core.mat.set(core.matrix);
- 64 //    core.normalMat.set(
- 65 //        SceneJS_math_transposeMat4(
- 66 //            SceneJS_math_inverseMat4(core.matrix, SceneJS_math_mat4())));
- 67 
- 68 
- 69     core.setDirty();
- 70 
- 71     this._engine.display.imageDirty = true;
- 72 
- 73     return this;
- 74 };
- 75 
- 76 SceneJS.XForm.prototype._compile = function () {
- 77     SceneJS_modelXFormStack.push(this._core);
- 78     this._compileNodes();
- 79     SceneJS_modelXFormStack.pop();
- 80 };
- 81 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_scenejs.js.html b/docs/symbols/src/src_core_scenejs.js.html deleted file mode 100644 index 834cdd8c..00000000 --- a/docs/symbols/src/src_core_scenejs.js.html +++ /dev/null @@ -1,194 +0,0 @@ -
  1 /**
-  2  * The SceneJS object.
-  3  */
-  4 var SceneJS = new (function () {
-  5 
-  6     /**
-  7      * This SceneJS version
-  8      */
-  9     this.VERSION = '3.0.0.0';
- 10 
- 11     this._baseStateId = 0;
- 12 
- 13     /**
- 14      * @property {SceneJS_Engine} Engines currently in existance
- 15      */
- 16     this._engines = {};
- 17 
- 18     this._engineIds = new SceneJS_Map();
- 19 
- 20     /**
- 21      * Creates a new scene from the given JSON description
- 22      *
- 23      * @param {String} json JSON scene description
- 24      * @param options Optional options
- 25      * @param options.simulateWebGLContextLost Optional options
- 26      * @returns {SceneJS.Scene} New scene
- 27      */
- 28     this.createScene = function (json, options) {
- 29 
- 30         if (!json) {
- 31             throw SceneJS_error.fatalError("param 'json' is null or undefined");
- 32         }
- 33 
- 34         if (json.id) {
- 35             if (this._engines[json.id]) {
- 36                 throw SceneJS_error.fatalError(
- 37                     SceneJS.errors.ILLEGAL_NODE_CONFIG,
- 38                     "Scene already exists with this ID: '" + json.id + "'");
- 39             }
- 40             this._engineIds.addItem(json.id, {});
- 41         } else {
- 42             json.id = this._engineIds.addItem({});
- 43         }
- 44 
- 45         var engine = new SceneJS_Engine(json, options);
- 46 
- 47         this._engines[json.id] = engine;
- 48 
- 49         SceneJS_events.fireEvent(SceneJS_events.SCENE_CREATED, {    // Notify modules that need to know about new scene
- 50             engine:engine
- 51         });
- 52 
- 53         return engine.scene;
- 54     };
- 55 
- 56     /**
- 57      * Gets an existing scene
- 58      *
- 59      * @param {String} sceneId ID of target scene
- 60      * @deprecated
- 61      * @returns {SceneJS.Scene} The selected scene
- 62      */
- 63     this.scene = function (sceneId) {
- 64 
- 65         var engine = this._engines[sceneId];
- 66 
- 67         return engine ? engine.scene : null;
- 68     };
- 69 
- 70     /**
- 71      * Gets an existing scene
- 72      *
- 73      * @param {String} sceneId ID of target scene
- 74      * @returns {SceneJS.Scene} The selected scene
- 75      */
- 76     this.getScene = function (sceneId) {
- 77 
- 78         var engine = this._engines[sceneId];
- 79 
- 80         return engine ? engine.scene : null;
- 81     };
- 82 
- 83     /**
- 84      * Gets existing scenes
- 85      *
- 86      * @returns  Existing scenes, mapped to their IDs
- 87      */
- 88     this.getScenes = function () {
- 89 
- 90         var scenes = {};
- 91 
- 92         for (var sceneId in this._engines) {
- 93             if (this._engines.hasOwnProperty(sceneId)) {
- 94                 scenes[sceneId] = this._engines[sceneId].scene;
- 95             }
- 96         }
- 97 
- 98         return scenes;
- 99     };
-100 
-101     /**
-102      * Tests if the given object is an array
-103      * @private
-104      */
-105     this._isArray = function (testObject) {
-106         return testObject && !(testObject.propertyIsEnumerable('length'))
-107             && typeof testObject === 'object' && typeof testObject.length === 'number';
-108     };
-109 
-110     /**
-111      *
-112      */
-113     this._shallowClone = function (o) {
-114         var o2 = {};
-115         for (var name in o) {
-116             if (o.hasOwnProperty(name)) {
-117                 o2[name] = o[name];
-118             }
-119         }
-120         return o2;
-121     };
-122 
-123     /**
-124      * Add properties of o to o2 where undefined or null on o2
-125      * @private
-126      */
-127     this._applyIf = function (o, o2) {
-128         for (var name in o) {
-129             if (o.hasOwnProperty(name)) {
-130                 if (o2[name] == undefined || o2[name] == null) {
-131                     o2[name] = o[name];
-132                 }
-133             }
-134         }
-135         return o2;
-136     };
-137 
-138     /**
-139      * Add properties of o to o2, overwriting them on o2 if already there.
-140      * The optional clear flag causes properties on o2 to be cleared first
-141      * @private
-142      */
-143     this._apply = function (o, o2, clear) {
-144         var name;
-145         if (clear) {
-146             for (name in o2) {
-147                 if (o2.hasOwnProperty(name)) {
-148                     delete o2[name];
-149                 }
-150             }
-151         }
-152         for (name in o) {
-153             if (o.hasOwnProperty(name)) {
-154                 o2[name] = o[name];
-155             }
-156         }
-157         return o2;
-158     };
-159 
-160 
-161     /**
-162      * Resets SceneJS, destroying all existing scenes
-163      */
-164     this.reset = function () {
-165 
-166         var temp = [];
-167 
-168         for (var id in this._engines) { // Collect engines to destroy
-169             if (this._engines.hasOwnProperty(id)) {
-170 
-171                 temp.push(this._engines[id]);
-172 
-173                 delete this._engines[id];
-174 
-175                 this._engineIds.removeItem(id);
-176             }
-177         }
-178 
-179         while (temp.length > 0) { // Destroy the engines
-180             temp.pop().destroy();
-181         }
-182 
-183         SceneJS_events.fireEvent(SceneJS_events.RESET);
-184     };
-185 
-186 })();
-187 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_status.js.html b/docs/symbols/src/src_core_status.js.html deleted file mode 100644 index 7f29c426..00000000 --- a/docs/symbols/src/src_core_status.js.html +++ /dev/null @@ -1,58 +0,0 @@ -
  1 /**
-  2  * Backend that tracks statistics on loading states of nodes during scene traversal.
-  3  *
-  4  * This supports the "loading-status" events that we can listen for on scene nodes.
-  5  *
-  6  * When a node with that listener is pre-visited, it will call getStatus on this module to
-  7  * save a copy of the status. Then when it is post-visited, it will call diffStatus on this
-  8  * module to find the status for its sub-nodes, which it then reports through the "loading-status" event.
-  9  *
- 10  * @private
- 11  */
- 12 var SceneJS_sceneStatusModule = new (function() {
- 13 
- 14     this.sceneStatus = {};
- 15 
- 16     var self = this;
- 17 
- 18     SceneJS_events.addListener(
- 19             SceneJS_events.SCENE_CREATED,
- 20             function(params) {
- 21                 self.sceneStatus[params.engine.id] = {
- 22                     numTasks: 0
- 23                 };
- 24             });
- 25 
- 26     SceneJS_events.addListener(
- 27             SceneJS_events.SCENE_DESTROYED,
- 28             function(params) {
- 29                 delete self.sceneStatus[params.engine.id];
- 30             });
- 31 
- 32     this.nodeLoading = function(node) {
- 33 
- 34         var status = self.sceneStatus[node._engine.id];
- 35 
- 36         if (!status) {
- 37             status = self.sceneStatus[node._engine.id] = {
- 38                 numTasks: 0
- 39             };
- 40 
- 41         }
- 42         status.numTasks++;
- 43     };
- 44 
- 45     this.nodeLoaded = function(node) {
- 46         this.sceneStatus[node._engine.id].numTasks--;
- 47     };
- 48 
- 49 })();
- 50 
- 51 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_webgl-debug-utils.js.html b/docs/symbols/src/src_core_webgl-debug-utils.js.html deleted file mode 100644 index e8d7b602..00000000 --- a/docs/symbols/src/src_core_webgl-debug-utils.js.html +++ /dev/null @@ -1,847 +0,0 @@ -
  1 
-  2 WebGLDebugUtils = function() {
-  3 
-  4 /**
-  5  * Wrapped logging function.
-  6  * @param {string} msg Message to log.
-  7  */
-  8 var log = function(msg) {
-  9   if (window.console && window.console.log) {
- 10     window.console.log(msg);
- 11   }
- 12 };
- 13 
- 14 /**
- 15  * Which arguements are enums.
- 16  * @type {!Object.<number, string>}
- 17  */
- 18 var glValidEnumContexts = {
- 19 
- 20   // Generic setters and getters
- 21 
- 22   'enable': { 0:true },
- 23   'disable': { 0:true },
- 24   'getParameter': { 0:true },
- 25 
- 26   // Rendering
- 27 
- 28   'drawArrays': { 0:true },
- 29   'drawElements': { 0:true, 2:true },
- 30 
- 31   // Shaders
- 32 
- 33   'createShader': { 0:true },
- 34   'getShaderParameter': { 1:true },
- 35   'getProgramParameter': { 1:true },
- 36 
- 37   // Vertex attributes
- 38 
- 39   'getVertexAttrib': { 1:true },
- 40   'vertexAttribPointer': { 2:true },
- 41 
- 42   // Textures
- 43 
- 44   'bindTexture': { 0:true },
- 45   'activeTexture': { 0:true },
- 46   'getTexParameter': { 0:true, 1:true },
- 47   'texParameterf': { 0:true, 1:true },
- 48   'texParameteri': { 0:true, 1:true, 2:true },
- 49   'texImage2D': { 0:true, 2:true, 6:true, 7:true },
- 50   'texSubImage2D': { 0:true, 6:true, 7:true },
- 51   'copyTexImage2D': { 0:true, 2:true },
- 52   'copyTexSubImage2D': { 0:true },
- 53   'generateMipmap': { 0:true },
- 54 
- 55   // Buffer objects
- 56 
- 57   'bindBuffer': { 0:true },
- 58   'bufferData': { 0:true, 2:true },
- 59   'bufferSubData': { 0:true },
- 60   'getBufferParameter': { 0:true, 1:true },
- 61 
- 62   // Renderbuffers and framebuffers
- 63 
- 64   'pixelStorei': { 0:true, 1:true },
- 65   'readPixels': { 4:true, 5:true },
- 66   'bindRenderbuffer': { 0:true },
- 67   'bindFramebuffer': { 0:true },
- 68   'checkFramebufferStatus': { 0:true },
- 69   'framebufferRenderbuffer': { 0:true, 1:true, 2:true },
- 70   'framebufferTexture2D': { 0:true, 1:true, 2:true },
- 71   'getFramebufferAttachmentParameter': { 0:true, 1:true, 2:true },
- 72   'getRenderbufferParameter': { 0:true, 1:true },
- 73   'renderbufferStorage': { 0:true, 1:true },
- 74 
- 75   // Frame buffer operations (clear, blend, depth test, stencil)
- 76 
- 77   'clear': { 0:true },
- 78   'depthFunc': { 0:true },
- 79   'blendFunc': { 0:true, 1:true },
- 80   'blendFuncSeparate': { 0:true, 1:true, 2:true, 3:true },
- 81   'blendEquation': { 0:true },
- 82   'blendEquationSeparate': { 0:true, 1:true },
- 83   'stencilFunc': { 0:true },
- 84   'stencilFuncSeparate': { 0:true, 1:true },
- 85   'stencilMaskSeparate': { 0:true },
- 86   'stencilOp': { 0:true, 1:true, 2:true },
- 87   'stencilOpSeparate': { 0:true, 1:true, 2:true, 3:true },
- 88 
- 89   // Culling
- 90 
- 91   'cullFace': { 0:true },
- 92   'frontFace': { 0:true },
- 93 };
- 94 
- 95 /**
- 96  * Map of numbers to names.
- 97  * @type {Object}
- 98  */
- 99 var glEnums = null;
-100 
-101 /**
-102  * Initializes this module. Safe to call more than once.
-103  * @param {!WebGLRenderingContext} ctx A WebGL context. If
-104  *    you have more than one context it doesn't matter which one
-105  *    you pass in, it is only used to pull out constants.
-106  */
-107 function init(ctx) {
-108   if (glEnums == null) {
-109     glEnums = { };
-110     for (var propertyName in ctx) {
-111       if (typeof ctx[propertyName] == 'number') {
-112         glEnums[ctx[propertyName]] = propertyName;
-113       }
-114     }
-115   }
-116 }
-117 
-118 /**
-119  * Checks the utils have been initialized.
-120  */
-121 function checkInit() {
-122   if (glEnums == null) {
-123     throw 'WebGLDebugUtils.init(ctx) not called';
-124   }
-125 }
-126 
-127 /**
-128  * Returns true or false if value matches any WebGL enum
-129  * @param {*} value Value to check if it might be an enum.
-130  * @return {boolean} True if value matches one of the WebGL defined enums
-131  */
-132 function mightBeEnum(value) {
-133   checkInit();
-134   return (glEnums[value] !== undefined);
-135 }
-136 
-137 /**
-138  * Gets an string version of an WebGL enum.
-139  *
-140  * Example:
-141  *   var str = WebGLDebugUtil.glEnumToString(ctx.getError());
-142  *
-143  * @param {number} value Value to return an enum for
-144  * @return {string} The string version of the enum.
-145  */
-146 function glEnumToString(value) {
-147   checkInit();
-148   var name = glEnums[value];
-149   return (name !== undefined) ? name :
-150       ("*UNKNOWN WebGL ENUM (0x" + value.toString(16) + ")");
-151 }
-152 
-153 /**
-154  * Returns the string version of a WebGL argument.
-155  * Attempts to convert enum arguments to strings.
-156  * @param {string} functionName the name of the WebGL function.
-157  * @param {number} argumentIndx the index of the argument.
-158  * @param {*} value The value of the argument.
-159  * @return {string} The value as a string.
-160  */
-161 function glFunctionArgToString(functionName, argumentIndex, value) {
-162   var funcInfo = glValidEnumContexts[functionName];
-163   if (funcInfo !== undefined) {
-164     if (funcInfo[argumentIndex]) {
-165       return glEnumToString(value);
-166     }
-167   }
-168   if (value === null) {
-169     return "null";
-170   } else if (value === undefined) {
-171     return "undefined";
-172   } else {
-173     return value.toString();
-174   }
-175 }
-176 
-177 /**
-178  * Converts the arguments of a WebGL function to a string.
-179  * Attempts to convert enum arguments to strings.
-180  *
-181  * @param {string} functionName the name of the WebGL function.
-182  * @param {number} args The arguments.
-183  * @return {string} The arguments as a string.
-184  */
-185 function glFunctionArgsToString(functionName, args) {
-186   // apparently we can't do args.join(",");
-187   var argStr = "";
-188   for (var ii = 0; ii < args.length; ++ii) {
-189     argStr += ((ii == 0) ? '' : ', ') +
-190         glFunctionArgToString(functionName, ii, args[ii]);
-191   }
-192   return argStr;
-193 };
-194 
-195 
-196 function makePropertyWrapper(wrapper, original, propertyName) {
-197   //log("wrap prop: " + propertyName);
-198   wrapper.__defineGetter__(propertyName, function() {
-199     return original[propertyName];
-200   });
-201   // TODO(gmane): this needs to handle properties that take more than
-202   // one value?
-203   wrapper.__defineSetter__(propertyName, function(value) {
-204     //log("set: " + propertyName);
-205     original[propertyName] = value;
-206   });
-207 }
-208 
-209 // Makes a function that calls a function on another object.
-210 function makeFunctionWrapper(original, functionName) {
-211   //log("wrap fn: " + functionName);
-212   var f = original[functionName];
-213   return function() {
-214     //log("call: " + functionName);
-215     var result = f.apply(original, arguments);
-216     return result;
-217   };
-218 }
-219 
-220 /**
-221  * Given a WebGL context returns a wrapped context that calls
-222  * gl.getError after every command and calls a function if the
-223  * result is not gl.NO_ERROR.
-224  *
-225  * @param {!WebGLRenderingContext} ctx The webgl context to
-226  *        wrap.
-227  * @param {!function(err, funcName, args): void} opt_onErrorFunc
-228  *        The function to call when gl.getError returns an
-229  *        error. If not specified the default function calls
-230  *        console.log with a message.
-231  * @param {!function(funcName, args): void} opt_onFunc The
-232  *        function to call when each webgl function is called.
-233  *        You can use this to log all calls for example.
-234  */
-235 function makeDebugContext(ctx, opt_onErrorFunc, opt_onFunc) {
-236   init(ctx);
-237   opt_onErrorFunc = opt_onErrorFunc || function(err, functionName, args) {
-238         // apparently we can't do args.join(",");
-239         var argStr = "";
-240         for (var ii = 0; ii < args.length; ++ii) {
-241           argStr += ((ii == 0) ? '' : ', ') +
-242               glFunctionArgToString(functionName, ii, args[ii]);
-243         }
-244         log("WebGL error "+ glEnumToString(err) + " in "+ functionName +
-245             "(" + argStr + ")");
-246       };
-247 
-248   // Holds booleans for each GL error so after we get the error ourselves
-249   // we can still return it to the client app.
-250   var glErrorShadow = { };
-251 
-252   // Makes a function that calls a WebGL function and then calls getError.
-253   function makeErrorWrapper(ctx, functionName) {
-254     return function() {
-255       if (opt_onFunc) {
-256         opt_onFunc(functionName, arguments);
-257       }
-258       var result = ctx[functionName].apply(ctx, arguments);
-259       var err = ctx.getError();
-260       if (err != 0) {
-261         glErrorShadow[err] = true;
-262         opt_onErrorFunc(err, functionName, arguments);
-263       }
-264       return result;
-265     };
-266   }
-267 
-268   // Make a an object that has a copy of every property of the WebGL context
-269   // but wraps all functions.
-270   var wrapper = {};
-271   for (var propertyName in ctx) {
-272     if (typeof ctx[propertyName] == 'function') {
-273        wrapper[propertyName] = makeErrorWrapper(ctx, propertyName);
-274      } else {
-275        makePropertyWrapper(wrapper, ctx, propertyName);
-276      }
-277   }
-278 
-279   // Override the getError function with one that returns our saved results.
-280   wrapper.getError = function() {
-281     for (var err in glErrorShadow) {
-282       if (glErrorShadow.hasOwnProperty(err)) {
-283         if (glErrorShadow[err]) {
-284           glErrorShadow[err] = false;
-285           return err;
-286         }
-287       }
-288     }
-289     return ctx.NO_ERROR;
-290   };
-291 
-292   return wrapper;
-293 }
-294 
-295 function resetToInitialState(ctx) {
-296   var numAttribs = ctx.getParameter(ctx.MAX_VERTEX_ATTRIBS);
-297   var tmp = ctx.createBuffer();
-298   ctx.bindBuffer(ctx.ARRAY_BUFFER, tmp);
-299   for (var ii = 0; ii < numAttribs; ++ii) {
-300     ctx.disableVertexAttribArray(ii);
-301     ctx.vertexAttribPointer(ii, 4, ctx.FLOAT, false, 0, 0);
-302     ctx.vertexAttrib1f(ii, 0);
-303   }
-304   ctx.deleteBuffer(tmp);
-305 
-306   var numTextureUnits = ctx.getParameter(ctx.MAX_TEXTURE_IMAGE_UNITS);
-307   for (var ii = 0; ii < numTextureUnits; ++ii) {
-308     ctx.activeTexture(ctx.TEXTURE0 + ii);
-309     ctx.bindTexture(ctx.TEXTURE_CUBE_MAP, null);
-310     ctx.bindTexture(ctx.TEXTURE_2D, null);
-311   }
-312 
-313   ctx.activeTexture(ctx.TEXTURE0);
-314   ctx.useProgram(null);
-315   ctx.bindBuffer(ctx.ARRAY_BUFFER, null);
-316   ctx.bindBuffer(ctx.ELEMENT_ARRAY_BUFFER, null);
-317   ctx.bindFramebuffer(ctx.FRAMEBUFFER, null);
-318   ctx.bindRenderbuffer(ctx.RENDERBUFFER, null);
-319   ctx.disable(ctx.BLEND);
-320   ctx.disable(ctx.CULL_FACE);
-321   ctx.disable(ctx.DEPTH_TEST);
-322   ctx.disable(ctx.DITHER);
-323   ctx.disable(ctx.SCISSOR_TEST);
-324   ctx.blendColor(0, 0, 0, 0);
-325   ctx.blendEquation(ctx.FUNC_ADD);
-326   ctx.blendFunc(ctx.ONE, ctx.ZERO);
-327   ctx.clearColor(0, 0, 0, 0);
-328   ctx.clearDepth(1);
-329   ctx.clearStencil(-1);
-330   ctx.colorMask(true, true, true, true);
-331   ctx.cullFace(ctx.BACK);
-332   ctx.depthFunc(ctx.LESS);
-333   ctx.depthMask(true);
-334   ctx.depthRange(0, 1);
-335   ctx.frontFace(ctx.CCW);
-336   ctx.hint(ctx.GENERATE_MIPMAP_HINT, ctx.DONT_CARE);
-337   ctx.lineWidth(1);
-338   ctx.pixelStorei(ctx.PACK_ALIGNMENT, 4);
-339   ctx.pixelStorei(ctx.UNPACK_ALIGNMENT, 4);
-340   ctx.pixelStorei(ctx.UNPACK_FLIP_Y_WEBGL, false);
-341   ctx.pixelStorei(ctx.UNPACK_PREMULTIPLY_ALPHA_WEBGL, false);
-342   // TODO: Delete this IF.
-343   if (ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL) {
-344     ctx.pixelStorei(ctx.UNPACK_COLORSPACE_CONVERSION_WEBGL, ctx.BROWSER_DEFAULT_WEBGL);
-345   }
-346   ctx.polygonOffset(0, 0);
-347   ctx.sampleCoverage(1, false);
-348   ctx.scissor(0, 0, ctx.canvas.width, ctx.canvas.height);
-349   ctx.stencilFunc(ctx.ALWAYS, 0, 0xFFFFFFFF);
-350   ctx.stencilMask(0xFFFFFFFF);
-351   ctx.stencilOp(ctx.KEEP, ctx.KEEP, ctx.KEEP);
-352   ctx.viewport(0, 0, ctx.canvas.width, ctx.canvas.height);
-353   ctx.clear(ctx.COLOR_BUFFER_BIT | ctx.DEPTH_BUFFER_BIT | ctx.STENCIL_BUFFER_BIT);
-354 
-355   // TODO: This should NOT be needed but Firefox fails with 'hint'
-356   while(ctx.getError());
-357 }
-358 
-359 function makeLostContextSimulatingCanvas(canvas) {
-360   var unwrappedContext_;
-361   var wrappedContext_;
-362   var onLost_ = [];
-363   var onRestored_ = [];
-364   var wrappedContext_ = {};
-365   var contextId_ = 1;
-366   var contextLost_ = false;
-367   var resourceId_ = 0;
-368   var resourceDb_ = [];
-369   var numCallsToLoseContext_ = 0;
-370   var numCalls_ = 0;
-371   var canRestore_ = false;
-372   var restoreTimeout_ = 0;
-373 
-374   // Holds booleans for each GL error so can simulate errors.
-375   var glErrorShadow_ = { };
-376 
-377   canvas.getContext = function(f) {
-378     return function() {
-379       var ctx = f.apply(canvas, arguments);
-380       // Did we get a context and is it a WebGL context?
-381       if (ctx instanceof WebGLRenderingContext) {
-382         if (ctx != unwrappedContext_) {
-383           if (unwrappedContext_) {
-384             throw "got different context"
-385           }
-386           unwrappedContext_ = ctx;
-387           wrappedContext_ = makeLostContextSimulatingContext(unwrappedContext_);
-388         }
-389         return wrappedContext_;
-390       }
-391       return ctx;
-392     }
-393   }(canvas.getContext);
-394 
-395   function wrapEvent(listener) {
-396     if (typeof(listener) == "function") {
-397       return listener;
-398     } else {
-399       return function(info) {
-400         listener.handleEvent(info);
-401       }
-402     }
-403   }
-404 
-405   var addOnContextLostListener = function(listener) {
-406     onLost_.push(wrapEvent(listener));
-407   };
-408 
-409   var addOnContextRestoredListener = function(listener) {
-410     onRestored_.push(wrapEvent(listener));
-411   };
-412 
-413 
-414   function wrapAddEventListener(canvas) {
-415     var f = canvas.addEventListener;
-416     canvas.addEventListener = function(type, listener, bubble) {
-417       switch (type) {
-418         case 'webglcontextlost':
-419           addOnContextLostListener(listener);
-420           break;
-421         case 'webglcontextrestored':
-422           addOnContextRestoredListener(listener);
-423           break;
-424         default:
-425           f.apply(canvas, arguments);
-426       }
-427     };
-428   }
-429 
-430   wrapAddEventListener(canvas);
-431 
-432   canvas.loseContext = function() {
-433     if (!contextLost_) {
-434       contextLost_ = true;
-435       numCallsToLoseContext_ = 0;
-436       ++contextId_;
-437       while (unwrappedContext_.getError());
-438       clearErrors();
-439       glErrorShadow_[unwrappedContext_.CONTEXT_LOST_WEBGL] = true;
-440       var event = makeWebGLContextEvent("context lost");
-441       var callbacks = onLost_.slice();
-442       setTimeout(function() {
-443           //log("numCallbacks:" + callbacks.length);
-444           for (var ii = 0; ii < callbacks.length; ++ii) {
-445             //log("calling callback:" + ii);
-446             callbacks[ii](event);
-447           }
-448           if (restoreTimeout_ >= 0) {
-449             setTimeout(function() {
-450                 canvas.restoreContext();
-451               }, restoreTimeout_);
-452           }
-453         }, 0);
-454     }
-455   };
-456 
-457   canvas.restoreContext = function() {
-458     if (contextLost_) {
-459       if (onRestored_.length) {
-460         setTimeout(function() {
-461             if (!canRestore_) {
-462               throw "can not restore. webglcontestlost listener did not call event.preventDefault";
-463             }
-464             freeResources();
-465             resetToInitialState(unwrappedContext_);
-466             contextLost_ = false;
-467             numCalls_ = 0;
-468             canRestore_ = false;
-469             var callbacks = onRestored_.slice();
-470             var event = makeWebGLContextEvent("context restored");
-471             for (var ii = 0; ii < callbacks.length; ++ii) {
-472               callbacks[ii](event);
-473             }
-474           }, 0);
-475       }
-476     }
-477   };
-478 
-479   canvas.loseContextInNCalls = function(numCalls) {
-480     if (contextLost_) {
-481       throw "You can not ask a lost contet to be lost";
-482     }
-483     numCallsToLoseContext_ = numCalls_ + numCalls;
-484   };
-485 
-486   canvas.getNumCalls = function() {
-487     return numCalls_;
-488   };
-489 
-490   canvas.setRestoreTimeout = function(timeout) {
-491     restoreTimeout_ = timeout;
-492   };
-493 
-494   function isWebGLObject(obj) {
-495     //return false;
-496     return (obj instanceof WebGLBuffer ||
-497             obj instanceof WebGLFramebuffer ||
-498             obj instanceof WebGLProgram ||
-499             obj instanceof WebGLRenderbuffer ||
-500             obj instanceof WebGLShader ||
-501             obj instanceof WebGLTexture);
-502   }
-503 
-504   function checkResources(args) {
-505     for (var ii = 0; ii < args.length; ++ii) {
-506       var arg = args[ii];
-507       if (isWebGLObject(arg)) {
-508         return arg.__webglDebugContextLostId__ == contextId_;
-509       }
-510     }
-511     return true;
-512   }
-513 
-514   function clearErrors() {
-515     var k = Object.keys(glErrorShadow_);
-516     for (var ii = 0; ii < k.length; ++ii) {
-517       delete glErrorShadow_[k];
-518     }
-519   }
-520 
-521   function loseContextIfTime() {
-522     ++numCalls_;
-523     if (!contextLost_) {
-524       if (numCallsToLoseContext_ == numCalls_) {
-525         canvas.loseContext();
-526       }
-527     }
-528   }
-529 
-530   // Makes a function that simulates WebGL when out of context.
-531   function makeLostContextFunctionWrapper(ctx, functionName) {
-532     var f = ctx[functionName];
-533     return function() {
-534       // log("calling:" + functionName);
-535       // Only call the functions if the context is not lost.
-536       loseContextIfTime();
-537       if (!contextLost_) {
-538         //if (!checkResources(arguments)) {
-539         //  glErrorShadow_[wrappedContext_.INVALID_OPERATION] = true;
-540         //  return;
-541         //}
-542 
-543         var result = f.apply(ctx, arguments);
-544         return result;
-545       }
-546     };
-547   }
-548 
-549   function freeResources() {
-550     for (var ii = 0; ii < resourceDb_.length; ++ii) {
-551       var resource = resourceDb_[ii];
-552       if (resource instanceof WebGLBuffer) {
-553         unwrappedContext_.deleteBuffer(resource);
-554       } else if (resource instanceof WebGLFramebuffer) {
-555         unwrappedContext_.deleteFramebuffer(resource);
-556       } else if (resource instanceof WebGLProgram) {
-557         unwrappedContext_.deleteProgram(resource);
-558       } else if (resource instanceof WebGLRenderbuffer) {
-559         unwrappedContext_.deleteRenderbuffer(resource);
-560       } else if (resource instanceof WebGLShader) {
-561         unwrappedContext_.deleteShader(resource);
-562       } else if (resource instanceof WebGLTexture) {
-563         unwrappedContext_.deleteTexture(resource);
-564       }
-565     }
-566   }
-567 
-568   function makeWebGLContextEvent(statusMessage) {
-569     return {
-570       statusMessage: statusMessage,
-571       preventDefault: function() {
-572           canRestore_ = true;
-573         }
-574     };
-575   }
-576 
-577   return canvas;
-578 
-579   function makeLostContextSimulatingContext(ctx) {
-580     // copy all functions and properties to wrapper
-581     for (var propertyName in ctx) {
-582       if (typeof ctx[propertyName] == 'function') {
-583          wrappedContext_[propertyName] = makeLostContextFunctionWrapper(
-584              ctx, propertyName);
-585        } else {
-586          makePropertyWrapper(wrappedContext_, ctx, propertyName);
-587        }
-588     }
-589 
-590     // Wrap a few functions specially.
-591     wrappedContext_.getError = function() {
-592       loseContextIfTime();
-593       if (!contextLost_) {
-594         var err;
-595         while (err = unwrappedContext_.getError()) {
-596           glErrorShadow_[err] = true;
-597         }
-598       }
-599       for (var err in glErrorShadow_) {
-600         if (glErrorShadow_[err]) {
-601           delete glErrorShadow_[err];
-602           return err;
-603         }
-604       }
-605       return wrappedContext_.NO_ERROR;
-606     };
-607 
-608     var creationFunctions = [
-609       "createBuffer",
-610       "createFramebuffer",
-611       "createProgram",
-612       "createRenderbuffer",
-613       "createShader",
-614       "createTexture"
-615     ];
-616     for (var ii = 0; ii < creationFunctions.length; ++ii) {
-617       var functionName = creationFunctions[ii];
-618       wrappedContext_[functionName] = function(f) {
-619         return function() {
-620           loseContextIfTime();
-621           if (contextLost_) {
-622             return null;
-623           }
-624           var obj = f.apply(ctx, arguments);
-625           obj.__webglDebugContextLostId__ = contextId_;
-626           resourceDb_.push(obj);
-627           return obj;
-628         };
-629       }(ctx[functionName]);
-630     }
-631 
-632     var functionsThatShouldReturnNull = [
-633       "getActiveAttrib",
-634       "getActiveUniform",
-635       "getBufferParameter",
-636       "getContextAttributes",
-637       "getAttachedShaders",
-638       "getFramebufferAttachmentParameter",
-639       "getParameter",
-640       "getProgramParameter",
-641       "getProgramInfoLog",
-642       "getRenderbufferParameter",
-643       "getShaderParameter",
-644       "getShaderInfoLog",
-645       "getShaderSource",
-646       "getTexParameter",
-647       "getUniform",
-648       "getUniformLocation",
-649       "getVertexAttrib"
-650     ];
-651     for (var ii = 0; ii < functionsThatShouldReturnNull.length; ++ii) {
-652       var functionName = functionsThatShouldReturnNull[ii];
-653       wrappedContext_[functionName] = function(f) {
-654         return function() {
-655           loseContextIfTime();
-656           if (contextLost_) {
-657             return null;
-658           }
-659           return f.apply(ctx, arguments);
-660         }
-661       }(wrappedContext_[functionName]);
-662     }
-663 
-664     var isFunctions = [
-665       "isBuffer",
-666       "isEnabled",
-667       "isFramebuffer",
-668       "isProgram",
-669       "isRenderbuffer",
-670       "isShader",
-671       "isTexture"
-672     ];
-673     for (var ii = 0; ii < isFunctions.length; ++ii) {
-674       var functionName = isFunctions[ii];
-675       wrappedContext_[functionName] = function(f) {
-676         return function() {
-677           loseContextIfTime();
-678           if (contextLost_) {
-679             return false;
-680           }
-681           return f.apply(ctx, arguments);
-682         }
-683       }(wrappedContext_[functionName]);
-684     }
-685 
-686     wrappedContext_.checkFramebufferStatus = function(f) {
-687       return function() {
-688         loseContextIfTime();
-689         if (contextLost_) {
-690           return wrappedContext_.FRAMEBUFFER_UNSUPPORTED;
-691         }
-692         return f.apply(ctx, arguments);
-693       };
-694     }(wrappedContext_.checkFramebufferStatus);
-695 
-696     wrappedContext_.getAttribLocation = function(f) {
-697       return function() {
-698         loseContextIfTime();
-699         if (contextLost_) {
-700           return -1;
-701         }
-702         return f.apply(ctx, arguments);
-703       };
-704     }(wrappedContext_.getAttribLocation);
-705 
-706     wrappedContext_.getVertexAttribOffset = function(f) {
-707       return function() {
-708         loseContextIfTime();
-709         if (contextLost_) {
-710           return 0;
-711         }
-712         return f.apply(ctx, arguments);
-713       };
-714     }(wrappedContext_.getVertexAttribOffset);
-715 
-716     wrappedContext_.isContextLost = function() {
-717       return contextLost_;
-718     };
-719 
-720     return wrappedContext_;
-721   }
-722 }
-723 
-724 return {
-725     /**
-726      * Initializes this module. Safe to call more than once.
-727      * @param {!WebGLRenderingContext} ctx A WebGL context. If
-728     }
-729    *    you have more than one context it doesn't matter which one
-730    *    you pass in, it is only used to pull out constants.
-731    */
-732   'init': init,
-733 
-734   /**
-735    * Returns true or false if value matches any WebGL enum
-736    * @param {*} value Value to check if it might be an enum.
-737    * @return {boolean} True if value matches one of the WebGL defined enums
-738    */
-739   'mightBeEnum': mightBeEnum,
-740 
-741   /**
-742    * Gets an string version of an WebGL enum.
-743    *
-744    * Example:
-745    *   WebGLDebugUtil.init(ctx);
-746    *   var str = WebGLDebugUtil.glEnumToString(ctx.getError());
-747    *
-748    * @param {number} value Value to return an enum for
-749    * @return {string} The string version of the enum.
-750    */
-751   'glEnumToString': glEnumToString,
-752 
-753   /**
-754    * Converts the argument of a WebGL function to a string.
-755    * Attempts to convert enum arguments to strings.
-756    *
-757    * Example:
-758    *   WebGLDebugUtil.init(ctx);
-759    *   var str = WebGLDebugUtil.glFunctionArgToString('bindTexture', 0, gl.TEXTURE_2D);
-760    *
-761    * would return 'TEXTURE_2D'
-762    *
-763    * @param {string} functionName the name of the WebGL function.
-764    * @param {number} argumentIndx the index of the argument.
-765    * @param {*} value The value of the argument.
-766    * @return {string} The value as a string.
-767    */
-768   'glFunctionArgToString': glFunctionArgToString,
-769 
-770   /**
-771    * Converts the arguments of a WebGL function to a string.
-772    * Attempts to convert enum arguments to strings.
-773    *
-774    * @param {string} functionName the name of the WebGL function.
-775    * @param {number} args The arguments.
-776    * @return {string} The arguments as a string.
-777    */
-778   'glFunctionArgsToString': glFunctionArgsToString,
-779 
-780   /**
-781    * Given a WebGL context returns a wrapped context that calls
-782    * gl.getError after every command and calls a function if the
-783    * result is not NO_ERROR.
-784    *
-785    * You can supply your own function if you want. For example, if you'd like
-786    * an exception thrown on any GL error you could do this
-787    *
-788    *    function throwOnGLError(err, funcName, args) {
-789    *      throw WebGLDebugUtils.glEnumToString(err) +
-790    *            " was caused by call to " + funcName;
-791    *    };
-792    *
-793    *    ctx = WebGLDebugUtils.makeDebugContext(
-794    *        canvas.getContext("webgl"), throwOnGLError);
-795    *
-796    * @param {!WebGLRenderingContext} ctx The webgl context to wrap.
-797    * @param {!function(err, funcName, args): void} opt_onErrorFunc The function
-798    *     to call when gl.getError returns an error. If not specified the default
-799    *     function calls console.log with a message.
-800    * @param {!function(funcName, args): void} opt_onFunc The
-801    *     function to call when each webgl function is called. You
-802    *     can use this to log all calls for example.
-803    */
-804   'makeDebugContext': makeDebugContext,
-805 
-806   /**
-807    * Given a canvas element returns a wrapped canvas element that will
-808    * simulate lost context. The canvas returned adds the following functions.
-809    *
-810    * loseContext:
-811    *   simulates a lost context event.
-812    *
-813    * restoreContext:
-814    *   simulates the context being restored.
-815    *
-816    * lostContextInNCalls:
-817    *   loses the context after N gl calls.
-818    *
-819    * getNumCalls:
-820    *   tells you how many gl calls there have been so far.
-821    *
-822    * setRestoreTimeout:
-823    *   sets the number of milliseconds until the context is restored
-824    *   after it has been lost. Defaults to 0. Pass -1 to prevent
-825    *   automatic restoring.
-826    *
-827    * @param {!Canvas} canvas The canvas element to wrap.
-828    */
-829   'makeLostContextSimulatingCanvas': makeLostContextSimulatingCanvas,
-830 
-831   /**
-832    * Resets a context to the initial state.
-833    * @param {!WebGLRenderingContext} ctx The webgl context to
-834    *     reset.
-835    */
-836   'resetToInitialState': resetToInitialState
-837 };
-838 
-839 }();
-840 
\ No newline at end of file diff --git a/docs/symbols/src/src_core_webgl.js.html b/docs/symbols/src/src_core_webgl.js.html deleted file mode 100644 index 7eab381e..00000000 --- a/docs/symbols/src/src_core_webgl.js.html +++ /dev/null @@ -1,844 +0,0 @@ -
  1 /** Maps SceneJS node parameter names to WebGL enum names
-  2  * @private
-  3  */
-  4 var SceneJS_webgl_enumMap = {
-  5     funcAdd:"FUNC_ADD",
-  6     funcSubtract:"FUNC_SUBTRACT",
-  7     funcReverseSubtract:"FUNC_REVERSE_SUBTRACT",
-  8     zero:"ZERO",
-  9     one:"ONE",
- 10     srcColor:"SRC_COLOR",
- 11     oneMinusSrcColor:"ONE_MINUS_SRC_COLOR",
- 12     dstColor:"DST_COLOR",
- 13     oneMinusDstColor:"ONE_MINUS_DST_COLOR",
- 14     srcAlpha:"SRC_ALPHA",
- 15     oneMinusSrcAlpha:"ONE_MINUS_SRC_ALPHA",
- 16     dstAlpha:"DST_ALPHA",
- 17     oneMinusDstAlpha:"ONE_MINUS_DST_ALPHA",
- 18     contantColor:"CONSTANT_COLOR",
- 19     oneMinusConstantColor:"ONE_MINUS_CONSTANT_COLOR",
- 20     constantAlpha:"CONSTANT_ALPHA",
- 21     oneMinusConstantAlpha:"ONE_MINUS_CONSTANT_ALPHA",
- 22     srcAlphaSaturate:"SRC_ALPHA_SATURATE",
- 23     front:"FRONT",
- 24     back:"BACK",
- 25     frontAndBack:"FRONT_AND_BACK",
- 26     never:"NEVER",
- 27     less:"LESS",
- 28     equal:"EQUAL",
- 29     lequal:"LEQUAL",
- 30     greater:"GREATER",
- 31     notequal:"NOTEQUAL",
- 32     gequal:"GEQUAL",
- 33     always:"ALWAYS",
- 34     cw:"CW",
- 35     ccw:"CCW",
- 36     linear:"LINEAR",
- 37     nearest:"NEAREST",
- 38     linearMipMapNearest:"LINEAR_MIPMAP_NEAREST",
- 39     nearestMipMapNearest:"NEAREST_MIPMAP_NEAREST",
- 40     nearestMipMapLinear:"NEAREST_MIPMAP_LINEAR",
- 41     linearMipMapLinear:"LINEAR_MIPMAP_LINEAR",
- 42     repeat:"REPEAT",
- 43     clampToEdge:"CLAMP_TO_EDGE",
- 44     mirroredRepeat:"MIRRORED_REPEAT",
- 45     alpha:"ALPHA",
- 46     rgb:"RGB",
- 47     rgba:"RGBA",
- 48     luminance:"LUMINANCE",
- 49     luminanceAlpha:"LUMINANCE_ALPHA",
- 50     textureBinding2D:"TEXTURE_BINDING_2D",
- 51     textureBindingCubeMap:"TEXTURE_BINDING_CUBE_MAP",
- 52     compareRToTexture:"COMPARE_R_TO_TEXTURE", // Hardware Shadowing Z-depth,
- 53     unsignedByte:"UNSIGNED_BYTE"
- 54 };
- 55 
- 56 var SceneJS_webgl_ProgramUniform = function (gl, program, name, type, size, location, logging) {
- 57 
- 58     var func = null;
- 59     if (type == gl.BOOL) {
- 60         func = function (v) {
- 61             gl.uniform1i(location, v);
- 62         };
- 63     } else if (type == gl.BOOL_VEC2) {
- 64         func = function (v) {
- 65             gl.uniform2iv(location, v);
- 66         };
- 67     } else if (type == gl.BOOL_VEC3) {
- 68         func = function (v) {
- 69             gl.uniform3iv(location, v);
- 70         };
- 71     } else if (type == gl.BOOL_VEC4) {
- 72         func = function (v) {
- 73             gl.uniform4iv(location, v);
- 74         };
- 75     } else if (type == gl.INT) {
- 76         func = function (v) {
- 77             gl.uniform1iv(location, v);
- 78         };
- 79     } else if (type == gl.INT_VEC2) {
- 80         func = function (v) {
- 81             gl.uniform2iv(location, v);
- 82         };
- 83     } else if (type == gl.INT_VEC3) {
- 84         func = function (v) {
- 85             gl.uniform3iv(location, v);
- 86         };
- 87     } else if (type == gl.INT_VEC4) {
- 88         func = function (v) {
- 89             gl.uniform4iv(location, v);
- 90         };
- 91     } else if (type == gl.FLOAT) {
- 92         func = function (v) {
- 93             gl.uniform1f(location, v);
- 94         };
- 95     } else if (type == gl.FLOAT_VEC2) {
- 96         func = function (v) {
- 97             gl.uniform2fv(location, v);
- 98         };
- 99     } else if (type == gl.FLOAT_VEC3) {
-100         func = function (v) {
-101             gl.uniform3fv(location, v);
-102         };
-103     } else if (type == gl.FLOAT_VEC4) {
-104         func = function (v) {
-105             gl.uniform4fv(location, v);
-106         };
-107     } else if (type == gl.FLOAT_MAT2) {
-108         func = function (v) {
-109             gl.uniformMatrix2fv(location, gl.FALSE, v);
-110         };
-111     } else if (type == gl.FLOAT_MAT3) {
-112         func = function (v) {
-113             gl.uniformMatrix3fv(location, gl.FALSE, v);
-114         };
-115     } else if (type == gl.FLOAT_MAT4) {
-116         func = function (v) {
-117             gl.uniformMatrix4fv(location, gl.FALSE, v);
-118         };
-119     } else {
-120         throw "Unsupported shader uniform type: " + type;
-121     }
-122 
-123     this.setValue = func;
-124 
-125 
-126     this.getValue = function () {
-127         return gl.getUniform(program, location);
-128     };
-129 
-130     this.getLocation = function () {
-131         return location;
-132     };
-133 };
-134 
-135 var SceneJS_webgl_ProgramSampler = function (gl, program, name, type, size, location) {
-136     this.bindTexture = function (texture, unit) {
-137         if (texture.bind(unit)) {
-138             gl.uniform1i(location, unit);
-139             return true;
-140         }
-141         return false;
-142     };
-143 };
-144 
-145 /** An attribute within a shader
-146  */
-147 var SceneJS_webgl_ProgramAttribute = function (gl, program, name, type, size, location) {
-148     this.bindFloatArrayBuffer = function (buffer) {
-149         buffer.bind();
-150         gl.enableVertexAttribArray(location);
-151         gl.vertexAttribPointer(location, buffer.itemSize, gl.FLOAT, false, 0, 0);   // Vertices are not homogeneous - no w-element
-152     };
-153 
-154 };
-155 
-156 /**
-157  * A vertex/fragment shader in a program
-158  *
-159  * @private
-160  * @param gl WebGL gl
-161  * @param gl.VERTEX_SHADER | gl.FRAGMENT_SHADER
-162  * @param source Source code for shader
-163  * @param logging Shader will write logging's debug channel as it compiles
-164  */
-165 var SceneJS_webgl_Shader = function (gl, type, source) {
-166 
-167     this.handle = gl.createShader(type);
-168 
-169     gl.shaderSource(this.handle, source);
-170     gl.compileShader(this.handle);
-171 
-172     this.valid = (gl.getShaderParameter(this.handle, gl.COMPILE_STATUS) != 0);
-173 
-174     if (!this.valid) {
-175 
-176         if (!gl.isContextLost()) { // Handled explicitely elsewhere, so wont rehandle here
-177 
-178             SceneJS.log.error("Shader program failed to compile: " + gl.getShaderInfoLog(this.handle));
-179             SceneJS.log.error("Shader source:");
-180             var lines = source.split('\n');
-181             for (var j = 0; j < lines.length; j++) {
-182                 SceneJS.log.error(lines[j]);
-183             }
-184 
-185             throw SceneJS_error.fatalError(
-186                 SceneJS.errors.SHADER_COMPILATION_FAILURE, "Shader program failed to compile");
-187         }
-188     }
-189 };
-190 
-191 /**
-192  * @class Wrapper for a WebGL program
-193  *
-194  * @param hash SceneJS-managed ID for program
-195  * @param gl WebGL gl
-196  * @param vertexSources Source codes for vertex shaders
-197  * @param fragmentSources Source codes for fragment shaders
-198  * @param logging Program and shaders will write to logging's debug channel as they compile and link
-199  */
-200 var SceneJS_webgl_Program = function (gl, vertexSources, fragmentSources) {
-201 
-202     var a, i, u, u_name, location, shader;
-203 
-204     this._uniforms = {};
-205     this._samplers = {};
-206     this._attributes = {};
-207 
-208     /* Create shaders from sources
-209      */
-210     this._shaders = [];
-211     for (i = 0; i < vertexSources.length; i++) {
-212         this._shaders.push(new SceneJS_webgl_Shader(gl, gl.VERTEX_SHADER, vertexSources[i]));
-213     }
-214     for (i = 0; i < fragmentSources.length; i++) {
-215         this._shaders.push(new SceneJS_webgl_Shader(gl, gl.FRAGMENT_SHADER, fragmentSources[i]));
-216     }
-217 
-218     /* Create program, attach shaders, link and validate program
-219      */
-220     var handle = gl.createProgram();
-221 
-222     for (i = 0; i < this._shaders.length; i++) {
-223         shader = this._shaders[i];
-224         if (shader.valid) {
-225             gl.attachShader(handle, shader.handle);
-226         }
-227     }
-228     gl.linkProgram(handle);
-229 
-230     this.valid = (gl.getProgramParameter(handle, gl.LINK_STATUS) != 0);
-231 
-232     var debugCfg = SceneJS_debugModule.getConfigs("shading");
-233     if (debugCfg.validate !== false) {
-234         gl.validateProgram(handle);
-235         this.valid = this.valid && (gl.getProgramParameter(handle, gl.VALIDATE_STATUS) != 0);
-236     }
-237 
-238     if (!this.valid) {
-239 
-240         if (!gl.isglLost()) { // Handled explicitely elsewhere, so wont rehandle here
-241 
-242             SceneJS.log.error("Shader program failed to link: " + gl.getProgramInfoLog(handle));
-243 
-244             SceneJS.log.error("Vertex shader(s):");
-245             for (i = 0; i < vertexSources.length; i++) {
-246                 SceneJS.log.error("Vertex shader #" + i + ":");
-247                 var lines = vertexSources[i].split('\n');
-248                 for (var j = 0; j < lines.length; j++) {
-249                     SceneJS.log.error(lines[j]);
-250 
-251                 }
-252             }
-253 
-254             SceneJS.log.error("Fragment shader(s):");
-255             for (i = 0; i < fragmentSources.length; i++) {
-256                 SceneJS.log.error("Fragment shader #" + i + ":");
-257                 var lines = fragmentSources[i].split('\n');
-258                 for (var j = 0; j < lines.length; j++) {
-259                     SceneJS.log.error(lines[j]);
-260                 }
-261             }
-262 
-263             throw SceneJS_error.fatalError(
-264                 SceneJS.errors.SHADER_LINK_FAILURE, "Shader program failed to link");
-265         }
-266     }
-267 
-268     /* Discover active uniforms and samplers
-269      */
-270 
-271     var numUniforms = gl.getProgramParameter(handle, gl.ACTIVE_UNIFORMS);
-272 
-273     for (i = 0; i < numUniforms; ++i) {
-274         u = gl.getActiveUniform(handle, i);
-275         if (u) {
-276             u_name = u.name;
-277             if (u_name[u_name.length - 1] == "\u0000") {
-278                 u_name = u_name.substr(0, u_name.length - 1);
-279             }
-280             location = gl.getUniformLocation(handle, u_name);
-281             if ((u.type == gl.SAMPLER_2D) || (u.type == gl.SAMPLER_CUBE) || (u.type == 35682)) {
-282 
-283                 this._samplers[u_name] = new SceneJS_webgl_ProgramSampler(
-284                     gl,
-285                     handle,
-286                     u_name,
-287                     u.type,
-288                     u.size,
-289                     location);
-290             } else {
-291                 this._uniforms[u_name] = new SceneJS_webgl_ProgramUniform(
-292                     gl,
-293                     handle,
-294                     u_name,
-295                     u.type,
-296                     u.size,
-297                     location);
-298             }
-299         }
-300     }
-301 
-302     /* Discover attributes
-303      */
-304 
-305     var numAttribs = gl.getProgramParameter(handle, gl.ACTIVE_ATTRIBUTES);
-306     for (i = 0; i < numAttribs; i++) {
-307         a = gl.getActiveAttrib(handle, i);
-308         if (a) {
-309             location = gl.getAttribLocation(handle, a.name);
-310             this._attributes[a.name] = new SceneJS_webgl_ProgramAttribute(
-311                 gl,
-312                 handle,
-313                 a.name,
-314                 a.type,
-315                 a.size,
-316                 location);
-317         }
-318     }
-319 
-320     this.setProfile = function (profile) {
-321         this._profile = profile;
-322     };
-323 
-324     this.bind = function () {
-325         gl.useProgram(handle);
-326         if (this._profile) {
-327             this._profile.program++;
-328         }
-329     };
-330 
-331     this.getUniformLocation = function (name) {
-332         var u = this._uniforms[name];
-333         if (u) {
-334             return u.getLocation();
-335         } else {
-336             // SceneJS.log.warn("Uniform not found in shader : " + name);
-337         }
-338     };
-339 
-340     this.getUniform = function (name) {
-341         var u = this._uniforms[name];
-342         if (u) {
-343             return u;
-344         } else {
-345             //      SceneJS.log.warn("Shader uniform load failed - uniform not found in shader : " + name);
-346         }
-347     };
-348 
-349     this.setUniform = function (name, value) {
-350         var u = this._uniforms[name];
-351         if (u) {
-352             u.setValue(value);
-353             if (this._profile) {
-354                 this._profile.uniform++;
-355             }
-356         } else {
-357             //      SceneJS.log.warn("Shader uniform load failed - uniform not found in shader : " + name);
-358         }
-359     };
-360 
-361     this.getAttribute = function (name) {
-362         var attr = this._attributes[name];
-363         if (attr) {
-364             return attr;
-365         } else {
-366             //  logging.warn("Shader attribute bind failed - attribute not found in shader : " + name);
-367         }
-368     };
-369 
-370     this.bindFloatArrayBuffer = function (name, buffer) {
-371         var attr = this._attributes[name];
-372         if (attr) {
-373             attr.bindFloatArrayBuffer(buffer);
-374             if (this._profile) {
-375                 this._profile.varying++;
-376             }
-377         } else {
-378             //  logging.warn("Shader attribute bind failed - attribute not found in shader : " + name);
-379         }
-380     };
-381 
-382     this.bindTexture = function (name, texture, unit) {
-383         var sampler = this._samplers[name];
-384         if (sampler) {
-385             if (this._profile) {
-386                 this._profile.texture++;
-387             }
-388             return sampler.bindTexture(texture, unit);
-389         } else {
-390             return false;
-391         }
-392     };
-393 
-394     this.unbind = function () {
-395         //     gl.useProgram(0);
-396     };
-397 
-398     this.destroy = function () {
-399 
-400         if (this.valid) {
-401 
-402             //   SceneJS.log.debug("Destroying shader program: '" + hash + "'");
-403             gl.deleteProgram(handle);
-404             for (var s in this._shaders) {
-405                 gl.deleteShader(this._shaders[s].handle);
-406             }
-407             this._attributes = null;
-408             this._uniforms = null;
-409             this._samplers = null;
-410             this.valid = false;
-411         }
-412     };
-413 };
-414 
-415 var SceneJS_webgl_Texture2D = function (gl, cfg) {
-416 
-417     this.target = gl.TEXTURE_2D;
-418     this.minFilter = cfg.minFilter;
-419     this.magFilter = cfg.magFilter;
-420     this.wrapS = cfg.wrapS;
-421     this.wrapT = cfg.wrapT;
-422     this.update = cfg.update;  // For dynamically-sourcing textures (ie movies etc)
-423     this.texture = cfg.texture;
-424     this.format = gl.RGBA;
-425     this.isDepth = false;
-426     this.depthMode = 0;
-427     this.depthCompareMode = 0;
-428     this.depthCompareFunc = 0;
-429 
-430     try {
-431         gl.bindTexture(this.target, this.texture);
-432 
-433         if (cfg.minFilter) {
-434             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, cfg.minFilter);
-435         }
-436 
-437         if (cfg.magFilter) {
-438             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, cfg.magFilter);
-439         }
-440 
-441         if (cfg.wrapS) {
-442             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, cfg.wrapS);
-443         }
-444 
-445         if (cfg.wrapT) {
-446             gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, cfg.wrapT);
-447         }
-448 
-449         if (cfg.minFilter == gl.NEAREST_MIPMAP_NEAREST ||
-450             cfg.minFilter == gl.LINEAR_MIPMAP_NEAREST ||
-451             cfg.minFilter == gl.NEAREST_MIPMAP_LINEAR ||
-452             cfg.minFilter == gl.LINEAR_MIPMAP_LINEAR) {
-453             gl.generateMipmap(gl.TEXTURE_2D);
-454         }
-455 
-456         gl.bindTexture(this.target, null);
-457 
-458     } catch (e) {
-459         throw SceneJS_error.fatalError(SceneJS.errors.ERROR, "Failed to create texture: " + e.message || e);
-460     }
-461 
-462     this.bind = function (unit) {
-463         if (this.texture) {
-464             gl.activeTexture(gl["TEXTURE" + unit]);
-465             gl.bindTexture(this.target, this.texture);
-466             if (this.update) {
-467                 this.update(gl);
-468             }
-469             return true;
-470         }
-471         return false;
-472     };
-473 
-474     this.unbind = function (unit) {
-475         if (this.texture) {
-476             gl.activeTexture(gl["TEXTURE" + unit]);
-477             gl.bindTexture(this.target, null);
-478         }
-479     };
-480 
-481     this.destroy = function () {
-482         if (this.texture) {
-483             gl.deleteTexture(this.texture);
-484             this.texture = null;
-485         }
-486     };
-487 };
-488 
-489 
-490 function SceneJS_webgl_ensureImageSizePowerOfTwo(image) {
-491     if (!SceneJS_webgl_isPowerOfTwo(image.width) || !SceneJS_webgl_isPowerOfTwo(image.height)) {
-492         var canvas = document.createElement("canvas");
-493         canvas.width = SceneJS_webgl_nextHighestPowerOfTwo(image.width);
-494         canvas.height = SceneJS_webgl_nextHighestPowerOfTwo(image.height);
-495         var ctx = canvas.getContext("2d");
-496         ctx.drawImage(image,
-497             0, 0, image.width, image.height,
-498             0, 0, canvas.width, canvas.height);
-499         image = canvas;
-500     }
-501     return image;
-502 }
-503 
-504 function SceneJS_webgl_isPowerOfTwo(x) {
-505     return (x & (x - 1)) == 0;
-506 }
-507 
-508 function SceneJS_webgl_nextHighestPowerOfTwo(x) {
-509     --x;
-510     for (var i = 1; i < 32; i <<= 1) {
-511         x = x | x >> i;
-512     }
-513     return x + 1;
-514 }
-515 
-516 /** Buffer for vertices and indices
-517  *
-518  * @private
-519  * @param gl  WebGL gl
-520  * @param type     Eg. ARRAY_BUFFER, ELEMENT_ARRAY_BUFFER
-521  * @param values   WebGL array wrapper
-522  * @param numItems Count of items in array wrapper
-523  * @param itemSize Size of each item
-524  * @param usage    Eg. STATIC_DRAW
-525  */
-526 
-527 var SceneJS_webgl_ArrayBuffer = function (gl, type, values, numItems, itemSize, usage) {
-528 
-529 
-530     this.type = type;
-531     this.itemSize = itemSize;
-532 
-533     this._allocate = function (values, numItems) {
-534         this.handle = gl.createBuffer();
-535         this.handle.numItems = numItems;
-536         this.handle.itemSize = itemSize;
-537         gl.bindBuffer(type, this.handle);
-538         gl.bufferData(type, values, usage);
-539         this.handle.numItems = numItems;
-540         gl.bindBuffer(type, null);
-541         this.numItems = numItems;
-542         this.length = values.length;
-543     };
-544 
-545     this._allocate(values, numItems);
-546 
-547     this.bind = function () {
-548         gl.bindBuffer(type, this.handle);
-549     };
-550 
-551     this.setData = function (data, offset) {
-552 
-553         if (data.length > this.length) {
-554             this.destroy();
-555             this._allocate(data, data.length);
-556 
-557         } else {
-558 
-559             if (offset || offset === 0) {
-560                 gl.bufferSubData(type, offset, data);
-561             } else {
-562                 gl.bufferData(type, data);
-563             }
-564         }
-565     };
-566 
-567     this.unbind = function () {
-568         gl.bindBuffer(type, null);
-569     };
-570 
-571     this.destroy = function () {
-572         gl.deleteBuffer(this.handle);
-573     };
-574 };
-575 
-576 
-577 var SceneJS_PickBuffer = function (cfg) {
-578 
-579     var canvas = cfg.canvas;
-580     var gl = canvas.gl;
-581 
-582     var pickBuf;
-583     var bound = false;
-584 
-585     /**
-586      * Called when WebGL context restored
-587      */
-588     this.webglRestored = function (_gl) {
-589         gl = _gl;
-590         pickBuf = null;
-591     };
-592 
-593     this._touch = function () {
-594 
-595         var width = canvas.canvas.width;
-596         var height = canvas.canvas.height;
-597 
-598         if (pickBuf) { // Currently have a pick buffer
-599             if (pickBuf.width == width && pickBuf.height == height) { // Canvas size unchanged, buffer still good
-600                 return;
-601             } else { // Buffer needs reallocation for new canvas size
-602 
-603                 gl.deleteTexture(pickBuf.texture);
-604                 gl.deleteFramebuffer(pickBuf.framebuf);
-605                 gl.deleteRenderbuffer(pickBuf.renderbuf);
-606             }
-607         }
-608 
-609         pickBuf = {
-610             framebuf:gl.createFramebuffer(),
-611             renderbuf:gl.createRenderbuffer(),
-612             texture:gl.createTexture(),
-613             width:width,
-614             height:height
-615         };
-616 
-617         gl.bindFramebuffer(gl.FRAMEBUFFER, pickBuf.framebuf);
-618 
-619         gl.bindTexture(gl.TEXTURE_2D, pickBuf.texture);
-620         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-621         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-622         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
-623         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
-624 
-625         try {
-626             // Do it the way the spec requires
-627             gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
-628         } catch (exception) {
-629             // Workaround for what appears to be a Minefield bug.
-630             var textureStorage = new WebGLUnsignedByteArray(width * height * 3);
-631             gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureStorage);
-632         }
-633         gl.bindRenderbuffer(gl.RENDERBUFFER, pickBuf.renderbuf);
-634         gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
-635         gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, pickBuf.texture, 0);
-636         gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, pickBuf.renderbuf);
-637         gl.bindTexture(gl.TEXTURE_2D, null);
-638         gl.bindRenderbuffer(gl.RENDERBUFFER, null);
-639         gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-640 
-641         /* Verify framebuffer is OK
-642          */
-643         gl.bindFramebuffer(gl.FRAMEBUFFER, pickBuf.framebuf);
-644         if (!gl.isFramebuffer(pickBuf.framebuf)) {
-645             throw  SceneJS_errorModule.fatalError("Invalid framebuffer");
-646         }
-647         var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
-648         switch (status) {
-649             case gl.FRAMEBUFFER_COMPLETE:
-650                 break;
-651             case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-652                 throw  SceneJS_errorModule.fatalError("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
-653             case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-654                 throw  SceneJS_errorModule.fatalError("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
-655             case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
-656                 throw  SceneJS_errorModule.fatalError("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
-657             case gl.FRAMEBUFFER_UNSUPPORTED:
-658                 throw  SceneJS_errorModule.fatalError("Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED");
-659             default:
-660                 throw  SceneJS_errorModule.fatalError("Incomplete framebuffer: " + status);
-661         }
-662 
-663         bound = false;
-664     };
-665 
-666     this.bind = function () {
-667 
-668         this._touch();
-669 
-670         if (bound) {
-671             return;
-672         }
-673 
-674         gl.bindFramebuffer(gl.FRAMEBUFFER, pickBuf.framebuf);
-675 
-676         bound = true;
-677     };
-678 
-679     this.clear = function () {
-680 
-681         if (!bound) {
-682             throw "Pick buffer not bound";
-683         }
-684 
-685         gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-686         gl.disable(gl.BLEND);
-687     };
-688 
-689 
-690     /** Reads pick buffer pixel at given coordinates, returns index of associated object else (-1)
-691      */
-692     this.read = function (pickX, pickY) {
-693         var x = pickX;
-694         var y = canvas.canvas.height - pickY;
-695         var pix = new Uint8Array(4);
-696         gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pix);
-697         return pix;
-698     };
-699 
-700     this.unbind = function () {
-701         gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-702         bound = false;
-703     };
-704 };
-705 
-706 var SceneJS_PickBufferOLD = function (cfg) {
-707 
-708     var canvas = cfg.canvas;
-709     var gl = cfg.canvas.gl;
-710 
-711     var pickBuf;
-712     this.bound = false;
-713 
-714     /**
-715      * Initialises the pick buffer
-716      * @param _gl WebGL context
-717      */
-718     this.init = function (_gl) {
-719 
-720         gl = _gl;
-721         pickBuf = null;
-722 
-723         var width = canvas.canvas.width;
-724         var height = canvas.canvas.height;
-725 
-726         if (pickBuf) { // Currently have a pick buffer
-727 
-728             if (pickBuf.width == width && pickBuf.height == height) { // Canvas size unchanged, buffer still good
-729                 return;
-730 
-731             } else { // Buffer needs reallocation for new canvas size
-732 
-733                 gl.deleteTexture(pickBuf.texture);
-734                 gl.deleteFramebuffer(pickBuf.framebuf);
-735                 gl.deleteRenderbuffer(pickBuf.renderbuf);
-736             }
-737         }
-738 
-739         pickBuf = {
-740             framebuf:gl.createFramebuffer(),
-741             renderbuf:gl.createRenderbuffer(),
-742             texture:gl.createTexture(),
-743             width:width,
-744             height:height
-745         };
-746 
-747         gl.bindFramebuffer(gl.FRAMEBUFFER, pickBuf.framebuf);
-748 
-749         gl.bindTexture(gl.TEXTURE_2D, pickBuf.texture);
-750         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
-751         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
-752         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
-753         gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
-754 
-755         try {
-756             // Do it the way the spec requires
-757             gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
-758         } catch (exception) {
-759             // Workaround for what appears to be a Minefield bug.
-760             var textureStorage = new WebGLUnsignedByteArray(width * height * 3);
-761             gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, textureStorage);
-762         }
-763 
-764         gl.bindRenderbuffer(gl.RENDERBUFFER, pickBuf.renderbuf);
-765         gl.renderbufferStorage(gl.RENDERBUFFER, gl.DEPTH_COMPONENT16, width, height);
-766         gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, pickBuf.texture, 0);
-767         gl.framebufferRenderbuffer(gl.FRAMEBUFFER, gl.DEPTH_ATTACHMENT, gl.RENDERBUFFER, pickBuf.renderbuf);
-768 
-769         gl.bindTexture(gl.TEXTURE_2D, null);
-770         gl.bindRenderbuffer(gl.RENDERBUFFER, null);
-771         gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-772 
-773         /* Verify framebuffer is OK
-774          */
-775         gl.bindFramebuffer(gl.FRAMEBUFFER, pickBuf.framebuf);
-776         if (!gl.isFramebuffer(pickBuf.framebuf)) {
-777             throw  SceneJS_error.fatalError("Invalid framebuffer");
-778         }
-779 
-780         var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
-781 
-782         switch (status) {
-783             case gl.FRAMEBUFFER_COMPLETE:
-784                 break;
-785             case gl.FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
-786                 throw  SceneJS_error.fatalError("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_ATTACHMENT");
-787             case gl.FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
-788                 throw  SceneJS_error.fatalError("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT");
-789             case gl.FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
-790                 throw  SceneJS_error.fatalError("Incomplete framebuffer: FRAMEBUFFER_INCOMPLETE_DIMENSIONS");
-791             case gl.FRAMEBUFFER_UNSUPPORTED:
-792                 throw  SceneJS_error.fatalError("Incomplete framebuffer: FRAMEBUFFER_UNSUPPORTED");
-793             default:
-794                 throw  SceneJS_error.fatalError("Incomplete framebuffer: " + status);
-795         }
-796 
-797         this.bound = false;
-798     };
-799 
-800     this.bind = function () {
-801         if (this.bound) {
-802             return;
-803         }
-804         gl.bindFramebuffer(gl.FRAMEBUFFER, pickBuf.framebuf);
-805         this.bound = true;
-806     };
-807 
-808     this.clear = function () {
-809         if (this.bound) {
-810             return;
-811         }
-812         gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
-813         gl.disable(gl.BLEND);
-814     };
-815 
-816 
-817     /** Reads pick buffer pixel at given coordinates, returns index of associated object else (-1)
-818      */
-819     this.read = function (pickX, pickY) {
-820         var x = pickX;
-821         var y = canvas.canvas.height - pickY;
-822         var pix = new Uint8Array(4);
-823         gl.readPixels(x, y, 1, 1, gl.RGBA, gl.UNSIGNED_BYTE, pix);
-824         return pix;
-825     };
-826 
-827     this.unbind = function () {
-828         if (this.bound) {
-829             return;
-830         }
-831         gl.bindFramebuffer(gl.FRAMEBUFFER, null);
-832         this.bound = false;
-833     };
-834 
-835     this.init(cfg.canvas.gl);
-836 };
-837 
\ No newline at end of file diff --git a/examples.html b/examples.html index d74c0e7c..aa3e5ee3 100644 --- a/examples.html +++ b/examples.html @@ -7,7 +7,6 @@ - @@ -16,6 +15,7 @@ html, body { height: 100%; } + body { margin: 0px; overflow: hidden; @@ -24,40 +24,171 @@ diff --git a/examples/_index.html b/examples/_index.html new file mode 100644 index 00000000..6cc03ab3 --- /dev/null +++ b/examples/_index.html @@ -0,0 +1,624 @@ + + + + + SceneJS v4.0 - Examples + + + + + +
+
+

SceneJS / examples

+ +

v4.0 pre

+
+
+ + + + + + \ No newline at end of file diff --git a/demos/plugins-backgrounds-gradient.html b/examples/background_gradient.html similarity index 95% rename from demos/plugins-backgrounds-gradient.html rename to examples/background_gradient.html index b126b0c3..0af96d91 100644 --- a/demos/plugins-backgrounds-gradient.html +++ b/examples/background_gradient.html @@ -21,7 +21,7 @@ + + + + + + + \ No newline at end of file diff --git a/examples/benchmarks_10000boxes.html b/examples/benchmarks_10000boxes.html new file mode 100644 index 00000000..d101e8a4 --- /dev/null +++ b/examples/benchmarks_10000boxes.html @@ -0,0 +1,81 @@ + + + + SceneJS Example + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/benchmarks_40000boxes.html b/examples/benchmarks_40000boxes.html new file mode 100644 index 00000000..ce8cb61b --- /dev/null +++ b/examples/benchmarks_40000boxes.html @@ -0,0 +1,81 @@ + + + + SceneJS Example + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/benchmarks_5000boxes.html b/examples/benchmarks_5000boxes.html new file mode 100644 index 00000000..6a0dd5fa --- /dev/null +++ b/examples/benchmarks_5000boxes.html @@ -0,0 +1,81 @@ + + + + SceneJS Example + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/cameras-orbit.html b/examples/cameras_orbit.html similarity index 80% rename from demos/cameras-orbit.html rename to examples/cameras_orbit.html index b6655db7..a5eaa4dd 100644 --- a/demos/cameras-orbit.html +++ b/examples/cameras_orbit.html @@ -21,7 +21,9 @@ + + + +
+ SceneJS experimental camera + plugin + +
+ + + + \ No newline at end of file diff --git a/examples/cameras_pickFlyOrbit_city.html b/examples/cameras_pickFlyOrbit_city.html new file mode 100644 index 00000000..2a242ca8 --- /dev/null +++ b/examples/cameras_pickFlyOrbit_city.html @@ -0,0 +1,103 @@ + + + + SceneJS Example + + + + + + + + +
+ SceneJS experimental camera + plugin + +
+ + + + \ No newline at end of file diff --git a/examples/cameras_pickFlyOrbit_terrain.html b/examples/cameras_pickFlyOrbit_terrain.html new file mode 100644 index 00000000..40e3cf5e --- /dev/null +++ b/examples/cameras_pickFlyOrbit_terrain.html @@ -0,0 +1,127 @@ + + + + SceneJS Example + + + + + + + + +
+ SceneJS experimental camera + plugin + +
+ + + + \ No newline at end of file diff --git a/demos/canvas-capture.html b/examples/canvas_capture.html similarity index 97% rename from demos/canvas-capture.html rename to examples/canvas_capture.html index f2ea8b72..a1d00b48 100644 --- a/demos/canvas-capture.html +++ b/examples/canvas_capture.html @@ -62,9 +62,9 @@ nodes:[ // City, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/object/buildings/city.js + // http://scenejs.org/api/latest/plugins/node/models/buildings/city.js { - type:"objects/buildings/city", + type:"models/buildings/city", width:600 } ] diff --git a/examples/canvas_capture_customSize.html b/examples/canvas_capture_customSize.html new file mode 100644 index 00000000..fdddbc33 --- /dev/null +++ b/examples/canvas_capture_customSize.html @@ -0,0 +1,117 @@ + + + + SceneJS Example + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/canvas-external.html b/examples/canvas_external.html similarity index 84% rename from demos/canvas-external.html rename to examples/canvas_external.html index 7657fb78..60517cab 100644 --- a/demos/canvas-external.html +++ b/examples/canvas_external.html @@ -12,13 +12,18 @@ -khtml-user-select: none; -webkit-user-select: none; } + #myCanvas { + width: 100%; + height: 100%; + margin: 0; + padding: 0; + position: absolute; + } - - - + - + @@ -55,7 +63,7 @@ yaw: 30, pitch: -30, zoom: 10, - zoomSensitivity: 10.0, + zoomSensitivity: 1.0, nodes: [ { type: "material", @@ -63,9 +71,9 @@ nodes: [ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } diff --git a/demos/canvas-transparent.html b/examples/canvas_transparent.html similarity index 95% rename from demos/canvas-transparent.html rename to examples/canvas_transparent.html index 21c97c20..3515980f 100644 --- a/demos/canvas-transparent.html +++ b/examples/canvas_transparent.html @@ -58,9 +58,9 @@ nodes: [ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } diff --git a/examples/colorBuffer_blendEnabled.html b/examples/colorBuffer_blendEnabled.html new file mode 100644 index 00000000..4ee2b8d8 --- /dev/null +++ b/examples/colorBuffer_blendEnabled.html @@ -0,0 +1,118 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/colorBuffer_colorMask.html b/examples/colorBuffer_colorMask.html new file mode 100644 index 00000000..0771d211 --- /dev/null +++ b/examples/colorBuffer_colorMask.html @@ -0,0 +1,124 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/configs-statusPopups.html b/examples/configs_disableStatusPopups.html similarity index 94% rename from demos/configs-statusPopups.html rename to examples/configs_disableStatusPopups.html index 803f1ded..e567f058 100644 --- a/demos/configs-statusPopups.html +++ b/examples/configs_disableStatusPopups.html @@ -52,9 +52,9 @@ nodes:[ // Torus primitive, - // implemented by plugin at ../../../../api/latest/plugins/node/prims/torus.js + // implemented by plugin at ../../../../api/latest/plugins/node/geometry/torus.js { - type:"prims/torus", + type:"geometry/torus", radius:1.0, tube:0.30, segmentsR:60, diff --git a/examples/configs_optimizations.html b/examples/configs_optimizations.html new file mode 100644 index 00000000..e567f058 --- /dev/null +++ b/examples/configs_optimizations.html @@ -0,0 +1,73 @@ + + + + SceneJS Example + + + + + + + + + + + \ No newline at end of file diff --git a/demos/configs-pluginPath.html b/examples/configs_pluginPath.html similarity index 95% rename from demos/configs-pluginPath.html rename to examples/configs_pluginPath.html index a19eb41d..40827f5b 100644 --- a/demos/configs-pluginPath.html +++ b/examples/configs_pluginPath.html @@ -50,9 +50,9 @@ nodes:[ // Torus primitive, - // implemented by plugin at ../../../../api/latest/plugins/node/prims/torus.js + // implemented by plugin at ../../../../api/latest/plugins/node/geometry/torus.js { - type:"prims/torus", + type:"geometry/torus", radius:1.0, tube:0.30, segmentsR:60, diff --git a/demos/css/prettify.css b/examples/css/prettify.css similarity index 100% rename from demos/css/prettify.css rename to examples/css/prettify.css diff --git a/demos/css/styles.css b/examples/css/styles.css similarity index 98% rename from demos/css/styles.css rename to examples/css/styles.css index 8f6c76e3..fcf53b6f 100644 --- a/demos/css/styles.css +++ b/examples/css/styles.css @@ -24,7 +24,7 @@ body { } .xeolabsLogo { - background-image: url("../examples/images/a-xeolabs-project.png"); + background-image: url("./images/a-xeolabs-project.png"); position: absolute; left: 0; top: 0; diff --git a/demos/depthBuf-clearDepth.html b/examples/depthBuffer_clearDepth.html similarity index 91% rename from demos/depthBuf-clearDepth.html rename to examples/depthBuffer_clearDepth.html index c43fd3c9..46e32a01 100644 --- a/demos/depthBuf-clearDepth.html +++ b/examples/depthBuffer_clearDepth.html @@ -22,7 +22,7 @@ + + + + + + + + \ No newline at end of file diff --git a/examples/effects_anaglyph_pickFlyOrbit.html b/examples/effects_anaglyph_pickFlyOrbit.html new file mode 100644 index 00000000..f06a22cb --- /dev/null +++ b/examples/effects_anaglyph_pickFlyOrbit.html @@ -0,0 +1,141 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/effects_oculusRift.html b/examples/effects_oculusRift.html new file mode 100644 index 00000000..5dc4176a --- /dev/null +++ b/examples/effects_oculusRift.html @@ -0,0 +1,90 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/effects_oculusRift_externalCanvas.html b/examples/effects_oculusRift_externalCanvas.html new file mode 100644 index 00000000..098c68df --- /dev/null +++ b/examples/effects_oculusRift_externalCanvas.html @@ -0,0 +1,93 @@ + + + + SceneJS Example + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/effects_oculusRift_pickFlyOrbit.html b/examples/effects_oculusRift_pickFlyOrbit.html new file mode 100644 index 00000000..27007a49 --- /dev/null +++ b/examples/effects_oculusRift_pickFlyOrbit.html @@ -0,0 +1,85 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/effects_stereo.html b/examples/effects_stereo.html new file mode 100644 index 00000000..01d072d7 --- /dev/null +++ b/examples/effects_stereo.html @@ -0,0 +1,127 @@ + + + + SceneJS Example + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/effects_stereo_pickFlyOrbit.html b/examples/effects_stereo_pickFlyOrbit.html new file mode 100644 index 00000000..2ed1c4d9 --- /dev/null +++ b/examples/effects_stereo_pickFlyOrbit.html @@ -0,0 +1,122 @@ + + + + SceneJS Example + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/environments_gridRoom_teapot.html b/examples/environments_gridRoom_teapot.html new file mode 100644 index 00000000..ccbcca33 --- /dev/null +++ b/examples/environments_gridRoom_teapot.html @@ -0,0 +1,63 @@ + + + + SceneJS Example + + + + + + + + + + + + + diff --git a/examples/environments_holoDeck.html b/examples/environments_holoDeck.html new file mode 100644 index 00000000..4f328339 --- /dev/null +++ b/examples/environments_holoDeck.html @@ -0,0 +1,63 @@ + + + + SceneJS Example + + + + + + + + + + + + + diff --git a/examples/environments_lawn_city.html b/examples/environments_lawn_city.html new file mode 100644 index 00000000..b727c825 --- /dev/null +++ b/examples/environments_lawn_city.html @@ -0,0 +1,99 @@ + + + + SceneJS Example + + + + + + + + +
+ SceneJS experimental camera + plugin + +
+ + + + \ No newline at end of file diff --git a/examples/environments_lawn_teapots.html b/examples/environments_lawn_teapots.html new file mode 100644 index 00000000..f4bd584f --- /dev/null +++ b/examples/environments_lawn_teapots.html @@ -0,0 +1,82 @@ + + + + SceneJS Example + + + + + + + + + + + + + diff --git a/examples/environments_modelView_teapot.html b/examples/environments_modelView_teapot.html new file mode 100644 index 00000000..c2689af4 --- /dev/null +++ b/examples/environments_modelView_teapot.html @@ -0,0 +1,46 @@ + + + + SceneJS Example + + + + + + + + + + + + + diff --git a/examples/exampleLinks.json b/examples/exampleLinks.json new file mode 100644 index 00000000..7dcc97b4 --- /dev/null +++ b/examples/exampleLinks.json @@ -0,0 +1,281 @@ +{ + + "showcase": [ + "#stuff made with SceneJS", + "scenegraph_firstExample", + "showcase_BioDigitalHuman", + "showcase_BioDigitalHuman_eye", + "showcase_earth", + "showcase_tronTank" + ], + + "configuration": [ + "#getting SceneJS ready", + "configuration_pluginPath", + "configuration_disableStatusPopups" + ], + + "scenegraph": [ + "#basic scene graph functionality", + "scenegraph_firstExample", + "scenegraph_events_misc", + "scenegraph_events_status", + "scenegraph_events_status2", + "scenegraph_nodes_adding", + "scenegraph_nodes_events_rendered", + "scenegraph_nodes_instancing", + "scenegraph_nodes_moving", + "scenegraph_multipleScenes", + "scenegraph_webglContextRecovery", + + "#selectively enable rendering modes for subgraphs", + "scenegraph_enable", + "scenegraph_tags", + "scenegraph_flags", + "scenegraph_flags_ambient", + "scenegraph_flags_backfaceLighting", + "scenegraph_flags_backfaces", + "scenegraph_flags_backfaceTexturing", + "scenegraph_flags_diffuse", + "scenegraph_flags_enabled", + "scenegraph_flags_frontface", + "scenegraph_flags_picking", + "scenegraph_flags_reflection", + "scenegraph_flags_specular", + "scenegraph_flags_transparent" + ], + + "canvas": [ + "canvas_capture", + "canvas_capture_customSize", + "canvas_external", + "canvas_external_transparent", + "canvas_transparent" + ], + + "cameras": [ + "camera_orbit", + "camera_path", + "camera_pickFlyOrbit_city", + "camera_pickFlyOrbit_terrain", + "camera_stereo", + "camera_oculusRift", + "camera_anaglyph" + ], + + "geometry": [ + "geometry_autoNormals", + "geometry_box", + "geometry_cylinder", + "geometry_lines", + "geometry_morphTargets", + "geometry_morphTargets_typedArrays", + "geometry_plane", + "geometry_points", + "geometry_sphere", + "geometry_teapot", + "geometry_vectorText", + "geometry_torus", + "geometry_torus_wireframe", + "geometry_triangles", + "geometry_typedArrays", + "geometry_vertexColors", + "geometry_heightmap", + "geometry_heightmap_texture", + "geometry_heightmap_texture_video", + "geometry_heightmap_transparent" + ], + + "transforms": [ + "transforms_modelling_hierarchy", + "transforms_modelling_matrix", + "transforms_modelling_rotate", + "transforms_modelling_scale", + "transforms_modelling_translate", + "transforms_modelling_quaternion", + "transforms_projection_default", + "transforms_projection_frustum", + "transforms_projection_ortho", + "transforms_projection_perspective", + "transforms_viewing" + ], + + "lighting": [ + "lighting_material", + "lighting_ambient", + "lighting_default", + "lighting_directional_view", + "lighting_directional_world", + "lighting_directional_world_texture", + "lighting_point_view", + "lighting_point_world" + ], + + "textures": [ + "texture_alpha", + "texture_alpha_add", + "texture_alpha_mix", + "texture_alpha_multiply", + "texture_alpha_video", + "texture_atlas", + "texture_color", + "texture_color_add", + "texture_color_animated", + "texture_color_multiply", + "texture_color_video", + "texture_emit", + "texture_emit_add", + "texture_emit_multiply", + "texture_emit_video", + "texture_multiTexture", + "texture_normals", + "texture_normals_video", + "texture_rtt_color", + "texture_rtt_depth", + "texture_rtt_depthAndColor", + "texture_rtt_heightmap", + "texture_rtt_manyTextures", + "texture_rtt_shader", + "texture_rtt_withVideo", + "texture_specular", + "texture_specular_add", + "texture_specular_multiply", + "texture_specular_video", + "texture_uvLayers" + ], + + "reflections": [ + "#environmental reflection using cubemaps", + "reflections_custom", + "reflections_intensity", + "reflections_multipleSeparate", + "reflections_multipleCombined", + "reflections_shinyRaptor", + "reflections_manyObjects", + "reflections_withNormalMap", + "reflections_withTransparency", + "reflections_withSpecularMaterial", + "reflections_withSpecularMap" + ], + + "skyboxes": [ + "skyboxes_custom", + "skyboxes_clouds", + "skyboxes_cloudySea", + "skyboxes_grimmNight", + "skyboxes_interstellarClouds", + "skyboxes_miramarClouds", + "skyboxes_stormyDays", + "skyboxes_violentDays" + ], + + "passes": [ + "#multiple passes on each render", + "passes_twoPasses", + "passes_threePasses" + ], + + "stages": [ + "#custom effect pipelines", + "stages_twoStages", + "stages_threeStages", + "stages_withPicking", + "stages_withReflection", + "stages_withSharedShader", + "stages_withTransparencySort" + ], + + "layers": [ + "#prioritised render bins", + "layers_enableDisable", + "layers_transparencySort" + ], + + "depthBuffer": [ + +// "#Depth buffer control", + "depthBuf_clearDepth", + "depthBuf_depthFunc", + "depthBuf_enableDisable" + ], + + "shaders": [ + "shaders_xray", + "shaders_scanline", + "shaders_custom_material_color", + "shaders_custom_texture", + "shaders_custom_twoTextures", + "shaders_custom_threeTextures", + "shaders_custom_transforms", + "shaders_vertexDisplacement" + ], + + "posteffects": [ + "postEffects_blur", + "postEffects_depthOfField", + "postEffects_fog", + "postEffects_lens", + "postEffects_scanlines", + "postEffects_sepia", + "postEffects_scanlinesAndSepia" + ], + + "physics": [ + "physics_balls", + "physics_boxes", + "physics_materials", + "physics_multithreaded" + ], + + "picking": [ + "picking_basic", + "picking_disabling", + "picking_names", + "picking_spheres", + "picking_throughTransparency", + "picking_rayPicking", + "picking_rayPicking_performance" + ], + + "importing": [ + "importing_3ds_lexus", + "importing_md2_lion", + "importing_obj_duck", + "importing_obj_raptor" + ], + + "optimization": [ + "#optimizing your scene graphs", + "optimization_discreteLOD", + "optimization_frustumClipping", + "optimization_instancing", + "optimization_textureAtlas", + "optimization_vertexSharing" + ], + + "benchmarks": [ + "benchmarks_5000boxes" + ], + + "extending": [ + "#adding new node types to SceneJS", + "extending_nodes_custom", + "extending_nodes_custom_animation", + "extending_nodes_custom_pubSub", + "extending_nodes_custom_tasks" + ], + + "environments": [ + "#prebuilt scenes to drop your nodes into", + "environments_lawn", + "environments_gridRoom", + "environments_holoDeck" + ], + + "models": [ + "#a selection of models from the examples library", + "models_vehicles_tank", + "models_buildings_city", + "models_space_earth" + ] +}; \ No newline at end of file diff --git a/demos/nodes-custom-basic.html b/examples/extending_nodes_custom.html similarity index 97% rename from demos/nodes-custom-basic.html rename to examples/extending_nodes_custom.html index f7580f30..eb0b0852 100644 --- a/demos/nodes-custom-basic.html +++ b/examples/extending_nodes_custom.html @@ -117,9 +117,9 @@ // Teapot primitive, - // implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/nodes-custom-animated.html b/examples/extending_nodes_custom_animation.html similarity index 97% rename from demos/nodes-custom-animated.html rename to examples/extending_nodes_custom_animation.html index 8342dc7e..2cd032c8 100644 --- a/demos/nodes-custom-animated.html +++ b/examples/extending_nodes_custom_animation.html @@ -77,9 +77,9 @@ nodes:[ // Teapot primitive, - // implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/nodes-custom-pubsub.html b/examples/extending_nodes_custom_pubSub.html similarity index 97% rename from demos/nodes-custom-pubsub.html rename to examples/extending_nodes_custom_pubSub.html index b1ef9f69..6ceae13d 100644 --- a/demos/nodes-custom-pubsub.html +++ b/examples/extending_nodes_custom_pubSub.html @@ -57,9 +57,9 @@ nodes:[ // Teapot primitive, - // implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/nodes-custom-tasks.html b/examples/extending_nodes_custom_tasks.html similarity index 97% rename from demos/nodes-custom-tasks.html rename to examples/extending_nodes_custom_tasks.html index 88df62b0..01384021 100644 --- a/demos/nodes-custom-tasks.html +++ b/examples/extending_nodes_custom_tasks.html @@ -62,9 +62,9 @@ nodes:[ // Teapot primitive, - // implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/examples/features.json b/examples/features.json new file mode 100644 index 00000000..36860f33 --- /dev/null +++ b/examples/features.json @@ -0,0 +1,472 @@ +[ + { + "title": "Scene graph", + "description": "Declarative JSON-based runtime-editable scene graph", + "nodes": [ + { + "nodes": [ + { + "title": "Transform hierarchies", + "page": "transforms_modelling_hierarchy" + } + ] + }, + { + "nodes": [ + { + "title": "Multiple scenes", + "page": "scenegraph_multipleScenes" + } + ] + }, + { + "nodes": [ + { + "title": "Auto WebGLContextLost recovery", + "page": "scenegraph_webglContextRecovery" + } + ] + } + ] + }, + { + "title": "Effects", + "description": "Extensible library of post-effects and shaders, access to full WebGL shader capabilities", + "nodes": [ + { + "nodes": [ + { + "title": "Depth-of-field", + "page": "postprocessing_depthOfField" + }, + { + "title": "Blur", + "page": "postprocessing_blur" + }, + { + "title": "Fog", + "page": "postprocessing_fog" + }, + { + "title": "X-Ray", + "page": "shaders_xray" + }, + { + "title": "Film grain", + "page": "postprocessing_filmGrain" + }, + { + "title": "Vertex displacement", + "page": "shaders_vertexDisplacement" + } + ] + }, + { + "nodes": [ + { + "title": "Reflection", + "page": "reflections_custom" + } + ] + }, + { + "nodes": [ + { + "title": "Custom fragment shaders", + "page": "shaders_custom_water" + } + ] + }, + { + "nodes": [ + { + "title": "Custom vertex shaders", + "page": "shaders_vertexDisplacement" + } + ] + }, + { + "nodes": [ + { + "title": "Transparency sorting", + "page": "layers_transparencySort" + } + ] + }, + { + "nodes": [ + { + "title": "Oculus Rift", + "page": "effects_oculusRift_pickFlyOrbit" + }, + { + "title": "Anaglyph 3D", + "page": "effects_anaglyph_pickFlyOrbit" + }, + { + "title": "Stereo", + "page": "effects_stereo_pickFlyOrbit" + } + ] + } + ] + }, + { + "title": "Physics", + "nodes": [ + { + "nodes": [ + { + "title": "Rigid body dynamics", + "page": "physics_balls" + } + ] + }, + { + "nodes": [ + { + "title": "Multithreaded", + "page": "physics_multithreaded" + } + ] + } + ] + }, + { + "title": "Importers", + "nodes": [ + { + "nodes": [ + { + "title": ".OBJ", + "page": "importing_obj_raptor" + }, + { + "title": ".3DS", + "page": "importing_3ds_lexus" + }, + { + "title": ".MD2", + "page": "importing_md2_lion" + } + ] + } + ] + }, + { + "title": "Optimization", + "nodes": [ + { + "nodes": [ + { + "title": "Frustum Culling", + "page": "optimization_frustumClipping" + } + ] + }, + { + "nodes": [ + { + "title": "Level-of-Detail", + "page": "optimization_discreteLOD" + } + ] + }, + { + "nodes": [ + { + "title": "Instancing", + "page": "optimization_instancing" + } + ] + }, + { + "nodes": [ + { + "title": "Vertex sharing", + "page": "optimization_vertexSharing" + } + ] + }, + { + "nodes": [ + { + "title": "Texture atlases", + "page": "optimization_textureAtlas" + } + ] + } + ] + }, + { + "title": "Picking", + "nodes": [ + { + "nodes": [ + { + "title": "Object picking", + "page": "picking_names" + } + ] + }, + { + "nodes": [ + { + "title": "3D ray picking", + "page": "picking_rayPicking_performance" + } + ] + } + ] + }, + { + "title": "Lighting", + "nodes": [ + { + "nodes": [ + { + "title": "Ambient", + "page": "lighting_ambient" + }, + { + "title": "Directional", + "page": "lighting_directional_world" + }, + { + "title": "Point", + "page": "lighting_point_world" + } + ] + } + ] + }, + { + "title": "Cameras", + "nodes": [ + { + "nodes": [ + { + "title": "Orthographic", + "page": "transforms_projection_ortho" + }, + { + "title": "Perspective", + "page": "transforms_projection_perspective" + }, + { + "title": "Frustum", + "page": "transforms_projection_frustum" + } + ] + }, + { + "nodes": [ + { + "title": "Orbiting", + "page": "cameras_orbit" + }, + { + "title": "Pick-Fly-Orbit", + "page": "cameras_pickFlyOrbit_city" + } + ] + } + ] + }, + { + "title": "Geometry", + "nodes": [ + { + "nodes": [ + { + "title": "Triangles", + "page": "geometry_triangles" + }, + { + "title": "Lines", + "page": "geometry_lines" + }, + { + "title": "Points", + "page": "geometry_points" + } + ] + }, + { + "nodes": [ + { + "title": "Plane", + "page": "geometry_plane" + }, + { + "title": "Box", + "page": "geometry_box" + }, + { + "title": "Cylinder", + "page": "geometry_cylinder" + }, + { + "title": "Sphere", + "page": "geometry_sphere" + }, + { + "title": "Torus", + "page": "geometry_torus" + }, + { + "title": "Teapot", + "page": "geometry_teapot" + } + ] + }, + { + "nodes": [ + { + "title": "Terrain", + "page": "geometry_heightmap" + } + ] + }, + { + "nodes": [ + { + "title": "Text", + "page": "geometry_vectorText" + } + ] + }, + { + "nodes": [ + { + "title": "Vertex coloring", + "page": "geometry_vertexColors" + } + ] + }, + { + "nodes": [ + { + "title": "Automatic normals", + "page": "geometry_autoNormals" + } + ] + } + ] + }, + { + "title": "Texture", + "nodes": [ + { + "nodes": [ + { + "title": "Color", + "page": "texture_color" + }, + { + "title": "Alpha", + "page": "texture_alpha" + }, + { + "title": "Specular", + "page": "texture_specular" + }, + { + "title": "Normal", + "page": "texture_normals" + }, + { + "title": "Glow", + "page": "texture_emit" + } + ] + }, + { + "nodes": [ + { + "title": "Procedural", + "page": "texture_procedural_color_water" + } + ] + }, + { + "nodes": [ + { + "title": "Reflection", + "page": "reflections_custom" + } + ] + }, + { + "nodes": [ + { + "title": "Multi-texturing", + "page": "texture_multiTexture" + } + ] + }, + { + "nodes": [ + { + "title": "Animation", + "page": "texture_animation" + } + ] + }, + { + "nodes": [ + { + "title": "Render-to-texture", + "page": "texture_rtt_color" + } + ] + }, + { + "nodes": [ + { + "title": "Video", + "page": "texture_video_color" + } + ] + }, + { + "nodes": [ + { + "title": "UV layers", + "page": "texture_uvLayers" + } + ] + } + ] + }, + + { + "title": "Asset library, eg:", + "nodes": [ + { + "nodes": [ + { + "title": "Skyboxes", + "page": "skyboxes_miramarClouds" + } + ] + }, + { + "nodes": [ + { + "title": "City", + "page": "models_buildings_city" + }, + { + "title": "Tank", + "page": "models_vehicles_tank" + }, + { + "title": "Earth", + "page": "models_space_earth" + } + ] + } + ] + } +] \ No newline at end of file diff --git a/demos/geometry-autoNormals.html b/examples/geometry_autoNormals.html similarity index 100% rename from demos/geometry-autoNormals.html rename to examples/geometry_autoNormals.html diff --git a/demos/geometry-box.html b/examples/geometry_box.html similarity index 83% rename from demos/geometry-box.html rename to examples/geometry_box.html index 171413c9..036b34d3 100644 --- a/demos/geometry-box.html +++ b/examples/geometry_box.html @@ -31,10 +31,10 @@ SceneJS.createScene({ nodes:[ - // Mouse-orbited camera, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/cameras/orbit.js + // Asset viewing environment, implemented by plugin at + // http://scenejs.org/api/latest/plugins/node/environments/assetViewer.js { - type:"cameras/orbit", + type:"environments/modelView", yaw:30, pitch:-30, zoom:5, @@ -47,9 +47,9 @@ nodes:[ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box", + type:"geometry/box", xSize: 1, ySize: 1, zSize: 1.2 diff --git a/demos/geometry-cylinder.html b/examples/geometry_cylinder.html similarity index 95% rename from demos/geometry-cylinder.html rename to examples/geometry_cylinder.html index c7b1c556..2dcbd666 100644 --- a/demos/geometry-cylinder.html +++ b/examples/geometry_cylinder.html @@ -47,10 +47,10 @@ nodes:[ // Cylinder primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/cylinder.js + // http://scenejs.org/api/latest/plugins/node/geometry/cylinder.js // Author: Moritz Kornher { - type:"prims/cylinder", + type:"geometry/cylinder", radiusTop:20, // Default 20 radiusBottom:20, // Default 20 height:100, // Default 100 diff --git a/examples/geometry_heightmap.html b/examples/geometry_heightmap.html new file mode 100644 index 00000000..cabee51d --- /dev/null +++ b/examples/geometry_heightmap.html @@ -0,0 +1,88 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/geometry_heightmap_fogAndGrid.html b/examples/geometry_heightmap_fogAndGrid.html new file mode 100644 index 00000000..4a6a0705 --- /dev/null +++ b/examples/geometry_heightmap_fogAndGrid.html @@ -0,0 +1,127 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/heightmaps-textured.html b/examples/geometry_heightmap_texture.html similarity index 82% rename from demos/heightmaps-textured.html rename to examples/geometry_heightmap_texture.html index 8ec18f8a..8b5d96d3 100644 --- a/demos/heightmaps-textured.html +++ b/examples/geometry_heightmap_texture.html @@ -20,7 +20,7 @@ + + + + + + + \ No newline at end of file diff --git a/demos/geometry-vertexColors.html b/examples/geometry_vertexColors.html similarity index 100% rename from demos/geometry-vertexColors.html rename to examples/geometry_vertexColors.html diff --git a/demos/images/chrome-experiment.png b/examples/images/chrome-experiment.png similarity index 100% rename from demos/images/chrome-experiment.png rename to examples/images/chrome-experiment.png diff --git a/demos/import-3ds-lexus.html b/examples/importing_3ds_lexus.html similarity index 100% rename from demos/import-3ds-lexus.html rename to examples/importing_3ds_lexus.html diff --git a/demos/import-md2-lion.html b/examples/importing_md2_lion.html similarity index 100% rename from demos/import-md2-lion.html rename to examples/importing_md2_lion.html diff --git a/demos/import-obj-duck.html b/examples/importing_obj_duck.html similarity index 100% rename from demos/import-obj-duck.html rename to examples/importing_obj_duck.html diff --git a/demos/import-obj-raptor.html b/examples/importing_obj_raptor.html similarity index 100% rename from demos/import-obj-raptor.html rename to examples/importing_obj_raptor.html diff --git a/demos/layers-enableDisable.html b/examples/layers_enableDisable.html similarity index 95% rename from demos/layers-enableDisable.html rename to examples/layers_enableDisable.html index e96b1145..ce652a6a 100644 --- a/demos/layers-enableDisable.html +++ b/examples/layers_enableDisable.html @@ -67,9 +67,9 @@ nodes:[ // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type:"geometry/sphere" } ] } @@ -96,9 +96,9 @@ z:3, nodes:[ - // Box primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -129,9 +129,9 @@ y:-1, nodes:[ - // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/layers-transparencySort.html b/examples/layers_transparencySort.html similarity index 94% rename from demos/layers-transparencySort.html rename to examples/layers_transparencySort.html index 507ded04..7012e0a4 100644 --- a/demos/layers-transparencySort.html +++ b/examples/layers_transparencySort.html @@ -78,9 +78,9 @@ nodes:[ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -114,9 +114,9 @@ nodes:[ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -145,9 +145,9 @@ nodes:[ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } diff --git a/demos/libs/cityBuilder.js b/examples/libs/cityBuilder.js similarity index 100% rename from demos/libs/cityBuilder.js rename to examples/libs/cityBuilder.js diff --git a/demos/libs/dat.gui.min.js b/examples/libs/dat.gui.min.js similarity index 100% rename from demos/libs/dat.gui.min.js rename to examples/libs/dat.gui.min.js diff --git a/demos/libs/gl-matrix-min.js b/examples/libs/gl-matrix-min.js similarity index 100% rename from demos/libs/gl-matrix-min.js rename to examples/libs/gl-matrix-min.js diff --git a/demos/libs/gl-matrix.js b/examples/libs/gl-matrix.js similarity index 100% rename from demos/libs/gl-matrix.js rename to examples/libs/gl-matrix.js diff --git a/demos/libs/jquery-1.8.3.min.js b/examples/libs/jquery-1.8.3.min.js similarity index 100% rename from demos/libs/jquery-1.8.3.min.js rename to examples/libs/jquery-1.8.3.min.js diff --git a/demos/libs/stats.min.js b/examples/libs/stats.min.js similarity index 100% rename from demos/libs/stats.min.js rename to examples/libs/stats.min.js diff --git a/demos/libs/sylvester.js b/examples/libs/sylvester.js similarity index 100% rename from demos/libs/sylvester.js rename to examples/libs/sylvester.js diff --git a/demos/lights-ambient.html b/examples/lighting_ambient.html similarity index 95% rename from demos/lights-ambient.html rename to examples/lighting_ambient.html index cbc02fbe..1f226d88 100644 --- a/demos/lights-ambient.html +++ b/examples/lighting_ambient.html @@ -62,9 +62,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/lights-default.html b/examples/lighting_default.html similarity index 97% rename from demos/lights-default.html rename to examples/lighting_default.html index a437cfde..e685bb90 100644 --- a/demos/lights-default.html +++ b/examples/lighting_default.html @@ -89,9 +89,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/lights-directional-view.html b/examples/lighting_directional_view.html similarity index 98% rename from demos/lights-directional-view.html rename to examples/lighting_directional_view.html index cebee806..e74e1032 100644 --- a/demos/lights-directional-view.html +++ b/examples/lighting_directional_view.html @@ -72,9 +72,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/lights-directional-world.html b/examples/lighting_directional_world.html similarity index 95% rename from demos/lights-directional-world.html rename to examples/lighting_directional_world.html index 051a10aa..76c3f0a8 100644 --- a/demos/lights-directional-world.html +++ b/examples/lighting_directional_world.html @@ -69,9 +69,9 @@ nodes:[ - // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/lights-directional-world-texture.html b/examples/lighting_directional_world_texture.html similarity index 96% rename from demos/lights-directional-world-texture.html rename to examples/lighting_directional_world_texture.html index 80449adc..8599e0fb 100644 --- a/demos/lights-directional-world-texture.html +++ b/examples/lighting_directional_world_texture.html @@ -79,9 +79,9 @@ nodes:[ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } diff --git a/examples/lighting_material_custom.html b/examples/lighting_material_custom.html new file mode 100644 index 00000000..0dd55109 --- /dev/null +++ b/examples/lighting_material_custom.html @@ -0,0 +1,109 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/materials-default.html b/examples/lighting_material_defaults.html similarity index 96% rename from demos/materials-default.html rename to examples/lighting_material_defaults.html index 595d13a8..c02a3abd 100644 --- a/demos/materials-default.html +++ b/examples/lighting_material_defaults.html @@ -21,6 +21,8 @@ + + + + + + \ No newline at end of file diff --git a/examples/models_space_earth.html b/examples/models_space_earth.html new file mode 100644 index 00000000..10d83797 --- /dev/null +++ b/examples/models_space_earth.html @@ -0,0 +1,53 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/models_vehicles_tank.html b/examples/models_vehicles_tank.html new file mode 100644 index 00000000..ddb3ecfd --- /dev/null +++ b/examples/models_vehicles_tank.html @@ -0,0 +1,54 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/movies/bumpMap.ogg b/examples/movies/bumpMap.ogg similarity index 100% rename from demos/movies/bumpMap.ogg rename to examples/movies/bumpMap.ogg diff --git a/demos/movies/bunny.ogg b/examples/movies/bunny.ogg similarity index 100% rename from demos/movies/bunny.ogg rename to examples/movies/bunny.ogg diff --git a/demos/movies/testVideo.ogv b/examples/movies/testVideo.ogv similarity index 100% rename from demos/movies/testVideo.ogv rename to examples/movies/testVideo.ogv diff --git a/examples/multipass_threePasses.html b/examples/multipass_threePasses.html new file mode 100644 index 00000000..12881471 --- /dev/null +++ b/examples/multipass_threePasses.html @@ -0,0 +1,121 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/multipass_twoPasses.html b/examples/multipass_twoPasses.html new file mode 100644 index 00000000..14f82489 --- /dev/null +++ b/examples/multipass_twoPasses.html @@ -0,0 +1,116 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/culling-frustum-detail.html b/examples/optimization_discreteLOD.html similarity index 92% rename from demos/culling-frustum-detail.html rename to examples/optimization_discreteLOD.html index 1b74af75..265646b0 100644 --- a/demos/culling-frustum-detail.html +++ b/examples/optimization_discreteLOD.html @@ -21,9 +21,9 @@ // // Demonstrates Detail Culling using the axis-aligned bounding box node defined -// by the plugin in http://scenejs.org/api/latest/plugins/node/frustum/lod.js +// by the plugin in http://scenejs.org/api/latest/plugins/node/cull/detail.js // -// The frustum/lod node encloses its child nodes in an axis-aligned World-space bounding +// The cull/detail node encloses its child nodes in an axis-aligned World-space bounding // box and enables the appropriate child for the box's current projected 2D canvas size. // As shown in the example below, we configure the node with a 2D size threshold for @@ -94,12 +94,12 @@ // Detail culling node, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/frustum/lod.js + // http://scenejs.org/api/latest/plugins/node/cull/detail.js // // More info at: https://github.com/xeolabs/scenejs/wiki/Detail-Culling nodes.push({ - type: "frustum/lod", + type: "cull/detail", // World-space axis-aligned bounding box min: [xPos - 8, yPos - 3, zPos - 5], @@ -148,9 +148,9 @@ nodes: [ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -187,9 +187,9 @@ nodes: [ // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type: "prims/sphere", + type: "geometry/sphere", radius: 5, latitudeBands: 16, // A fairly low-rez sphere longitudeBands: 16 @@ -225,9 +225,10 @@ nodes: [ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" + //type: "models/space/planets/earth" } ] } diff --git a/demos/culling-frustum.html b/examples/optimization_frustumClipping.html similarity index 95% rename from demos/culling-frustum.html rename to examples/optimization_frustumClipping.html index 8df4b69c..6aa45655 100644 --- a/demos/culling-frustum.html +++ b/examples/optimization_frustumClipping.html @@ -24,7 +24,7 @@ + + + + + + + + + \ No newline at end of file diff --git a/demos/nodes-cores-sharing.html b/examples/optimization_instancing.html similarity index 100% rename from demos/nodes-cores-sharing.html rename to examples/optimization_instancing.html diff --git a/examples/optimization_textureAtlas.html b/examples/optimization_textureAtlas.html new file mode 100644 index 00000000..0f755294 --- /dev/null +++ b/examples/optimization_textureAtlas.html @@ -0,0 +1,117 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/demos/geometry-vertexSharing.html b/examples/optimization_vertexSharing.html similarity index 100% rename from demos/geometry-vertexSharing.html rename to examples/optimization_vertexSharing.html diff --git a/examples/physics_balls.html b/examples/physics_balls.html new file mode 100644 index 00000000..4d26c457 --- /dev/null +++ b/examples/physics_balls.html @@ -0,0 +1,236 @@ + + + + SceneJS Example + + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/physics-boxes.html b/examples/physics_boxes.html similarity index 96% rename from demos/physics-boxes.html rename to examples/physics_boxes.html index b6b75e12..52d08b7c 100644 --- a/demos/physics-boxes.html +++ b/examples/physics_boxes.html @@ -106,9 +106,9 @@ nodes:[ // Grid ground plane geometry, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/grid.js + // http://scenejs.org/api/latest/plugins/node/geometry/grid.js { - type:"prims/grid", + type:"geometry/grid", size:{ x:1000, z:1000 }, xSegments:200, zSegments:200 @@ -130,7 +130,7 @@ ] }); - // Returns a bunch of "prims/sphere" nodes, each wrapped by a spherical "physics/body" node + // Returns a bunch of "geometry/sphere" nodes, each wrapped by a spherical "physics/body" node function makeBodies(numBodies) { var nodes = []; @@ -195,9 +195,9 @@ nodes:[ // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/box", + type:"geometry/box", xSize:xSize / 2, ySize:ySize / 2, zSize:zSize / 2 diff --git a/demos/physics-materials.html b/examples/physics_materials.html similarity index 92% rename from demos/physics-materials.html rename to examples/physics_materials.html index f97b5551..8a9f3655 100644 --- a/demos/physics-materials.html +++ b/examples/physics_materials.html @@ -138,13 +138,6 @@ // Mass not relevant for unmoving object? mass:0.0, - // The coefficient of restitution (COR) of two colliding objects is a - // fractional value representing the ratio of speeds after and before - // an impact, taken along the line of the impact. - restitution:0.9, - - friction:0.3, - // Specify that this body is not able to move movable:false, @@ -160,9 +153,9 @@ nodes:[ // Grid ground plane geometry, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/grid.js + // http://scenejs.org/api/latest/plugins/node/geometry/grid.js { - type:"prims/grid", + type:"geometry/grid", size:{ x:50, z:50 }, xSegments:100, zSegments:100 @@ -184,7 +177,7 @@ } -// Returns a bunch of "prims/sphere" nodes, each wrapped by a spherical "physics/body" node +// Returns a bunch of "geometry/sphere" nodes, each wrapped by a spherical "physics/body" node function makeBodies(numBodies, systemId) { var nodes = []; @@ -238,9 +231,9 @@ nodes:[ // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere", + type:"geometry/sphere", radius:1 } ] diff --git a/demos/physics-multithreaded.html b/examples/physics_multithreaded.html similarity index 96% rename from demos/physics-multithreaded.html rename to examples/physics_multithreaded.html index 78c03d98..0ca79259 100644 --- a/demos/physics-multithreaded.html +++ b/examples/physics_multithreaded.html @@ -136,9 +136,9 @@ nodes:[ // Grid ground plane geometry, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/grid.js + // http://scenejs.org/api/latest/plugins/node/geometry/grid.js { - type:"prims/grid", + type:"geometry/grid", size:{ x:50, z:50 }, xSegments:20, zSegments:20 @@ -160,7 +160,7 @@ } -// Returns a bunch of "prims/sphere" nodes, each wrapped by a spherical "physics/body" node +// Returns a bunch of "geometry/sphere" nodes, each wrapped by a spherical "physics/body" node function makeBodies(numBodies, systemId) { var nodes = []; @@ -214,9 +214,9 @@ nodes:[ // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere", + type:"geometry/sphere", radius:1, latitudeBands:16, // A fairly low-rez sphere diff --git a/demos/picking.html b/examples/picking_basic.html similarity index 93% rename from demos/picking.html rename to examples/picking_basic.html index 03f4d2e1..e2dcf132 100644 --- a/demos/picking.html +++ b/examples/picking_basic.html @@ -59,7 +59,8 @@ // Pickable red teapot with name "redTeapot" { - type: "name", name: "redTeapot", + type: "name", + name: "redTeapot", nodes: [ { type: "material", color: { r: 1.0, g: 0.3, b: 0.3 }, @@ -69,9 +70,9 @@ nodes: [ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } @@ -82,7 +83,8 @@ // Pickable blue teapot with name "blueTeapot" { - type: "name", name: "blueTeapot", + type: "name", + name: "blueTeapot", nodes: [ { type: "material", color: { r: 0.3, g: 0.3, b: 1.0 }, @@ -92,9 +94,9 @@ nodes: [ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } diff --git a/demos/picking-disabling.html b/examples/picking_disabling.html similarity index 95% rename from demos/picking-disabling.html rename to examples/picking_disabling.html index 4e46bc54..05447e5e 100644 --- a/demos/picking-disabling.html +++ b/examples/picking_disabling.html @@ -64,9 +64,9 @@ nodes: [ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } @@ -93,9 +93,9 @@ nodes: [ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } diff --git a/demos/picking-names.html b/examples/picking_names.html similarity index 96% rename from demos/picking-names.html rename to examples/picking_names.html index b2f04ab1..cd58e3da 100644 --- a/demos/picking-names.html +++ b/examples/picking_names.html @@ -103,9 +103,9 @@ nodes:[ - // Box primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -137,9 +137,9 @@ nodes:[ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -170,9 +170,9 @@ nodes:[ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -203,9 +203,9 @@ nodes:[ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -236,9 +236,9 @@ nodes:[ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -289,9 +289,9 @@ nodes:[ // Node type implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } @@ -329,9 +329,9 @@ nodes:[ // Node type implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } @@ -369,9 +369,9 @@ nodes:[ // Node type implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } @@ -409,9 +409,9 @@ nodes:[ // Node type implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } @@ -454,9 +454,9 @@ nodes:[ // Node type implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -495,9 +495,9 @@ nodes:[ - // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type:"geometry/sphere" } ] } diff --git a/demos/picking-ray.html b/examples/picking_rayPicking.html similarity index 94% rename from demos/picking-ray.html rename to examples/picking_rayPicking.html index 5b099184..df50ee32 100644 --- a/demos/picking-ray.html +++ b/examples/picking_rayPicking.html @@ -62,9 +62,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -82,9 +82,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -109,9 +109,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -171,9 +171,9 @@ z:0.1, nodes:[ - // Sphere primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // Sphere primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type:"geometry/sphere" } ] } diff --git a/demos/picking-ray-spheres.html b/examples/picking_rayPicking_performance.html similarity index 97% rename from demos/picking-ray-spheres.html rename to examples/picking_rayPicking_performance.html index 1bfb32bf..f30b3319 100644 --- a/demos/picking-ray-spheres.html +++ b/examples/picking_rayPicking_performance.html @@ -100,9 +100,9 @@ nodes:[ // Sphere geometry node implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type:"geometry/sphere" } ] } @@ -164,9 +164,9 @@ z:0.2, nodes:[ - // Sphere primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // Sphere primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type:"geometry/sphere" } ] } diff --git a/demos/picking-spheres.html b/examples/picking_spheres.html similarity index 98% rename from demos/picking-spheres.html rename to examples/picking_spheres.html index f71d4097..ccdada5e 100644 --- a/demos/picking-spheres.html +++ b/examples/picking_spheres.html @@ -86,9 +86,9 @@ shine: 70.0, nodes: [ - // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type: "prims/sphere" + type: "geometry/sphere" } ] } diff --git a/demos/picking-throughTransparency.html b/examples/picking_throughTransparency.html similarity index 95% rename from demos/picking-throughTransparency.html rename to examples/picking_throughTransparency.html index 4917b191..368c8972 100644 --- a/demos/picking-throughTransparency.html +++ b/examples/picking_throughTransparency.html @@ -64,9 +64,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -91,9 +91,9 @@ nodes:[ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box", xSize:3.5, ySize:2, zSize:3.5 + type:"geometry/box", xSize:3.5, ySize:2, zSize:3.5 } ] } diff --git a/examples/postprocessing_blur.html b/examples/postprocessing_blur.html new file mode 100644 index 00000000..4f092702 --- /dev/null +++ b/examples/postprocessing_blur.html @@ -0,0 +1,124 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/postprocessing_crt.html b/examples/postprocessing_crt.html new file mode 100644 index 00000000..677ae49d --- /dev/null +++ b/examples/postprocessing_crt.html @@ -0,0 +1,73 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/postprocessing_custom_twoStagesWithPicking.html b/examples/postprocessing_custom_twoStagesWithPicking.html new file mode 100644 index 00000000..6a93c4c0 --- /dev/null +++ b/examples/postprocessing_custom_twoStagesWithPicking.html @@ -0,0 +1,268 @@ + + + + SceneJS Example + + + + + + + + + + +
Click on an object to pick it +
+ + + + + \ No newline at end of file diff --git a/examples/postprocessing_depthOfField.html b/examples/postprocessing_depthOfField.html new file mode 100644 index 00000000..44c706ab --- /dev/null +++ b/examples/postprocessing_depthOfField.html @@ -0,0 +1,171 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/postprocessing_depthOfField_autofocus.html b/examples/postprocessing_depthOfField_autofocus.html new file mode 100644 index 00000000..8e165f53 --- /dev/null +++ b/examples/postprocessing_depthOfField_autofocus.html @@ -0,0 +1,128 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/postprocessing_filmGrain.html b/examples/postprocessing_filmGrain.html new file mode 100644 index 00000000..ef418876 --- /dev/null +++ b/examples/postprocessing_filmGrain.html @@ -0,0 +1,75 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/effects-fog.html b/examples/postprocessing_fog.html similarity index 89% rename from demos/effects-fog.html rename to examples/postprocessing_fog.html index 5ef64dba..9d32ea22 100644 --- a/demos/effects-fog.html +++ b/examples/postprocessing_fog.html @@ -19,7 +19,7 @@ + + + + + + \ No newline at end of file diff --git a/examples/postprocessing_pipeline.html b/examples/postprocessing_pipeline.html new file mode 100644 index 00000000..292b240c --- /dev/null +++ b/examples/postprocessing_pipeline.html @@ -0,0 +1,187 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/postprocessing_scanlines.html b/examples/postprocessing_scanlines.html new file mode 100644 index 00000000..0b4b4eef --- /dev/null +++ b/examples/postprocessing_scanlines.html @@ -0,0 +1,73 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/postprocessing_scanlinesAndSepia.html b/examples/postprocessing_scanlinesAndSepia.html new file mode 100644 index 00000000..336e8217 --- /dev/null +++ b/examples/postprocessing_scanlinesAndSepia.html @@ -0,0 +1,90 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/postprocessing_sepia.html b/examples/postprocessing_sepia.html new file mode 100644 index 00000000..6bc46d64 --- /dev/null +++ b/examples/postprocessing_sepia.html @@ -0,0 +1,79 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/import-3ds-teapot.html b/examples/postprocessing_technicolor.html similarity index 55% rename from demos/import-3ds-teapot.html rename to examples/postprocessing_technicolor.html index fc11c423..103c6b2a 100644 --- a/demos/import-3ds-teapot.html +++ b/examples/postprocessing_technicolor.html @@ -20,48 +20,48 @@ \ No newline at end of file diff --git a/examples/reflections_clouds.html b/examples/reflections_clouds.html new file mode 100644 index 00000000..6d78d496 --- /dev/null +++ b/examples/reflections_clouds.html @@ -0,0 +1,102 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/reflection.html b/examples/reflections_custom.html similarity index 94% rename from demos/reflection.html rename to examples/reflections_custom.html index 8c23f4bb..3f54c736 100644 --- a/demos/reflection.html +++ b/examples/reflections_custom.html @@ -28,7 +28,7 @@ // // 1. a "reflect" node, which defines a cube map texture to be reflected on child geometries, // 2. a "material" node, which defines the amount of surface reflectivity via its "specular" property, and - // 3. one or more geometry nodes (eg. "prims/teapot"), which define the surface. + // 3. one or more geometry nodes (eg. "geometry/teapot"), which define the surface. // // The amount of reflectivity of the surface is controlled by the "specular" property // on the material, while the intensity of the cube map texture that is applied is @@ -85,9 +85,9 @@ nodes: [ // Teapot primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } diff --git a/demos/reflection-intensity.html b/examples/reflections_intensity.html similarity index 89% rename from demos/reflection-intensity.html rename to examples/reflections_intensity.html index 316131dd..c3ba8ba9 100644 --- a/demos/reflection-intensity.html +++ b/examples/reflections_intensity.html @@ -27,7 +27,7 @@ // // 1. a "reflect" node, which defines a cube map texture to be reflected on child geometries, // 2. a "material" node, which defines the amount of surface reflectivity via its "specular" property, and - // 3. one or more geometry nodes (eg. "prims/teapot"), which define the surface. + // 3. one or more geometry nodes (eg. "geometry/teapot"), which define the surface. // // The amount of reflectivity of the surface is controlled by the "specular" property // on the material, while the intensity of the cube map texture that is applied is @@ -71,7 +71,7 @@ x: -30, nodes: [ - { type: "prims/vectorText", text: "Intensity 0.05" }, + { type: "geometry/vectorText", text: "Intensity 0.05" }, // Reflection cube map // Images taken from: http://hristo.oskov.com/projects/cs418/mp3/ @@ -90,9 +90,9 @@ nodes: [ // Tron tank primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/objects/vehicles/tank.js + // http://scenejs.org/api/latest/plugins/node/models/vehicles/tank.js { - type: "objects/vehicles/tank" + type: "models/vehicles/tank" } ] } @@ -105,7 +105,7 @@ x: -10, nodes: [ - { type: "prims/vectorText", text: "Intensity 0.2" }, + { type: "geometry/vectorText", text: "Intensity 0.2" }, // Reflection cube map // Images taken from: http://hristo.oskov.com/projects/cs418/mp3/ @@ -124,9 +124,9 @@ nodes: [ // Tron tank primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/objects/vehicles/tank.js + // http://scenejs.org/api/latest/plugins/node/models/vehicles/tank.js { - type: "objects/vehicles/tank" + type: "models/vehicles/tank" } ] } @@ -139,7 +139,7 @@ x: 10, nodes: [ - { type: "prims/vectorText", text: "Intensity 0.4" }, + { type: "geometry/vectorText", text: "Intensity 0.4" }, // Reflection cube map // Images taken from: http://hristo.oskov.com/projects/cs418/mp3/ @@ -158,9 +158,9 @@ nodes: [ // Tron tank primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/objects/vehicles/tank.js + // http://scenejs.org/api/latest/plugins/node/models/vehicles/tank.js { - type: "objects/vehicles/tank" + type: "models/vehicles/tank" } ] } @@ -171,7 +171,7 @@ x: 30, nodes: [ - { type: "prims/vectorText", text: "Intensity 1.0" }, + { type: "geometry/vectorText", text: "Intensity 1.0" }, // Reflection cube map // Images taken from: http://hristo.oskov.com/projects/cs418/mp3/ @@ -190,9 +190,9 @@ nodes: [ // Tron tank primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/objects/vehicles/tank.js + // http://scenejs.org/api/latest/plugins/node/models/vehicles/tank.js { - type: "objects/vehicles/tank" + type: "models/vehicles/tank" } ] } diff --git a/demos/reflection-multipleObjects.html b/examples/reflections_manyObjects.html similarity index 97% rename from demos/reflection-multipleObjects.html rename to examples/reflections_manyObjects.html index 367adcf5..9585a321 100644 --- a/demos/reflection-multipleObjects.html +++ b/examples/reflections_manyObjects.html @@ -77,9 +77,9 @@ nodes: [ - // Box primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -102,9 +102,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -127,9 +127,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -152,9 +152,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -177,9 +177,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -213,7 +213,7 @@ nodes: [ { - type: "prims/torus" + type: "geometry/torus" } ] } @@ -242,7 +242,7 @@ nodes: [ { - type: "prims/torus" + type: "geometry/torus" } ] } @@ -271,7 +271,7 @@ nodes: [ { - type: "prims/torus" + type: "geometry/torus" } ] } @@ -300,7 +300,7 @@ nodes: [ { - type: "prims/torus" + type: "geometry/torus" } ] } @@ -332,9 +332,9 @@ nodes: [ - // Node type implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Node type implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } @@ -365,9 +365,9 @@ nodes: [ - // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type: "prims/sphere" + type: "geometry/sphere" } ] } diff --git a/demos/reflection-multiple.html b/examples/reflections_multipleCombined.html similarity index 95% rename from demos/reflection-multiple.html rename to examples/reflections_multipleCombined.html index 50fe8ff8..4f9e643f 100644 --- a/demos/reflection-multiple.html +++ b/examples/reflections_multipleCombined.html @@ -21,7 +21,7 @@ + + + + + + + \ No newline at end of file diff --git a/demos/reflection-obj.html b/examples/reflections_shinyRaptor.html similarity index 95% rename from demos/reflection-obj.html rename to examples/reflections_shinyRaptor.html index 7434d914..329a93f8 100644 --- a/demos/reflection-obj.html +++ b/examples/reflections_shinyRaptor.html @@ -76,7 +76,7 @@ type: "texture", layers: [ { - src: "../../../models/obj/raptor.jpg" + src: "models/obj/raptor.jpg" } ], nodes: [ @@ -91,7 +91,7 @@ { type: "import/obj", - src: "../../../models/obj/raptor.obj" + src: "models/obj/raptor.obj" } ] } diff --git a/examples/reflections_withNormalMap.html b/examples/reflections_withNormalMap.html new file mode 100644 index 00000000..8aa25212 --- /dev/null +++ b/examples/reflections_withNormalMap.html @@ -0,0 +1,173 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/reflection-specularMap.html b/examples/reflections_withSpecularMap.html similarity index 94% rename from demos/reflection-specularMap.html rename to examples/reflections_withSpecularMap.html index ee319ee8..3e0c0745 100644 --- a/demos/reflection-specularMap.html +++ b/examples/reflections_withSpecularMap.html @@ -91,9 +91,9 @@ nodes: [ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -119,9 +119,9 @@ nodes: [ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -147,9 +147,9 @@ nodes: [ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/reflection-specularity.html b/examples/reflections_withSpecularMaterial.html similarity index 93% rename from demos/reflection-specularity.html rename to examples/reflections_withSpecularMaterial.html index fdbfe2fe..f7257057 100644 --- a/demos/reflection-specularity.html +++ b/examples/reflections_withSpecularMaterial.html @@ -28,7 +28,7 @@ // // 1. a "reflect" node, which defines a cube map texture to be reflected on child geometries, // 2. a "material" nodes, which defines the amount of surface reflectivity via its "specular" property, and - // 3. a geometry node (eg. "prims/teapot"), which define the surface. + // 3. a geometry node (eg. "geometry/teapot"), which define the surface. // // // While the amount of reflectivity of the surface is controlled by the "specular" property on the @@ -92,9 +92,9 @@ nodes: [ // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type: "prims/sphere" + type: "geometry/sphere" } ] } @@ -117,9 +117,9 @@ nodes: [ // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type: "prims/sphere" + type: "geometry/sphere" } ] } @@ -142,9 +142,9 @@ nodes: [ // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type: "prims/sphere" + type: "geometry/sphere" } ] } diff --git a/demos/reflection-transparent.html b/examples/reflections_withTransparency.html similarity index 96% rename from demos/reflection-transparent.html rename to examples/reflections_withTransparency.html index ec0353da..bc734dc3 100644 --- a/demos/reflection-transparent.html +++ b/examples/reflections_withTransparency.html @@ -78,9 +78,9 @@ nodes: [ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -127,7 +127,7 @@ { type: "material", color: { r: 0.2, g: 1.0, b: 0.2 }, - alpha: 0.5, + alpha: 0.4, specular: 0.5, nodes: [ @@ -140,9 +140,9 @@ nodes: [ // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type: "prims/teapot" + type: "geometry/sphere" } ] } diff --git a/demos/culling-enable.html b/examples/scenegraph_enable.html similarity index 96% rename from demos/culling-enable.html rename to examples/scenegraph_enable.html index 23f37d21..6c7a28ee 100644 --- a/demos/culling-enable.html +++ b/examples/scenegraph_enable.html @@ -67,9 +67,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/scene-events-misc.html b/examples/scenegraph_events_misc.html similarity index 89% rename from demos/scene-events-misc.html rename to examples/scenegraph_events_misc.html index 54da2309..3f48917e 100644 --- a/demos/scene-events-misc.html +++ b/examples/scenegraph_events_misc.html @@ -19,15 +19,21 @@ diff --git a/demos/scene-events-status2.html b/examples/scenegraph_events_status2.html similarity index 93% rename from demos/scene-events-status2.html rename to examples/scenegraph_events_status2.html index 580c63cf..a231db5c 100644 --- a/demos/scene-events-status2.html +++ b/examples/scenegraph_events_status2.html @@ -34,8 +34,8 @@ type:"cameras/orbit", yaw:-100, pitch:-10, - zoom:10, - zoomSensitivity:10.0, + zoom:6, + zoomSensitivity:1.0, nodes:[ { @@ -54,9 +54,9 @@ nodes:[ // Planet Earth, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/objects/space/planets/earth.js + // http://scenejs.org/api/latest/plugins/node/models/space/planets/earth.js { - type:"objects/space/planets/earth" + type:"models/space/planets/earth" } ] } diff --git a/demos/geometry-text.html b/examples/scenegraph_firstExample.html similarity index 53% rename from demos/geometry-text.html rename to examples/scenegraph_firstExample.html index 448edcb7..488a2f47 100644 --- a/demos/geometry-text.html +++ b/examples/scenegraph_firstExample.html @@ -26,40 +26,32 @@ pluginPath:"../api/latest/plugins" }); - // Create scene - SceneJS.createScene({ + // Define scene + var scene = SceneJS.createScene({ nodes:[ - - // Mouse-orbited camera, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/cameras/orbit.js { - type:"cameras/orbit", - yaw:30, - pitch:-30, - zoom:20, - zoomSensitivity:1.0, + type:"lookAt", + eye:{ y:5, z:7 }, + look:{ x:0, y:1, z:0 }, nodes:[ - - // Override default material to make text glow blue { type:"material", - color:{ r:0.5, g:0.5, b:1.0 }, - emit:1, - nodes:[ + color:{ r:0.3, g:0.3, b:1.0 }, + nodes:[ { - type:"translate", - x:-10, + type:"rotate", + id:"myRotate", + y:1.0, + angle:0, + nodes:[ - // A line of vector text + // Teapot primitive, implemented by plugin at + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"geometry", - source:{ - type:"vectorText", - text:"One line of vector text, please." - } + type:"geometry/teapot" } ] } @@ -70,6 +62,18 @@ ] }); + // On each frame, spin the teapot a little bit + + scene.getNode("myRotate", function (myRotate) { + + var angle = 0; + + scene.on("tick", + function () { + myRotate.setAngle(angle += 0.5); + }); + }); + \ No newline at end of file diff --git a/demos/flags.html b/examples/scenegraph_flags.html similarity index 96% rename from demos/flags.html rename to examples/scenegraph_flags.html index b334567e..f5a8b3d1 100644 --- a/demos/flags.html +++ b/examples/scenegraph_flags.html @@ -69,9 +69,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/flags-ambient.html b/examples/scenegraph_flags_ambient.html similarity index 97% rename from demos/flags-ambient.html rename to examples/scenegraph_flags_ambient.html index b69b6d19..72d72d35 100644 --- a/demos/flags-ambient.html +++ b/examples/scenegraph_flags_ambient.html @@ -114,9 +114,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/flags-backfaceLighting.html b/examples/scenegraph_flags_backfaceLighting.html similarity index 96% rename from demos/flags-backfaceLighting.html rename to examples/scenegraph_flags_backfaceLighting.html index 1ff94c76..87921598 100644 --- a/demos/flags-backfaceLighting.html +++ b/examples/scenegraph_flags_backfaceLighting.html @@ -69,9 +69,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/flags-backfaceTexturing.html b/examples/scenegraph_flags_backfaceTexturing.html similarity index 96% rename from demos/flags-backfaceTexturing.html rename to examples/scenegraph_flags_backfaceTexturing.html index 2c87e1d7..d7df5194 100644 --- a/demos/flags-backfaceTexturing.html +++ b/examples/scenegraph_flags_backfaceTexturing.html @@ -80,9 +80,9 @@ nodes:[ // Plane primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/plane.js + // http://scenejs.org/api/latest/plugins/node/geometry/plane.js { - type:"prims/plane" + type:"geometry/plane" } ] } diff --git a/demos/flags-backfaces.html b/examples/scenegraph_flags_backfaces.html similarity index 96% rename from demos/flags-backfaces.html rename to examples/scenegraph_flags_backfaces.html index ef1263f0..d1114deb 100644 --- a/demos/flags-backfaces.html +++ b/examples/scenegraph_flags_backfaces.html @@ -66,9 +66,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/flags-diffuse.html b/examples/scenegraph_flags_diffuse.html similarity index 97% rename from demos/flags-diffuse.html rename to examples/scenegraph_flags_diffuse.html index 13e4b35f..92b12d3f 100644 --- a/demos/flags-diffuse.html +++ b/examples/scenegraph_flags_diffuse.html @@ -111,9 +111,9 @@ ], nodes:[ - // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/flags-enabled.html b/examples/scenegraph_flags_enabled.html similarity index 96% rename from demos/flags-enabled.html rename to examples/scenegraph_flags_enabled.html index 3c84c496..90523ba0 100644 --- a/demos/flags-enabled.html +++ b/examples/scenegraph_flags_enabled.html @@ -66,9 +66,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/flags-frontface.html b/examples/scenegraph_flags_frontface.html similarity index 96% rename from demos/flags-frontface.html rename to examples/scenegraph_flags_frontface.html index 943ea626..41cc3328 100644 --- a/demos/flags-frontface.html +++ b/examples/scenegraph_flags_frontface.html @@ -66,9 +66,9 @@ nodes:[ - // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/flags-picking.html b/examples/scenegraph_flags_picking.html similarity index 97% rename from demos/flags-picking.html rename to examples/scenegraph_flags_picking.html index 225d0647..41dffbba 100644 --- a/demos/flags-picking.html +++ b/examples/scenegraph_flags_picking.html @@ -66,9 +66,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/flags-reflection.html b/examples/scenegraph_flags_reflection.html similarity index 97% rename from demos/flags-reflection.html rename to examples/scenegraph_flags_reflection.html index a031e9ab..5c3720b3 100644 --- a/demos/flags-reflection.html +++ b/examples/scenegraph_flags_reflection.html @@ -94,9 +94,9 @@ nodes: [ // Teapot primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } diff --git a/demos/flags-specular.html b/examples/scenegraph_flags_specular.html similarity index 97% rename from demos/flags-specular.html rename to examples/scenegraph_flags_specular.html index 3dbc549e..9d8b35a7 100644 --- a/demos/flags-specular.html +++ b/examples/scenegraph_flags_specular.html @@ -112,9 +112,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } diff --git a/demos/flags-transparent.html b/examples/scenegraph_flags_transparent.html similarity index 94% rename from demos/flags-transparent.html rename to examples/scenegraph_flags_transparent.html index 3bb8c459..a4aecf40 100644 --- a/demos/flags-transparent.html +++ b/examples/scenegraph_flags_transparent.html @@ -74,9 +74,9 @@ nodes:[ - // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -98,9 +98,9 @@ y:0.4, z:0.4, nodes:[ - // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type:"geometry/sphere" } ] } diff --git a/demos/scenes-multiple.html b/examples/scenegraph_multipleScenes.html similarity index 84% rename from demos/scenes-multiple.html rename to examples/scenegraph_multipleScenes.html index 659da7b4..aa4965e1 100644 --- a/demos/scenes-multiple.html +++ b/examples/scenegraph_multipleScenes.html @@ -69,10 +69,10 @@ // A different primitive type for each scene { type:[ - "prims/torus", // http://scenejs.org/api/latest/plugins/node/prims/torus.js - "prims/teapot", // http://scenejs.org/api/latest/plugins/node/prims/teapot.js - "prims/box", // http://scenejs.org/api/latest/plugins/node/prims/box.js - "prims/sphere" // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + "geometry/torus", // http://scenejs.org/api/latest/plugins/node/geometry/torus.js + "geometry/teapot", // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js + "geometry/box", // http://scenejs.org/api/latest/plugins/node/geometry/box.js + "geometry/sphere" // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js ][i % 4] } ] diff --git a/demos/nodes-adding.html b/examples/scenegraph_nodes_adding.html similarity index 51% rename from demos/nodes-adding.html rename to examples/scenegraph_nodes_adding.html index 81a4d6f8..38cbef85 100644 --- a/demos/nodes-adding.html +++ b/examples/scenegraph_nodes_adding.html @@ -25,7 +25,7 @@ // Point SceneJS to the bundled plugins SceneJS.setConfigs({ - pluginPath:"../api/latest/plugins" + pluginPath: "../api/latest/plugins" }); // Create scene @@ -34,54 +34,60 @@ // Add mouse-orbited camera, implemented by plugin at // http://scenejs.org/api/latest/plugins/node/cameras/orbit.js scene.addNode({ - type:"cameras/orbit", - yaw:30, - pitch:-30, - zoom:5, - zoomSensitivity:10.0 - }, - - // The 'cameras/orbit' node is instantiated from an asynchronously-loaded plugin, - // so we need to get the node instance via callback. + type: "cameras/orbit", + yaw: 30, + pitch: -30, + zoom: 7, + zoomSensitivity: 1.0, + + nodes: [ + + // We can't use #addNode to add nodes to a "cameras/orbit" node, + // so we'll insert this container node that we can get by ID + { + id: "content" + } + ] + }); - function (cameraOrbit) { + scene.getNode("content", + function (content) { // Create blue torus - var material = cameraOrbit.addNode({ - type:"material", - color:{ r:0.2, g:0.2, b:0.6 } + var material = content.addNode({ + type: "material", + color: { r: 0.2, g: 0.2, b: 0.6 } }); var translate = material.addNode({ - type:"translate", - x:-4 + type: "translate", + x: -2 }); + // Torus primitive, implemented by plugin at + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js var geometry = translate.addNode({ - type:"geometry", - source:{ - type:"torus" - } + type: "geometry/torus" }); // Create red torus - var material2 = scene.addNode({ - type:"material", - color:{ r:0.6, g:0.2, b:0.2 } + var material2 = content.addNode({ + type: "material", + color: { r: 0.6, g: 0.2, b: 0.2 } }); // This time we'll add a subgraph of nodes + material2.addNode({ + type: "translate", + x: 2, + nodes: [ - material.addNode({ - type:"translate", - x:4, - nodes:[ - // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // Torus primitive, implemented by plugin at + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type: "geometry/torus" } ] }); diff --git a/demos/node-events-rendered.html b/examples/scenegraph_nodes_events_rendered.html similarity index 95% rename from demos/node-events-rendered.html rename to examples/scenegraph_nodes_events_rendered.html index f0a9d420..77bf6fb1 100644 --- a/demos/node-events-rendered.html +++ b/examples/scenegraph_nodes_events_rendered.html @@ -106,7 +106,7 @@ // Point SceneJS to the bundled plugins SceneJS.setConfigs({ - pluginPath:"../../../api/latest/plugins" + pluginPath:"../api/latest/plugins" }); var scene = SceneJS.createScene({ @@ -132,9 +132,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -151,9 +151,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -170,9 +170,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/examples/scenegraph_nodes_instancing.html b/examples/scenegraph_nodes_instancing.html new file mode 100644 index 00000000..3a57b7aa --- /dev/null +++ b/examples/scenegraph_nodes_instancing.html @@ -0,0 +1,183 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/nodes-moving.html b/examples/scenegraph_nodes_moving.html similarity index 94% rename from demos/nodes-moving.html rename to examples/scenegraph_nodes_moving.html index 913f47cb..b5ea76da 100644 --- a/demos/nodes-moving.html +++ b/examples/scenegraph_nodes_moving.html @@ -60,9 +60,9 @@ }); // Torus primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js translate.addNode({ - type: "prims/torus", + type: "geometry/torus", id: "myTorus" }); @@ -83,9 +83,9 @@ }); // Sphere primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js translate2.addNode({ - type: "prims/sphere", + type: "geometry/sphere", id: "mySphere" }); diff --git a/demos/culling-regex.html b/examples/scenegraph_tags.html similarity index 93% rename from demos/culling-regex.html rename to examples/scenegraph_tags.html index 8885066e..87032d18 100644 --- a/demos/culling-regex.html +++ b/examples/scenegraph_tags.html @@ -64,9 +64,9 @@ nodes:[ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -91,9 +91,9 @@ nodes:[ // Sphere geometry node implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type:"geometry/sphere" } ] } @@ -123,9 +123,9 @@ nodes:[ // Node type implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -152,9 +152,9 @@ nodes:[ // Node type implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } diff --git a/examples/scenegraph_webglContextRecovery.html b/examples/scenegraph_webglContextRecovery.html new file mode 100644 index 00000000..5f5e22d6 --- /dev/null +++ b/examples/scenegraph_webglContextRecovery.html @@ -0,0 +1,425 @@ + + + + SceneJS V3 Lost WebGL Context Recovery + + + + + + +
+
+ + + + + + \ No newline at end of file diff --git a/examples/setups_lawn.html b/examples/setups_lawn.html new file mode 100644 index 00000000..2c6bb2c8 --- /dev/null +++ b/examples/setups_lawn.html @@ -0,0 +1,49 @@ + + + + SceneJS Example + + + + + + + + + + + + + diff --git a/examples/setups_workshop.html b/examples/setups_workshop.html new file mode 100644 index 00000000..e8064af5 --- /dev/null +++ b/examples/setups_workshop.html @@ -0,0 +1,45 @@ + + + + SceneJS Example + + + + + + + + + + + + + diff --git a/examples/shaders_custom_material_color.html b/examples/shaders_custom_material_color.html new file mode 100644 index 00000000..5c739ffe --- /dev/null +++ b/examples/shaders_custom_material_color.html @@ -0,0 +1,87 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/shaders_custom_skybox.html b/examples/shaders_custom_skybox.html new file mode 100644 index 00000000..46edbb65 --- /dev/null +++ b/examples/shaders_custom_skybox.html @@ -0,0 +1,201 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/shaders_custom_water.html b/examples/shaders_custom_water.html new file mode 100644 index 00000000..96d755d7 --- /dev/null +++ b/examples/shaders_custom_water.html @@ -0,0 +1,105 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/shaders_custom_withTexture.html b/examples/shaders_custom_withTexture.html new file mode 100644 index 00000000..8d622f00 --- /dev/null +++ b/examples/shaders_custom_withTexture.html @@ -0,0 +1,83 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/shaders_custom_withThreeTextures.html b/examples/shaders_custom_withThreeTextures.html new file mode 100644 index 00000000..3c103ecd --- /dev/null +++ b/examples/shaders_custom_withThreeTextures.html @@ -0,0 +1,107 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/shaders_custom_withTransforms.html b/examples/shaders_custom_withTransforms.html new file mode 100644 index 00000000..f2b8e42a --- /dev/null +++ b/examples/shaders_custom_withTransforms.html @@ -0,0 +1,89 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/shaders_custom_withTwoTextures.html b/examples/shaders_custom_withTwoTextures.html new file mode 100644 index 00000000..b56111a1 --- /dev/null +++ b/examples/shaders_custom_withTwoTextures.html @@ -0,0 +1,96 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/effects-crt.html b/examples/shaders_scanline.html similarity index 86% rename from demos/effects-crt.html rename to examples/shaders_scanline.html index 77352815..c2850285 100644 --- a/demos/effects-crt.html +++ b/examples/shaders_scanline.html @@ -21,7 +21,7 @@ + + + + + + + + + + + + diff --git a/demos/skyboxes-clouds.html b/examples/skyboxes_clouds.html similarity index 87% rename from demos/skyboxes-clouds.html rename to examples/skyboxes_clouds.html index d544fb3f..e594d153 100644 --- a/demos/skyboxes-clouds.html +++ b/examples/skyboxes_clouds.html @@ -20,7 +20,7 @@ + + + + + + \ No newline at end of file diff --git a/demos/skyboxes-grimmNight.html b/examples/skyboxes_grimmNight.html similarity index 91% rename from demos/skyboxes-grimmNight.html rename to examples/skyboxes_grimmNight.html index 9e7ca7df..b9e58f4f 100644 --- a/demos/skyboxes-grimmNight.html +++ b/examples/skyboxes_grimmNight.html @@ -20,7 +20,7 @@ + + + + + + \ No newline at end of file diff --git a/examples/stages_scanlines.html b/examples/stages_scanlines.html new file mode 100644 index 00000000..e5e840df --- /dev/null +++ b/examples/stages_scanlines.html @@ -0,0 +1,184 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/stages_threeStages.html b/examples/stages_threeStages.html new file mode 100644 index 00000000..1a28f36c --- /dev/null +++ b/examples/stages_threeStages.html @@ -0,0 +1,229 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/stages_twoStages.html b/examples/stages_twoStages.html new file mode 100644 index 00000000..b20da581 --- /dev/null +++ b/examples/stages_twoStages.html @@ -0,0 +1,185 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/stages_withPicking.html b/examples/stages_withPicking.html new file mode 100644 index 00000000..57ee8fc5 --- /dev/null +++ b/examples/stages_withPicking.html @@ -0,0 +1,245 @@ + + + + SceneJS Example + + + + + + + + + + + +
Click on an object to pick it +
+ + + + \ No newline at end of file diff --git a/examples/stages_withReflection.html b/examples/stages_withReflection.html new file mode 100644 index 00000000..8df90f9c --- /dev/null +++ b/examples/stages_withReflection.html @@ -0,0 +1,185 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/stages_withSharedShader.html b/examples/stages_withSharedShader.html new file mode 100644 index 00000000..485be4ad --- /dev/null +++ b/examples/stages_withSharedShader.html @@ -0,0 +1,220 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/stages_withTransparencySort.html b/examples/stages_withTransparencySort.html new file mode 100644 index 00000000..1c072917 --- /dev/null +++ b/examples/stages_withTransparencySort.html @@ -0,0 +1,256 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/nodes-custom-drinkingBird.html b/examples/tests_drinkingBird.html similarity index 85% rename from demos/nodes-custom-drinkingBird.html rename to examples/tests_drinkingBird.html index 1e27a50c..f5ec425c 100644 --- a/demos/nodes-custom-drinkingBird.html +++ b/examples/tests_drinkingBird.html @@ -21,7 +21,7 @@ + + + + + + + \ No newline at end of file diff --git a/demos/textures-alphaMap-multiply.html b/examples/texture_alpha_multiply.html similarity index 93% rename from demos/textures-alphaMap-multiply.html rename to examples/texture_alpha_multiply.html index 4b814aa7..c3021068 100644 --- a/demos/textures-alphaMap-multiply.html +++ b/examples/texture_alpha_multiply.html @@ -1,7 +1,7 @@ - SceneJS V3 Texture Animation + SceneJS Example @@ -69,9 +69,9 @@ ], nodes:[ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -93,9 +93,9 @@ nodes:[ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } diff --git a/demos/textures-colorMap-animated.html b/examples/texture_animation.html similarity index 97% rename from demos/textures-colorMap-animated.html rename to examples/texture_animation.html index e99d2a34..dbd910c7 100644 --- a/demos/textures-colorMap-animated.html +++ b/examples/texture_animation.html @@ -79,9 +79,9 @@ nodes: [ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/textures-bumpMap.html b/examples/texture_bump.html similarity index 91% rename from demos/textures-bumpMap.html rename to examples/texture_bump.html index b92b820e..1dade8b9 100644 --- a/demos/textures-bumpMap.html +++ b/examples/texture_bump.html @@ -66,18 +66,18 @@ type:"texture", layers:[ { - uri:"textures/normal_map.jpg", + uri:"textures/normalMap.png", wrapS:"repeat", wrapT:"repeat", - applyTo:"normals" + applyTo:"normals" // Apply to geometry normal vectors } ], nodes:[ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } diff --git a/demos/textures-colorMap.html b/examples/texture_color.html similarity index 95% rename from demos/textures-colorMap.html rename to examples/texture_color.html index 2c1c8353..9210610f 100644 --- a/demos/textures-colorMap.html +++ b/examples/texture_color.html @@ -48,9 +48,9 @@ nodes: [ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/textures-colorMap-add.html b/examples/texture_color_add.html similarity index 95% rename from demos/textures-colorMap-add.html rename to examples/texture_color_add.html index dbbe661d..df9a3da5 100644 --- a/demos/textures-colorMap-add.html +++ b/examples/texture_color_add.html @@ -56,9 +56,9 @@ nodes: [ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/textures-colorMap-multiply.html b/examples/texture_color_multiply.html similarity index 93% rename from demos/textures-colorMap-multiply.html rename to examples/texture_color_multiply.html index 6f59927a..b49c8d21 100644 --- a/demos/textures-colorMap-multiply.html +++ b/examples/texture_color_multiply.html @@ -54,9 +54,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/textures-glowMap.html b/examples/texture_emit.html similarity index 97% rename from demos/textures-glowMap.html rename to examples/texture_emit.html index c8c6ac5d..7518d062 100644 --- a/demos/textures-glowMap.html +++ b/examples/texture_emit.html @@ -71,9 +71,9 @@ ], nodes: [ - // Torus primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/torus.js + // Torus primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type: "prims/torus", + type: "geometry/torus", radius: 1.0, tube: 0.30, segmentsR: 60, diff --git a/demos/textures-glowMap-add.html b/examples/texture_emit_add.html similarity index 98% rename from demos/textures-glowMap-add.html rename to examples/texture_emit_add.html index 229c27c0..6d04fd2a 100644 --- a/demos/textures-glowMap-add.html +++ b/examples/texture_emit_add.html @@ -86,9 +86,9 @@ nodes:[ // Torus primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus", + type:"geometry/torus", radius:1.0, tube:0.30, segmentsR:60, diff --git a/demos/textures-glowMap-multiply.html b/examples/texture_emit_multiply.html similarity index 98% rename from demos/textures-glowMap-multiply.html rename to examples/texture_emit_multiply.html index 84d8b4c2..1399322e 100644 --- a/demos/textures-glowMap-multiply.html +++ b/examples/texture_emit_multiply.html @@ -85,9 +85,9 @@ nodes:[ // Torus primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus", + type:"geometry/torus", radius:1.0, tube:0.30, segmentsR:60, diff --git a/examples/texture_legacy_color.html b/examples/texture_legacy_color.html new file mode 100644 index 00000000..f243daae --- /dev/null +++ b/examples/texture_legacy_color.html @@ -0,0 +1,68 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_lib_oil.html b/examples/texture_lib_oil.html new file mode 100644 index 00000000..7c61a5ec --- /dev/null +++ b/examples/texture_lib_oil.html @@ -0,0 +1,63 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_lib_slime.html b/examples/texture_lib_slime.html new file mode 100644 index 00000000..00feb4bf --- /dev/null +++ b/examples/texture_lib_slime.html @@ -0,0 +1,63 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_lib_tunnel.html b/examples/texture_lib_tunnel.html new file mode 100644 index 00000000..2358b2fc --- /dev/null +++ b/examples/texture_lib_tunnel.html @@ -0,0 +1,63 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_lib_water.html b/examples/texture_lib_water.html new file mode 100644 index 00000000..8d71b1e4 --- /dev/null +++ b/examples/texture_lib_water.html @@ -0,0 +1,63 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/demos/textures-multitexture.html b/examples/texture_multiTexture.html similarity index 72% rename from demos/textures-multitexture.html rename to examples/texture_multiTexture.html index 0b29f902..56ffd10f 100644 --- a/demos/textures-multitexture.html +++ b/examples/texture_multiTexture.html @@ -20,49 +20,50 @@ // Point SceneJS to the bundled plugins SceneJS.setConfigs({ - pluginPath:"../api/latest/plugins" + pluginPath: "../api/latest/plugins" }); // Create scene var scene = SceneJS.createScene({ - nodes:[ + nodes: [ // Orbiting camera node, implemented by plugin at // http://scenejs.org/api/latest/plugins/node/cameras/orbit.js { - type:"cameras/orbit", - yaw:30, - pitch:-30, - zoom:10, - zoomSensitivity:1.0, + type: "cameras/orbit", + yaw: 30, + pitch: -30, + zoom: 7, + zoomSensitivity: 1.0, - nodes:[ + nodes: [ // Custom lighting to simulate the Sun { - type:"lights", - lights:[ + type: "lights", + lights: [ { - mode:"dir", - color:{ r:1.0, g:1.0, b:1.0 }, - diffuse:true, - specular:true, - dir:{ x:-0.5, y:-0.5, z:-0.75 } + mode: "dir", + color: { r: 1.0, g: 1.0, b: 1.0 }, + diffuse: true, + specular: true, + dir: { x: -0.5, y: -0.5, z: -0.75 } } ], - nodes:[ + nodes: [ { - type:"rotate", - z:1, - angle:195, - nodes:[ + type: "rotate", + z: 1, + angle: 195, + + nodes: [ { - type:"rotate", - y:1, - id:"earth-rotate", + type: "rotate", + y: 1, + id: "earth-rotate", - nodes:[ + nodes: [ // Layer 0: Earth's surface with color, specular // and emissive maps @@ -70,53 +71,62 @@ // The priority on this layer ensure that it's rendered before the // clouds in the second layer { - type:"layer", - priority:0, + type: "layer", + priority: 0, enabled: true, - nodes:[ + nodes: [ { - type:"scale", - x:2, - y:2, - z:2, + type: "scale", + x: 2, + y: 2, + z: 2, - nodes:[ + nodes: [ { - type:"material", - emit:1, - color:{ r:1.0, g:1.0, b:1.0 }, - specularColor:{ r:0.5, g:0.5, b:0.5 }, - specular:5.0, - shine:70.0, + type: "material", + emit: 1, + color: { r: 1.0, g: 1.0, b: 1.0 }, + specularColor: { r: 0.5, g: 0.5, b: 0.5 }, + specular: 5.0, + shine: 70.0, - nodes:[ + nodes: [ - // Multitexture containing color, specular and emission maps + // Color map { - type:"texture", - layers:[ - { - src:"textures/earth.jpg", - applyTo:"color" // Apply to material "color" property (default) - }, - { - src:"textures/earth-specular.png", - applyTo:"specular" // Apply to material "specular" property - } , - { - src:"textures/earth-lights.gif", - applyTo:"emit" // Apply to material "emit" property - } - ], - nodes:[ + type: "textureMap", + src: "textures/earth.jpg", + applyTo: "color", - // Sphere geometry node implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + nodes: [ + + // Specular map for shiny oceans { - type:"prims/sphere", - latitudeBands:120, - longitudeBands:120 + type: "textureMap", + src: "textures/earth-specular.png", + applyTo: "specular", + + nodes: [ + + // Glow map for lights on night side + { + type: "textureMap", + src: "textures/earth-lights.gif", + applyTo: "emit", + + nodes: [ + + // Sphere geometry node implemented by plugin at + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js + { + type: "geometry/sphere", + latitudeBands: 120, + longitudeBands: 120 + } + ] + } + ] } ] } @@ -131,63 +141,59 @@ // The priority on this this layer ensures that it's rendered after the // Earth surface in the previously-defined layer { - type:"layer", - priority:1, + type: "layer", + priority: 1, - nodes:[ + nodes: [ // Flags to enable cloud transparency { - type:"flags", - flags:{ - transparent:true, - specular:true + type: "flags", + flags: { + transparent: true, + specular: true }, - nodes:[ + nodes: [ // Material with alpha channel { - type:"material", - emit:0.1, - alpha:0.7, - color:{ r:1, g:1, b:1 }, - specularColor:{ r:1.0, g:1.0, b:1.0 }, - specular:0.5, - shine:1.0, - nodes:[ + type: "material", + emit: 0.1, + alpha: 0.7, + color: { r: 1, g: 1, b: 1 }, + specularColor: { r: 1.0, g: 1.0, b: 1.0 }, + specular: 0.5, + shine: 1.0, + nodes: [ { - type:"scale", - x:2.05, - y:2.05, - z:2.05, + type: "scale", + x: 2.05, + y: 2.05, + z: 2.05, - nodes:[ + nodes: [ // Alpha map for clouds { - type:"texture", - layers:[ - { - src:"textures/earthclouds.jpg", - applyTo:"alpha", // Apply to material "alpha" property - flipY:false - } - ], + type: "textureMap", + src: "textures/earthclouds.jpg", + applyTo: "alpha", // Apply to material "alpha" property + flipY: false, - nodes:[ + nodes: [ { - type:"rotate", - y:1, - id:"clouds-rotate", - nodes:[ + type: "rotate", + y: 1, + id: "clouds-rotate", + nodes: [ // Sphere geometry node implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere", - latitudeBands:120, - longitudeBands:120 + type: "geometry/sphere", + latitudeBands: 120, + longitudeBands: 120 } ] diff --git a/examples/texture_procedural.html b/examples/texture_procedural.html new file mode 100644 index 00000000..35b88ed6 --- /dev/null +++ b/examples/texture_procedural.html @@ -0,0 +1,82 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_procedural_alpha.html b/examples/texture_procedural_alpha.html new file mode 100644 index 00000000..470a238f --- /dev/null +++ b/examples/texture_procedural_alpha.html @@ -0,0 +1,130 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_procedural_color.html b/examples/texture_procedural_color.html new file mode 100644 index 00000000..1977842d --- /dev/null +++ b/examples/texture_procedural_color.html @@ -0,0 +1,93 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_procedural_color_mold.html b/examples/texture_procedural_color_mold.html new file mode 100644 index 00000000..2d4fe44e --- /dev/null +++ b/examples/texture_procedural_color_mold.html @@ -0,0 +1,93 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_procedural_color_water.html b/examples/texture_procedural_color_water.html new file mode 100644 index 00000000..8b47f689 --- /dev/null +++ b/examples/texture_procedural_color_water.html @@ -0,0 +1,83 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_procedural_emit.html b/examples/texture_procedural_emit.html new file mode 100644 index 00000000..a5255087 --- /dev/null +++ b/examples/texture_procedural_emit.html @@ -0,0 +1,116 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_procedural_specular.html b/examples/texture_procedural_specular.html new file mode 100644 index 00000000..69370450 --- /dev/null +++ b/examples/texture_procedural_specular.html @@ -0,0 +1,118 @@ + + + + SceneJS Example + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_rtt.html b/examples/texture_rtt.html new file mode 100644 index 00000000..16675e55 --- /dev/null +++ b/examples/texture_rtt.html @@ -0,0 +1,168 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_rtt_color.html b/examples/texture_rtt_color.html new file mode 100644 index 00000000..d6aaebe2 --- /dev/null +++ b/examples/texture_rtt_color.html @@ -0,0 +1,167 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_rtt_depth.html b/examples/texture_rtt_depth.html new file mode 100644 index 00000000..1c4d45df --- /dev/null +++ b/examples/texture_rtt_depth.html @@ -0,0 +1,169 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_rtt_depthAndColor.html b/examples/texture_rtt_depthAndColor.html new file mode 100644 index 00000000..35d6e40a --- /dev/null +++ b/examples/texture_rtt_depthAndColor.html @@ -0,0 +1,232 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/texture_rtt_depthAndColor2.html b/examples/texture_rtt_depthAndColor2.html new file mode 100644 index 00000000..fb12ef22 --- /dev/null +++ b/examples/texture_rtt_depthAndColor2.html @@ -0,0 +1,242 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/textures-rtt-heightmap.html b/examples/texture_rtt_heightmap.html similarity index 70% rename from demos/textures-rtt-heightmap.html rename to examples/texture_rtt_heightmap.html index 040de841..07886dde 100644 --- a/demos/textures-rtt-heightmap.html +++ b/examples/texture_rtt_heightmap.html @@ -20,6 +20,16 @@ + + + + + + \ No newline at end of file diff --git a/demos/textures-rtt-shared-texture.html b/examples/texture_rtt_sharedTexture.html similarity index 84% rename from demos/textures-rtt-shared-texture.html rename to examples/texture_rtt_sharedTexture.html index 2fe4e676..874598e6 100644 --- a/demos/textures-rtt-shared-texture.html +++ b/examples/texture_rtt_sharedTexture.html @@ -29,35 +29,27 @@ nodes: [ //------------------------------------------------------------------------------------------- - // First subgraph renders our rotating teapot, with skybox, to a texture. - // - // The subgraph is wrapped in an framebuf node, which captures each frame the subgraph - // renders and makes it available by ID as an image source for the texture node defined in the - // second subgraph, defined further down in this example. - // - // We're also wrapping it in a "layer" node with a low rendering priority to ensure that - // it renders first, so that the framebuf is ready for the textures that need it. - // - // The framebuf captures the frames to a hidden frame buffer, so they will not render by - // themselves and will only be visible via the texture. + // First pass renders our rotating teapot, with skybox, to a texture. + //------------------------------------------------------------------------------------------ { type: "layer", - priority: 0, + priority: 1, + nodes: [ { - type: "framebuf", - id: "myFrameBuf", + type: "colorTarget", + id: "myColorTarget", nodes: [ - // Cloudy sea skybox, implemented by plugin at http://scenejs.org/api/latest/plugins/node/skyboxes/cloudySea.js + // Cloudy sea skybox, implemented by plugin at http://scenejs.org/api/latest/plugins/node/skybox/cloudySea.js // Skybox, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/skyboxes/grimmNight.js + // http://scenejs.org/api/latest/plugins/node/skybox/grimmNight.js { - type: "skyboxes/cloudySea", + type: "skybox/cloudySea", size: 5000 // Box half-size on each axis - default is 5000 }, { @@ -87,9 +79,9 @@ nodes: [ // Node type implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } @@ -100,19 +92,16 @@ ] } ] - }, //------------------------------------------------------------------------------------------- // The second subgraph renders four geometry primitives, all wrapped with a shared texture - // that is dynamically sourced from the framebuf defined in the subgraph above. - // - // We also wrap the whole subgraph in a "layer" node that has a lower priority than the - // "layer" wrapped around the framebuf's subgraph. + // that is dynamically sourced from the colorTarget defined in the subgraph above. //------------------------------------------------------------------------------------------*/ + { type: "layer", - priority: 1, + priority: 2, nodes: [ @@ -127,11 +116,11 @@ nodes: [ - // Color map texture, sourcing from the framebuf created earlier, + // Color map texture, sourcing from the colorTarget created earlier, // applying to the four geometry primitives in its subgraph { type: "textureMap", - framebuf: "myFrameBuf", + target: "myColorTarget", nodes: [ @@ -153,9 +142,9 @@ nodes: [ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -187,9 +176,9 @@ nodes: [ // Sphere primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type: "prims/sphere" + type: "geometry/sphere" } ] } @@ -222,9 +211,9 @@ nodes: [ // Torus primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type: "prims/torus" + type: "geometry/torus" } ] } @@ -251,9 +240,9 @@ nodes: [ // Cylinder primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/cylinder.js + // http://scenejs.org/api/latest/plugins/node/geometry/cylinder.js { - type: "prims/cylinder" + type: "geometry/cylinder" } ] } diff --git a/examples/texture_rtt_withVideo.html b/examples/texture_rtt_withVideo.html new file mode 100644 index 00000000..b0a70651 --- /dev/null +++ b/examples/texture_rtt_withVideo.html @@ -0,0 +1,176 @@ + + + + SceneJS Example + + + + + + + + + + + + \ No newline at end of file diff --git a/demos/textures-specularMap.html b/examples/texture_specular.html similarity index 96% rename from demos/textures-specularMap.html rename to examples/texture_specular.html index 0d47717b..2e1529f5 100644 --- a/demos/textures-specularMap.html +++ b/examples/texture_specular.html @@ -82,9 +82,9 @@ nodes: [ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type: "prims/torus" + type: "geometry/torus" } ] } diff --git a/demos/textures-specularMap-add.html b/examples/texture_specular_add.html similarity index 96% rename from demos/textures-specularMap-add.html rename to examples/texture_specular_add.html index 6e1968e5..51676209 100644 --- a/demos/textures-specularMap-add.html +++ b/examples/texture_specular_add.html @@ -83,9 +83,9 @@ nodes:[ // Torus primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } diff --git a/demos/textures-specularMap-multiply.html b/examples/texture_specular_multiply.html similarity index 96% rename from demos/textures-specularMap-multiply.html rename to examples/texture_specular_multiply.html index 87505b4c..11904bed 100644 --- a/demos/textures-specularMap-multiply.html +++ b/examples/texture_specular_multiply.html @@ -84,9 +84,9 @@ nodes:[ // Torus primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } diff --git a/examples/texture_uvLayers.html b/examples/texture_uvLayers.html new file mode 100644 index 00000000..6210cd51 --- /dev/null +++ b/examples/texture_uvLayers.html @@ -0,0 +1,115 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/demos/textures-video-alphaMap.html b/examples/texture_video_alpha.html similarity index 91% rename from demos/textures-video-alphaMap.html rename to examples/texture_video_alpha.html index 7b493822..73c32a5b 100644 --- a/demos/textures-video-alphaMap.html +++ b/examples/texture_video_alpha.html @@ -55,18 +55,18 @@ nodes: [ // Video texture, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/textures/video.js + // http://scenejs.org/api/latest/plugins/node/texture/video.js { - type: "textures/video", + type: "texture/video", src: "movies/testVideo.ogv", applyTo: "alpha", nodes: [ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -88,9 +88,9 @@ nodes: [ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/textures-video-bumpMap.html b/examples/texture_video_bump.html similarity index 92% rename from demos/textures-video-bumpMap.html rename to examples/texture_video_bump.html index 182f9a0e..a119c325 100644 --- a/demos/textures-video-bumpMap.html +++ b/examples/texture_video_bump.html @@ -63,9 +63,9 @@ nodes: [ // Video texture, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/textures/video.js + // http://scenejs.org/api/latest/plugins/node/texture/video.js { - type: "textures/video", + type: "texture/video", src: "movies/bumpMap.ogg", wrapS: "repeat", wrapT: "repeat", @@ -73,9 +73,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/textures-video-colorMap.html b/examples/texture_video_color.html similarity index 91% rename from demos/textures-video-colorMap.html rename to examples/texture_video_color.html index 2a7cd2a8..7662c210 100644 --- a/demos/textures-video-colorMap.html +++ b/examples/texture_video_color.html @@ -39,17 +39,17 @@ nodes: [ // Video texture, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/textures/video.js + // http://scenejs.org/api/latest/plugins/node/texture/video.js { - type: "textures/video", + type: "texture/video", src: "movies/bunny.ogg", nodes: [ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/textures-video-glowMap.html b/examples/texture_video_emit.html similarity index 93% rename from demos/textures-video-glowMap.html rename to examples/texture_video_emit.html index 94571ce1..3310b729 100644 --- a/demos/textures-video-glowMap.html +++ b/examples/texture_video_emit.html @@ -60,17 +60,17 @@ nodes: [ // Video texture, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/textures/video.js + // http://scenejs.org/api/latest/plugins/node/texture/video.js { - type: "textures/video", + type: "texture/video", src: "movies/testVideo.ogv", applyTo: "emit", nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/textures-video-specularMap.html b/examples/texture_video_specular.html similarity index 94% rename from demos/textures-video-specularMap.html rename to examples/texture_video_specular.html index 8fb1a7b6..0d4acae4 100644 --- a/demos/textures-video-specularMap.html +++ b/examples/texture_video_specular.html @@ -76,17 +76,17 @@ nodes: [ // Video texture, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/textures/video.js + // http://scenejs.org/api/latest/plugins/node/texture/video.js { - type: "textures/video", + type: "texture/video", src: "movies/testVideo.ogv", applyTo: "specular", nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } diff --git a/demos/textures/BrickWall.jpg b/examples/textures/BrickWall.jpg similarity index 100% rename from demos/textures/BrickWall.jpg rename to examples/textures/BrickWall.jpg diff --git a/demos/textures/MediumCloud.png b/examples/textures/MediumCloud.png similarity index 100% rename from demos/textures/MediumCloud.png rename to examples/textures/MediumCloud.png diff --git a/demos/textures/alphaMap.jpg b/examples/textures/alphaMap.jpg similarity index 100% rename from demos/textures/alphaMap.jpg rename to examples/textures/alphaMap.jpg diff --git a/demos/textures/asteroidBump.jpg b/examples/textures/asteroidBump.jpg similarity index 100% rename from demos/textures/asteroidBump.jpg rename to examples/textures/asteroidBump.jpg diff --git a/demos/textures/asteroidColor.jpg b/examples/textures/asteroidColor.jpg similarity index 100% rename from demos/textures/asteroidColor.jpg rename to examples/textures/asteroidColor.jpg diff --git a/demos/textures/asteroidNormal.jpg b/examples/textures/asteroidNormal.jpg similarity index 100% rename from demos/textures/asteroidNormal.jpg rename to examples/textures/asteroidNormal.jpg diff --git a/demos/textures/chainLinkAlphaMap.jpg b/examples/textures/chainLinkAlphaMap.jpg similarity index 100% rename from demos/textures/chainLinkAlphaMap.jpg rename to examples/textures/chainLinkAlphaMap.jpg diff --git a/demos/textures/city/HighRiseGlass.jpg b/examples/textures/city/HighRiseGlass.jpg similarity index 100% rename from demos/textures/city/HighRiseGlass.jpg rename to examples/textures/city/HighRiseGlass.jpg diff --git a/demos/textures/city/HighRiseGlassSpecular.jpg b/examples/textures/city/HighRiseGlassSpecular.jpg similarity index 100% rename from demos/textures/city/HighRiseGlassSpecular.jpg rename to examples/textures/city/HighRiseGlassSpecular.jpg diff --git a/demos/textures/city/highrise-windows.jpg b/examples/textures/city/highrise-windows.jpg similarity index 100% rename from demos/textures/city/highrise-windows.jpg rename to examples/textures/city/highrise-windows.jpg diff --git a/demos/textures/city/pixelcity_windows7.jpg b/examples/textures/city/pixelcity_windows7.jpg similarity index 100% rename from demos/textures/city/pixelcity_windows7.jpg rename to examples/textures/city/pixelcity_windows7.jpg diff --git a/demos/textures/cloud.jpg b/examples/textures/cloud.jpg similarity index 100% rename from demos/textures/cloud.jpg rename to examples/textures/cloud.jpg diff --git a/demos/textures/cloud.png b/examples/textures/cloud.png similarity index 100% rename from demos/textures/cloud.png rename to examples/textures/cloud.png diff --git a/demos/textures/clouds-box.jpg b/examples/textures/clouds-box.jpg similarity index 100% rename from demos/textures/clouds-box.jpg rename to examples/textures/clouds-box.jpg diff --git a/demos/textures/clouds.jpg b/examples/textures/clouds.jpg similarity index 100% rename from demos/textures/clouds.jpg rename to examples/textures/clouds.jpg diff --git a/demos/textures/cloudsBackground.jpg b/examples/textures/cloudsBackground.jpg similarity index 100% rename from demos/textures/cloudsBackground.jpg rename to examples/textures/cloudsBackground.jpg diff --git a/demos/textures/compressed/test-dxt1.crn b/examples/textures/compressed/test-dxt1.crn similarity index 100% rename from demos/textures/compressed/test-dxt1.crn rename to examples/textures/compressed/test-dxt1.crn diff --git a/demos/textures/compressed/test-dxt1.dds b/examples/textures/compressed/test-dxt1.dds similarity index 100% rename from demos/textures/compressed/test-dxt1.dds rename to examples/textures/compressed/test-dxt1.dds diff --git a/demos/textures/compressed/test-dxt5.crn b/examples/textures/compressed/test-dxt5.crn similarity index 100% rename from demos/textures/compressed/test-dxt5.crn rename to examples/textures/compressed/test-dxt5.crn diff --git a/demos/textures/compressed/test-dxt5.dds b/examples/textures/compressed/test-dxt5.dds similarity index 100% rename from demos/textures/compressed/test-dxt5.dds rename to examples/textures/compressed/test-dxt5.dds diff --git a/demos/textures/compressed/test.bmp b/examples/textures/compressed/test.bmp similarity index 100% rename from demos/textures/compressed/test.bmp rename to examples/textures/compressed/test.bmp diff --git a/demos/textures/compressed/test.gif b/examples/textures/compressed/test.gif similarity index 100% rename from demos/textures/compressed/test.gif rename to examples/textures/compressed/test.gif diff --git a/demos/textures/compressed/test.jpg b/examples/textures/compressed/test.jpg similarity index 100% rename from demos/textures/compressed/test.jpg rename to examples/textures/compressed/test.jpg diff --git a/demos/textures/compressed/test.png b/examples/textures/compressed/test.png similarity index 100% rename from demos/textures/compressed/test.png rename to examples/textures/compressed/test.png diff --git a/demos/textures/compressed/test.tga b/examples/textures/compressed/test.tga similarity index 100% rename from demos/textures/compressed/test.tga rename to examples/textures/compressed/test.tga diff --git a/demos/textures/crossGridSpecularMap.jpg b/examples/textures/crossGridSpecularMap.jpg similarity index 100% rename from demos/textures/crossGridSpecularMap.jpg rename to examples/textures/crossGridSpecularMap.jpg diff --git a/demos/textures/earth-lights.gif b/examples/textures/earth-lights.gif similarity index 100% rename from demos/textures/earth-lights.gif rename to examples/textures/earth-lights.gif diff --git a/demos/textures/earth-specular.gif b/examples/textures/earth-specular.gif similarity index 100% rename from demos/textures/earth-specular.gif rename to examples/textures/earth-specular.gif diff --git a/demos/textures/earth-specular.jpg b/examples/textures/earth-specular.jpg similarity index 100% rename from demos/textures/earth-specular.jpg rename to examples/textures/earth-specular.jpg diff --git a/demos/textures/earth-specular.png b/examples/textures/earth-specular.png similarity index 100% rename from demos/textures/earth-specular.png rename to examples/textures/earth-specular.png diff --git a/demos/textures/earth.jpg b/examples/textures/earth.jpg similarity index 100% rename from demos/textures/earth.jpg rename to examples/textures/earth.jpg diff --git a/demos/textures/earthBump.jpg b/examples/textures/earthBump.jpg similarity index 100% rename from demos/textures/earthBump.jpg rename to examples/textures/earthBump.jpg diff --git a/demos/textures/earthclouds.jpg b/examples/textures/earthclouds.jpg similarity index 100% rename from demos/textures/earthclouds.jpg rename to examples/textures/earthclouds.jpg diff --git a/demos/textures/general-zod.jpg b/examples/textures/general-zod.jpg similarity index 100% rename from demos/textures/general-zod.jpg rename to examples/textures/general-zod.jpg diff --git a/demos/textures/grid.jpg b/examples/textures/grid.jpg similarity index 100% rename from demos/textures/grid.jpg rename to examples/textures/grid.jpg diff --git a/demos/textures/heightMap.jpg b/examples/textures/heightMap.jpg similarity index 100% rename from demos/textures/heightMap.jpg rename to examples/textures/heightMap.jpg diff --git a/demos/textures/heightmap.jpg b/examples/textures/heightmap.jpg similarity index 100% rename from demos/textures/heightmap.jpg rename to examples/textures/heightmap.jpg diff --git a/demos/textures/heightmap.png b/examples/textures/heightmap.png similarity index 100% rename from demos/textures/heightmap.png rename to examples/textures/heightmap.png diff --git a/examples/textures/holodeck/bottom.jpg b/examples/textures/holodeck/bottom.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5f7358b93283594cf4625eaa04a56deb161f7d8b GIT binary patch literal 58464 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

m{$P)WDt9t_2gl_ro* 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 literal 0 HcmV?d00001 diff --git a/examples/textures/holodeck/east.jpg b/examples/textures/holodeck/east.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fce7f5afd943d978429656e669c611ab00061383 GIT binary patch literal 142573 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%0DVQ{`&i=;s*)+!G)}p>2 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 p?Pv)F#j2%1(=Bgm-!pSSDd|Jglt1!VvL literal 0 HcmV?d00001 diff --git a/examples/textures/holodeck/north.jpg b/examples/textures/holodeck/north.jpg new file mode 100644 index 0000000000000000000000000000000000000000..5d768d8916425a9a824b643c77307d817fe4454a GIT binary patch literal 142800 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

)}&0yNzDYs2RTa?bb%>H642&2N`|~l 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

WX7b73R*GR9ho{2Q*QRQh?(5Wh;LMDufr0E(fp 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�r!e!kq-6P1FatbT#E-|1Cz+%-Q0+0 zGF6d`pL9iaNP;z!sDV9CU)4TRUn=p{PcQLp4cINk zP(GwmT^I^E9iwqUCBmJvGE`O$u$;msIBpAFFjj$JY59KX(l^(r@;?6nrqxP+!fhX4 zr+qJLNl~#JQEUDDe z6mT{kDHr-tPa8=Lsr@MAVeS;EGUg5dxARj2xmjxNoVhVho281e021ge7Z*rYl4TDj zQd6usFgO>NN>}LaRg|?Yt(uBw*2~PS6s@;gIb1@417!oyX5VAM2kfcL1{|k%09`6i ze!@%EM_zCe>jE>5}MXQ&=h}mNczbcyynpJQoTUktnK9q=U zM3v8g$eEy&C;{R?GEk`U+)qz0Q2=}9&GILj>abV0gs;^kTB>RaZ8eUppPT9yuMIlX zcBgej1cRa!LUbWAxaJr;mF|AE@$JW#qKNk(KzeW1Kz%~dE`+WkQnIf}X`vlU_s}CV z8;NG1vs7`s)~2gxt_o60-8$9XC)gSk--q=7~jOtE8!*s(O~G4zl|W zDW@89GE{}6l&vaBA_yZ<01lHnsL+)fb%LcC%p|Ct#=D zBIv?9+qDx35m?Gl54ErpqMZpoEU+9&oxqA+Ou=cTw&F@wg}9X@$bvTn7$Ac(3=l*S zAdU!d9FCVH#igh<9f;W@yHxaPNd%ul0U^&zJ}hI3^@(L%#cxefR$WZ})f@0PjP4-}UeDJ``*co9&@OMq8y6 z5x63yxc$Fh1)lATDDdVPH>;X6Qc$--Ya&90E2Xxbb-3NeLc^dP6at61PS}7qyFfi| zR8jBthWH|!-;dmz5o@o_wA%ZNakOkf;W6fYC~_H&BT{hQor^M8a)hgh=C@Ke>0#U+ zmnD7lz#pLn$K|~3R~46(s>ma{X7rq}S1{r2N&zZWfGrRQq=TYB(b4eZ#@xNZ+}^{D z)CI9rnuY_mtK}g|pQcih3KHVc;wc2e&}5B7DJBTg=0_~?A1*GgP~IulzZMRRE? z_G+fgln|&XZNi<>Oel#@P$Z5}bF%TviuUQBQoscK23|KpL&55PD8hMCeC`syv4v@~*$t}LH4?B^$G#@^dqR#UvcZi{mw2! z-#Kkq?R^>@x#5?bQrNC(DpKhZOopnWNC^ZCEhx8qirU-lh4}e%#DA$pr5zy z(}$)zEsoA(MnfBBJ5^_e$aEvA8`5IY%7^BPR41k5a2ODM#+atBVRBd;v=s6%v@)%l z&lIXl!D26pfGvu%1qnPaqo!RluxO=@DUsqG0&?D^ip&{?n{))YEmVVWAcT!uR>#~y z*UWGvJ7dzVo^M>tg(JDqNtho_y%Yq&_s+d|DO|f(@jnf!ceYcIK_gf?^w`F}L*Kx? z?Q2#)b?b{y>OGkdp$0Q7m{5&=uoLm)EqOH)LFPVTquVFKWy?l=$L;>>@87?%{{H|P zU(G2NP9MnQle3(*Aghf4NXy#Z`}Y0^WAG|`B6eJT=efaSR#oLn3cIwYKs)B5PMM5J znSrmD1}7S4I9Cy9sQ}18H^2F!xROENxll7BU=F@t4g_CiddhbByJk^w5L+M(gsJvM zvId5I&`CWwH5WH6^|X}~bqhl2>RMATCsi``o(AXQ+&b#;$ ze4FgWamIIwj9H9WdXEjN<55vXK(s9m+}kw^Q*Jnt0Sql55Qy=n3d|Vd?qfVV zB!qz3bqIjlX#gmtQQ_4`U_}l%$JmFMH>#WNBCT7_IHeXT^ASx(%#wzgL4cg8ASqju zpaCEbFL3zoP3FEr9LFMA@w{50RijA^kqP6Er9C=`%B9)W6j{hRHp?7&h&W~oy)4b9yM>%3P4wcl*=A9HV^+q}>#S8|;`wE=J=58Y9W#M-V z%gScl(}(8kN)$ysBSBIW;y$a75CJ6U4x_|L;xnjyYLqk-2jwUv$r|V*SU-N;Wko{- z>f&Vi>+3VLk9ha_Zim>?7LD}V;rn{)#)G9wt}?t7=~GJeYepl62$P~TQLUW?`I(N( zyOw8iU6`@#fXQTTW$e#({gycdCvZU^>#5@I z@{gKW8xL~k!)Uo;8X8N3EV^H5L2FwfYmk)$B&0e-6F*Q8BR0w|b7Pfd*AL+pqgAVV zW9CkyxiPP-!p&W{uW+i=w|VIsmJwQU-_v%vkRyYgNbp05gC7 z&;30(nYl&D`rKP{O~(64QA=Z?cxGkh*3*^mprt{Og#fPP5(3Oh<_CllZmt@{cv}_c zU4_c9i_^&Ey{M5kO@jY zva&WjC3*ys1jdFSnOT1_vvy*i6Hf;V$>tzNYdcyS; zBBvR^F*Pj1c3JG)js+GKZVCxczfYw+vPUncENa?#<9S39Kc-!zjYM+CJk`hFfH-v) zOf^93_opdQPRmqO%XOUNB>Oyj=3CZ0yobYx98)=#<5cC2zX-`%xnf3pcczZ_tvl?nT?#BCi3=W> z!?7$`+_a2Hx8%4gJc39T&UQ-m;7+8g1&k|1XJM&qNb=+Z%PZ(Aml}>BBa8rDq#Fps z*V43sWx5$!boLsPxgYU<=m2%$LZ=Jj2cK*B67E|{4s|BqRiMqWA+xFTI}WkIC8p;` zC=|3LVp~Z$lLOg;K#rrqFaVz;q;RzV06h6Tk{WLkTGZpd9H^!RMsxrqB37jnl^_C1 zGBqG@K`)scon&5)36U+Q@6(a_K>&3f9J zA83-riBJF=I|D?W5t(SgIGYh(?Y1gAP0EEu^0ti(1f>gtmz(1j^R{ zPXyw_WwP>%0;QA%hHaFE>Vnu(>MN^C2`LG0GmkjyvH$>`R6x^-64a}G#*UifM@`+Z z`UBMNJxD2BE$flcg{3YbBzTgg1enx-H8JhWom{B5S5(_>n4a9-T@6EwKFh85oztzH zs)GmFP;*x2+yuTDtBS|E({i767 zqJmlEk@4t=ss`DalmYI2yh4Y{%oT|vjxIxxmPcXJ98+=WWql5!7C7=UJDn>r3mY9P z5(0y$)3Vns9K)D4s})?SR>k7@;zI~|wKn}VBWi>;LWg*TC{AENAxa`9c(0wT@fG_N zVoE$OW1+iOTC6E5sCtf)t@?K>lt@y0#?V_*ni-@5a>8aLa87Y`=Es9@&1LTQQq{86 zMp`dFljz&;3>D-?Sp#({BneR(aR8^ZA0mKKzYA=@`TH!%Bppw8uij@<(D16`T&p#6 zlwIcO#qV+n4D-iU8u8katr;35jx_b5sbH6_SoB1iL%AMS(QSBR<#2Qk1vu(nlM_lx z5YUQsvyFz!)vr3evQq83k;wO_*|jukKxt%*9^pWT{2Ik%rYtw`H7EEsyUhOp#dYd9 z*rCGMtyN5gVf*p%9X@NWjR89S1b)Y<5?xc;8<6P<2Nzk7Q~0d)KkY@uBEA`LfuRyJ=uK-3n&?ivYg2TMyEnSdF>ge-u6R17o0SzSozkn=qztj%DngLU%0MnHFhcvXQkjJr z(}Aq-n_QY+HIS`ygI&WzcC7S{O3%ll*EY8n)Yzc}Z0x;isp@qerYa7%;`Ps4kWE?o?hV?dhzl zue_}kH1zb1y8G@WQ{I#`(p0qsg#w}yKpK)a;7-~wo-13AX2ZCJVJ)Npt6h16n@pgy z*WD!UI5wE)nq0TQRrJ=}X?miy)xS^e6v?fp?-JuGI`>W#s09K6S|k`LI)fn=$=W-R z9qZGKtbb8D3PHTYh;9h!`i}$rADVI=DaPfkjo^7K%r~sP@3fxM{{X>kV1L^7A@iS`E)m!MCr|4h zd>Y%gX%5fEv2lznfCM8!Mg-};jrvJ5>8}at?IGFvK>RSWkbLO|zM7z)hx&Ltht2L~ z=*CZ#xl{5E{+?U#{{ZY)`+fWfPvtio^`rxpUIVD>R`{q<*?qs2!2bYX{@($nn+sy^ zX{YZn{vkts`z2~swzveNyhddxmY_mJl6C-}J~{#Ar73ThmQ*WJiz{H})&Ql@YDR!` zAE$_A9iuq{>xpTsTV`9XEiJa&bYV+c)}WLjDGd^(Ekp#QNh(wUCyPmj)k^)5s@imA zqJ4u_+B>ASO*+{wf!zoRCB1vS1e~XH3STz)#%Ge#!=_t`TjOG-xumXa3rq24MTuEs z7OGYx#uau`tPZdrUADmByiSi8iyD{Uwh0^)t8olGu5ReQS+6+Nu;n+gchaS_z!0Ng#=WLE)kJ zEsTHQ_9EB+0IMz+R7Yh#?;)Q zX;3L6VH#-%jWOCov-ZEo3ns_=)iO1njrpC=$A+yxHo1H?D#D&vWo1aJ)`=zP${$f9 zuLNr#D~c+8MMZt9GM=rg6(EqTx0T#}=2t0hZb^`@Ev%M8)V2OEj3|Oz7j4ZXI+HAt zk48yeEl7zV^z|Yu^(uw~g|UGD0BiV&di>dN)Bgb2{&D5MM?k_Ds9UG-ZvGT0=1r!$ zGiCGcCvzmupJ3p+9?~73{{Z2Qm*Gf1LO)*))pn5V{4IuYm5i&|y3zx#T{R8QuUUdT zj~;FLz0AJjURPyTa*t%odu?^?iu!(gAD535{H5b3*6QUKPL*}lZ;Blsoa}EdbbEIo z5AE&ZwstP6x;29@77Lpf8VZYjz|=OyV=vOUrXMmKLLLZGkt!llpfe;MA^zG}GU)Cy zv0p88R|@4^ZOdk%G*tB!3rS%~ha3zgMIe-sCIKn}Ns-0w!Q9^EUN^j=&4e%Z`=!-v zxbJgEOOZ)sB34%JRD>Z=5&ZAM{7!I=1n;b#Xj%i=u6n~|O`Zms;MtWO`EXNqaf=vFO8TB=xel2|=xzh^GY z3Mg-KZ)=ZL$#JOoil?9GoY64f!x4B;b1lc|t{pe)uF z#f8?=aQ*y(wCVF@d7Vd_F~3e1uDDYarkx~V+weW=cD2_61R2-3pMUA#xUAk8Qv7ui8BBmyY`^D<$vFf=;O)5AhQIc5%GoTnEfr7cLgd-6fjvfkAL}`YP6G+0Jsb@0Z_)mL9lFuo{DtpwOFfRt;N+grT!hG4{+sev{5(1Kz)F7ffB1TgL0j8}!Vsk^5SSIYz&7aGkx}Gsl`du>1LOlOM%0fByi@ zALD)j8_OO%q>;&PYq<4oc{aHIAs#k#4bvr$b_rn0z84y6h~DwhyS z03;|RkaWpx=hr0R;xS#LQkVjqZ?8;}edB54Mb3M2dFzp4j}+T|qNUd9+e0j5Q?58t zmfOsfr#5An5=b9!0GzWspXF0mo%l9e7k?VwrF?`i-*#BGk~DG$p&!bQf@s`0F-U}s zt2pp!$M6(5<~~}LGmm~db3rUn*|&oND?q$WBto`ENgUdRk_lkwWt6Nf(#|?uYI6^k zIFkk9yPb`y3ypmvPM4@^si~?TLzHfkre#ebU@0jXd`3tCTr?@{IEf3&<&N@DxCE-* zRzM`_yIKy1Ndh|VX=@Wkif1d_VKprwj`*pXbkw-EQjnmg(HWeC9Kk3gl!KHKV8d^7 zuanHW<1XSWYcDjlHsemxDGoN`4ppIOQ(;I_NFb#`K^pI&W*^O*<=TrlzqBu7;hw{lu3r|FpmzJmtpnY& zUPBsf%yF@4BafvCA|S+MHHEM3)DkRre(gv(PtEmuY9%sS0!FZQf^?oW6^HM^*AL9s zbd;`SP}KsHn8Y6J6q)Oxm?MIbP0v0~ujtMuwi1ykC4|Wve?z9zrtz-{j`OFK0oMV< zmZ{96{M{yG=tqJ)hm_8TNwiNgIYT>#;F%CYsQuiJ%mM6lasBo+y&vQ5d_J00wO53%tP@++A)Dynv{t}Lglrmdw&X4zj~O!G}wFhEG7 zeb-Qwcj+D!g`XHOBq{@co_wBFBHzYXQjKe(saZE`Z98R3rKoVnv@qHRtvI6#LPvz_ zG7Qb`bDNY3pW`j7VW+bVcGvkmCt^;fBzc#<5Xbl@7#HpK3)LOcrIyt5l*k7$XlWrX z2wY|QpcA1y1<9Dq;qx-`N*r$^h^;P;N{oI>W-s;LH7iP8yg^r~9bO7c>KrQ{VUMM!`X5=@AXhZpyoL4UbcB1uZ8=9+!M0FtJC z4!?h?lg2djW0hsZMk2I*VLywg5#j zPJpzj#UVjiP*#MZas!nktN;Piifp!9H^?(wYI(TcLW)qxKwX->$3l;CqqDQUR0tyo zNjuiNooi2xFERSE*S}#>Us> zWhZLtRg|i-vXuwIUm0@VBIG#?eYq=Hgo2Kx3bK)>jzla{SfpK~u}H3xMoPNtq^WPg z_`e8qe-1eH53^MV+3xPPTC9cER-};NEvi)kMpEDafOU{$(w=knXs*LmzlB&Xo!Xlk zYZ|DnwxJ3x&;a^eacqQ-6G=!XEM03|_WDG@Yf+%DmQhwX&dg3y84=^b%KPLon zWUG;7>c;A`M=V7dvN%bkEa86bO}cDl)O$-X*{UPARp-mD^kCdJ6qSSXYXnLZ4zmUh zl0+W58P;G6p4Vwwxw&yURjn#F27a^+W7lo<^x(r=MZVik)eSyY7^fsM%BSd%R;32h zn_P%0DR25Igo6V?E!y6$nOxeqoahJH+5iwH0V81`f_y?Z9klJxbrb0n}_G5S70T{VkK2>fWSUdcL0vF+ymd-Z+boa zT%JRAYO?amm5b%|4cxI?&7o>_X&ESq0YRoy9t?*-H8L|Sk_Q$?5It1YmhAN!%XKVU zs-9)k#I&}WT9Dw7M5RJR&ZCH4@y^>#+nAP~Tj6@Ps%jTfhi{iQ&SvSUnsEsCK1Td&@2k8!x_bs@*qr5!rh`qrA1bZM1n>b-gD zi!e>y!&xmdHQ6VUYcC_QwBll7fEQw$rN-@lyIk*A2ksTFR#c^RH7m?gggmsR4WxKb zkOs&anL3h5XH-=w$jNno)gdq zq?6aDPlumRyN%UGx7J9_p&96%|x_X(m!VWa-!Tf%oyeqm&39f_i?#j0sXx zwqLvL%JoFfQ6*^CsI<;btHOKl@0@yQI+`3ihBjbB zl*vQ}E+^`S8Bapw9u(Yg5>OnVA-LMz0%$TXRI0T~~!UF@n)h<4jW1QL)_H zC=rz}S5{@pl_-5>6)p>Yad2N_K%J5P_i} z0HdrxfaB)}HST=J#1GXv;@Y;br8jP(L5AtrNhwJQnD16KT8YpY5=xX|r7uI!dY{z? z;W5*Rybp&q7AMQ)kHly4DrB)EpH-?Pr_?p$cIqZVPgRKl+>(5t`e>lU=RCD?ZgAMC zHHobviKdJMT#bmnK;Qt1DM8cGP9Bv~2d>enFh>gQN`awFz!@9Rfuu&?Zk}cYaE4TY z(tLm)ug}s+=no3DN=cyuPpa0ZL%0*>Jw4vB#-$r6B);JR2>PJJD2eeOMD*BZ;eitc zMkIC)zz=^pr==ilGAfC*y{A}H7H0(K671nm7kt7o}AzP>it0+pijzz#VH0Dx38 z5E79($=zBA5GRXE+1HdVV_ZbmD!fxG<_jxi`1AZ}k^ zyQebog|`n|TUlw^hSgT`0V$@VO4HsrvL`CsNGV3U%7O5n3}S7VYn1pUltVODn+>$B z<-$?lIMOvFk~1yE0s%7vGPF8yqVr3cNrbHq2N=xx?A&b;Sa#CXr!f$Yl~P$}v|G`D zXg^CyAQ}qAwdJ=I7nt%3P^qU%b%zlYilHs!BRi7o2l-80Y10R9yL;UmKAkyA!(E`c zpH0g=9OWIo#?gPgvZ^a>Ita|eDnUZ(3PF@5D3~LlJxJh7R8+fDQ0+xSigo&j7W2-y zsZ!i=MQU1!l2l12Urr@HX7dKGnApDIh^`Jr8l77fs%Hr;u|$Os+JXs$snC$E1cZP( zo+IA!ihi>sjd~d1m&@)foKFcHQ^aJ--wA6cDu76p*J)Hfi78cEr1w2j8DH@5J;pXp!_01a`}jAC zPJYWxQS~FY%lMwecl=O-#K`~-r>~y= z{{T)34`QBK8*Q4e9^9$&)!q~tw-*x%ZjC3xw8#(~8JEy_wSp&#C(B$UoO_Jycw&(a zxNa4#nx!Q(-O-^*FDQ|)Dewcgi%t(!wu=pN`vx@3Qd8To?VuHq5`+^@%#b`W<8TD) z8|mtY^V^xWKNU}k(n*^3b!wCq^kpGT7_P@Tr%FVURFr@O zsHy+}b(KJ!$@Spmc4Wc7f}Ekl6sl|?`pRV2J|G1ZypTy&yOkC0C#*zp9eI6aYZK$F zD`Hz{bK9>JiBeWGeG_h_*Gxf?l@P6T%qNbE=&5YjcMP)JQZ~h!%92P(5GiR&i0d9S z{5|GIVErRGBUZ<8t~m-w?{3Wb8G?5#u@$RW5CJE1OymRg8w0nE8|1eiGf~gxwyP!U zxcn7Opd_VK`$peM>QmCzEaT#0KB@sb8t@A{X<}h|=M{Ad94;|rq;8Q320~UzN!DU= zwkJY;!CY0_I>C9;K+ywqji=Cg{@zk=HnAlRB<40RyRCHY3X9cR5VBMJn=TfTHri57 zx{Z2n!C~4(DEA%KV4X{GG0;p6Cqb-8FnE4(N}pwM3=S*dR1V&g1j zPe6Jezp6F+(|g5wf6*VRe*PTKJw%rj9t`(@0(-zSL_jA)u-nUz0qbeo*}Z%seE`#4 zL=TUU;E^n{#Ea<2z#v|r4v%kf@}A#^e*XZEfe9+Ck~?*v>O0X;NbCl?u>3zR+VSTJ zB~RjPfQp-l%odGCoZY8AZjOS9-x?k)7(BB>T=}UU&pvb zsHQow1-wiGba)bA4uA>r^w*A;RBJ0!$r16Fc?eB7T%v z1MBem<~b00cct0(?P{X_1G(34?9uvaA0hGLK0TPQ9aziB>P4UcI*Shr6WNckn_44X zz~6ry!t+q6Jjlk$ov|Iq$nNnxFmtQV?jNg(lba6PQ_P%d2&M#I>!xC4ECV4)nVksp z2Z;GETS?Q|g!KVGtNjzktixJkhQxiuz43V7;2-&gKl(r8f0vB;%jqcP+^Ky;8sxe0 zqN}m|vy>nmx40d>{+`|&z2dyb{S^ML9Vl1uY0zs;Jtjg&U548G`o|ax_R%_1X|Bl{ z0(INabm%@iNpX_UFo4NU@!-kskE`X=%ZYX-GKj&6)1|`>pnhZ9KzyUWZ*KeiJW@dd z#9K^_)Bx75)%j7sPg?#Aoz~MXdGnE(gxhPUSq_0 z6gB2TV2GI%Ywxjn2&MqHNbl&%e!J;ELE};RGaNTKfvq&C@#A>~>UJaPQ@UAtb*-}K zzPedkBBNlg%XU5da^sY60LJ#TTa^|U}0D+^4*a6VN(0<DjGb(hq*Lu>?~Noeuv1&JpZ=kBr-t#6A}%n8V6Jl7>e9Jz5PUWG^b}`VBdF>2ZTYxeF3@=~@yk5`>G1uBAA9S02UY|Pgls_l zLMNuad{`SF`w2(z-}^d$#{5%!8vg*UpZ%i$0Q%l9_h4*(8NXey4Rhc(Sla9Ds9K|I9Y*)sezZ_!Tfov9z4Pgs-RQ9Lx}9cGl1e^ zrH~95Bk0~cX`tgJ`KH!5ADOr=aY_kRwnd|o)M^M4Sc9g%Mi$cR_L@#5J&xH+d-w6F z{Jwg;uYf)iAt-T4C*ye*=?v>a$~BBV&X!}gtr=yFwly{?BnM;<9Mw#aeaGLR*W6rIh;Y?P8f_GH&nlFV09`AqQkp5yNI;h42pLD85%+sS zL`xe2H4~7XXd+AcL(R8J{VG zv53iE#at+svDWNUokEV2BoZ=pq3Zdgl|*wy-pv%zI47&e>q^E~w2e{@fcc+)#y31` zRJx?qt!Pm~lC-HMCKQDx6qO|YN|IoMG6)3gvV$vP4{}>1KvqCvHHq8Qaq(_aW+lSj za-tL!^|N};<6ZUXru(blZxSIdlJY{YagHW16rw_eIm zh598Z2SSseQ9@2+&ZK4^lz1`qwAf#pcoV&6*{f|A`(Vrx65wraB6du}jHy|H8k8Lm z8NZU7K3H>_+=hjDmyYLUWw`9HXgyiT4Dn zDekVUr$tYM1?m=Y7VP745c*cCSeCr$*nrAMM5w@N;*lCTp_M^dA(lB8vF+zD1cC@4 zkYsh(gZ6#gJ#cm1H@>R(NNLC5BL9nkg5l85|XK zbzngZq>UeNK^i(El__VTb}Kcecx*tzXeW%7bdecZT}b(M2-7JAN|r`eM`dEM%j|83 zIk|(@DjH$->R9$m-Ko-*E}8O>m8~tPN>WsFHlgMqLDr4)r<67Pxx6j@8Q*6 z^<14=SLjTZD%nMr8Dl$ESLh&n{H(hw%5+hKD+MY?g!Q~-%uTy^`|y}-*N~&B(N+Z* zq>;CEk||KEkw}E3k+QO%aES!WX|EXEOr-h8+(-4#ryr8yN!(ACr*Wh7-@ot&#Ycq22?R#JWRP_8>OTDs3)oi?U2xs*-Ep+mR8ds3 zSxyq`4iqUNPN6CUND4^@R45TJU=chdxRI{jhfRGauAhG%X+RZ}W+0lnVy?3fB4^$1 z)_C(`IH#{PGe(ldBr>DNBCDgLM<6Q7%F03Ca6t#yj}mB2JzMmwR+>mBirr_9Se>Ji zHWnc6u8gd@+jj@BVmpFE9qb`e<@*ZQ?iG&*>gs43b;^iHQ;r!DppXQR091)2N!0NG zbKkSAqnR}CT1bX%hl)&~&@(CM zbyl8J8tn&AV}1~r=T;x0<|WUU*qWibUirk-SnJ&(AtCRtM(U2mr)0PJSrh;SB*q=a zoAiX9 z_(>^S=vXb8?8=qvASE|3kvCDIk_$0RsB1_k2^_=Mvunwx=9Q`U+*6J?6t^5&%HDa^ zR5DbhtwgD6QIjep@Kv#;Ta_4o`c_6?n(OkUY$b*L@Fbt~@FKf8I^*2aw5@ZZ1Se7w zJ)xP>Bhq)%O|>kzsYK!H_kWv7tVjZKtnO!kyBRsaHFRO*KN2Yifughe#m2xFCeV2ca4f zw+ZT{s~VbGldnb|J8!Z#_xvY|VBF&FiE= zVD9b1^1(Uzek#{be?*Oacd`!lJYy@Efg2O+>E-W<{cfBcgfBSi`$=N6Q>kvgwD-?t zQktb;s0BRgfXX09N>A2SlK`GHEEr<@iLUfkTU`Z0>g%0LZRTabgb5kkaY{%54TG6c z;yVG?g0so)QCazGhtgJB_VqLEH><0`DS{GI;(Nsbl?WOoBSeo1M42HR>zq^Kc>P52 z*vs2SS~Woq6MIjIolvp#(TEYJW}aOlf}xLt4j02Latl8bb{V3@SClJ`nPQtEIO$7bi*AmcDpFGUNg&la0r3?XC<+m-XgWlh+8dm8n6jwo5zFctWJ|Xps2>1lK`GJ-=?pprj*iE6{RUmif8vC zBn+PrHurIHyCd>R%jLv#0}@dvTj(4qv{Td}L%yg*Ymu?V+;HJH~HvJiUByih8wz`uQub1d6pW z(K3mg8Dotac}oh_BI?|hCryJKb28cv%{-fHmpEOEg~fy`5#CVUMRTf1%}#}Yq%agj zq$MOIYZ2lxn@acF8=N0JUEAf&f~sxw1H8UG%KR?9oB6h6nIMs_<05DBql;V5zGyMa z92rt*fqM~M8&xf)jf5$0BrIevhR~HPB_cppSO^Lr{ayoo?fcDrU0r2c70=e!y6r_v z>!zqHTAfi+)KpQ_t11NOo|*x|OUo=R&RfW>d43y)32YyjgOn_zua|S`Lq83_J5y`hJw6* zc-EhFE9dhzc+)CkRoAN!1M!wE{{Ua!d!FaUacZ|1l4@Gn{{X7l_WBOhy@3A!9sDaW z=i+J8UhQ2*pIH8A-ZkmNd*TPF(0q7uu|;3(iHZu{T2}Or`5v9oo}2r&9Bkmc6?n!t zs>z2b=&I7It$Q@;TIt?xDPu5G%ax%ip6DnIi6>6HLpJJEishN-hB#}iv&|uvJtR=1 zvdI4c&U-2&9e)5jk>bW2PE#drg$lH7NoMVcDprivuz{wq@Ix3Z)zwjYoELUwR7H1Y z3WS0s*h`fqx@!Jo+^L9NNi>#{;tq_aew8!+5aw`4c2)q%0%+2BkkZ@_pq(_~=?rlqsnP-+fPgoQT9Tgy?<47p=d z9vC~v0WY;CKDhHInwK}}8LX(ZS{+rs-`!KZ<0m4rxVDspDGJM#E$2#%kf_#p$s9b% z=8v0p`31lZ9}g+J8cIi`mFc^~iL3LFo03Ia4xpXsn2)cGNuFr9F9njmC_IwVrxzZ@ zO9WCg*vjNqQIN_i#~Zk0Niw+* zO#SRf=O_8tz58qaGrqeI8A{bleQBz8$I5^6OJ7HB{{ZOQ@7(_Yzs9nc2T1t)$o(8` zP^$>S`@Qq8#t#@x4aA)-_1pecB}D%K?uS$P=Z)$sb<5h?0^eOSL5ezq z1~dc)zS#5B@giAb5y`os{l@Y+0ubN7Sec0|Jodh$3i6{FUKYOXNVUGpMquW7 z3M376Fp>z=nbdJs{!iQri0l)E*sw zCC zC5puz5Xd8`D&4-@>gfyAAFS^{FLUj!rNk(Ht8i>g^2EzE9yyWa*CR2plj5z`y_T;T zkEFk-B8LSBPe)kw0tMg8;1|?YIa5(lP_dbH4?6P6omA_paGr!oCw+C-SsW?ZltZr- z56A;(KU#mNef(&e8<+dvUOIm)!L0`f3;OifWRSl>9EAvOMPCdgceuRH}4!RfqHXZx+{{W2qf4fJ=IjLJS$@>-E z^%LHmz&EA;0IKW6fyuT#qncPDsFJJwAppk7Dkf)Ly>;{BsM{4WP8nD!GA*tRv=KuS z_h?{gFbr|bk0348>*o#x@9659Z|8=IaoShfM1-86t;WJ+lLJyo&;z9PA8e;6!_`QQ zQA1D+00@djZ7^qVEjHJTNBUV@12x2<4y+d+GwmH%4!n$NM^dv5=|^qv+kWH5x$*{+ z#l&Z6VwNYHmRuoaib$NSILsVC^vfJt7@3b*X8UfzD+#RhF?*2<{4!q#c4se;ULpPu7V(eP@SKRDFO%f$aNEnkR?{!(EDpDXLkhM9U8{@=R(J($L@_ z@49^W=|_>bbmBf$;OnYLSzW4~wGcCSno39oK+eh=>+n2tU}$b>)8_kx9sd9msrAr( z5!`Ha>*YKi-oiK6FMN}?(7sfPt2^Gz<8Gx$bpQh1RUu(6B>fmLq=686iOzqd?IoXx z;j*!q*|E8S6S6unSZ`No_Ih2k46vx#0BnK2`tbMiA*WX5*va9u5PF!5v?5q0iA&VI zK0e4snh4al!{lNt6^ZFxk)g0R`*2}D!LD~y*0#|@7q%OzLV`>w#4kFCAOSgCNIUHt zYsFBxtot}VP9yUf{M;2!ly?R^^B6Z3Qd6zxTc}MFy~`_cYMjlHl>n(wp6tRwIY2xM z8=VEq*?<=6@JiD&MN{jy(R4rPo)3JY&c&PZ{{V?ud80Gds`%N9N`bvf6FqUT&ZqgI z7t`BXJ_dZ-!dR!w^44LiVn{PI@wt?EtIZ-AZDW!PgQ_TGUZHy(Ibc{fRK3S=OJz$l z;W|g{zaEmg-UqM557Wk9o9;Ph=K9$L12lCpss8{sA_u>yFnIVVZd(5U2iG2+8cLmX zpYUf*KdVE-U`rAI0F8(L0J_D${{Tt;{{RXzR@nEabNKuny?=FI8&3V1r;h8nea)L&70p%C+HnE}1y_8-?XZ_g%F$7A2|z9+l!Gu- zl!31bFF5$*e4B~n5(5+8#YOhD5U&}Lo}$QXM1VOY%~;62BV~#&W8uH$21d>^KlWva zEXPZcz}UGOO4d>+?<}I$9%g5*h`+YP^%>chNs!TCr^Nl+*OkY)weup|O(l{juEhw6 zLCOP;K+pq`WSRWAF|fP~2h-pCet6@gzGvW?EPsKo*m|L)zKeyq)l!lYM|<3HA?b2-cPc! zq8Ox+lOaMbs&*t;qmYk`#(@(%01Wuj3l=)@t!z{!*n=fLxwx zeWT&V{j!3*2cm|w!5`j_!9NDhzM5)djatepfT(nu3fPhT=~Mj?{{R&mdV{C04^@&M ziIjS=e(2ftBj2*?{xj+RH{mq(E(+29$!HC!{{Tg^t?o_lb-xd%;p0oZ*KI!k0PEM? z!3OMM&T(tFFP9hExS*{i%QKHCBs>dkVZy4&gNsq1Je8mgvsH1zOxwr*uynx(E5aqm(sqq)f2j(r;Gj_nZL#JwX#16c1luy$&{|OZGO>@nUmHE z4REG<>=NZhI_a@oF4bp~W=FKICEDf|7=Gt#Wj}-#Mjfl6akTi}X|Po7GL$5gH`jeTUp>)|LuZ+pVmnXizZ{!soDPkne@EVz?2nl z5{u0RJ9M{NN77RAR+RT;OG3g|3KEh^a;OxmP_75}Ywk$7g)tiOy@HLyX1&xAUc(J3 zUdvjuIl@p5izg|7B_#?yctv?X%PrvZIS(%R8+sF0o@B;6%m7OfyP0Y$vFR|{P%Km- zx(gOnI&rrbnjB3t7^rz3DFpW@R*q?m2*l*@Qbw~wW;6&SdGX6IkSRkcp)BySi81Vn zOlfLDR9SG!7a4PF3Ol6EkZ0Fky1-ItJ<1$F`lP8z^a=-0SU+@c!V;+K!Tx1eqB8kJ7YA4wsH(w&iS}BF(?Ce>{d#VEw&O?4(E-#XkEF8o0VICl_HXAs z{{S6-VcGGYVS>>;Cas;W$R@RtdU}S&{vW=(e-Yc<4+vn1(Ce>Vc(9y@=M`ry?~T#d zy0@^+&D6DA%G5}tTGRllY<@@tg0Lb8&#_d%E?cXcQ9`Kdff4=e{-ErjJGp{2l0N=D zB9gX0npRG~-p}j*0POlt!-)B8b~ibXvyI3IrmJc)j0?rogo0z1CN6puEU?7j&EotahWWjN z#S80Zpj6ZQO_u83MJL=SL^4T-3vbROw|G+EzRJReND4zXh;X(8pj&QOl7BVe9^!jK&xskGXx#gFV|D@F!j-O-JZEDO&)#6;K|TaUn3N66<4qf za>p_$d9b-AWRK+z<*C~$BVSS*3PoEs6GeFwwJc+QtRCtYC3I}$WM zf4K0ih;X&*4qa<4R||bxRWx-AVbqFuR1&n45Tu}jl?YNy%ord?2;!QoZ%I^k{`Y&= z{7p0?&VD>-$m~~|DCUZ2q>5BoBatPIk@cqDkG ziR(@pIU{yQQ@BY5Sx7zDcGx5kPtrnx6Yd>nU(xD(^y}`BW~-#v`{|9N{4zhReZ6Ck z!j`RH-jzOZY2KYZGJTuzvq?!-n#xrwnxqeDV3JsL00XEbl2AbFB*vamJbiaghxya@ z9Cmd708z)${{X@9^1Kt95FbKu_w~kEjS!~sA^rN=B)uY7|7>i>@7{WhTB+D6jG$ADo#ZuNg+v6PN6~wR>w{Vt^zTH z>>u(5qrk?M&fydgFIk}x&K;486yXomC#q0LZ8N15GU)S8AVX)OQ%0U2v4ZRRS z*dUK^LHdn&(OzRauNu#?7FJxIHPwd0DH&OaU{^#CbX4qj8`vNatJ%Sp$209YTNh=TlQ2yCr2M1~4bz&(2}8<|!{exMZ?fP}8LK`pM@UiDljoAK;d7p0B4e#L8WWHNKN zr$XI<>Div6!ctgV0Q!ZC4$P-r_DL6~@CynRAK)4g0*-;Abd#iJfv3JU>Bdyx3?xWD zgZBRbJzAf)#rflb)lb@An$^{9QBl;Qrn05(<%U~rN>i>aPyk3936&Kuw$Sn|l>Y!nM@WT<1;Bxw^$wZNQgzE4ulYY3X~kFV1=%)F9U`l9 zAoW9mBuOmLNCXmvWtY(3s)9(&f-@jhE0i3*!VgoS$1v@8q5w5}s)Or!Z6TPl^wwGNW zIMU?{R1$@m0GNP!kUl%k++4%u7nr770dlnlk74$`?!&C>>7lJ_{{H|G=kr5~`cdzZ z<#tMwtX@}r;{^8>J;^_S_TO&>C7xX1%>ctT!#aOAnUmDcy1*LgJUVFkYl7)mQ_o?m zQ6)15l_x0FgaHJ~v{ZB_Uc3p)4%WQgSJJA!l%*z63KRiQ(4R5@+orSAjk<2uJnO_4 zYD-13v5K0y$J?f-X|%j^I^v+MP@$D55~VAmQ#upGdp=M3irsyAs!>A{G`1yd&DB&y z4DL%36+)_(W+$)*e%<8K^Dm1?@WmE;F*TbqM+I8(Ve>LeEYmoO7||BbQ#_97s;W2h z05n@_SzqPe4P6#*!JAkoB7yc)h?DW$7?OQ>QngtqZB(t%Td0|&rfo`6De2n?Z7Nxn z5H=Z%{)ifJrOUfEC8NR=HCV#uQFOo7)6+Xpl@f}2K(r-6h8YSeOel#`%A6o-p|=#D zwBKpFt`5ZX7*7G!wks|D4j(Az~U{bZ7?!C-Uzw>38$#$GuV zf=e<}!gRyJNB4i}Yd#}8pN9-3@;A(|(e!2L#)Sw-moIq|IMe`& z6+$Qg9q1~kC)>cf`LDubgv6YiEUOnnj+`!FDAv0wt)LVQ00M!aGyns^g=>~LB}4?_ zTS|;hlxZXYcO6fZL~G_`?x&TQGDq=7*R&tRQ_#-BI-Py~oCiv7+T7)%Ky_CtY|ayu zeK|1_4y%wlos6qpfa7I7x%tePo0}s;(fy;Ri>!JLqBWi}c^&4NX6VaOWgWNn-Tf2w z><+cQ-_(3|i_Lxwq3Uwn$}!O(VRIda)866H{C&TNgHuV$>ci z1uaz$AuC!^pQ_t!hzUXfN=KQK!n2)mPF>~ru9>{lQ_quWOjN1l@7a(*n@MDtG^mLQ zX7rRlQIPcj2n>84VYv=Blw&2yVe`2=RV&;3IJKI&9C)5~tS6NsHtagiut3op1sA0n z%u$kFLOfxpvnIZo>N?6rKTT4FH&DWmypFc5N*9+ZidEGz0+S$uldEB#Qs983sNl;; z8Hf8GkQ1z!5v&hC*TC)VL)$|Z;NEA}VeVhohNvyH$)~FeDpO_jDM?D32vCO?3sZ#8 zgs0uba!+s0c7+6ss|16lkBxun#Om$>e{STvA7VQ<_W1EHoSt8^DU+Gz(11W6VP^r?Q6%WyC*Nb- zejW{ze4xPEe-f=Kf_Ar~O*feLbv*~UPT$Hb2%5%JycK9lLZGQs35`MA!T5f@0qFTc zIpROrRtLE+{{Y$#KV81r8LX8$~l?P;av%-0! z!SfkxW+NHQbCxnWJN0PMgX~Pw32j=LVTB#d-A0{F)g+Db#~Mi^e5l?Hvv@|&U|}@2 z3r#(>hn-XJF+|UH(%i}t98wdaR8gVOW`Qz5Ap-Tw+&zfjYNGpxX|AuZ-*n5Bw99=> zHcn!O(y2-Ui7HV@1w@jmjU`GbwA(Gr)~)J?8KY=FP~wZOIOA-EJmZR5iBguV>MA6O z@(?%%-2Ls>%={V6d{>9CmDv2tLt0Y9PnT3!Q-w-XEtcE^xpU+yx z){f;|Xtx9w?%J_p*t8);ioB_0qd`VVWM`DDaR|c$wE(Y95(ta(~g^&R2=mvpDrq2H5fpnbwFP`~F(?KK-;k z#31vh%b49+ImUULOalFbojdGz*>CULeTRPsKIO^YUoNp_yc1)TtLeADK>8NwIK z(%ZDwR0k_lN8X|5n{CF&bDe8YZ4MRq%0N*7fJEqa-gG@{xV+L-g54cvRf1BasTA%I zw2)*FKp=t$AVd&2O8KG0xn~8)4^qiJEbgVs#s-1{ z$Ec2ztPWcf%5l`Qm^|gYy&D$p(1uHuZc~;U6sDk-O2KYvrRWcC4M`g+xl%pU9}pA# zo4^Wr<$eTN)tT27oZG^RiBTkyXE7wolyxRanVvC@O<)Z_i1uywHqjp*oky<$x0yY? z`QL+a)+fUBH^BWRmhDkROzlW?zNS!qj5<)@N|cbGoWKm(WQiw+NBX0j`GGf951y3+ zPb2id)I7Lx)A9$-JCy2Mub80K?NzU425k0G7{fdfO%Y@ym17)uq<6@Q%PBfpEt-N)UIJSJ{f%eE$Hx%zx2; z{?m=`^+LNq7JL5yo#}FA&mW9tjsF0`Z`L~P$Ep7SM_)NuMc10gr%Qql>jqD3dwjjm z*SEKbu=&^J%60mD-#-07b$=jdj)%+!^?TUtj{USe8+Gz;0O)@KtmZ+F;Pm+qPM*3? zrwaC51!BW$eRdo?#idm#390rfa>`!_@gTZ^;ZaGPsv|Je1D1FMf9j0$=l%9${)_(r z_Pknd$UU=phs{21(P6x8bW^tVQx_PeWUL|QR-(x-cZ*P1Y$y~bKncud2NnE}$lo>a zcpR={E0CpYAB?9h+fYZC$l7@#gHBZ|%edXQqB@3`U1W`K#H>G<+!vK(>fkY4%PVgF zNX;Euw(&V?wd_d+Yd1X?p3S)-Ln2dI{Zw1*DuJI%U&?KEFpa73j1dbk<;;yEn z3E~Fr57p4!5pI3@8meV?ZZ%U*p7pgMK#3j_6qN#%2}wx=@C5N+Zl2H>TK9OfRo&QH z?N=(A1uTcsrG{NnTUwAD2^r83q7n#6It>Q_9$fH#Yvv%foNp-&C&Ro(YBq9rsqHNm zXy%1ra}y&-j5zjC8)q@*o{{4TtY5hZn+WwE;agThx z5B~oEWY7ElzhC=&12>$0T%O~b=RfZ& ztjhP-ZS~{h{k}Qm%F>4}wC6HJ6!+s^zug3S&z$ea;p7LKqIG7>Q0wR;qwU<6b?@Kb ze#G|HyM1-z>GPAz^8-dXmT%K1_x{4p0uNfB-uT^nfID~jzpuf{Zqlk&TBc%|#@VJq zT4@;^P(x?{At6hZ5P$+isF+M@1n|hIqsm9gjQ7N?$d$`GZv-B6%MvQ3d^FzD4|It9u?WXJ;}IVDqb&>vbg)U z8lP3@Em~S`mq;;8^F+~0Br7zXGPzdhV(rp&c3Fj=9ht2|Cxy++E;}@`G#61Ott5{X zi#6qf#bYYZ9fzfvN4g&pKM#+kH*JmTG7!U8SgPe$bManOcyr z0bIsmB7Y>L$FbkZ> z5K)yGTpjletgH`kLk%4f;3ChPJRUIBW#xI;o*7yx7EB&(BuQeDXrzh5T=`ucBu7#K zR*iw~JQv0CvjvR?5w(Hk>`9)Zr`Qg2P&|osU{2sQKU#Qub=3Vz=}P( zIm}5vIWk6rQ23Z0i`>uMs61-F+hd%yiOidwHg?2-d+^x;lg)k$qv`V8%djIu>|D=q2`Ad-{l5*3p9VI^gD~xu zwN*BYH66a8OsTcIM%iIbH@QQZ2uq11eN_bjKp+k_Z`gL(eWWd1=qc-|km6RRDq9X9 zIN4HC;7QOaI)XoUc6pT$larAxt;U28O8N& zs}Q24$JkQTa=g=%kqw2M*$PvaDLxkxujvV)W_<>-KTCOUtYrnq&N0wE_yy^F;L$XF<{o zb?Y29IrnSFR{S+ve&zknqL%M$VaMFJD5=Uzg*p;UDX^fVJlPpL#>!Qcq^T+iJPa1Q zUh|EX>S?Mg7-{xheW%-TF9o!;9IhaOsS8O=9es5NkK9j&@~&@;d)Q3;3@gr&TCHa% zdK*>Qw#Z&TQNtvIW;sxmVijxxdIC9*O zl6*bDfO?XWcic$;jlDP*be*xexXXa5<4uu31p=3d9!i3u2^vX)NILPeS=!f|vEQ|D zrplw^Pj;=y`r~*8bpvm4GH)M~eq+Gin`SC>H+aw67q!1~hkGAgk8gj^z_gxd@cB^4 zoR2JAe)#(*E;p_BAGDuue{W((a=r<8<<1QYLHrxGm|ArV9brI;1w;|hboACZkP~jF zw%h%hg|6bAgv%`@OHvsVn=4^TQ9=T?Z6qNim`DeJ{GQi5+bcj93PTD^!WGe7M_KD5 ztZ%~gS8HBuE}dZ9Y5u5zkz2tV$dLq?GBut)+wyCl%+M{1`1#Z~WtSypWd~|D7DR9k zjQRZ7>fx8`<~lKqPNni9D#n7+(D2^>+&; z4NYA{3YECfE-gVJA#x6-LPl#nEeNdZY9y}8oQFsN)b7@L>(H(nI2 zsoMJ+=?`T}1g+{N{{Sl9##<#w3NQje1O&D>KZ)c&t62<;n5q4Btr@p++*G>Qg|1_r zAE6 zo?8#rGKIFKAxK**N`jJMNl-9B1Qe(kAc%p+5!#QLijT+HC#VS1a88618)!Y#!$~}@ z=Y#?>m03sx5tX(<1Z*Gc*wF<0_VB)cF?ia!M$Y8bm9)zE%%YG(XpiT%2q5fe9>?l5 z3hlDrNpGd5rKYDtRLr0ymeLMZ!8x)fWaX2fJ8c>m8J(yZZCuT+J=$ZrM@^;=oQ-zl z^F62emRm>Ttiedspaa%t!=}Hdh*uut+s-n*eC>AbjcH^wyT~HJS=`+hC%8)>KyZS)!{RQ%-5r9v1$UPp?j!_~y!_t} zx9<1bGgVVv-P7|_*O{l!oIdk!_1`W4S5a0$7Jz_&0FZw>0RJ`sQva*{Kb8Lt^8Ylz z|8D-*2f#x|1Rw&C5a*rv)BpeiBHCND|EFM}0|AIg$SA022=CrHxZ%Ea zKtg$|qXOT(!v(%|M#MuxrUjs&a!R0~<7)ulo4EuL&?OZ%+z`@(xcYw(5tDNBNW%7R zF-X7+yi(GdTIQ~d{4&}WmS5c9DUE!xayq(J?j9kb$wf`g0}EtKQ0w5Z)Nk`?#e<9C zB`rfsZ%?H{03aZt{NG`r|1Y4oxPSnRxArf1Z|z8LRb*5QG~9QXK$QQrp`hZS(E{)} z(cepG5YU;q5E5|(B^3gRN$4eE4gEiEKwt)L?UZ?5K4}?QO&xRB;Bffj(%vm2kCc{M zXmVOn^8zWqrPUXYkdnrhfgw5f)NiFtgTu=Qx)#=9|JDJRNC zAc*^v-BWV}EDUa?$5`On{&M;CS`2v|VspKp|B5^kjss*bKHmD))HIsgL_#Zd z0Y3&r{L+!8nvGXzY3`n9Fe}G}_L&DSQH+YZ-Hf$rVkn_QOOKiT(c5xT0ne3pq4=o! zK@zKLqd!)HKWd8; z4KIEz?gL!EiZ&#yj5^_`q?{mz^1cp}F~Rlnz6Q0mg|=gG?nR(PZ%De*HuIEEtfu0! z{73roYl9iglTmR-x7dbZ+^t~k^g@CSDm1#c_y=H0+Rtqp&CgFa5k-DrViQ@P{mFQT z<8^aSs+LY%pQa5$m>SUb4f@@&VF-(4MN9b3@=1|W3uTZxI_&2Bcrn7yAdiY~g`l|H z<23WJes*#6!eqC;&$iYr%f#bp6$Za59>Mo&Y=9zA2P5;v+IWO`^!;M zKY!t7?Rrbg`}4LhvViBZT|(?059sadE9ceg&PtknwRATOSn{<{0hlk^qZqorP8Yum8)n4syg8oVHm zoxiR~o+J|~E9|Fj`Sswuf1iFSL05y_G8b+VjMMa#l@Ny2js0@jaksy3Cr+Z4q-x&X z^Wtc(bu^Oc`?P-L9Bh_!FDZ|l=26>|)&RotZ#s1lO;k{nN4CT}_Q_v7h&-D5LXi|S z;nJ4)l)Mu4YfN3QPytyq?!V zy6&~(&+LY7$O%_*_9^Jk{ZJ}XuN!qQ1Efu2{76=(uI@yKoMwJ3#nT%1CZx}2d01WB zrs~gv(@Z-|x;2kw?vd69$!E1nkpM4Ux2-cdNS{<33F3A3I~>)2fNksT&m2t3ji)erHLu}QHFhS zx;~ojD=#LMyM|=ek%~p9pt+Lk2q#GTo6AjK?1C+S#zBAdLm_J2*N?0? zw>{ma(3oETKXG;{3c{BM5jHh;TiJKFZDFSPENTJM&oyl$Wt0hKN`EVUap4Kx|SgUWJVMQm~m>3_6jbntCs3~9f3g}QIW-o4%0Ff+XB(& z=D*;n)Cgv)EyB9WaCsyRMAFGzJ-ap2_pRKy!yc1&KG~Y1EeeTirwd;#gvtKolV3Ma zGli`SuUsCv#oV$Z$}|gC7??6aov)ojt)OC_ChXJP;mUB1`|U;}}GNAFvTO#HD% z({v#0A!RpchVUWzw^#h3&s2RKhsaB7{!H@yEiJpkvGJCLS-^^~&1*a;39Z?MnCNgu zAVI#(aFtVG1AA8LBnngx`Rh_5ny=$A*Z$O2H98TcBlf%16Wd6LbnzXbSe&=Px6^i} zgOGR9?IiYR-;!xP#R&BaBuSAjZmrE(U!LPB_go;VX6)-YDYBS6g}<52nlKVOpH*m#6|!h&{aaklh3ya+BkY*-vWx$O~!aT(M;JoU72{Y-PpYNraJx89-N3=R7#!v1$_qQiA#>UV6 zz<&S&gy%1#maDWF>wl5SUineuvcujH6Op6>yFmMin=n@eQp-#)>HkKz&RFTQzXv@X z^szsFr-_XbL(FC<=e_dx;1H@rOEx=iPoyw{M;|K2cC+i}ba}r6Vt*|a4x?XbG zI}3*{p4@xCwDSrHwak{eqv6P2Ln3F>YzbV|+JG3s7~8LqgKcUO;zB*AJu(i}GF4?E z)}(<*tp7y+^67M4r<8dK8$b>VvK&@MAAD_P;82*S1d_pc3 zZ8axTn?{Q=8mG{{wr-WZkL|~WeFT?d8(=ZZeM$(+{jfJmX7kl1SMLt((;u`G`fwy_ zU%Sx+rs4=PW64>QbL_~;=LgkMv)TY2IG;?5rz{d06VJg~OiQm}~Q zzoXqHdtF^qzZ)8CvS$gk*I=Ztm@b!k(iv})MQJhFD8a9a#SRot{*8tmCp7;3B55V- zqV4{Yp^7-5`bLfTQ$^ed&p{f_v~)&}aoof|{arY%gLS>gX73!^YcZtW;{i?g66s`| zPAG=u%=kbra1Ev|EBYE5l<__w>njtk`iY!}lT{Nz{p{xef}xEWb`U>-CC3=TD0wKh zF(29sTgNH!R$pGZb>!_%p>A23&;xXIcCufkh6&TIM@8DqY4hp7opO|k8|nwOUlZqf z@5M;JY!r_9irlw66a~Rva23Xfr5a{cugNWfgM1G4dRQFR=x?JJ2^x-a{qnw9{FqL3 z6~xIOJl*~9nPNBO-bUa#L2bo}y$}zTtf(B&k|xe;YLrk^a(CNO7)em5abNiifByaF zAu4juo|Yl1NUr&4ZKGi6(w4$RF|Sf%Aoct7ZoW0zvKpa5B(tI{EIIbY zmCHZpb#Pp$(AHfe=v{PSAIHLwTV>^t zb`Kx5O6ZU>Tjd@~R@I~zu2_!x1)3nzrjWh(7%GTKNyF7ll3hh@xU63Nm*#@$WV4GH ziQ~-Y?H`I?gBCKa&3lW3Mg7`Yc+wFEHK^G7>$QRs2T6g60w0TixeYfh+!lj!i zA{7$=;;5fG|E=LA^&m)FMydN$HIbyuxJlO>poXjc66Cin?q&FXVXtimm!Dc}dbm2a z-e5>CWJ*DpF7}&-u_>i*m3?y4SNk)wd=98SGAF&FEf?+IDsKUv40K#tempgxy)z^0 z-9GQta_exIb9#y0N2vO{=<76W?w`%iI3r@|q9Q&BgS_@wWnB_GHwoQNA}41glnVPj zT^@a>%|Z$M+>qnLlrqlW4mIr>pmd*&&QHj_Kb&aRZK;Kev8hHLS!8 zWtq5yNi*lC@md{H9>TlIBcrq)t1LZ;STyErdC~(;z;zS9eh4j;JTln(qEe)G74O!0M!;;*}Ub zTehQofN!YFBPS#w$u7n=i7EBueLx*lR%UcAjt5nqrGwc?jji)|R|GAeY%YHtrL(md z(;VZa2!n94@L~ACZ$zwHq1kBbB)@cu#%*)($Qor|n25(VMCmC-4lPfD^L6y;7P@kg zEENL@FQ`eh5F_IGX^r*J3ddwsWEs2X{2gHagovrcD4VttkL$rjOy?>B>rOO<*;G$; zOV?woD@@Rx!qr~~JI}wc2Sz-`=v{gRy{VB#W+GzPQ<;rj=Ooy4pL-|rXP#Ef#kEi> zFtib-!jUNw1O-rXv^zd>BPc4vwN9cq#%q)!1Z^(Oms?{7#Q$AN#L>k4Db;qKid2&FZ7wR(TfJff|Wy} zZqU`<-85=O7sPNZA+xT zU{G*ji^3FjgZa+{DSyZQy2U#uQFNy|foYyqN(1D?37Arp4?oA|ai|{SpcSIW={~Al=03kKaupCoe#Ebw=5yPA^7llV%i-%p znn0fe9WkEwhFb{%kl1sTpH}m<bOSgP zUmrq)XrksP#Mb$#lgFf${T(XZ>OOh**M072$nSi|Y_M=ZC%g1oofZ^$H@C?hfp&s6 z$>(A=e~Q|fg!6f&$Y+Tq zO~LXk2MQXrgSgM%(i%fJ6C`?;EbRPKva*`E;^S-)6PqksVjF2Nm%pZ(VLq_aix zQMCfZ+*i{Sug)cV5Pi@P!AQ)CpE(WZ4VQqXwPP+PwJ^fJes@+{U1v^&YK-TvHT zfC&GOiiC+AuL14swcC4Of(TZsz=$#9jKg>0^yzWzX9B{g&1%ak>e3BHXh3!ph(LHt zavXb<(Z-RhCf4boOOrpm{x?Q2dKdd+D&Xif7Z6W1r%*^>ZBuV~Va#gf_z@7_;69Wd za6mmN@@>OHu76H>2D4qSb9fq*$4F}^AA}jaUodCs@bSxe>wKlG;C9TGi<;Fl!%jeO4G!QehW#zPS^_0|5>oYhKPB&CcD3&AjwU+5v{!4D6 zrx9u7xjE-wpWZH#b@fb)1to$gO2;gPXC!1Fu{6Qge*iV4)^>I-ckADj{UlY*oJkG8 zsDl2quKwxr*l0J|G9>Q>{eJQCI2|~sQoo?xq{yCML~>c&)N&Sk*O&C* zYEO*c)y-$jP3;%11$cL%yS%;saJrCc<~8IhJRdmS6%}ziGeRtJd@*uI~Bjxw$UqNa1W!*g8NPaf&u{Wh>_9pb|L<2V`*A9ZLJJ)@^tHgoQX^+^Koc0FLJ=e@g(TR7?+*kr->R5#asO zCfsFP(eI{@&W>38qmms_v(bf@zASTtbR#6DY3%c*zJ@y+Zt~Z~Z01|tE01W-yH*ld zghs3U<_$#X!3ZdO3+z+Q0?V%(t>d?`1v8sEu(TlFTc{_+3IFpD~O zwpfM~NRfg<5G+q_=~(~dCoFqaQ`+~bRlZM`i5{s=Gp~bjluFdl+8;~pw(=hU z1x^wdK$~*NYy_`U$<(3q>8gz;itju7ao`y)iol_XrdibXrNbX*Xb*}5%x7q>JV|EMo_KOQ zs2b}@89QcsZ!pk2^!J2IukyqD~(ak)4js!7g#z?HoQKAqfaM z7Nwiu?P|zK&RI;Ya~CUN#xTaWQY#fDWg`@wKgNNcND8xfRggZx=j=nBPTRp2iN^_H0t46 z`y+_*|LD|1r>{{&W9N3d+Iokyu}QT^Xapc3$b7{q;7EifLA%p>-E|Es!WRd| z&%vOa{9pEMPrhouf3Y^lA?T2`3h>KlnFc&MQlIaf-|c$yrv#cirV|V*b!3Q>s&hrb zGGARMAsflKrjzBx5ndEDYRLYm~QA&Nd=Jj*_Zdi ztX!?EyVau;V)8~W#~&M%9H2%mH6eeGnI0P8q8gm~5c;){Icmz=J=C-Jep`RMaR&IY zq|3d{7F~lyvJZ2kW`Ka(h<6YTSQJDP?q}21Us3AuPzcJz+sM;z|EFVhL1A5{kLRQ%KMabTFmhX<36jk2CMo4v}LT8a~evw7`IK*00x zUNQ7=-P1;iV`Q741meJGbf5Z_pM7I zeBN;-E+{MfTQf>zY>I=)*3-r65m*z+w!bJXW4e;UP2ZXw86ki6=Bl%`>#UbzZ9| z^de7Pae+u7)M|~P8_Fjv@k)*PN)7&*N;V<)``~MB@n|B(JBiG*>|j&?cR|^!Fr1_AhYfxEl8e zV~)DHyrxFq;jjXKup`YZAJMBoPmiDkyU0su+`rcb0D;I$)$+aq;e_F}o_`m&wnG4x zODh}M24`noSLI4)=0@`j_|sH6CR4f&gGEYU+VSTYame z1df$AS%Y5w_dTZLgN7sv_|6!6gR$jjFtd!%(A1kmdF;ODsa=BX_vSAeIq7&BLDz#s zltlCWWA+JokJI$so&>J79~(ioNyMHC5W0OfdxH{FW<^+v0xYH6>g{?6H_Ul#RaE@1 zb5|N|w*wI_{P0ZCqgi(CM!TsA!5^;vTi}sZzQOm0E`n$!3``KoDrNVxOkOG>JP|Ri zxsambL_-6pI{qlDFwXW8p;*09*`r>&Sh9JcP{|eo&VboQ#jYO=MPY%1=-$;Krwl00 zdbKbSR(%Cwqd0vwf6-<@e?j|R8U30WH2J({SDOY$9d50j2(HF@)5{5-`4n%BYu0oc zEL6?T%O5pRmT1(6X(bg+U<6{m-y-NGH0;a_i51LljJ9{9p9wnHNxpCYxAr}*ZPej+ zotv1;!w%(N+%$A`MzllsRh!8GtafFcpwnNz3?<%wvA0v5Ov?aN%?tS-%zjz~31zOP zEeo#iD!o2O)xqO;PF{|b9EC*JP#0=*T*5vJjiT(p+rFm$q~+x0>X6h##Dw>EKB~{=LGw+a2gy-osq5JdpR9Nm!PK`28%1T z!_&!vU}hX>Z5ck6xh$<M|`;tqiHgnz_mNzDyzq$F6Y|46K^5NU0!*Vh2&JHdv4TT?ou< z?}DF{o~7tQ!`vRTnGur-0Vlg-R@U^5NAealJcUqc(am{KtlCYSSq0Uo0v_K^;SRx6?7C^?)a?wlK zp+ktJ>%K)XbO2lI5U@=m&`~f*X~Kz;F2BWB>N?(wFoG_*pXM&GpGGOkX#d<-3eRXX zcIB3LvW$Or_!w8H1k08m030c3fbt9(qpZI>&DZ{>blR+i6buWtuw%|V!Cwic%vK4R z2~lB~%haZY_5n#dJ@;nFWfW@&-=3n@pFvpp`)|CA7s=qbVeg_j-`27IvCh3wq4g;3{L!v}i< zi{P8N$Xb@xOUa4$cIDWjkC9#ROuU2uY9k;SQX89o2{hS4Q&HhW7Q+3d*OhbY5TUIp zZt2N>!Bc&`m#|lIKIg-edo2R_=lo!`ggn7Kq;xAGlJ(rt=2&81<5hB81*1md*Vv)M zO?_T>bs7eG2&-gp2^hGKqPQnaKf{W^$1$BJg)yiLqSv@lS+D2Dtndxf@Q{gSU8W=*i&f!=iv6! z6XAg8@S~@abPNl=ldN7XqD54B6-THfjHtMvxSFOMJc@^!CWGYpr`b9G%smQNMGf-P z(~a60T(bC@IY8pUx6`gkmoi5(544NGb&|FNH8VzLgI^1XH(?qpakW46SYCO^VXZr~w zxoo{SvIkTwgDcqQ6XZU%SDlWJ1pN*l_F!o-6l?j4^3?=Nj4N;C=}(`SAS6VlB8%CK zUmrrmECEZ#f~X(p0@0OHIdClaUoZxC);HQ-2b7v#5_$x5e+1Xp)5Nr1IvaisR#HsZ z4p6CI6!Or9a4>3aH8B5Y?{TJ$SH?_AGE4qIHB06x zUi-u0N2PAlyltwFmATM|=~mwelTx)Pk<@fr@i7cL9YyoYaS>3h8k;= zhVxHCS4-jZ+lH}q9~W!n^(xH+xSEGO)Fk+T~#N6%tWP!qP9{xH+p7ld*T9a zN>~Mg!U2%w3I|2}6fjK*%{{a91vL4Z#URe_2W0ut(OrJ=cg~rW)c0Z$go+vwrEK-I z4exT@6*7nuHQLXVTr1^+&+MH71_O?73Bzhyz_ zzGKZ@o6z4y>}(4W!FYszq3@SDWEa=?i?~$k*3V0hd$}clKEK#_k_!*T9_Pt3LDs4h zwBv4ebJ$Ow_$~zg0T5ECf)?AB)*Re-t2uSLuC@=rjAb99&DR#%2JJ+8AQL*i*a=L73qZUE7OGU&f?>($GDiq$F-&xq>2o&;UL@334DnNgdF~K}7u+ zU_`Y{mdjAa9==4lE^UXqA+5WevT@OSW{jchwXU-esYerA&J6mLij=9k((qpzZ^Nzi zmQNiWcWNeY2ae88nczP_u|k=2S(^SYK33~NW@YtVc3P!ljsBxPM2Ft^iKnobwxAKu zTCxG%>01wA2-{JkYl-Vw0*3GxJoHF;JPc?bEb$cirYjuiujKisp;l0B{U>e`&a4Jk zPzQ)wNb`DXfzEW3=S(B9D>@1+H&y}!!4=y(-=KP!1y`(8=?Mv~1$wyh#Sg5xK3zpl+J7ZUxjMd!DNl9>o1^bVYO*^ z%Y6omEn7dm-gF8&MU|YyfGDg~AuKkF_vm|VY_y(DS!F|RF&%SJX4`IJ??rXf%i;dh)2K1MnHrLv0P!iuUAndV|3Ows7YG~M zlj&dHs0YhMD2SSpiGMlZRbw62d6A#`lmsDPL1<}(oGWA&k zDD~~N?tNMsw1g}c&u&UJ^P6b+hQ?frpa+`A#OmNt_b@h~ro9>${wd76UjZggkGv-v zQs_b0rdOhCw)g?9bRObt@3NN6wfW#l5yYIS(tK;5wGmcEG^dn15AW5s!axS)LR5iw zK(YYjv^O`Ji_~v-(ip7L2Vb7ijC`kz-iN_oIzM~ZkCbZ>ZNOFvf$jB0vgi0=<;5RD z%MoE15^i1L4T37;;_1pf5~hK9xBz)YNm5#7AZDLBCx92Fevad44#%LYQoNED2D{@r zOmkz7a)1Zb=Q-c*72Odi;6PjN0hq)R-%OoXN6rk z2EGq1mS7Iept{4*r2qzOEyK3i%P&)DNYlj%7a#2lU8s?EiXSZmOxNNRySeT89b+&= z`rTYUJVCBSUB3q@wE#VTHO(5>N*U-23%L^xoAh&02qS==2>_G>8DEV}(Mr`cbsErq znrL?=za*3%7E>R`){HZsDRRSAIrrMqeyGohhn%tEYsP|9JD-ElWQ~am{9z=oUIHBszPN zTsr8gV`zU<#ZVuoMps<5SdxDfMl*5pJRPa(Bs2{}rYrGsr4SyEXB1P@Kcg+}gS1J!FH?XQxQ znf16e;G0}G6Zn+`@in5pc$s26+HtaJYt}c@3zW`YwQKm1UlrBw1Of#5Xg@4@9WRdG z4I4M8m!<^|Aaf4XQfD8>;|5M4;`bp`0KWdP_0@2fl`T^)QS?Y#VxIV_`wdFsH=6yC zU2MDfXsE=_*c&b@uYUBOcYC6($1vG!F_{YUL`vj9A>`Y(Hbv;cnZK58(qgF3J68U& zlp)0kE{q`9j66C8_R}4doWeY}cE4-pcrd+W&!f_9FogR9AcIAV3s#WIR2EyzrB#3- z*&Z^tkzQxHA+H?qJHA&^y1gzrUh>%nhTCaw-+Wpuca2%fg$~H7=R~o!B z7O!e`_XRg8XgaQM7PE6C&48HDzQs75>&V*3*y8?>n@Wa2&Tb94LZzNEv`xy683Dlo zcDtCIhl=~D%nn#oA9ni>AWr>b*hoaAwI^lu?~h|0zyN<=I2^iYwTh69BUs6nSboz$ zEivf&UIS6XQxQ23x^n2;y%_PHp)6;^T$k zmli^0+zp*>6v3Wg=`|3DnmVcB&6MXeibTOr_Jf@1XcR)M?kFNqJU7ZG2=@b+A(1fN zBvf+4y(luexJJ|6aDzgxO+SV);R3*hOD7ulK56C0g6xAgI-H$PL9WJaBh=lNhe?8X zMAkg-mn1ncBoP{ zxKwtSPIwxYODC*3!s%dzfsnz}^ z@epNLs&H(2LR>Pobz4F*w8SP=cul?^a9CgeCM5p@IOt~IorULit8C58@wvxC14*3j z_dTfbx&HxJOr-RG#!Y(ENRm0NfeFbF7y((i2GqjiW$umh8OG;<$a-y`l44-^Ry2*q zDX7%+SKMhimso7fk2U`V=E9TME|RbN`|jU7i$6l+Xj_OpvRy-w&RKh8M)M&7X0dS5 z_)7ZW{1X0__4&W-;9r3ab%=qwf~m2A$5*@arPbT_8wT+};!TcL3JC5pc?Nw9>_Omu zVw`!be9CgM&OdE@!Wcsh6S|**pvt^9*-l-%ki1M;n!MfM_@imDY>wpl+0SV7srS|9 zlgy>P%2~tM(WC})tPQ7t_Vu5-)qH;-5(;DdA9A0#hRO00&v_(us#;o1H2ViqZjYW; zVbUJHmCx_)uDgnMHgRoiO2FooB$0Fs1h&Cs6I8Sa3X-V<^6JQkdiwlR5@EbJGv?TG z#sfItGA7%%cfDmM&CjDSDs_G33CK7R%>Xn*59W9h5J8G!kyI3-dwOo8^ z<~j>bPRZAY$m=|hAZ%h2Fs&S2IW(umO~PD-mY7((*Ha1Zc^+0Bp<#blg4LU$%@hPV ztickr(lNEkM4|+P_nhVs9@}}YTe=~Gl=c{dz0Q;prc@@lVfoUI67TYZuj@MdG+z?0 z`(DhcGl&7-BGaqeL7FLQ4+j}NB<$T1*1)@zhNe2gK%H{2&B*7e_rxa8P~3J7tz>%tJ#i?<2$)KyOn zg#iV5Ca3yP=xV;{Y}U-6(5_?a^N=Uu0%zoufWyo~N^$}|dUQrb7!{X#Z*_%L`oJze zItDuzw)BQj0-3`*LqDH%GN#UAo$?<0s#&*As3tp0%I9I|fW{ z{%pMQH+0!FHkFJ4M$FCFoZ63VbWArAS3YUHWA?0IkE%lT|F8_ozs*-XH1}r3B%o_# zC2ZHcGXt^{&0}=Hic*4$0F1zy!{{Hr@ZC42fJy)sQm6wH@S6wy$m{jw0JS=zQSY<7zuJ$E(NWF4^C0&;bf>IMUd`AK(mJB=sdXI~E+yew_oLEEa zc^;op!ukyghp67j;-VbK7p#&5PC)c+~=13Y^G=@?Ww?!rxU!ST{d4Nq~-*IPDG~BgWU|cXZTiKGtS`f``L~# z!KSH}>)dw3cRNj=Pl6F|xezTtybMguiMBomhLK}%wix3-*#nb9yUa0?o;+XwTqE!^AA+??vsO&k>6Zw$h>n0o1%j-1`swH03 zkG^)>bF>LP#B0^|4zh&|2S+Hi-}G+XtC@@0>6A{nEC28bn30OLBR*r_z#NJvSOQ^I z)WKJTDcWAmTK@xNznlg1mz}oBtRbB9B?Ox_m7BA)gUjVPL$K$cZTmFNEq|A0oxboy zr-WZ@IAS*`XPpr-YamFjM=_7&kV+t^)S%Ps?iS;tQ$X27Oczhv+*=T}FF*RTPNs$7 zJrT8oaYobiO5~C$O=0*-pSkX9%27ZmHR8-*@er~BCPPDkhH6&O;OV&{>btkGD(rlTPk zmcUKfv9`5%pAEvKe!u;4hIG-dP_*e&rdP6JR}ZOIA*(%&P>)~Cc)gf;*@$vnOet}^r_yFj z36y^pEoX5zXfbT57Mf{uQcG2+l&+p5G5-o`+2LBON-G$=DCi=CAsSmTI}U}nNlHqn zqLE$vl;^vXE;55wP<;VQ1EWLk)pkx5t$8r@cq6v3x3x4cY6yII7HrgZ`b%rCO^(+{ zB=HDQ)Qd_2L7+6AX%Hu?MBTU6)q@X|=a`Fm##v-y4j&8IPMxwq1msl9U{GkXLPRj! zRSfNTnYN4|dos-E?bG`~;&2W_mfn}%!(v8aR*NENdd&NS zH>5&>iHhT~xq$NQ_`BqU;kb%_M{f?@%WG*nuU4ZC#toL6P)T8FEpV+8e6JLRH)|B@ z6M9^zqH=D-r$cm^zY|WIV@TH#x@ENMGVy9aquYh>`v0`(3{JWXpNn-2$eNJ5kPMJE zlmI;~H80jn<$AX@XCjd3sWD!g;x^^zA?ehg9-C{Fl&|)!yw} zB7%OsN}iq}Vj_Fw>WPD4{K^T2XDdJWYULAywk)VYPE! zgm0m;G*j;pBRBigbUyn=$#;lhmKHxX{Oq7C^Tdz|Ww~ssOjveKMpa1>=QWD;{ zrB$gWJ`cK`qE<;Tyf_@~xWQFPJu98CCV$3`Adm|C$Y$qXlW(DvzNS&YAf_Wt+UB?Kd;t@rxU=Kf8$((^G+rQAf9pq%jC$V!MH%SfJnGPY5_d>llm zf`D%#%SULYabGGDjLnL|D1atG6GF7tuJtAf>-ue%RQS6_PgOH&KwOI|;aZ09qjR&g z9ks7p-4`aGGulvhFFsPC45JDwR4CY`jz(K4D`botl0cNTcmOaA+B|kNTE@4nm%Ed| z@^q~J0eER=?awOWJ6myU@yUl%)1y-!c!ugDv=3c6IKml*w&(I(aUVc+cAwBtLlop{ zZ#1afZl^UdL@;NM{~o`DH1iYqsnQOsGi_S|=mLZVYvpN9$Zs(Ms+Wb}-yQ5)Ha@nT z!OI`LeuA3_-xqiyDruDJvZEGr!5{Q(mDCDL6B{;TOPT?i6VTDJ;&dMr&KEWbu*9H> zy$mzOlZb35xz#oM8>o~?_F;>9JIE5Jan(r+ zP&^qSl61zhEo8WcMhCMx$I@4K0sYQd@9yrl9F>T{2?J`T3c7g^XiU{lcCMwCkQpG* z4K_ys5>cp#4XN^K{hfIKKLE8rO25;tddx~fwF2b9Qb9b_{f0*QG%tUT4wth1{P&B; zdqu$*Hu%OdVcnPI_bVqnC08*HVN%ISQqc)!F$gg@cnZRJf=Om9K|)=yNxN>v5yYiP zNU22m#YD=&E=h8tNvfQ^Ne=E6`?x}jF}K~Br3flO#4_mx(gzVri6PBR8oGxTHw&)s zkMLF2@QMA7ka9R!{F)DIXHig2mglc*yMEiWt9Cp~dXY+^F)ou+lOc+1Sn$yE-kOHe z>%pX?tzobb3e* zQ0PH&fJ#zIS(EhdNT%}Xmxlym$YH`q2=bO>3gsBklG>8mIBai7G@Mvl)8kVS03|#m z5K^H2Q7{0eS-wLmb|LwgaiYXhl7$qcGI9>tkP8~0eC%my)|=_&QpK`r6Kv~dT)9@& z9$cwXDR9>8i7rBGo!3@SIow$RYf<%-qm#K&Fg~to-l$vpm44A_7nO3IO{d&4VL+$G zFhemSHy)Uzw9;2db!lw{*GfX1UOCC;AdVKv=?>mdf%|Mp?h`rltZ!GLt?%6i-c4tO zVziP~!YMEuy#*sx@;cCi&d7hsqyGRFeIx6&+^iL*Cs`FFa1S&VsV)hj%nw-{n$M%9 z`eqVwV_Mk&;3kt31o(6tZ~nd`6zgWMsYwdIZXgL6C2$7adi(|k{{WPanR3kZgYO{< z0$_|%hfrb~W9E;XU#@zcJKM8$*yj2>ddGWA!Z=d-#ZgmsUiYLZ6TV8Q=#3HpJW7U@ zswv6^mMYFA@WXGaaWVG{CxPiuBZl5jI-AcJm7TVI4B;esm2ODtk zu=RUW>i7MZOQ~LUxpe9GRRRRakE#)7R7n+Btvt(6bL+| zgOrc~5v$eu<*8v+Dwgd^RU)PFn%at~kvo*WBFJ*S9gocPX(&g98m5|OY_d1&+xSo&-kqlT?zVrB}sptz?w~xH(EUAb&DCoM(QXTMiYvx8vLKaB(6t zts|XkU#@pQn=4H(zP{fh#Y$6%&@05H5gn3{LH<6Znhjj)&tz}{;zZ#{C2COs0^0iq zXR@cAvrd@^2}otfUcA)d$vP!3=7XQ6+1IC53Q_}hg}Pi=z(}RW7~6FpS0O0`{T|LR zBUd#!#TBmht@0&DB)JQ&at73#_>A=1ZOPffwq?DZ+Ht1PaJCk`u_Q#@x5eU^GoDJQ z(BiHPAQY%cS&B*oM=4s9=kU5xQcKzJdaxwnI$d5*4~XYZq&ah|dR&s_>@^z#bGA$Y z%-(9wxx-7j&z?_KrHPP2SCYXkPbP*-JCBJK&%m`A+1;!f_Ku>_t@`D&8jVbWN{;<5 zL+>>PJ5iA9#$iWz;B6`9P(o6GNjL)l0i2SWZ*W&GdnGj+f~O{}IlGpt5xG+PqUs|x zPounsLYa*i1SQ9uSOp3pOC%f|aKrm^-fwGI4{6w+4BU8uX}ct*NtK5%V#Hh|Mh;+w z^@E8BE+N03gqC}0gM4kcOh~2}zu^M7DMb?)FfCd{VBGTzLo-{OZ%+awZMow3aMI+= z!>w5UGy$h{BZPisczwiaAn<1xm^BB*Ry}qTh78;_s)yx$2QA@T=3}!;0FXC6-ua!~`uAG{@?3U&x7cmgTS^kQ2NaQoM0hrUbm7MHp-IUNOHnj-2z0`gVkG6aP z<>~&egN8f$v8ZnPiMwjyv5mQ*fTA`8flM0@!ATouCv&o<{dZetG&kfjatDGaBmV%p z-j~VyyB@`NkJ_Fu#@8+%y>Hct3F*X%uO~5K#fc0QIs(i?z!c@mSwwQoH|WS!`+3w%kN#l!p+mQ-vWw z6r3C!5x5*VY#l+psyCgr25rewl@?`Y1ZgZfVwT=v*$G39I1^87lr1|b1*aoyjre~n z>^wLGf>dCP$Rv>sIgrKbH3YqT8N+G&!R=2A?E?_u%bNO8kdmEPl|*o;i-iqpDoir8 zsBt9#GD^Je76*xmv(a8sQ6@Z|8bJw62y0r}iBD7kG|qt2mvxv|Z!loW?N=5ENdS3Z zDq5HlJnECoy-S?C4Tfz3iA$NL5J)893!Ok*NAY&_#m$EvBuL2-w`Le$e`SU@>KaB?=-OCnImiYB86&93<=H+-80o$^AKlcO*&~q`Ek__= z0Ag~Zu5pTgtgoa4xhgveIKgpI$mi`#Hx&vcBR z4ZIH#@{R^K-^cTO{?43VN?s8l5S5a+T#jjc$f%~RZi9oO!C-xqsi^_WA7 zf+{`pZd9{D+wbq;ZP#Zc{g+%J{NIJ{;z4%&Avp|z^_n$BlWOcCP$xQ{RHhuFa5h#W zz79u$C&Ukb3zpNXHQFOf%ClFca;qnpVx>+zq~~Xu-wK!@j1^m=+m zwq!1lJE>5%z^IbRB|b?QsSoER*A2*S{HW9|O9VZhr6cW~F_mE_(5q!C@K$6Uk4ztF zI6XS>Uh5QPuF1U}MoCP{N=k9L0_a}p^F2XNvnk2jgbqy$F(cl#qr|Re-c)vIeyc@~ zZUPQA$yJod!&Bu4i@bnNyvVf$7#EbVDWZcKw-hyzuB`lv5!ywkfd2pnrL*c3-Trm8 ziFt^!u>z85_{e%F9S(n3%r93a6MY&)Z_-*WHqeEiV*?go}IA-OBw3MkA zE!r50kYNG{IkC(U&Vs=&Y4$>DY9BH>^By`46)Pg5$Hya+^lrT5?-A zY*3YT0GnlGB$3x`(njQMvVj~9mq^4#%kKd^w5X*?gD}h}N0j7iP-^t-&d5?Y6VL>B zOd_OJITAps4NrPaTzAoR^pJoy{{TLfe-SXpKjBB0e?2v`f6GiNULa7aO%|WZ9=eRd z>};%3X)ApCWn(&$dDCw|!Te=H}`>mC#eL&IrBU<2(B#0I}&5Pb4>_GcjN?;J%>b0yMnLG?&J2Vgcm4muy7 z&y0-lUl@oFm_SZJ!h`2VtDj?Ap=@bwwA>P*nsF7_e0-rkq8{1;)(leuC(MfpBr8;` z@oSiRc5w>Zdf4PRkoKd3;jRAw)fLzVt~{U~DrOnHY21@rQ1}9}oD7ORNRJL=dJNH! ze0)Li85!%ts>e_6>dYg?@3uky)n6DWzJ3R&&f5{};MMSK2g5j8Dt`96n(8?_EmF{l zPid}Ao7R>WUX!@dk-W|Jkr6-%SgbodtzZn80M035p1?4l3gL)qs#kK|Do>7A}ZRJn5sDo9#>Yt`H4)IC|# z*+XumsV${RP~|xFR0k;p9~^mutsLbmN#+Fl$tRm)JTv5Yv@=okh@s;C(dzuo zURq^qjn%|jlvF&|IVe;!YD4>)+6WQJtTF)Y1+vV7ds)7#OVmsuVQE1HDg-iv%+40&h;Ta}KV2z8%h7;)CB+_zcGlUYb4)P%7wn|C`o1EQ!+FK*D!gA408^er({{RBrH6&>#1DPi-$36DuS8vARV32uIoUbd zV*|)_>%X^gzXzvgrFVK=UQ*TSt5F^a<|i9jwB-I1uiW<*9qrVyJ3a zDonb7Q9f`6ZZHkpT#9pgv$mI&Oott6^Qfj{!p>FFjRq_o?6Etbgep;WaY83zu}}oD zej$_OA3HX@X=uf9N+GF9Qj|diH=SN#fPZpqap;#P+M`cNC{kBwQ4~H&0Qxov@*O%1 zeR(67Xky{kOZ$|l5m{huox-R#!ji3y<9?^Z7(4My&PEh5mG4eo=DFJ?*R071s9Eb6 z9w5O~TM|JP4DK7zY(SHlKfJ5bp5ETWY>XIDJdtpek{9QMrNft~VhI_N-QCuc+zsJ8 zp&1KFAY*j&IoomKecVHhDZ$Pc&+8#T6?1H?9AhV9d@;Y57G`oYmyEZ1_xe9IyMFDH zQJ1%Em?y4Ld{rXh$Z$B`fDeA#aL*!|{v}?N{eJ#7?pw4;%zeH#T=0k=Wl~ODPyn)W zCr~o4s>qjTbS+z$;k~Wu;rt)qnuqK8ID2Vte04icN8dNUEZ-G>WYkROewfb(i*h0& zZX1JvL~&hLaXFAjlEFN)1hd#SdQRpeL*BC(r>;;5ga8iVys9}PCk*u0F2Q3qxS*|f z1|KN|k#t?o+8-r@K~eRF?XYEZp-N1Cy8K=f2}%lt?&;EQU}W^m#@w&$D6}hAt~9Hc zKNc#zc}`Eljg9l1ZS{LI!L_eTQuKoOO42ptjuVU zp`}q)q!LPjAOZqTZaI!!yzT7d($O5D5lT`5Ljy-OC$pD;8rn%Yc+jGiL_tD$OF2zR zVWB50Qka&Qi5eo)2}LDDB>AF(gEc)yPn(Wn-D|^T(tS=)fIkNXM4b5yf%S3D@~3;8 z0_Q(Ie+ZsXHt2JV_;m61aUNAL58ssigcxyQORR7nwM9&tJ!p}eWm=tWR|9;6BsY~10RcM#MovK6Z2LFj z){CKFtgM8BaCxv!HW()d=RY@x9n*F>xT@Rs%>Y``pR#BS12b^M06P{fT20Ft)9?yEm{l@y%bffmfIa!^x&1sJ9h%lglTK5m zN#@i#&o4GcF>6o>$2Wk;8*DZmcnyw`NQ;BK<~fNGN+j^86)4adiGY?49q4;snW72u zsfzq!i}w2teh+2q(o%@3-j^D}hKEQHiijgI9$|oT3Fnhjvd9@S@q$~cE;OcZmU;a~ z$JUVs)ut8_)yb9Glr>=EVdyOYFnV;))_558{{WxuGNRugnf+-E169Tiz5bvPsI z;<%fPXcn?gLWaKEU&e~4P?DY^Vw}|A^Kvqy&`{U8?PV&k@K{uHD`WS z_AEJwu?Y~>!^8ln$Qo;wXD-`FDobiu9-vA_NgSg-L#E@|#6~;Bp+xhQD1?EzAPn!1 z4Z3vc$Elc%;B|_t4G+-PP&=;&+wRX)r|Qvuq?62q9u(#JY@NLDrfihl&U~N2nAt>b z#j6>PIc_)_Axxz>s*6nX_0K!EwW=Ze^9X+SVht`ym ztxnUk?a3ECDM?22hWi?o>UgPyOi;wF)Se- zP4k6V`n+;`V&W1MrVr;As|?MumuxkTD8(m)vH;YFa#`7^&sx4#>64)WlZcNp9DsTxXgOL*sgoWnmk`iMLMcEsBT{wckSyZX?o^?maKMl?ZFM}YL^MWRSIbb} z`&8p(r}OXB<9u=DtP+$XWF(L8mCd@3o(^%Jf0h)c@8q4dZ2UQ6dMr2mnp%$D{x&D6 zd3dqlz=aJbiE{9R00#)_lH~RzW_vlch9h@~F(d7}XKRkdl9VG*9f55dI@kj3XCyIk+DS;}b#z$)2pJ@wgcJgfJOSUs zIKc5d8d@V5zo&{)y;jqA*142+&n+f`N=JviT@nfEa5xwZ>>t~Z@e+LH zt(8FTSJXk* z+qr6iBN)%$TNwkuU~D@0l1V&k0IBmnCZ0B{#2uc#t5LLB@x))n$RuP>zh#t$>_J~` zTr8y|fT_aS*0AyfRA%h-w*q7NHS(5I5M4L)Dk*`f}$LsiKAAb@)h)(4yN%}j7a-f#fd@S zN0op;H6fHM-&Y6KVi?2-Qei>^i6FqLUX+BvIs(}o#UDEkrtlQn&MX>hZg1YI#im52ZdMEZ~0mk5;9Q_`APdd=z(`3Aa9$(!R6sYu3=8IW8qXS?D z+Z>V(;UkVhg(y{8^KedXOEfxwoP zXKWq3di(SFy_`}j%xR$nk54{rYDy#mYsvfhpL*M+9g%GvDk)YJy#X164Iui}mm(Z` zEk#=++Br1Bm!Skx;=>>M)EQUDCbDDGUE)d2sd8i- zW8g}dAdfNVdE2K!j)#tFTs3g0UGl6$g?;Si8m{e9#CTblH|xBS zF}5zQDeS?dv&l>;k1HO800cx#`*(uK?C)qn|q(`H`ZUjgF$S+(hzj5l!J z7pw_Mb;FM_EeQ2!ilw1xM;Ra$03AUpR||)#n!yf%I}N==nDn>Uiqauh2c*91Y_@`_ zMJWZxR@yM790ZkRM`VI?!C|U!>Qk+2$`vvU%AA*^(v*l$qrWagfxDT-xVD&%+s>Xu z0=20qCO@#r9{B4BaJ0fl3dVq*Cofi@W80a& z-O)mdpwyb>9H9J%eiMLtcx1}S9>eP=#1W1Jm1*7aB_+lzyRAy`0^O{7$9#nkK=oF9 z{z|;gd50x{UhPW~4^X3>NMd|5(>6V})0DGNDcW=V)=`kQ2etTjdn*Fpd`N__q11{L zxL`_{hi_h1)6T(mz_0a(eFLECQ{X;zNv~xx4{M@aw%J^R@ck5|x=!_4cpH@vf7^SE zbnqVTJu6P{{4x!Zcaj0vTXn6^D`Uc*bB>)z>&CgW38<3T{{RQAB$4(-b%h|BC>fNv zFW4M*=xPa$?D)Z&!Wd>^7HYXJ@SsPWpNT=?RVos4C$)eU66_VQ{j1%0yA57b_#XS0 zl99gd>6xhAKwnb=6m%*qMI|JtgeT5W0G<$NY*_myg!oS4V&L3&UpD)|uBVtitSl1t z%$-f1n>Ix{bUB^NbyPaIQe(cZIwVvBIw>m@Hk` z%#!V>Aci?-X7l3W2D~I!u>11;7Ixl{os(mor0vf1ys%~$y)U>DFrv!LO-aB80wy}% zFD6>lKwLlpCxo6C0I^e9zK-sDY)Xm_&hPNCLOO&{yAVNJ`1p++oze@U-)BthsPgM{ zcyidcpe96F6*w$B%EM|nTQ15&h$ST|0cc6WhCs;7Nv&Fad{i|u=$}fnu9}@XTlB{w zPl0dMrNoedK%gM0nK9tI9n__0aRp7dq?I8Qh=4{8OrYZQXB8+&0|u;B4yu0Q=F-0vj~7c>Dd$rIg*z zZPN%ck#=>66zAfJfQJV#Dyk69lUJ%q$={9LcDfr&qU4}pgWf0MnrBXB0H6%tl#n;` z0P!8UraF}Ci)-zDdgNofSH)WK!nr{yBjC=5pdNmEal06krg7M$tW*4{Qx zyXM+3{?M?U`Fd>k5K3K_Rr_|%PfV&@L`(^2Qz`3WtuV@#P=u0K!j%vKQxFLW^_!;G zc7aqwR~-SzS4pU$meEek&iheEb{4@GfRkJ1*oJ%Tr`kZ zz*G`QN{f~p&+LIzg9ljab0^J-0x~ES#HsnRSct+_x|b+yyCv3J3sQjzNnbLQJyGOo zYgGoZT+>_nmqMjfYjqcE*4wSYq`{X_n&V8}btSs(q=E@( z)y0SwuZ&v)!_F)#Km+NQw_AA*I@1v)Q4~;52}vaOdO>3S^{so_w^`fij6vCsB^*ly z{GALdub)C6+oiobs_pU5^)$q}pWvw;t~y(&X7aPSKsQCUIg`{@={_UR)BO5y1q~(D zZfuP=zji%7DBMG)_`#+0$6qcuB+-isBc*Eyhys!Vl)!^f3$r*f%R%ozyn^OO2Z1YMPHFK=d?5?C`aS zy)57`tESt?+dmD`dUzB2KW)7K054nBqNGO3f~_Tt|7mO$H9JmJ)B}Uc~YZo zk7np9JZZ(ZYJ#|kSI<&|H#Q)<^R8ArOe7R=#v7?0u$NY(pTOW&ndg~q*054+OLqOW zVQs8nEB^Y~{v(pQZp=w{%-$1mB_15KvSJXp@dP!kK?o`ZWF<_VB^nDGZW5P3!#Hi! zT-=vIs$V%c2a^{B2ObrrxvAUQu}Z2{wEfyuN(D`p>GhN?%6z!f8)?N#Wo5S)73b30 z%5boi6rNL%F~0^ThugOmsim``T+|BHzcNmsOMX0R-7bAHL-CPk(;4)JTAdm@j$-Zw90D(Oi7Zs&RH1^rI=T{XgNlMm~sW}A@ z0SB>}!4=m#JHJUL!*-#xZRhb_@q(~*`G4J#y=;tG={aC!gwiJ?L{uno7Nm%ZLKF(h z93e-9soYrzM%_PnD6kR5vkXWAXci^llA^#D9b<=QJ-H0cjr|?FZCH9)r%|QcR2Z_D zw5aV!k1DNAVfLK#K(0qwc48bugCLZx30MjQq-S_nTy)P;D>|`#RH+sf7<64wi zf#NP5Bmy5MY{h+6??0_4cn|k9#Qy;1(EkAQI}fALcPqMX@Q{?T4`vvWAt|U-7%2cJ zTEt_^oeO1YDa+c-?auOt8yMxa+Psq@fL= zN?MYHsDpR75Jn%vz&&nzw2(^|@>n2p&meong72jnaiQ;Ji~x$TI-G)()SQ^n`IGI; ziyEdKf`wu1JH(p~Q%!2&NiJc+`MWljggE2QNDg)v46YTDfG@=R~K*7S&0!B75vaU^u#} zLufBZb*8!2QbH0IRIXA0Bpej_uSBif`d@z1t=dIWw^LQiXh=*7L>YAnt6__lD$6VgBOQo_>DnDip&^EDJ;Z<^|fd8nztjGd@7KnE zzQlJQj&sOsYx$V5A;N@#5nN|AaTg#8`bn=pO}p$Z()WSu65BGw%VWd=mV`2^5@G-a zKN#~3%B05XJHbU;otWZ8@Va<>o*ICw<{~k7uO@8X-Z!&4NwKk9(2|>y>IGhE?%TM7!sL9C37~V#>e;@p%>LfB zid9zQu%4vUY4s*iMX9pm&?QEg({B2D72U1KuRN5w$U?akLb(Vaa-8sDXqCHh+L~D8 z8^e^HkVL^Ag#3^E14xADmqEx#T(b- z&KQbFbPy6q4dpWcGf}>YzI`|{^A z22fAQ%6yt6#2JYFbT~^|k=Au#NlKQ7KwGDY!4^j_w^7^c@qMhZD!4r246G!(bK;6A z-Rabxx>t7Eu=LKujV|G!#*-e?p|t#Y6>4KIvg%+n%-gLyF%CB1DgjAa5}-)RQg-49 z*4;AHingw54N8?^-gO#m>yk{EQ{dY*$#EseTskmA(WEg?afjMhD#Bc8#i2zC2~p)I zjtsS`3WRrOOdGo>q;k0O{gX`LZRoc=K+}qF>d`6b)CLMQBt;PiH3|s?9OiU2$~TXla(4MCB=NIJE?&2}x3xppXf`;p?V4VW|-HBEXk6z`Y?t ziF(^ICQO%WS7XMD9h$^9Uy~vCsfcNo8EqH! z4KGrjC=isRN1zN#5aoq~&weKx&tr6w{{R_U*XPU^sO&Y@T^z?yj1wN0$JQ zQfrM0wO-Sj#Xf^csn+JA?6n>csW2tfWfmK91Q^}z?e))g+hivg$5lD`B`g$6Vuqt!Id~PI*?go*7csge4_PQh)(9B)>0hXdK(J{@C!N>r?nfyGiu0Y&N9EuG7{*Fr!S6$wjF z!VoJI(o}Jdf^I+_C*OnRuHKjGJBrD$uS6v$Dp9rTfD9aglT8CBZo2`w+pf{OL}+sR zZNPD&W-lHTit#9vf>N5$mK;Zxb|_hx@nN0IY(Pf(am4l@kaVI4zNuhvLwa z^*CnqSPkt>Hk~@;wBorhjRRuV#pBrBBk!O1N&s*zlw zY4U0Hx>ZVzAy-{yK#Nm@E(E6;a+yO2crz`C?kSR_Eh$n`P^BS5n5iTrSogL5zSzuA zw88=GJW(?5Z$lnd<0VaYaE&E{9&{f^ZIw3jJ1N>GD%&nGz3}!Ey{{{-Eb5^`oPh)4 zqbd^OCMQ-_L0VFy!W5TEjzyl_&}x~BDG0r)~M8ky34gFEx6N&g&&zNHn~AaT6!reN=knTAdVnSLa}dIx`};Eg=k#! zB1yQaF2gI0bthL-9I9%1I-t*2U81fj;(q$mufL~p`+Nm(Ez$t8fyl5zl6w%M-h zv>>81%N6E`R3LIHrgh69Mz>s(-S2ABNik#Ki{Qio%GC)0FxxN>6KhjbM*`M!yCvG9 zUK|V=dYYad*@{S_Zd%-OFZp z?+$G*3|_b18N6g}=r@8>7G^XMVZ$*LgdnV>sHGfKD?Vr-J7;7Yva3TDrNYw{YFp2{ zN2s=hqI@?Tb!v$CN*h9CDN0g~$U;FR_!GmgPi-s3i}ur#F4nl>LyujjJp0mUwKiB` zrsRURq&(y_AqYS@Qr4uQ1AL9tUyl%>p~7Qcpw^G~ssYQt(XEFgcvJmW@ncYlupj)R z^w^Lw6hATxk{VowV^)OVYyl12$&nXb5p+abJOg9Va z%9+rWQ;0fA1&df=?8`DNTE%JEa%0A5(pyh?A?BDtS(tEyt>w0oq7q0*B;XT_0(h6T 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%0AL=cayoDxN7n6X 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

YA{7V6s~!b`hx#mg}c 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

  • PFVJL>~fc)i3377$>x4&OS|_ren(% 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%0AmsEUvA69KObK_}*jO+d9 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%0DW8oVRM;5 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 Xn{hog(%Qug1SrV=yVJFP*RuWr9mkI| literal 0 HcmV?d00001 diff --git a/demos/textures/normal_map.jpg b/examples/textures/normal_map.jpg similarity index 100% rename from demos/textures/normal_map.jpg rename to examples/textures/normal_map.jpg diff --git a/demos/textures/oilySheen.jpg b/examples/textures/oilySheen.jpg similarity index 100% rename from demos/textures/oilySheen.jpg rename to examples/textures/oilySheen.jpg diff --git a/demos/textures/pattern.jpg b/examples/textures/pattern.jpg similarity index 100% rename from demos/textures/pattern.jpg rename to examples/textures/pattern.jpg diff --git a/api/latest/plugins/node/reflections/textures/clouds/a.png b/examples/textures/reflection/clouds/a.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/clouds/a.png rename to examples/textures/reflection/clouds/a.png diff --git a/api/latest/plugins/node/reflections/textures/clouds/b.png b/examples/textures/reflection/clouds/b.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/clouds/b.png rename to examples/textures/reflection/clouds/b.png diff --git a/api/latest/plugins/node/reflections/textures/clouds/bottom.png b/examples/textures/reflection/clouds/bottom.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/clouds/bottom.png rename to examples/textures/reflection/clouds/bottom.png diff --git a/api/latest/plugins/node/reflections/textures/clouds/c.png b/examples/textures/reflection/clouds/c.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/clouds/c.png rename to examples/textures/reflection/clouds/c.png diff --git a/api/latest/plugins/node/reflections/textures/clouds/d.png b/examples/textures/reflection/clouds/d.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/clouds/d.png rename to examples/textures/reflection/clouds/d.png diff --git a/api/latest/plugins/node/reflections/textures/clouds/top.png b/examples/textures/reflection/clouds/top.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/clouds/top.png rename to examples/textures/reflection/clouds/top.png diff --git a/api/latest/plugins/node/reflections/textures/london/neg-x.png b/examples/textures/reflection/london/neg-x.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/london/neg-x.png rename to examples/textures/reflection/london/neg-x.png diff --git a/api/latest/plugins/node/reflections/textures/london/neg-y.png b/examples/textures/reflection/london/neg-y.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/london/neg-y.png rename to examples/textures/reflection/london/neg-y.png diff --git a/api/latest/plugins/node/reflections/textures/london/neg-z.png b/examples/textures/reflection/london/neg-z.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/london/neg-z.png rename to examples/textures/reflection/london/neg-z.png diff --git a/api/latest/plugins/node/reflections/textures/london/pos-x.png b/examples/textures/reflection/london/pos-x.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/london/pos-x.png rename to examples/textures/reflection/london/pos-x.png diff --git a/api/latest/plugins/node/reflections/textures/london/pos-y.png b/examples/textures/reflection/london/pos-y.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/london/pos-y.png rename to examples/textures/reflection/london/pos-y.png diff --git a/api/latest/plugins/node/reflections/textures/london/pos-z.png b/examples/textures/reflection/london/pos-z.png similarity index 100% rename from api/latest/plugins/node/reflections/textures/london/pos-z.png rename to examples/textures/reflection/london/pos-z.png diff --git a/demos/textures/reflectionSpecularMap1.jpg b/examples/textures/reflectionSpecularMap1.jpg similarity index 100% rename from demos/textures/reflectionSpecularMap1.jpg rename to examples/textures/reflectionSpecularMap1.jpg diff --git a/demos/textures/reflectionSpecularMap2.jpg b/examples/textures/reflectionSpecularMap2.jpg similarity index 100% rename from demos/textures/reflectionSpecularMap2.jpg rename to examples/textures/reflectionSpecularMap2.jpg diff --git a/demos/textures/reflectionSpecularMap3.jpg b/examples/textures/reflectionSpecularMap3.jpg similarity index 100% rename from demos/textures/reflectionSpecularMap3.jpg rename to examples/textures/reflectionSpecularMap3.jpg diff --git a/demos/textures/sand.jpg b/examples/textures/sand.jpg similarity index 100% rename from demos/textures/sand.jpg rename to examples/textures/sand.jpg diff --git a/demos/textures/superman.jpg b/examples/textures/superman.jpg similarity index 100% rename from demos/textures/superman.jpg rename to examples/textures/superman.jpg diff --git a/demos/textures/texture-atlas.jpg b/examples/textures/texture-atlas.jpg similarity index 100% rename from demos/textures/texture-atlas.jpg rename to examples/textures/texture-atlas.jpg diff --git a/demos/textures/weirdAlphaMap.gif b/examples/textures/weirdAlphaMap.gif similarity index 100% rename from demos/textures/weirdAlphaMap.gif rename to examples/textures/weirdAlphaMap.gif diff --git a/demos/textures/weirdGlowMap.jpg b/examples/textures/weirdGlowMap.jpg similarity index 100% rename from demos/textures/weirdGlowMap.jpg rename to examples/textures/weirdGlowMap.jpg diff --git a/demos/transforms-model-hierarchy.html b/examples/transforms_modelling_hierarchy.html similarity index 95% rename from demos/transforms-model-hierarchy.html rename to examples/transforms_modelling_hierarchy.html index f1943f36..f30baaa7 100644 --- a/demos/transforms-model-hierarchy.html +++ b/examples/transforms_modelling_hierarchy.html @@ -68,9 +68,9 @@ nodes: [ - // Box primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -93,9 +93,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -118,9 +118,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -143,9 +143,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -168,9 +168,9 @@ nodes: [ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type: "prims/box" + type: "geometry/box" } ] } @@ -204,7 +204,7 @@ nodes: [ { - type: "prims/torus" + type: "geometry/torus" } ] } @@ -233,7 +233,7 @@ nodes: [ { - type: "prims/torus" + type: "geometry/torus" } ] } @@ -262,7 +262,7 @@ nodes: [ { - type: "prims/torus" + type: "geometry/torus" } ] } @@ -291,7 +291,7 @@ nodes: [ { - type: "prims/torus" + type: "geometry/torus" } ] } @@ -323,9 +323,9 @@ nodes: [ - // Node type implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Node type implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } @@ -356,9 +356,9 @@ nodes: [ - // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type: "prims/sphere" + type: "geometry/sphere" } ] } diff --git a/demos/transforms-model-matrix.html b/examples/transforms_modelling_matrix.html similarity index 96% rename from demos/transforms-model-matrix.html rename to examples/transforms_modelling_matrix.html index de26bff4..0ef4b0e3 100644 --- a/demos/transforms-model-matrix.html +++ b/examples/transforms_modelling_matrix.html @@ -57,9 +57,9 @@ nodes:[ - // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/examples/transforms_modelling_quaternion.html b/examples/transforms_modelling_quaternion.html new file mode 100644 index 00000000..5febdd10 --- /dev/null +++ b/examples/transforms_modelling_quaternion.html @@ -0,0 +1,138 @@ + + + + SceneJS Example + + + + + + + + + + \ No newline at end of file diff --git a/demos/transforms-model-rotate.html b/examples/transforms_modelling_rotate.html similarity index 93% rename from demos/transforms-model-rotate.html rename to examples/transforms_modelling_rotate.html index 6df9ced4..e0bfcbf7 100644 --- a/demos/transforms-model-rotate.html +++ b/examples/transforms_modelling_rotate.html @@ -51,9 +51,9 @@ nodes:[ - // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/transforms-model-scale.html b/examples/transforms_modelling_scale.html similarity index 96% rename from demos/transforms-model-scale.html rename to examples/transforms_modelling_scale.html index ed411c0e..97021503 100644 --- a/demos/transforms-model-scale.html +++ b/examples/transforms_modelling_scale.html @@ -53,9 +53,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/transforms-model-translate.html b/examples/transforms_modelling_translate.html similarity index 94% rename from demos/transforms-model-translate.html rename to examples/transforms_modelling_translate.html index 05cc54a6..e025a521 100644 --- a/demos/transforms-model-translate.html +++ b/examples/transforms_modelling_translate.html @@ -52,9 +52,9 @@ nodes:[ - // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // Teapot primitive, implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/transforms-projection-default.html b/examples/transforms_projection_default.html similarity index 95% rename from demos/transforms-projection-default.html rename to examples/transforms_projection_default.html index e9bd4b02..866d7659 100644 --- a/demos/transforms-projection-default.html +++ b/examples/transforms_projection_default.html @@ -55,9 +55,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/transforms-projection-frustum.html b/examples/transforms_projection_frustum.html similarity index 98% rename from demos/transforms-projection-frustum.html rename to examples/transforms_projection_frustum.html index 0580dda6..6df6a9e4 100644 --- a/demos/transforms-projection-frustum.html +++ b/examples/transforms_projection_frustum.html @@ -62,9 +62,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/transforms-projection-ortho.html b/examples/transforms_projection_ortho.html similarity index 96% rename from demos/transforms-projection-ortho.html rename to examples/transforms_projection_ortho.html index 21737175..6efcfeba 100644 --- a/demos/transforms-projection-ortho.html +++ b/examples/transforms_projection_ortho.html @@ -60,9 +60,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/demos/transforms-projection-perspective.html b/examples/transforms_projection_perspective.html similarity index 96% rename from demos/transforms-projection-perspective.html rename to examples/transforms_projection_perspective.html index efae068b..fd0bfeab 100644 --- a/demos/transforms-projection-perspective.html +++ b/examples/transforms_projection_perspective.html @@ -60,9 +60,9 @@ nodes: [ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type: "prims/teapot" + type: "geometry/teapot" } ] } diff --git a/demos/transforms-view.html b/examples/transforms_viewing.html similarity index 98% rename from demos/transforms-view.html rename to examples/transforms_viewing.html index ca032c0c..4411f0fb 100644 --- a/demos/transforms-view.html +++ b/examples/transforms_viewing.html @@ -54,9 +54,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/examplesold/features.json b/examplesold/features.json deleted file mode 100644 index 66be3e43..00000000 --- a/examplesold/features.json +++ /dev/null @@ -1,427 +0,0 @@ -[ - { - "title":"Scene graph", - "nodes":[ - { - "nodes":[ - { - "title":"Transform hierarchies", - "page":"transformHierarchy" - } - ] - }, - { - "nodes":[ - { - "title":"Multiple scenes", - "page":"multipleScenes" - } - ] - }, - { - "nodes":[ - { - "title":"Auto WebGLContextLost recovery", - "page":"webglContextLost" - } - ] - } - ] - }, - { - "title":"Physics", - "status":"alpha", - "nodes":[ - { - "nodes":[ - { - "title":"Rigid body dynamics", - "page":"physicsBouncingSpheres" - } - ] - }, - { - "nodes":[ - { - "title":"Multiple physics systems", - "page":"physicsBouncingSpheresMultiSystems" - } - ] - } - ] - }, - { - "title":"Importers", - "nodes":[ - { - "nodes":[ - { - "title":".OBJ", - "page":"importObj" - }, - { - "title":".3DS", - "page":"import3ds" - }, - { - "title":".MD2", - "page":"importMd2" - } - ] - } - ] - }, - { - "title":"Optimization", - "nodes":[ - { - "nodes":[ - { - "title":"Frustum Culling", - "page":"frustumVisibilityCulling" - } - ] - }, - { - "nodes":[ - { - "title":"Level-of-Detail", - "page":"frustumDetailCulling" - } - ] - }, - { - "nodes":[ - { - "title":"Instancing", - "page":"sharedNodeCores" - } - ] - }, - { - "nodes":[ - { - "title":"Vertex sharing", - "page":"vertexSharing" - } - ] - }, - { - "nodes":[ - { - "title":"Texture atlases", - "page":"textureAtlas" - } - ] - } - ] - }, - { - "title":"Picking", - "nodes":[ - { - "nodes":[ - { - "title":"Object picking", - "page":"namePaths" - } - ] - }, - { - "nodes":[ - { - "title":"3D ray picking", - "page":"rayPicking" - } - ] - } - ] - }, - { - "title":"Unlimited lights", - "nodes":[ - { - "nodes":[ - { - "title":"Ambient", - "page":"ambientLight" - }, - { - "title":"Directional", - "page":"directionalWorldLight" - }, - { - "title":"Point", - "page":"pointWorldLight" - } - ] - } - ] - }, - { - "title":"Cameras", - "nodes":[ - { - "nodes":[ - { - "title":"Orthographic", - "page":"orthoProjection" - }, - { - "title":"Perspective", - "page":"perspectiveProjection" - }, - { - "title":"Frustum", - "page":"frustumProjection" - } - ] - }, - { - "nodes":[ - { - "title":"Orbiting", - "page":"customNodesCameraOrbit" - }, - { - "title":"Pick-Fly-Orbit", - "page":"cameraPickFlyOrbit" - } - ] - } - ] - }, - { - "title":"Geometry", - "nodes":[ - { - "nodes":[ - { - "title":"Triangles", - "page":"customTriangles" - }, - { - "title":"Lines", - "page":"customLines" - }, - { - "title":"Points", - "page":"customPoints" - } - ] - }, - { - "nodes":[ - { - "title":"Plane", - "page":"planeNodePrim" - }, - { - "title":"Box", - "page":"boxNodePrim" - }, - { - "title":"Cylinder", - "page":"cylinderNodePrim" - }, - { - "title":"Sphere", - "page":"sphereNodePrim" - }, - { - "title":"Torus", - "page":"torusNodePrim" - }, - { - "title":"Teapot", - "page":"teapotNodePrim" - } - ] - }, - { - "nodes":[ - { - "title":"Terrain", - "page":"customHeightmap" - } - ] - }, - { - "nodes":[ - { - "title":"Vector text", - "page":"vectorText" - } - ] - }, - { - "nodes":[ - { - "title":"Vertex coloring", - "page":"customVertexColors" - } - ] - }, - { - "nodes":[ - { - "title":"Automatic normals", - "page":"autoNormals" - } - ] - } - ] - }, - { - "title":"Texture", - "nodes":[ - { - "nodes":[ - { - "title":"Color", - "page":"colorMap" - }, - { - "title":"Alpha", - "page":"alphaMap" - }, - { - "title":"Specular", - "page":"specularMap" - }, - { - "title":"Bump", - "page":"bumpMap" - }, - { - "title":"Glow", - "page":"glowMap" - } - ] - }, - { - "nodes":[ - { - "title":"Reflection", - "page":"cubeMap" - } - ] - }, - { - "nodes":[ - { - "title":"Multitexturing", - "page":"multitexturing" - } - ] - }, - { - "nodes":[ - { - "title":"Texture animation", - "page":"colorMapAnimation" - } - ] - }, - { - "nodes":[ - { - "title":"Video texture", - "page":"videoColorMap" - } - ] - }, - { - "nodes":[ - { - "title":"UV layers", - "page":"uvLayers" - } - ] - }, - { - "nodes":[ - { - "title":"Texture plugin API", - "page":"videoAlphaMap" - } - ] - } - ] - }, - { - "title":"Shaders, eg:", - "nodes":[ - { - "nodes":[ - { - "title":"Custom fragment shaders", - "page":"xrayShader" - } - ] - }, - { - "nodes":[ - { - "title":"Custom vertex shaders", - "page":"vertexDisplaceShader" - } - ] - }, - { - "nodes":[ - { - "title":"Transparency sorting", - "page":"transparencySorting" - } - ] - } - ] - }, - { - "title":"Features library, eg:", - "nodes":[ - { - "nodes":[ - { - "title":"Skyboxes", - "page":"customSkybox" - }, - { - "title":"Heightmaps", - "page":"customHeightmap" - } - ] - }, - { - "nodes":[ - { - "title":"City", - "page":"city" - }, - { - "title":"Tank", - "page":"tronTank" - }, - { - "title":"Earth", - "page":"customNodesEarth" - } - ] - } - ] - }, - { - "title":"Utilities", - "nodes":[ - { - "nodes":[ - { - "title":"Canvas image capture", - "page":"canvasCapture" - } - ] - } - ] - } -] \ No newline at end of file diff --git a/examplesold/index.json b/examplesold/index.json index f1f86c54..7e627ca1 100644 --- a/examplesold/index.json +++ b/examplesold/index.json @@ -221,7 +221,7 @@ { "title":"Configuring depth buffer for subgraphs", "tip":"", - "tags":["depthbuf"], + "tags":["depthBuf"], "nodes":[ { "title":"Toggle depth testing", diff --git a/examplesold/pages/configuration/pluginPath.html b/examplesold/pages/configuration/pluginPath.html index 37ae0c23..d17ef50b 100644 --- a/examplesold/pages/configuration/pluginPath.html +++ b/examplesold/pages/configuration/pluginPath.html @@ -53,9 +53,9 @@ nodes:[ // Torus primitive, - // implemented by plugin at ../../../../api/latest/plugins/node/prims/torus.js + // implemented by plugin at ../../../../api/latest/plugins/node/geometry/torus.js { - type:"prims/torus", + type:"geometry/torus", radius:1.0, tube:0.30, segmentsR:60, diff --git a/examplesold/pages/configuration/statusPopups.html b/examplesold/pages/configuration/statusPopups.html index 100fa02a..f6e04cac 100644 --- a/examplesold/pages/configuration/statusPopups.html +++ b/examplesold/pages/configuration/statusPopups.html @@ -53,9 +53,9 @@ nodes:[ // Torus primitive, - // implemented by plugin at ../../../../api/latest/plugins/node/prims/torus.js + // implemented by plugin at ../../../../api/latest/plugins/node/geometry/torus.js { - type:"prims/torus", + type:"geometry/torus", radius:1.0, tube:0.30, segmentsR:60, diff --git a/examplesold/pages/demos/bubbles.html b/examplesold/pages/demos/bubbles.html index 095b77b7..60601a7d 100644 --- a/examplesold/pages/demos/bubbles.html +++ b/examplesold/pages/demos/bubbles.html @@ -73,9 +73,9 @@ nodes:[ // Grid ground, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/grid.js + // http://scenejs.org/api/latest/plugins/node/geometry/grid.js { - type:"prims/grid", + type:"geometry/grid", size:{ x:1000, z:1000 }, xSegments:200, zSegments:200 @@ -84,9 +84,9 @@ }, // Cloudy sea skybox, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/skyboxes/miramarClouds.js + // http://scenejs.org/api/latest/plugins/node/skybox/miramarClouds.js { - type:"skyboxes/cloudySea" + type:"skybox/cloudySea" }, //-------------------------------------------------------------------------------- @@ -266,9 +266,9 @@ angle:0 }); this.rotate.addNode( - // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // Sphere geometry node implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type:"geometry/sphere" }); this.angle = 0; this.angleInc = Math.random() - 0.5; diff --git a/examplesold/pages/demos/city.html b/examplesold/pages/demos/city.html index ad1673bb..3f9fc2c5 100644 --- a/examplesold/pages/demos/city.html +++ b/examplesold/pages/demos/city.html @@ -59,15 +59,15 @@ nodes: [ // Clouds skybox, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/skyboxes/clouds.js + // http://scenejs.org/api/latest/plugins/node/skybox/clouds.js { - type: "skyboxes/clouds" + type: "skybox/clouds" }, // Fog effect, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/effects/fog.js + // http://scenejs.org/api/latest/plugins/node/shader/fog.js { - type: "effects/fog", + type: "shader/fog", mode: "exp2", // Quadratic density: 0.1, // Fog density start: 30.0, // Near starting point @@ -81,9 +81,9 @@ nodes: [ // Grid ground, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/object/ground/grid.js + // http://scenejs.org/api/latest/plugins/node/models/ground/grid.js { - type: "prims/grid", + type: "geometry/grid", size: { x: 10000, z: 10000 }, width: 10000, height: 10000, @@ -103,9 +103,9 @@ nodes: [ // City, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/object/buildings/city.js + // http://scenejs.org/api/latest/plugins/node/models/buildings/city.js { - type: "objects/buildings/city", + type: "models/buildings/city", width: 600 } ] diff --git a/examplesold/pages/demos/clouds.html b/examplesold/pages/demos/clouds.html index 7b336e67..3a7985d0 100644 --- a/examplesold/pages/demos/clouds.html +++ b/examplesold/pages/demos/clouds.html @@ -180,9 +180,9 @@ z:scale, nodes:[ - // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/prims/box.js + // Box primitive implemented by plugin at http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } diff --git a/examplesold/pages/demos/earth.html b/examplesold/pages/demos/earth.html index fa0b0ed0..c7f7b706 100644 --- a/examplesold/pages/demos/earth.html +++ b/examplesold/pages/demos/earth.html @@ -53,9 +53,9 @@ nodes:[ // Earth, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/objects/space/planets/earth.js + // http://scenejs.org/api/latest/plugins/node/models/space/planets/earth.js { - type:"objects/space/planets/earth" + type:"models/space/planets/earth" } ] } diff --git a/examplesold/pages/demos/firstExample.html b/examplesold/pages/demos/firstExample.html index 5ab47b88..6f50fc42 100644 --- a/examplesold/pages/demos/firstExample.html +++ b/examplesold/pages/demos/firstExample.html @@ -49,9 +49,9 @@ nodes:[ // Teapot primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } diff --git a/examplesold/pages/demos/ghostTrees.html b/examplesold/pages/demos/ghostTrees.html index 5e1f93ce..ac225cbb 100644 --- a/examplesold/pages/demos/ghostTrees.html +++ b/examplesold/pages/demos/ghostTrees.html @@ -28,7 +28,7 @@ // http://www.chromeexperiments.com/detail/ghost-trees/ // // The tree generation code is wrapped in a custom SceneJS node type defined in: - // http://scenejs.org/api/latest/plugins/node/objects/plants/ghostTree.js + // http://scenejs.org/api/latest/plugins/node/models/plants/ghostTree.js // // All the parameters for the tree generator are exposed as configurations // for the node type. @@ -69,7 +69,7 @@ nodes:[ // Procedurally-generated tree nodes, implemented by plugin at: - // http://scenejs.org/api/latest/plugins/node/objects/plants/ghostTree.js + // http://scenejs.org/api/latest/plugins/node/models/plants/ghostTree.js // // This plugin integrates the Ghost Trees generator from the Chrome Experiment // by Marek Kapolka: http://www.chromeexperiments.com/detail/ghost-trees/ @@ -83,7 +83,7 @@ nodes:[ { - type:"objects/plants/ghostTree", + type:"models/plants/ghostTree", minSegmentLength:1, maxSegmentLength:3, minSegmentAngle:Math.PI / 16, @@ -106,7 +106,7 @@ nodes:[ { - type:"objects/plants/ghostTree", + type:"models/plants/ghostTree", minSegmentLength:1, maxSegmentLength:2, minSegmentAngle:Math.PI / 16, @@ -129,7 +129,7 @@ nodes:[ { - type:"objects/plants/ghostTree", + type:"models/plants/ghostTree", minSegmentLength:1, maxSegmentLength:2, minSegmentAngle:Math.PI / 16, @@ -152,7 +152,7 @@ nodes:[ { - type:"objects/plants/ghostTree", + type:"models/plants/ghostTree", minSegmentLength:1, maxSegmentLength:2, minSegmentAngle:Math.PI / 16, diff --git a/examplesold/pages/demos/orbitPicked.html b/examplesold/pages/demos/orbitPicked.html index d78350f1..beecb35a 100644 --- a/examplesold/pages/demos/orbitPicked.html +++ b/examplesold/pages/demos/orbitPicked.html @@ -56,9 +56,9 @@ // nodes:[ // // // Sphere primitive implemented by plugin at -// // http://scenejs.org/api/latest/plugins/node/prims/sphere.js +// // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js // { -// type:"prims/sphere" +// type:"geometry/sphere" // } // ] // } @@ -92,9 +92,9 @@ // nodes:[ // // // Sphere primitive implemented by plugin at -// // http://scenejs.org/api/latest/plugins/node/prims/sphere.js +// // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js // { -// type:"prims/sphere" +// type:"geometry/sphere" // } // ] // } @@ -137,9 +137,9 @@ nodes:[ // Box primitive, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -164,9 +164,9 @@ nodes:[ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -191,9 +191,9 @@ nodes:[ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -218,9 +218,9 @@ nodes:[ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -245,9 +245,9 @@ nodes:[ // Box primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/box.js + // http://scenejs.org/api/latest/plugins/node/geometry/box.js { - type:"prims/box" + type:"geometry/box" } ] } @@ -284,9 +284,9 @@ nodes:[ // Torus primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } @@ -317,9 +317,9 @@ nodes:[ // Torus primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } @@ -350,9 +350,9 @@ nodes:[ // Torus primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } @@ -383,9 +383,9 @@ nodes:[ // Torus primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/torus.js + // http://scenejs.org/api/latest/plugins/node/geometry/torus.js { - type:"prims/torus" + type:"geometry/torus" } ] } @@ -418,9 +418,9 @@ nodes:[ // Teapot primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/teapot.js + // http://scenejs.org/api/latest/plugins/node/geometry/teapot.js { - type:"prims/teapot" + type:"geometry/teapot" } ] } @@ -452,9 +452,9 @@ nodes:[ // Sphere primitive implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/prims/sphere.js + // http://scenejs.org/api/latest/plugins/node/geometry/sphere.js { - type:"prims/sphere" + type:"geometry/sphere" } ] } diff --git a/examplesold/pages/demos/physics.html b/examplesold/pages/demos/physics.html index 0f24dc36..b763bc7a 100644 --- a/examplesold/pages/demos/physics.html +++ b/examplesold/pages/demos/physics.html @@ -71,7 +71,7 @@ // Node type implemented by plugin at http://scenejs.org/api/latest/plugins/node/ground/grid.js { - type: "objects/ground/grid", + type: "models/ground/grid", size: { x: 10000, z: 10000 }, xSegments: 100, zSegments: 100 diff --git a/examplesold/pages/demos/pickFlyOrbitCity.html b/examplesold/pages/demos/pickFlyOrbitCity.html index 753019a8..52b6070a 100644 --- a/examplesold/pages/demos/pickFlyOrbitCity.html +++ b/examplesold/pages/demos/pickFlyOrbitCity.html @@ -157,15 +157,15 @@ nodes:[ // Clouds skybox, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/skyboxes/clouds.js + // http://scenejs.org/api/latest/plugins/node/skybox/clouds.js { - type:"skyboxes/clouds" + type:"skybox/clouds" }, // Fog effect, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/effects/fog.js + // http://scenejs.org/api/latest/plugins/node/shader/fog.js { - type:"effects/fog", + type:"shader/fog", mode:"exp2", // Quadratic density:0.1, // Fog density start:30.0, // Near starting point @@ -180,9 +180,9 @@ nodes:[ // Grid ground, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/object/ground/grid.js + // http://scenejs.org/api/latest/plugins/node/models/ground/grid.js { - type:"prims/grid", + type:"geometry/grid", size:{ x:10000, z:10000 }, width:10000, height:10000, @@ -203,9 +203,9 @@ nodes:[ // Solid green surface under the grid, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/object/ground/grid.js + // http://scenejs.org/api/latest/plugins/node/models/ground/grid.js { - type:"prims/grid", + type:"geometry/grid", size:{ x:10000, z:10000 }, width:10000, height:10000, @@ -228,9 +228,9 @@ nodes:[ // City, implemented by plugin at - // http://scenejs.org/api/latest/plugins/node/object/buildings/city.js + // http://scenejs.org/api/latest/plugins/node/models/buildings/city.js { - type:"objects/buildings/city", + type:"models/buildings/city", width:600 } ] diff --git a/examplesold/pages/demos/pickFlyOrbitTerrain.html b/examplesold/pages/demos/pickFlyOrbitTerrain.html index d25bca5c..dabb0806 100644 --- a/examplesold/pages/demos/pickFlyOrbitTerrain.html +++ b/examplesold/pages/demos/pickFlyOrbitTerrain.html @@ -115,7 +115,7 @@
  • > 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 BHx~c^ literal 0 HcmV?d00001 diff --git a/examples/textures/holodeck/south.jpg b/examples/textures/holodeck/south.jpg new file mode 100644 index 0000000000000000000000000000000000000000..fb728e30e0a9ee2bdf44131fe7caac8846124437 GIT binary patch literal 143894 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 Axc~qF literal 0 HcmV?d00001 diff --git a/examples/textures/holodeck/top.jpg b/examples/textures/holodeck/top.jpg new file mode 100644 index 0000000000000000000000000000000000000000..facca573ece2f4361a08b64bda10235728898c14 GIT binary patch literal 188470 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