https://www.sirikata.com/wiki/api.php?action=feedcontributions&user=Danielrh&feedformat=atomSirikata Wiki - User contributions [en]2024-03-29T14:54:39ZUser contributionsMediaWiki 1.35.7https://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=802JavascriptGraphicsAPI2011-02-21T01:36:48Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[0,0,0,1],//defaults to 0,0,0,1 if absent, but first 3 elements offset the mesh from the pivot point and last scales it<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
Should we use "parentbone" or "attachment_point"?<br />
<br />
FIXME: We should default these values to the last position, not to identity. Otherwise we basically have to send everything each time.<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[0,0,0,1],//defaults to 0,0,0,1 if absent: first 3 values offset mesh from pivot, last scales it<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
type:"collada",//string that specifies file format<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
}<br />
<br />
===Querying mesh aspect ratio for an object===<br />
{<br />
msg:"QueryMeshAspectRatio",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
Message <u>from the graphics system</u> to respond to mesh aspect ratio query<br />
{<br />
msg:"MeshAspectRatio",<br />
aspect:[.025,.75,.661] // this should reflect the absolute bounding box if scale were identity [0,0,0,1.0]<br />
}<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:["ColorTint","HowManyIterations"]<br />
value:[[.24,.24,.25,1.0],[1,0,0,0]]<br />
type:["float4", "int4"]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true,<br />
shader:"http://www.example.com/pointLight.shader"// light shader for ray tracing (empty by default)<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Creating camera properties on an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Destroying and cleaning up a camera===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
texobjid:"9a10e9c1-31fb-43e8-9a20-6545d9a62fdb", // Id of object with a mesh<br />
texname:"example.png"//overwrites this texture on the texobjid object.<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
===Detach a camera from its render target"===<br />
{<br />
msg:DetachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Event handling==<br />
<br />
===Mouse Events===<br />
<br />
Messages <u>from the graphics system</u> for standard browser events:<br />
{<br />
msg:"mousemove",<br />
event:{...},// implementation-specific event object.<br />
x:100,//X coordinate of the mouse, relative to canvas<br />
y:102,//Y coordinate of the mouse, relative to canvas<br />
clientX:110,//X coordinate of the mouse, relative to client area of window<br />
clientY:302,//Y coordinate of the mouse, relative to client area of window<br />
spaceid:"loop://localhost",//Space ID of the view the mouse is hovering over.<br />
camerapos:[0,0,0],//Start of the mouse ray.<br />
dir:[1,0,0],//Direction of the mouse ray.<br />
shiftKey:false,//See keyup/keydown<br />
ctrlKey:false,//See keyup/keydown<br />
altKey:false,//See keyup/keydown<br />
}<br />
<br />
{<br />
msg:"mousedown",<br />
event:{...},<br />
button:0,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102,<br />
clientX:110,<br />
clientY:302,<br />
spaceid:"loop://localhost",<br />
camerapos:[0,0,0],<br />
dir:[1,0,0],<br />
shiftKey:false,<br />
ctrlKey:false,<br />
altKey:false,<br />
}<br />
<br />
{<br />
msg:"mouseup",<br />
event:{...},<br />
button:0,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102,<br />
clientX:110,<br />
clientY:302,<br />
spaceid:"loop://localhost",<br />
camerapos:[0,0,0],<br />
dir:[1,0,0],<br />
shiftKey:false,<br />
ctrlKey:false,<br />
altKey:false,<br />
}<br />
<br />
{<br />
msg:"wheel",<br />
event:{...},<br />
dy:40,//Basic unit of scroll==120, may be smaller on e.g. mac trackpads with wheel acceleration.<br />
dx:0,//Left-right scroll<br />
shiftKey:false,<br />
ctrlKey:false,<br />
altKey:false,<br />
}<br />
<br />
A click occurs after a mouseup event when the mousedown and mouseup are in close proximity. Contains the same properties as mouseup.<br />
{<br />
msg:"click",<br />
...<br />
}<br />
<br />
A drag occurs after each mousemove between a mousedown and a mouseup. Contains the same properties as mousemove, but also has deltas:<br />
{<br />
msg:"drag",<br />
...<br />
dx:5,//How many pixels did the mouse move since mousedown<br />
dy:10,//How many pixels did the mouse move since mousedown<br />
}<br />
<br />
A drop occurs after mouseup, if the mouse has moved (drag events fired). Contains the same properties as click, but also has deltas:<br />
{<br />
msg:"drop",<br />
...<br />
dx:5,//How many pixels did the mouse move since mousedown<br />
dy:10,//How many pixels did the mouse move since mousedown<br />
}<br />
<br />
<br />
As an alternative to the Raytrace request, we introduce pick message that will return additional 3D data.<br />
Since raytracing is an expensive operation, it is fired only on mousedown.<br />
<br />
This message also contains a copy of fields from the mousedown event, so applications can choose to use this event instead of mousedown.<br />
<br />
{<br />
msg:"pick",<br />
...<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",//which object was hit? May be null.<br />
pos:[1,2,3],//where on the surface did it hit? May be null.<br />
normal:[.5,0,.86],//what's the direction of the normal is at that point? May be null.<br />
}<br />
<br />
To save traffic we allow messages <u>to the graphics system</u> that enable/disable these messages:<br />
{<br />
msg:"Enable",<br />
type:"mousemove"//message type<br />
}<br />
<br />
{<br />
msg:"Enable",<br />
type:"drag"//message type<br />
}<br />
<br />
{<br />
msg:"Enable",<br />
type:"pick"//message type<br />
}<br />
<br />
More advanced messages, such as pickover, pickout, and others can be derived from the messages described above and we should keep this list as simple as possible. For example, pickover and pickout can be derived from mouseover and pick messages (when object ID under cursor changes than it's a pickover for the new object and pickout for the old one).<br />
<br />
Moreover, we can use mouseover, mouseout to enable/disable picking to reduce inter-thread traffic. (FIXME: what are mouseover and mouseout? They don't seem to be implemented or used.)<br />
<br />
===Keyboard===<br />
<br />
For a description of keyCode and other properties, see the [https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent KeyEvent page from MDC].<br />
<br />
glgegfx gives keyDown for each auto-repeat. For example: keyDown,keyDown,...,keyDown,keyUp.<br />
<br />
This messages are sent <u>from the graphics system</u> in response to user's actions towards keyboard:<br />
{<br />
msg:"keydown"//key was pressed, but not released<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
shiftKey:true,<br />
repeat:false,//true if this keyDown is due to a keyboard repeat.<br />
keyCode:25//See MDC [https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent KeyEvent] for list of codes<br />
}<br />
<br />
{<br />
msg:"keyup",//key was released<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
shiftKey:true,<br />
keyCode:25//See MDC [https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent KeyEvent] for list of codes<br />
}<br />
<br />
===Requesting intersection===<br />
<br />
Request <u>to the graphics system</u>:<br />
{<br />
msg:"Raytrace",<br />
id:5,//request ID<br />
pos:[2,3,4],//origin of the ray<br />
dir:[.24,.33,.5],//direction of the ray<br />
multiple:true//if false, only return first hit, otherwise return all intersections<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
Response <u>from the graphics system</u>:<br />
{<br />
msg:"Intersections",<br />
id:5,//request ID<br />
results:[{<br />
pos:[2,3,4],<br />
normals:[0,1,0],<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
},{<br />
pos:[2.23,3.32,4.49],//positions of the points of intersections<br />
normal:[.5,0,.86],//normals of the surface at intersections points<br />
id:"a33ff133-58dd-2272-dd6a-12aadc31d173"//object IDs for each intersected surface<br />
}]<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
== Customizing the background ==<br />
<br />
{<br />
msg:"Background"<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
curtextures=["http://example.com/a.jpg","http://example.com/b.jpg"]<br />
background_type="skydome"#skydome[1 or 2 textures], skybox [6 textures]<br />
prevtextures=["http://example.com/old_a.jpg","http://example.com/old_b.jpg"]#optional for fade in effects<br />
curweight=.75#weight of curtextures=.75 versus prevtextures=.25<br />
}<br />
<br />
<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
; point: The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
; oriented_common: Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
; oriented_self: Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
; perpendicular_common: Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
; perpendicular_self: Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
and<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
; point: The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
; oriented_self: Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
; perpendicular_self: Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=801JavascriptGraphicsAPI2011-02-21T01:32:14Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[0,0,0,1],//defaults to 0,0,0,1 if absent, but first 3 elements offset the mesh from the pivot point and last scales it<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
Should we use "parentbone" or "attachment_point"?<br />
<br />
FIXME: We should default these values to the last position, not to identity. Otherwise we basically have to send everything each time.<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[0,0,0,1],//defaults to 0,0,0,1 if absent: first 3 values offset mesh from pivot, last scales it<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
type:"collada",//string that specifies file format<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
}<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:["ColorTint","HowManyIterations"]<br />
value:[[.24,.24,.25,1.0],[1,0,0,0]]<br />
type:["float4", "int4"]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true,<br />
shader:"http://www.example.com/pointLight.shader"// light shader for ray tracing (empty by default)<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Creating camera properties on an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Destroying and cleaning up a camera===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
texobjid:"9a10e9c1-31fb-43e8-9a20-6545d9a62fdb", // Id of object with a mesh<br />
texname:"example.png"//overwrites this texture on the texobjid object.<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
===Detach a camera from its render target"===<br />
{<br />
msg:DetachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Event handling==<br />
<br />
===Mouse Events===<br />
<br />
Messages <u>from the graphics system</u> for standard browser events:<br />
{<br />
msg:"mousemove",<br />
event:{...},// implementation-specific event object.<br />
x:100,//X coordinate of the mouse, relative to canvas<br />
y:102,//Y coordinate of the mouse, relative to canvas<br />
clientX:110,//X coordinate of the mouse, relative to client area of window<br />
clientY:302,//Y coordinate of the mouse, relative to client area of window<br />
spaceid:"loop://localhost",//Space ID of the view the mouse is hovering over.<br />
camerapos:[0,0,0],//Start of the mouse ray.<br />
dir:[1,0,0],//Direction of the mouse ray.<br />
shiftKey:false,//See keyup/keydown<br />
ctrlKey:false,//See keyup/keydown<br />
altKey:false,//See keyup/keydown<br />
}<br />
<br />
{<br />
msg:"mousedown",<br />
event:{...},<br />
button:0,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102,<br />
clientX:110,<br />
clientY:302,<br />
spaceid:"loop://localhost",<br />
camerapos:[0,0,0],<br />
dir:[1,0,0],<br />
shiftKey:false,<br />
ctrlKey:false,<br />
altKey:false,<br />
}<br />
<br />
{<br />
msg:"mouseup",<br />
event:{...},<br />
button:0,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102,<br />
clientX:110,<br />
clientY:302,<br />
spaceid:"loop://localhost",<br />
camerapos:[0,0,0],<br />
dir:[1,0,0],<br />
shiftKey:false,<br />
ctrlKey:false,<br />
altKey:false,<br />
}<br />
<br />
{<br />
msg:"wheel",<br />
event:{...},<br />
dy:40,//Basic unit of scroll==120, may be smaller on e.g. mac trackpads with wheel acceleration.<br />
dx:0,//Left-right scroll<br />
shiftKey:false,<br />
ctrlKey:false,<br />
altKey:false,<br />
}<br />
<br />
A click occurs after a mouseup event when the mousedown and mouseup are in close proximity. Contains the same properties as mouseup.<br />
{<br />
msg:"click",<br />
...<br />
}<br />
<br />
A drag occurs after each mousemove between a mousedown and a mouseup. Contains the same properties as mousemove, but also has deltas:<br />
{<br />
msg:"drag",<br />
...<br />
dx:5,//How many pixels did the mouse move since mousedown<br />
dy:10,//How many pixels did the mouse move since mousedown<br />
}<br />
<br />
A drop occurs after mouseup, if the mouse has moved (drag events fired). Contains the same properties as click, but also has deltas:<br />
{<br />
msg:"drop",<br />
...<br />
dx:5,//How many pixels did the mouse move since mousedown<br />
dy:10,//How many pixels did the mouse move since mousedown<br />
}<br />
<br />
<br />
As an alternative to the Raytrace request, we introduce pick message that will return additional 3D data.<br />
Since raytracing is an expensive operation, it is fired only on mousedown.<br />
<br />
This message also contains a copy of fields from the mousedown event, so applications can choose to use this event instead of mousedown.<br />
<br />
{<br />
msg:"pick",<br />
...<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",//which object was hit? May be null.<br />
pos:[1,2,3],//where on the surface did it hit? May be null.<br />
normal:[.5,0,.86],//what's the direction of the normal is at that point? May be null.<br />
}<br />
<br />
To save traffic we allow messages <u>to the graphics system</u> that enable/disable these messages:<br />
{<br />
msg:"Enable",<br />
type:"mousemove"//message type<br />
}<br />
<br />
{<br />
msg:"Enable",<br />
type:"drag"//message type<br />
}<br />
<br />
{<br />
msg:"Enable",<br />
type:"pick"//message type<br />
}<br />
<br />
More advanced messages, such as pickover, pickout, and others can be derived from the messages described above and we should keep this list as simple as possible. For example, pickover and pickout can be derived from mouseover and pick messages (when object ID under cursor changes than it's a pickover for the new object and pickout for the old one).<br />
<br />
Moreover, we can use mouseover, mouseout to enable/disable picking to reduce inter-thread traffic. (FIXME: what are mouseover and mouseout? They don't seem to be implemented or used.)<br />
<br />
===Keyboard===<br />
<br />
For a description of keyCode and other properties, see the [https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent KeyEvent page from MDC].<br />
<br />
glgegfx gives keyDown for each auto-repeat. For example: keyDown,keyDown,...,keyDown,keyUp.<br />
<br />
This messages are sent <u>from the graphics system</u> in response to user's actions towards keyboard:<br />
{<br />
msg:"keydown"//key was pressed, but not released<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
shiftKey:true,<br />
repeat:false,//true if this keyDown is due to a keyboard repeat.<br />
keyCode:25//See MDC [https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent KeyEvent] for list of codes<br />
}<br />
<br />
{<br />
msg:"keyup",//key was released<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
shiftKey:true,<br />
keyCode:25//See MDC [https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent KeyEvent] for list of codes<br />
}<br />
<br />
===Requesting intersection===<br />
<br />
Request <u>to the graphics system</u>:<br />
{<br />
msg:"Raytrace",<br />
id:5,//request ID<br />
pos:[2,3,4],//origin of the ray<br />
dir:[.24,.33,.5],//direction of the ray<br />
multiple:true//if false, only return first hit, otherwise return all intersections<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
Response <u>from the graphics system</u>:<br />
{<br />
msg:"Intersections",<br />
id:5,//request ID<br />
results:[{<br />
pos:[2,3,4],<br />
normals:[0,1,0],<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
},{<br />
pos:[2.23,3.32,4.49],//positions of the points of intersections<br />
normal:[.5,0,.86],//normals of the surface at intersections points<br />
id:"a33ff133-58dd-2272-dd6a-12aadc31d173"//object IDs for each intersected surface<br />
}]<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
== Customizing the background ==<br />
<br />
{<br />
msg:"Background"<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
curtextures=["http://example.com/a.jpg","http://example.com/b.jpg"]<br />
background_type="skydome"#skydome[1 or 2 textures], skybox [6 textures]<br />
prevtextures=["http://example.com/old_a.jpg","http://example.com/old_b.jpg"]#optional for fade in effects<br />
curweight=.75#weight of curtextures=.75 versus prevtextures=.25<br />
}<br />
<br />
<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
; point: The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
; oriented_common: Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
; oriented_self: Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
; perpendicular_common: Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
; perpendicular_self: Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
and<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
; point: The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
; oriented_self: Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
; perpendicular_self: Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=725JavascriptGraphicsAPI2011-01-25T23:10:03Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
Should we use "parentbone" or "attachment_point"?<br />
<br />
FIXME: We should default these values to the last position, not to identity. Otherwise we basically have to send everything each time.<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
type:"collada",//string that specifies file format<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
}<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:["ColorTint","HowManyIterations"]<br />
value:[[.24,.24,.25,1.0],[1,0,0,0]]<br />
type:["float4", "int4"]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true,<br />
shader:"http://www.example.com/pointLight.shader"// light shader for ray tracing (empty by default)<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Creating camera properties on an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Destroying and cleaning up a camera===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
texobjid:"9a10e9c1-31fb-43e8-9a20-6545d9a62fdb", // Id of object with a mesh<br />
texname:"example.png"//overwrites this texture on the texobjid object.<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
===Detach a camera from its render target"===<br />
{<br />
msg:DetachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Event handling==<br />
<br />
===Mouse Events===<br />
<br />
Messages <u>from the graphics system</u> for standard browser events:<br />
{<br />
msg:"mousemove",<br />
event:{...},// implementation-specific event object.<br />
x:100,//X coordinate of the mouse, relative to canvas<br />
y:102,//Y coordinate of the mouse, relative to canvas<br />
clientX:110,//X coordinate of the mouse, relative to client area of window<br />
clientY:302,//Y coordinate of the mouse, relative to client area of window<br />
spaceid:"loop://localhost",//Space ID of the view the mouse is hovering over.<br />
camerapos:[0,0,0],//Start of the mouse ray.<br />
dir:[1,0,0],//Direction of the mouse ray.<br />
shiftKey:false,//See keyup/keydown<br />
ctrlKey:false,//See keyup/keydown<br />
altKey:false,//See keyup/keydown<br />
}<br />
<br />
{<br />
msg:"mousedown",<br />
event:{...},<br />
button:0,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102,<br />
clientX:110,<br />
clientY:302,<br />
spaceid:"loop://localhost",<br />
camerapos:[0,0,0],<br />
dir:[1,0,0],<br />
shiftKey:false,<br />
ctrlKey:false,<br />
altKey:false,<br />
}<br />
<br />
{<br />
msg:"mouseup",<br />
event:{...},<br />
button:0,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102,<br />
clientX:110,<br />
clientY:302,<br />
spaceid:"loop://localhost",<br />
camerapos:[0,0,0],<br />
dir:[1,0,0],<br />
shiftKey:false,<br />
ctrlKey:false,<br />
altKey:false,<br />
}<br />
<br />
{<br />
msg:"wheel",<br />
event:{...},<br />
dy:40,//Basic unit of scroll==120, may be smaller on e.g. mac trackpads with wheel acceleration.<br />
dx:0,//Left-right scroll<br />
shiftKey:false,<br />
ctrlKey:false,<br />
altKey:false,<br />
}<br />
<br />
A click occurs after a mouseup event when the mousedown and mouseup are in close proximity. Contains the same properties as mouseup.<br />
{<br />
msg:"click",<br />
...<br />
}<br />
<br />
A drag occurs after each mousemove between a mousedown and a mouseup. Contains the same properties as mousemove, but also has deltas:<br />
{<br />
msg:"drag",<br />
...<br />
dx:5,//How many pixels did the mouse move since mousedown<br />
dy:10,//How many pixels did the mouse move since mousedown<br />
}<br />
<br />
A drop occurs after mouseup, if the mouse has moved (drag events fired). Contains the same properties as click, but also has deltas:<br />
{<br />
msg:"drop",<br />
...<br />
dx:5,//How many pixels did the mouse move since mousedown<br />
dy:10,//How many pixels did the mouse move since mousedown<br />
}<br />
<br />
<br />
As an alternative to the Raytrace request, we introduce pick message that will return additional 3D data.<br />
Since raytracing is an expensive operation, it is fired only on mousedown.<br />
<br />
This message also contains a copy of fields from the mousedown event, so applications can choose to use this event instead of mousedown.<br />
<br />
{<br />
msg:"pick",<br />
...<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",//which object was hit? May be null.<br />
pos:[1,2,3],//where on the surface did it hit? May be null.<br />
normal:[.5,0,.86],//what's the direction of the normal is at that point? May be null.<br />
}<br />
<br />
To save traffic we allow messages <u>to the graphics system</u> that enable/disable these messages:<br />
{<br />
msg:"Enable",<br />
type:"mousemove"//message type<br />
}<br />
<br />
{<br />
msg:"Enable",<br />
type:"drag"//message type<br />
}<br />
<br />
{<br />
msg:"Enable",<br />
type:"pick"//message type<br />
}<br />
<br />
More advanced messages, such as pickover, pickout, and others can be derived from the messages described above and we should keep this list as simple as possible. For example, pickover and pickout can be derived from mouseover and pick messages (when object ID under cursor changes than it's a pickover for the new object and pickout for the old one).<br />
<br />
Moreover, we can use mouseover, mouseout to enable/disable picking to reduce inter-thread traffic. (FIXME: what are mouseover and mouseout? They don't seem to be implemented or used.)<br />
<br />
===Keyboard===<br />
<br />
For a description of keyCode and other properties, see the [https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent KeyEvent page from MDC].<br />
<br />
glgegfx gives keyDown for each auto-repeat. For example: keyDown,keyDown,...,keyDown,keyUp.<br />
<br />
This messages are sent <u>from the graphics system</u> in response to user's actions towards keyboard:<br />
{<br />
msg:"keydown"//key was pressed, but not released<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
shiftKey:true,<br />
repeat:false,//true if this keyDown is due to a keyboard repeat.<br />
keyCode:25//See MDC [https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent KeyEvent] for list of codes<br />
}<br />
<br />
{<br />
msg:"keyup",//key was released<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
shiftKey:true,<br />
keyCode:25//See MDC [https://developer.mozilla.org/en/DOM/Event/UIEvent/KeyEvent KeyEvent] for list of codes<br />
}<br />
<br />
===Requesting intersection===<br />
<br />
Request <u>to the graphics system</u>:<br />
{<br />
msg:"Raytrace",<br />
id:5,//request ID<br />
pos:[2,3,4],//origin of the ray<br />
dir:[.24,.33,.5],//direction of the ray<br />
multiple:true//if false, only return first hit, otherwise return all intersections<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
Response <u>from the graphics system</u>:<br />
{<br />
msg:"Intersections",<br />
id:5,//request ID<br />
results:[{<br />
pos:[2,3,4],<br />
normals:[0,1,0],<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
},{<br />
pos:[2.23,3.32,4.49],//positions of the points of intersections<br />
normal:[.5,0,.86],//normals of the surface at intersections points<br />
id:"a33ff133-58dd-2272-dd6a-12aadc31d173"//object IDs for each intersected surface<br />
}]<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
== Customizing the background ==<br />
<br />
{<br />
msg:"Background"<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
curtextures=["http://example.com/a.jpg","http://example.com/b.jpg"]<br />
background_type="skydome"#skydome[1 or 2 textures], skybox [6 textures]<br />
prevtextures=["http://example.com/old_a.jpg","http://example.com/old_b.jpg"]#optional for fade in effects<br />
curweight=.75#weight of curtextures=.75 versus prevtextures=.25<br />
}<br />
<br />
<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
; point: The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
; oriented_common: Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
; oriented_self: Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
; perpendicular_common: Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
; perpendicular_self: Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
and<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
; point: The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
; oriented_self: Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
; perpendicular_self: Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=650JavascriptGraphicsAPI2010-07-07T07:29:06Z<p>Danielrh: /* Updating shader property (Vertex and Fragment float4) for an object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
Should we use "parentbone" or "attachment_point"?<br />
<br />
FIXME: We should default these values to the last position, not to identity. Otherwise we basically have to send everything each time.<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
}<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:["ColorTint","HowManyIterations"]<br />
value:[[.24,.24,.25,1.0],[1,0,0,0]]<br />
type:"float4"<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Creating camera properties on an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Destroying and cleaning up a camera===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
texobjid:"9a10e9c1-31fb-43e8-9a20-6545d9a62fdb", // Id of object with a mesh<br />
texname:"example.png"//overwrites this texture on the texobjid object.<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
===Detach a camera from its render target"===<br />
{<br />
msg:DetachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Clicking===<br />
The standard javascript callbacks are always enabled... you will get the following messages from time to time on the receiving stream.<br />
<br />
{<br />
msg:"onclick",<br />
which:2,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102<br />
}<br />
<br />
every onclick will produce a matching onrelease, even if the mouse is outside the window<br />
{<br />
msg:"onrelease",<br />
which:2,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102<br />
}<br />
<br />
{<br />
msg:"drag",<br />
queryid:8//messages will come back with an id field set the same<br />
x:103,<br />
y:105<br />
}<br />
<br />
===MouseMove===<br />
{<br />
msg:"EnableMouseMove",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
{<br />
msg:"DisableMouseMove",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
<br />
<br />
{<br />
msg:"mousemove",<br />
x:100,<br />
y:102<br />
}<br />
<br />
{<br />
msg:"EnableMouseDownUp",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
<br />
{<br />
msg:"mousedown",<br />
which:2,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102<br />
}<br />
{<br />
msg:"mouseup",<br />
x:100,<br />
y:102<br />
}<br />
<br />
<br />
===Keyboard===<br />
<br />
{<br />
msg: "keypress"<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
repeat:false<br />
shiftKey:true<br />
which:25//see keyCode<br />
}<br />
{<br />
msg: "keydown"<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
repeat:false<br />
shiftKey:true<br />
which:25//see keyCode<br />
}<br />
{<br />
msg: "keyup"<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
repeat:false<br />
shiftKey:true<br />
which:25//see keyCode<br />
}<br />
<br />
===Picking===<br />
{<br />
msg:"EnablePicking",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
{<br />
msg:"DisablePicking",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
<br />
<br />
Responses look like<br />
{<br />
msg:"Pick",<br />
queryid:8//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//where on the surface did it hit?<br />
normal:[.5,0,.86],//what the direction of the normal is at that point<br />
x: 100, //relative to canvas<br />
y: 200<br />
}<br />
{<br />
msg:"PickDrag",<br />
queryid:8//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//where on the surface did the drag FIRST hit?<br />
normal:[.5,0,.86],//what the direction of the normal is at that point<br />
planedelta:[.24,.52,.25]//how far did it move in the camera plane<br />
perpdelta:[0,1,0]//how far did it move perpendicular to camera plane<br />
x: 100, // original pixel coordinates of mousedown, relative to canvas<br />
y: 200,<br />
xdelta: 15, // delta from original pixel coordinates.<br />
ydelta: 3<br />
}<br />
{<br />
msg:"PickRelease",<br />
queryid:8//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//where on the surface did the drag FIRST hit?<br />
normal:[.5,0,.86],//what the direction of the normal is at that point<br />
planedelta:[.24,.52,.25]//how far did it move in the camera plane<br />
perpdelta:[0,1,0]//how far did it move perpendicular to camera plane<br />
x: 100, // original pixel coordinates of mousedown, relative to canvas<br />
y: 200,<br />
xdelta: 15, // delta from original pixel coordinates.<br />
ydelta: 3<br />
}<br />
<br />
===Pick/Hovering==<br />
{<br />
msg:"EnablePickHover",<br />
queryid:9,//messages will come back with an id field set the same<br />
approximate:true//defaults to true...if true, then only rough bounds are used<br />
}<br />
{<br />
msg:"DisablePickHover",<br />
queryid:9,//messages will come back with an id field set the same<br />
approximate:true//defaults to true...if true, then only rough bounds are used<br />
}<br />
Responses look like<br />
{<br />
msg:"HoverFocus",<br />
queryid:9//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//approx where on the surface did it hit?<br />
x:100,//screen coords<br />
y:102<br />
}<br />
{<br />
msg:"HoverBlur",<br />
queryid:9//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
x:100,//screen coords<br />
y:102<br />
}<br />
<br />
<br />
<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=649JavascriptGraphicsAPI2010-07-07T07:28:18Z<p>Danielrh: /* Adding/changing mesh property for an object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
Should we use "parentbone" or "attachment_point"?<br />
<br />
FIXME: We should default these values to the last position, not to identity. Otherwise we basically have to send everything each time.<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
}<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Creating camera properties on an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Destroying and cleaning up a camera===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
texobjid:"9a10e9c1-31fb-43e8-9a20-6545d9a62fdb", // Id of object with a mesh<br />
texname:"example.png"//overwrites this texture on the texobjid object.<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
===Detach a camera from its render target"===<br />
{<br />
msg:DetachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Clicking===<br />
The standard javascript callbacks are always enabled... you will get the following messages from time to time on the receiving stream.<br />
<br />
{<br />
msg:"onclick",<br />
which:2,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102<br />
}<br />
<br />
every onclick will produce a matching onrelease, even if the mouse is outside the window<br />
{<br />
msg:"onrelease",<br />
which:2,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102<br />
}<br />
<br />
{<br />
msg:"drag",<br />
queryid:8//messages will come back with an id field set the same<br />
x:103,<br />
y:105<br />
}<br />
<br />
===MouseMove===<br />
{<br />
msg:"EnableMouseMove",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
{<br />
msg:"DisableMouseMove",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
<br />
<br />
{<br />
msg:"mousemove",<br />
x:100,<br />
y:102<br />
}<br />
<br />
{<br />
msg:"EnableMouseDownUp",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
<br />
{<br />
msg:"mousedown",<br />
which:2,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102<br />
}<br />
{<br />
msg:"mouseup",<br />
x:100,<br />
y:102<br />
}<br />
<br />
<br />
===Keyboard===<br />
<br />
{<br />
msg: "keypress"<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
repeat:false<br />
shiftKey:true<br />
which:25//see keyCode<br />
}<br />
{<br />
msg: "keydown"<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
repeat:false<br />
shiftKey:true<br />
which:25//see keyCode<br />
}<br />
{<br />
msg: "keyup"<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
repeat:false<br />
shiftKey:true<br />
which:25//see keyCode<br />
}<br />
<br />
===Picking===<br />
{<br />
msg:"EnablePicking",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
{<br />
msg:"DisablePicking",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
<br />
<br />
Responses look like<br />
{<br />
msg:"Pick",<br />
queryid:8//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//where on the surface did it hit?<br />
normal:[.5,0,.86],//what the direction of the normal is at that point<br />
x: 100, //relative to canvas<br />
y: 200<br />
}<br />
{<br />
msg:"PickDrag",<br />
queryid:8//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//where on the surface did the drag FIRST hit?<br />
normal:[.5,0,.86],//what the direction of the normal is at that point<br />
planedelta:[.24,.52,.25]//how far did it move in the camera plane<br />
perpdelta:[0,1,0]//how far did it move perpendicular to camera plane<br />
x: 100, // original pixel coordinates of mousedown, relative to canvas<br />
y: 200,<br />
xdelta: 15, // delta from original pixel coordinates.<br />
ydelta: 3<br />
}<br />
{<br />
msg:"PickRelease",<br />
queryid:8//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//where on the surface did the drag FIRST hit?<br />
normal:[.5,0,.86],//what the direction of the normal is at that point<br />
planedelta:[.24,.52,.25]//how far did it move in the camera plane<br />
perpdelta:[0,1,0]//how far did it move perpendicular to camera plane<br />
x: 100, // original pixel coordinates of mousedown, relative to canvas<br />
y: 200,<br />
xdelta: 15, // delta from original pixel coordinates.<br />
ydelta: 3<br />
}<br />
<br />
===Pick/Hovering==<br />
{<br />
msg:"EnablePickHover",<br />
queryid:9,//messages will come back with an id field set the same<br />
approximate:true//defaults to true...if true, then only rough bounds are used<br />
}<br />
{<br />
msg:"DisablePickHover",<br />
queryid:9,//messages will come back with an id field set the same<br />
approximate:true//defaults to true...if true, then only rough bounds are used<br />
}<br />
Responses look like<br />
{<br />
msg:"HoverFocus",<br />
queryid:9//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//approx where on the surface did it hit?<br />
x:100,//screen coords<br />
y:102<br />
}<br />
{<br />
msg:"HoverBlur",<br />
queryid:9//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
x:100,//screen coords<br />
y:102<br />
}<br />
<br />
<br />
<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=ElysiaObjectHost&diff=648ElysiaObjectHost2010-07-02T05:56:43Z<p>Danielrh: </p>
<hr />
<div>To get the Elysia object host building you need the following items<br />
<br />
1) Download msysgit but read step 2 and 3 before installing<br />
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&can=2&q=<br />
<br />
2) During the installer, for the first question, select the middle option "Run git from windows command line"<br />
<br />
3) For the second question about CRLF keep the top (default) option (convert to unix linefeeds when committing)<br />
<br />
4) Go to the start menu, Program Files, Git and select "Git bash"<br />
<br />
5) in the bash prompt type<br />
ssh-keygen<br />
<br />
hit enter through every option (don't bother with a password, the consequence is that someone could commit code to github if your laptop were stolen)<br />
<br />
6) find c:\Documents and Settings\yourusername\.ssh\id_rsa.pub or in Vista/Windows 7 it may be c:\Users\yourusername\.ssh\id_rsa.pub and open it up in a text editor<br />
<br />
7) Make a new account at http://github.com<br />
<br />
8) browse to http://github.com/elysia/elysia and click fork in the top right<br />
<br />
9) go to account settings, and add a public key-- copy and paste the text from id_rsa.pub into github interface<br />
<br />
10) Download and install tortoisegit <br />
http://code.google.com/p/tortoisegit/<br />
<br />
Make sure to select using openssh.exe instead of putty and tell it the path to msysgit at c:\Program Files\git\bin\<br />
<br />
11) right click where you want to check out the data from and choose<br />
<br />
git clone...<br />
<br />
type in <br />
<br />
git@github.com:yourusername/elysia.git<br />
<br />
and then it should check out the data<br />
<br />
12)<br />
open up the elysia folder<br />
<br />
right click on blank space and do TortoiseGit -> "Submodule Update"<br />
<br />
13) load up CMake GUI http://www.cmake.org/cmake/help/runningcmake.html<br />
<br />
Select both source and build directories to be elysia\brain\build<br />
<br />
Make sure the output target is "Visual Studio 9 2008"<br />
<br />
then click configure twice<br />
<br />
then generate<br />
<br />
then quit<br />
<br />
14) load brain.sln up in visual studio and build it<br />
<br />
15) the output should be in elysia\brain\build\Debug or Release<br />
<br />
copy the files (dll's) from elysia\externals\win32depends\bin to elysia\brain\build\Debug and elysia\brain\build\Release<br />
These will allow the graphics system to run (and would have been necessary with svn as well)<br />
<br />
now you can run<br />
<br />
brainsandbox_d -test<br />
<br />
you should see<br />
<br />
1/10<br />
2/10<br />
3/10<br />
4/10<br />
5/10<br />
6/10<br />
7/10<br />
8/10<br />
9/10<br />
10/10<br />
firefire</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=ElysiaObjectHost&diff=647ElysiaObjectHost2010-07-02T05:55:01Z<p>Danielrh: </p>
<hr />
<div>To get the Elysia object host building you need the following items<br />
<br />
1) Download msysgit but read step 2 and 3 before installing<br />
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&can=2&q=<br />
<br />
2) During the installer, for the first question, select the middle option "Run git from windows command line"<br />
<br />
3) For the second question about CRLF keep the top (default) option (convert to unix linefeeds when committing)<br />
<br />
4) Go to the start menu, Program Files, Git and select "Git bash"<br />
<br />
5) in the bash prompt type<br />
ssh-keygen<br />
<br />
hit enter through every option (don't bother with a password, the consequence is that someone could commit code to github if your laptop were stolen)<br />
<br />
6) find c:\Documents and Settings\yourusername\.ssh\id_rsa.pub or in Vista/Windows 7 it may be c:\Users\yourusername\.ssh\id_rsa.pub and open it up in a text editor<br />
<br />
7) Make a new account at http://github.com<br />
<br />
8) browse to http://github.com/elysia/elysia and click fork in the top right<br />
<br />
9) go to account settings, and add a public key-- copy and paste the text from id_rsa.pub into github interface<br />
<br />
10) Download and install tortoisegit <br />
http://code.google.com/p/tortoisegit/<br />
<br />
Make sure to select using openssh.exe instead of putty and tell it the path to msysgit at c:\Program Files\git\bin\<br />
<br />
11) right click where you want to check out the data from and choose<br />
<br />
git clone...<br />
<br />
type in <br />
<br />
git@github.com:yourusername/elysia.git<br />
<br />
and then it should check out the data<br />
<br />
12)<br />
open up the elysia folder<br />
<br />
right click on blank space and do TortoiseGit -> "Submodule Update"<br />
<br />
13) load up CMake GUI http://www.cmake.org/cmake/help/runningcmake.html<br />
<br />
Select both source and build directories to be elysia\brain\build<br />
<br />
then click configure twice<br />
<br />
then generate<br />
<br />
then quit<br />
<br />
14) load brain.sln up in visual studio and build it<br />
<br />
15) the output should be in elysia\brain\build\Debug or Release<br />
<br />
copy the files (dll's) from elysia\externals\win32depends\bin to elysia\brain\build\Debug and elysia\brain\build\Release<br />
These will allow the graphics system to run (and would have been necessary with svn as well)<br />
<br />
now you can run<br />
<br />
brainsandbox_d -test<br />
<br />
you should see<br />
<br />
1/10<br />
2/10<br />
3/10<br />
4/10<br />
5/10<br />
6/10<br />
7/10<br />
8/10<br />
9/10<br />
10/10<br />
firefire</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=ElysiaObjectHost&diff=646ElysiaObjectHost2010-07-02T05:53:43Z<p>Danielrh: </p>
<hr />
<div>To get the Elysia object host building you need the following items<br />
<br />
1) Download msysgit but read step 2 and 3 before installing<br />
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&can=2&q=<br />
<br />
2) During the installer, for the first question, select the middle option "Run git from windows command line"<br />
<br />
3) For the second question about CRLF keep the top (default) option (convert to unix linefeeds when committing)<br />
<br />
4) Go to the start menu, Program Files, Git and select "Git bash"<br />
<br />
5) in the bash prompt type<br />
ssh-keygen<br />
<br />
hit enter through every option (don't bother with a password, the consequence is that someone could commit code to github if your laptop were stolen)<br />
<br />
6) find c:\Documents and Settings\yourusername\.ssh\id_rsa.pub or in Vista/Windows 7 it may be c:\Users\yourusername\.ssh\id_rsa.pub and open it up in a text editor<br />
<br />
7) Make a new account at http://github.com<br />
<br />
8) browse to http://github.com/elysia/elysia and click fork in the top right<br />
<br />
9) go to account settings, and add a public key-- copy and paste the text from id_rsa.pub into github interface<br />
<br />
10) Download and install tortoisegit <br />
http://code.google.com/p/tortoisegit/<br />
<br />
Make sure to select using openssh.exe instead of putty and tell it the path to msysgit at c:\Program Files\git\bin\<br />
<br />
11) right click where you want to check out the data from and choose<br />
<br />
git clone...<br />
<br />
type in <br />
<br />
git@github.com:yourusername/elysia.git<br />
<br />
and then it should check out the data<br />
<br />
12)<br />
open up the elysia folder<br />
<br />
right click on blank space and do TortoiseGit -> "Submodule Update"<br />
<br />
13) load up CMake GUI http://www.cmake.org/cmake/help/runningcmake.html<br />
<br />
Select source and build directories to be elysia\brain\build<br />
<br />
then click configure twice<br />
<br />
then generate<br />
<br />
then quit<br />
<br />
14) load brain.sln up in visual studio and build it<br />
<br />
15) the output should be in elysia\brain\build\Debug or Release<br />
<br />
copy the files (dll's) from elysia\externals\win32depends\bin to elysia\brain\build\Debug and elysia\brain\build\Release<br />
These will allow the graphics system to run (and would have been necessary with svn as well)<br />
<br />
now you can run<br />
<br />
brainsandbox_d -test<br />
<br />
you should see<br />
<br />
1/10<br />
2/10<br />
3/10<br />
4/10<br />
5/10<br />
6/10<br />
7/10<br />
8/10<br />
9/10<br />
10/10<br />
firefire</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=ElysiaObjectHost&diff=645ElysiaObjectHost2010-07-02T05:40:47Z<p>Danielrh: </p>
<hr />
<div>To get the Elysia object host building you need the following items<br />
<br />
1) Download msysgit but read step 2 and 3 before installing<br />
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&can=2&q=<br />
<br />
2) During the installer, for the first question, select the middle option "Run git from windows command line"<br />
<br />
3) For the second question about CRLF keep the top (default) option (convert to unix linefeeds when committing)<br />
<br />
4) Go to the start menu, Program Files, Git and select "Git bash"<br />
<br />
5) in the bash prompt type<br />
ssh-keygen<br />
<br />
hit enter through every option (don't bother with a password, the consequence is that someone could commit code to github if your laptop were stolen)<br />
<br />
6) find c:\Documents and Settings\yourusername\.ssh\id_rsa.pub or in Vista/Windows 7 it may be c:\Users\yourusername\.ssh\id_rsa.pub and open it up in a text editor<br />
<br />
7) Make a new account at http://github.com<br />
<br />
8) browse to http://github.com/elysia/elysia and click fork in the top right<br />
<br />
9) go to account settings, and add a public key-- copy and paste the text from id_rsa.pub into github interface<br />
<br />
10) Download and install tortoisegit <br />
http://code.google.com/p/tortoisegit/<br />
<br />
Make sure to select using openssh.exe instead of putty and tell it the path to msysgit at c:\Program Files\git\bin\<br />
<br />
11) right click where you want to check out the data from and choose<br />
<br />
git clone...<br />
<br />
type in <br />
<br />
git@github.com:yourusername/elysia.git<br />
<br />
and then it should check out the data<br />
<br />
12)<br />
open up the elysia folder<br />
<br />
right click on blank space and do TortoiseGit -> "Submodule Update"<br />
<br />
13) load up CMake GUI<br />
<br />
Select source and build directories to be elysia\brain\build<br />
<br />
then click configure twice<br />
<br />
then generate<br />
<br />
then quit<br />
<br />
14) load brain.sln up in visual studio and build it<br />
<br />
15) the output should be in elysia\brain\build\Debug or Release<br />
<br />
copy the files (dll's) from elysia\externals\win32depends\bin to elysia\brain\build\Debug and elysia\brain\build\Release<br />
These will allow the graphics system to run (and would have been necessary with svn as well)<br />
<br />
now you can run<br />
<br />
brainsandbox_d -test<br />
<br />
you should see<br />
<br />
1/10<br />
2/10<br />
3/10<br />
4/10<br />
5/10<br />
6/10<br />
7/10<br />
8/10<br />
9/10<br />
10/10<br />
firefire</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=ElysiaObjectHost&diff=644ElysiaObjectHost2010-07-02T05:37:20Z<p>Danielrh: </p>
<hr />
<div>To get the Elysia object host building you need the following items<br />
<br />
1) Download msysgit but read step 2 and 3 before installing<br />
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&can=2&q=<br />
<br />
2) During the installer, for the first question, select the middle option "Run git from windows command line"<br />
<br />
3) For the second question about CRLF keep the top (default) option (convert to unix linefeeds when committing)<br />
<br />
4) Go to the start menu, Program Files, Git and select "Git bash"<br />
<br />
5) in the bash prompt type<br />
ssh-keygen<br />
<br />
hit enter through every option (don't bother with a password, the consequence is that someone could commit code to github if your laptop were stolen)<br />
<br />
6) find c:\Documents and Settings\yourusername\.ssh\id_rsa.pub or in Vista/Windows 7 it may be c:\Users\yourusername\.ssh\id_rsa.pub and open it up in a text editor<br />
<br />
7) Make a new account at http://github.com<br />
<br />
8) browse to http://github.com/elysia/elysia and click fork in the top right<br />
<br />
9) go to account settings, and add a public key-- copy and paste the text from id_rsa.pub into github interface<br />
<br />
10) Download and install tortoisegit <br />
http://code.google.com/p/tortoisegit/<br />
<br />
Make sure to select using openssh.exe instead of putty and tell it the path to msysgit at c:\Program Files\git\bin\<br />
<br />
11) right click where you want to check out the data from and choose<br />
<br />
git clone...<br />
<br />
type in <br />
<br />
git@github.com:yourusername/elysia.git<br />
<br />
and then it should check out the data<br />
<br />
12)<br />
open up the elysia folder<br />
<br />
right click on blank space and do "submodule update"<br />
<br />
13) load up CMake GUI<br />
<br />
Select source and build directories to be elysia\brain\build<br />
<br />
then click configure twice<br />
<br />
then generate<br />
<br />
then quit<br />
<br />
14) load brain.sln up in visual studio and build it<br />
<br />
15) the output should be in elysia\brain\build\Debug or Release<br />
<br />
copy the files (dll's) from elysia\externals\win32depends\bin to elysia\brain\build\Debug and elysia\brain\build\Release<br />
These will allow the graphics system to run (and would have been necessary with svn as well)<br />
<br />
now you can run<br />
<br />
brainsandbox_d -test<br />
<br />
you should see<br />
<br />
1/10<br />
2/10<br />
3/10<br />
4/10<br />
5/10<br />
6/10<br />
7/10<br />
8/10<br />
9/10<br />
10/10<br />
firefire</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=ElysiaObjectHost&diff=643ElysiaObjectHost2010-07-02T05:36:34Z<p>Danielrh: </p>
<hr />
<div>To get the Elysia object host building you need the following items<br />
<br />
1) Download msysgit but read step 2 before installing<br />
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&can=2&q=<br />
<br />
2) During the installer, for the first question, select the middle option "Run git from windows command line"<br />
<br />
3) For the second question about CRLF keep the top (default) option (convert to unix linefeeds when committing)<br />
<br />
4) Go to the start menu, Program Files, Git and select "Git bash"<br />
<br />
5) in the bash prompt type<br />
ssh-keygen<br />
<br />
hit enter through every option (don't bother with a password, the consequence is that someone could commit code to github if your laptop were stolen)<br />
<br />
6) find c:\Documents and Settings\yourusername\.ssh\id_rsa.pub or in Vista/Windows 7 it may be c:\Users\yourusername\.ssh\id_rsa.pub and open it up in a text editor<br />
<br />
7) Make a new account at http://github.com<br />
<br />
8) browse to http://github.com/elysia/elysia and click fork in the top right<br />
<br />
9) go to account settings, and add a public key-- copy and paste the text from id_rsa.pub into github interface<br />
<br />
10) Download and install tortoisegit <br />
http://code.google.com/p/tortoisegit/<br />
<br />
Make sure to select using openssh.exe instead of putty and tell it the path to msysgit at c:\Program Files\git\bin\<br />
<br />
11) right click where you want to check out the data from and choose<br />
<br />
git clone...<br />
<br />
type in <br />
<br />
git@github.com:yourusername/elysia.git<br />
<br />
and then it should check out the data<br />
<br />
12)<br />
open up the elysia folder<br />
<br />
right click on blank space and do "submodule update"<br />
<br />
13) load up CMake GUI<br />
<br />
Select source and build directories to be elysia\brain\build<br />
<br />
then click configure twice<br />
<br />
then generate<br />
<br />
then quit<br />
<br />
14) load brain.sln up in visual studio and build it<br />
<br />
15) the output should be in elysia\brain\build\Debug or Release<br />
<br />
copy the files (dll's) from elysia\externals\win32depends\bin to elysia\brain\build\Debug and elysia\brain\build\Release<br />
These will allow the graphics system to run (and would have been necessary with svn as well)<br />
<br />
now you can run<br />
<br />
brainsandbox_d -test<br />
<br />
you should see<br />
<br />
1/10<br />
2/10<br />
3/10<br />
4/10<br />
5/10<br />
6/10<br />
7/10<br />
8/10<br />
9/10<br />
10/10<br />
firefire</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=ElysiaObjectHost&diff=642ElysiaObjectHost2010-06-25T05:36:01Z<p>Danielrh: </p>
<hr />
<div>To get the Elysia object host building you need the following items<br />
<br />
1) Download and install msysgit<br />
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&can=2&q=<br />
<br />
2) For the first question, select the middle option "Run git from windows command line"<br />
<br />
3) For the second question about CRLF keep the top (default) option (convert to unix linefeeds when committing)<br />
<br />
4) Go to the start menu, Program Files, Git and select "Git bash"<br />
<br />
5) in the bash prompt type<br />
ssh-keygen<br />
<br />
hit enter through every option (don't bother with a password, the consequence is that someone could commit code to github if your laptop were stolen)<br />
<br />
6) find c:\Documents and Settings\yourusername\.ssh\id_rsa.pub or in Vista/Windows 7 it may be c:\Users\yourusername\.ssh\id_rsa.pub and open it up in a text editor<br />
<br />
7) Make a new account at http://github.com<br />
<br />
8) browse to http://github.com/elysia/elysia and click fork in the top right<br />
<br />
9) go to account settings, and add a public key-- copy and paste the text from id_rsa.pub into github interface<br />
<br />
10) Download and install tortoisegit <br />
http://code.google.com/p/tortoisegit/<br />
<br />
Make sure to select using openssh.exe instead of putty and tell it the path to msysgit at c:\Program Files\git\bin\<br />
<br />
11) right click where you want to check out the data from and choose<br />
<br />
git clone...<br />
<br />
type in <br />
<br />
git@github.com/yourusername/elysia.git<br />
<br />
and then it should check out the data<br />
<br />
12)<br />
open up the elysia folder<br />
<br />
right click on blank space and do "submodule update"<br />
<br />
13) load up CMake GUI<br />
<br />
Select source and build directories to be elysia\brain\build<br />
<br />
then click configure twice<br />
<br />
then generate<br />
<br />
then quit<br />
<br />
14) load brain.sln up in visual studio and build it<br />
<br />
15) the output should be in elysia\brain\build\Debug or Release<br />
<br />
copy the files (dll's) from elysia\externals\win32depends\bin to elysia\brain\build\Debug and elysia\brain\build\Release<br />
These will allow the graphics system to run (and would have been necessary with svn as well)<br />
<br />
now you can run<br />
<br />
brainsandbox_d -test<br />
<br />
you should see<br />
<br />
1/10<br />
2/10<br />
3/10<br />
4/10<br />
5/10<br />
6/10<br />
7/10<br />
8/10<br />
9/10<br />
10/10<br />
firefire</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=ElysiaObjectHost&diff=641ElysiaObjectHost2010-06-25T05:29:29Z<p>Danielrh: </p>
<hr />
<div>To get the Elysia object host building you need the following items<br />
<br />
1) Download and install msysgit<br />
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&can=2&q=<br />
<br />
2) For the first question, select the middle option "Run git from windows command line"<br />
<br />
3) For the second question about CRLF keep the top (default) option (convert to unix linefeeds when committing)<br />
<br />
4) Go to the start menu, Program Files, Git and select "Git bash"<br />
<br />
5) in the bash prompt type<br />
ssh-keygen<br />
<br />
hit enter through every option (don't bother with a password, the consequence is that someone could commit code to github if your laptop were stolen)<br />
<br />
6) find c:\Documents and Settings\yourusername\.ssh\id_rsa.pub or in Vista/Windows 7 it may be c:\Users\yourusername\.ssh\id_rsa.pub and open it up in a text editor<br />
<br />
7) Make a new account at http://github.com<br />
<br />
8) browse to http://github.com/elysia/elysia and click fork in the top right<br />
<br />
9) go to account settings, and add a public key-- copy and paste the text from id_rsa.pub into github interface<br />
<br />
10) Download and install tortoisegit <br />
http://code.google.com/p/tortoisegit/<br />
<br />
Make sure to select using openssh.exe instead of putty and tell it the path to msysgit at c:\Program Files\git\bin\<br />
<br />
11) right click where you want to check out the data from and choose<br />
<br />
git clone...<br />
<br />
type in <br />
<br />
git@github.com/yourusername/elysia.git<br />
<br />
and then it should check out the data<br />
<br />
12)<br />
open up the elysia folder<br />
<br />
right click on blank space and do "submodule update"<br />
<br />
13) load up CMake GUI<br />
Select source and build directories to be elysia\brain\build<br />
then click configure twice<br />
then generate<br />
then quit<br />
<br />
14) load brain.sln up in visual studio and build it<br />
<br />
15) the output should be in elysia\brain\build\Debug or Release<br />
<br />
copy the files (dll's) from elysia\externals\win32depends\bin to elysia\brain\build\Debug and elysia\brain\build\Release<br />
These will allow the graphics system to run (and would have been necessary with svn as well)<br />
<br />
now you can run<br />
<br />
brainsandbox_d -test<br />
<br />
you should see<br />
<br />
1/10<br />
2/10<br />
3/10<br />
4/10<br />
5/10<br />
6/10<br />
7/10<br />
8/10<br />
9/10<br />
10/10<br />
firefire</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=ElysiaObjectHost&diff=640ElysiaObjectHost2010-06-25T05:18:49Z<p>Danielrh: New page: To get the Elysia object host building you need the following items 1) Download and install msysgit http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&...</p>
<hr />
<div>To get the Elysia object host building you need the following items<br />
<br />
1) Download and install msysgit<br />
http://code.google.com/p/msysgit/downloads/detail?name=Git-1.7.0.2-preview20100309.exe&can=2&q=<br />
<br />
2) For the first question, select the middle option "Run git from windows command line"<br />
<br />
3) For the second question about CRLF keep the top (default) option (convert to unix linefeeds when committing)<br />
<br />
4) Go to the start menu, Program Files, Git and select "Git bash"<br />
<br />
5) in the bash prompt type<br />
ssh-keygen<br />
<br />
hit enter through every option (don't bother with a password, the consequence is that someone could commit code to github if your laptop were stolen)<br />
<br />
6) find c:\Documents and Settings\yourusername\.ssh\id_rsa.pub or in Vista/Windows 7 it may be c:\Users\yourusername\.ssh\id_rsa.pub and open it up in a text editor<br />
<br />
7) Make a new account at http://github.com<br />
<br />
8) browse to http://github.com/elysia/elysia and click fork in the top right<br />
<br />
9) go to account settings, and add a public key-- copy and paste the text from id_rsa.pub into github interface<br />
<br />
10) Download and install tortoisegit <br />
http://code.google.com/p/tortoisegit/<br />
<br />
Make sure to select using openssh.exe instead of putty and tell it the path to msysgit at c:\Program Files\git\bin\<br />
<br />
11)</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=632JavascriptGraphicsAPI2010-06-13T09:17:58Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
Should we use "parentbone" or "attachment_point"?<br />
<br />
FIXME: We should default these values to the last position, not to identity. Otherwise we basically have to send everything each time.<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Creating camera properties on an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Destroying and cleaning up a camera===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
texobjid:"9a10e9c1-31fb-43e8-9a20-6545d9a62fdb", // Id of object with a mesh<br />
texname:"example.png"//overwrites this texture on the texobjid object.<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
===Detach a camera from its render target"===<br />
{<br />
msg:DetachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", // Camera object's id<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Clicking===<br />
The standard javascript callbacks are always enabled... you will get the following messages from time to time on the receiving stream.<br />
<br />
{<br />
msg:"onclick",<br />
which:2,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102<br />
}<br />
<br />
every onclick will produce a matching onrelease, even if the mouse is outside the window<br />
{<br />
msg:"onrelease",<br />
which:2,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102<br />
}<br />
<br />
{<br />
msg:"drag",<br />
queryid:8//messages will come back with an id field set the same<br />
x:103,<br />
y:105<br />
}<br />
<br />
===MouseMove===<br />
{<br />
msg:"EnableMouseMove",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
{<br />
msg:"DisableMouseMove",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
<br />
<br />
{<br />
msg:"mousemove",<br />
x:100,<br />
y:102<br />
}<br />
<br />
{<br />
msg:"EnableMouseDownUp",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
<br />
{<br />
msg:"mousedown",<br />
which:2,//right mouse button = 2, left mouse button = 0<br />
x:100,<br />
y:102<br />
}<br />
{<br />
msg:"mouseup",<br />
x:100,<br />
y:102<br />
}<br />
<br />
<br />
===Keyboard===<br />
<br />
{<br />
msg: "keypress"<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
repeat:false<br />
shiftKey:true<br />
which:25//see keyCode<br />
}<br />
{<br />
msg: "keydown"<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
repeat:false<br />
shiftKey:true<br />
which:25//see keyCode<br />
}<br />
{<br />
msg: "keyup"<br />
altKey:true,<br />
metaKey:false,<br />
ctrlKey:true,<br />
repeat:false<br />
shiftKey:true<br />
which:25//see keyCode<br />
}<br />
<br />
===Picking===<br />
{<br />
msg:"EnablePicking",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
{<br />
msg:"DisablePicking",<br />
queryid:8,//messages will come back with an id field set the same<br />
drag:false//defaults to false...if true, then deltas are sent until up is received?<br />
}<br />
<br />
<br />
Responses look like<br />
{<br />
msg:"Pick",<br />
queryid:8//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//where on the surface did it hit?<br />
normal:[.5,0,.86],//what the direction of the normal is at that point<br />
screencoordinates:[100,200]//relative to canvas?<br />
}<br />
{<br />
msg:"PickDrag",<br />
queryid:8//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//where on the surface did the drag FIRST hit?<br />
normal:[.5,0,.86],//what the direction of the normal is at that point<br />
planedelta:[.24,.52,.25]//how far did it move in the camera plane<br />
perpdelta:[0,1,0]//how far did it move perpendicular to camera plane<br />
}<br />
{<br />
msg:"PickRelease",<br />
queryid:8//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//where on the surface did the drag FIRST hit?<br />
normal:[.5,0,.86],//what the direction of the normal is at that point<br />
planedelta:[.24,.52,.25]//how far did it move in the camera plane<br />
perpdelta:[0,1,0]//how far did it move perpendicular to camera plane<br />
x:102,//screen coords<br />
y:101<br />
}<br />
<br />
===Pick/Hovering==<br />
{<br />
msg:"EnablePickHover",<br />
queryid:9,//messages will come back with an id field set the same<br />
approximate:true//defaults to true...if true, then only rough bounds are used<br />
}<br />
{<br />
msg:"DisablePickHover",<br />
queryid:9,//messages will come back with an id field set the same<br />
approximate:true//defaults to true...if true, then only rough bounds are used<br />
}<br />
Responses look like<br />
{<br />
msg:"HoverFocus",<br />
queryid:9//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
pos:[1,2,3],//approx where on the surface did it hit?<br />
x:100,//screen coords<br />
y:102<br />
}<br />
{<br />
msg:"HoverBlur",<br />
queryid:9//messages will come back with an id field set the same<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
x:100,//screen coords<br />
y:102<br />
}<br />
<br />
<br />
<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=629JavascriptGraphicsAPI2010-05-29T02:25:10Z<p>Danielrh: /* Creating a new graphics object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
spaceid:"aaaaaaaa-bbbb-cccc-dada-134234ab98",//<-- optional (defaults to the empty space, 0)<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
Should we use "parentbone" or "attachment_point"?<br />
<br />
FIXME: We should default these values to the last position, not to identity. Otherwise we basically have to send everything each time.<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=608JavascriptGraphicsAPI2010-03-14T21:19:21Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=607JavascriptGraphicsAPI2010-03-14T21:18:47Z<p>Danielrh: Undo revision 602 by Danielrh (Talk) Quaternions take too much computation to compute in JS just for interthread transfer</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=Installing_the_NVidia,_COLLADA,_and_Ogre_Plugins&diff=606Installing the NVidia, COLLADA, and Ogre Plugins2010-03-08T10:10:02Z<p>Danielrh: /* Installing COLLADA for Maya */</p>
<hr />
<div>Sirikata requires a number of plugins in order for your content to be imported into the engine. Instead of supporting multitudes of file types, these plugins allow for us to ensure that there is a standard way of creating content for Sirikata so that everything is uniform, making it easier to pinpoint problems (should there be any).<br />
<br />
== Installing the NVidia .dds file format plugin for Photoshop 32-bit ==<br />
<br />
#Go the [http://developer.nvidia.com/object/photoshop_dds_plugins.html NVidia plugin page] and download the latest version.<br />
#Once you have downloaded the plugin, follow the on screen instructions for installation.<br />
#You will be asked to choose a folder for installation. It will use the default Adobe directory. If you have installed Photoshop anywhere else, please change it accordingly.<br />
#Finish the installation and open Photoshop. Go to File > New and create a new, blank document.<br />
#Go to File > Save As… and choose D3D/DDS (*.DDS). If you see this option, that means the installation of the plugin was successful.<br />
<br />
=== Troubleshooting for NVidia .dds plugin ===<br />
#The plugin does not work with 64-bit versions of Photoshop. If you have a 64-bit version of Windows, you will need to install the plugin for the 32-bit version of Photoshop, installed by default in C:\Program Files (x86)\Adobe.<br />
#If you cannot choose .DDS from the Save As… menu, the plugin may not have been installed properly. Go to your Photoshop folder, normally located at C:\Program Files\Adobe, or C:\Program Files (x86)\Adobe for Windows 64-bit, and open your Photoshop directory. Go to Plug-ins and then File Formats. Inside this director you should see a list of files with the extension .8BI. You should see the file dds.8BI. If not, run the installer again and make sure you install to the right directory (the installer wants the root directory of Photoshop, so always install to there: C:\Program Files\Adobe\Adobe Photoshop CSX).<br />
<br />
<br />
<br />
== Installing the Ogre Exporter for 3ds Max 9 32-bit ==<br />
<br />
#Download the [http://www.sirikata.com/res/dev_preview/SirikataSceneExporter.zip Ogre Exporter for 3ds Max 32].<br />
#Open SirikataSceneExport.zip and open the folder “OgreExporter.”<br />
#Navigate to your 3ds Max 9 folder, located at C:\Program Files\Autodesk\3ds Max 9 for 64-bit and C:\Program Files\Autodesk\3ds Max 9 for 32-bit computers.<br />
#Open the 3ds Max 9 folder.<br />
#Go back to SirikataSceneExport.zip and copy the contents of “OgreExporter” into the main 3ds Max 9 folder. (See first image below)<br />
#Give Windows permission to overwrite any necessary files.<br />
# Download the [http://graphics.stanford.edu/~danielrh/OgreExporter-0.1.4.zip newest version of Ogre Exporter] (currently 0.1.4). Copy the .gup file into your 3ds Max 9/plugins folder and allow Windows to overwrite the older .gup file.<br />
#Start 3ds Max and open your file. When it is ready to be exported, go to OgreMax > Export Selected 0.1.3. (See second image below)<br />
#THE OGRE EXPORTER CAUSES 3DS MAX TO CRASH ON STARTUP. READ THE TROUBLESHOOTING SECTION FOR MORE INFORMATION.<br />
<br />
<br />
Copying the files from SirikataSceneExport.zip to C:\Program Files (x86)\Autodesk\3ds Max 9:<br />
<br />
[[Image:SirikataSceneExport.jpg|Copying the files from SirikataSceneExport.zip to C:\Program Files (x86)\Autodesk\3ds Max 9.]]<br />
<br />
<br />
Finding OgreMax:<br />
<br />
[[Image:SirikataSceneExport2.jpg|Finding OgreMax.]]<br />
<br />
=== Troubleshooting for Ogre Exporter ===<br />
#The exporter currently has a bug which our team has been unable to fix. Every time the exporter is used, 3ds Max creates a .mnu file that is located in C:\Documents and Settings\Administrator\Local Settings\Application Data\Autodesk\3dsmax\9 - 32bit\enu\UI. The file, DefaultUI.mnu, causes 3ds Max 9 to crash the next time it is loaded unless you delete DefaultUI.mnu prior to opening the program. It is suggested that you make a shortcut to this folder and keep it on your Desktop or with your other Sirikata files so that it is easy to access. A fix for this problem is underway and will be released ASAP.<br />
#If you have any other problems with the Ogre Exporter, you may have installed it wrong. Make sure that the file OgreMaxSceneExporter.gup is in the plugins folder, found at C:\Program Files\Autodesk\3ds Max 9\plugins. If the file is located in plugins but you are still having problems, read on below.<br />
#Even if all of the Ogre Exporter files appear to be in order, if it does not appear as it should within 3ds Max 9, try reinstalling the plugin by copying all the files over again. You may have originally placed them in the wrong directory.<br />
<br />
<br />
<br />
== Installing COLLADA for 3ds Max 9 32-bit ==<br />
# Download [http://sourceforge.net/projects/colladamaya/files/ COLLADA for 3ds Max 9]. Under the dropdown menu COLLADAMax 1.4.1 plug-ins, choose ColladaMax_FREE_3.05C.exe. When you open this file, it should automatically find your 3ds Max 9 file folder.<br />
# Follow the on screen instructions. You will be prompted to choose if you want to install the plugin for more than one version of Max. You may install as many options as you want as long as the plugin is installed for 3ds Max 9.<br />
# Open 3ds Max and go to File > Import. You should be able to choose “COLLADA (*.DAE, *.XML)” under the file type options.<br />
<br />
<br />
<br />
<br />
== Installing COLLADA for Maya ==<br />
<br />
# Download [http://opencollada.org/download.html OpenCOLLADA for Maya]. Under the dropdown menu OpenCOLLADA 1.2.2 plug-ins, choose 32bit. When you open this file, it should automatically find your Maya folder.<br />
# Follow the on screen instructions. You will be prompted to choose if you want to install the plugin for more than one version of Max. You may install as many options as you want as long as the plugin is installed for your version of Maya.<br />
# Open Maya and go to File > Export Selected. You should be able to choose “COLLADA” under file type options.</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=605JavascriptGraphicsAPI2010-03-04T23:53:20Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],//absolute position<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//quaternion<br />
rotation:[100,0,.25,.25],//normalized quaternion indicating rotational axis with magnitude living in the w term<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,4,3],//absolute position<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotation:[100,0,.25,.25],//normalized quaternion indicating rotational axis with magnitude living in the w term<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=604JavascriptGraphicsAPI2010-03-04T23:51:36Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s). The interpolation scheme should use cubic interpolation using the most current update's position and orientation along with the displayed position and location of the object when that update was received to provide a smooth scheme.<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],//absolute position<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//quaternion<br />
rotation:[100,0,.25,.25],//normalized quaternion indicating rotational axis with magnitude living in the w term<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,4,3],//absolute position<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotation:[100,0,.25,.25],//normalized quaternion indicating rotational axis with magnitude living in the w term<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=603JavascriptGraphicsAPI2010-03-04T23:49:16Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],//absolute position<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//quaternion<br />
rotation:[100,0,.25,.25],//normalized quaternion indicating rotational axis with magnitude living in the w term<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,4,3],//absolute position<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotation:[100,0,.25,.25],//normalized quaternion indicating rotational axis with magnitude living in the w term<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
===Attach a camera to a render target"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
target:0//writes to this framebuffer--- 0 for left ,1 right for stereo, etc.<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=602JavascriptGraphicsAPI2010-03-04T23:46:56Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
id's can be anything from human readable strings to uuids to integers. They just each must be unique and chosen by the user of the API<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],//absolute position<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//quaternion<br />
rotation:[100,0,.25,.25],//normalized quaternion indicating rotational axis with magnitude living in the w term<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,4,3],//absolute position<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotation:[100,0,.25,.25],//normalized quaternion indicating rotational axis with magnitude living in the w term<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
attachment_point:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=599JavascriptGraphicsAPI2010-02-10T00:33:19Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
<br />
==Should an object just be a sprite==<br />
We figured that a collada square file may be a more compat representation for a sprite and can contain the appropriate shader, materials, etc<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=598JavascriptGraphicsAPI2010-02-10T00:32:28Z<p>Danielrh: /* Streaming some joint locations */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0],<br />
interpolate:true//if false then the bone should snap to the location unless smooth is set (in which case it should interpolate as quickly as possible) defaults to true<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=597JavascriptGraphicsAPI2010-02-10T00:30:01Z<p>Danielrh: /* Moving a graphics object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
interpolate:true,//set to false if the object should snap to new position<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=596JavascriptGraphicsAPI2010-02-10T00:29:18Z<p>Danielrh: /* Adding/changing mesh property for an object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Updating shader property (Vertex and Fragment float4) for an object===<br />
{<br />
msg:"MeshShaderUniform"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"ColorTint"<br />
value:[.24,.24,.25,1.0]<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=595JavascriptGraphicsAPI2010-02-10T00:27:37Z<p>Danielrh: /* Adding/changing mesh property for an object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard property is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=594JavascriptGraphicsAPI2010-02-10T00:27:18Z<p>Danielrh: /* Adding/changing mesh property for an object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard object is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
This approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=593JavascriptGraphicsAPI2010-02-10T00:26:53Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
note if the billboard object is present and not false, it should be set to one of the following 3 strings<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see http://www.ogre3d.org/docs/manual/manual_35.html#SEC191 and http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=592JavascriptGraphicsAPI2010-02-10T00:25:55Z<p>Danielrh: Undo revision 591 by Danielrh (Talk)</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=591JavascriptGraphicsAPI2010-02-10T00:24:39Z<p>Danielrh: Reverted edits by Danielrh (Talk) to last version by PatrickHorn</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=590JavascriptGraphicsAPI2010-02-10T00:23:49Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=589JavascriptGraphicsAPI2010-02-10T00:22:56Z<p>Danielrh: /* Removing point sprite property from object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=588JavascriptGraphicsAPI2010-02-10T00:22:43Z<p>Danielrh: /* Making an object a point sprite */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
===Removing point sprite property from object===<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
{<br />
msg:"DestroySprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=587JavascriptGraphicsAPI2010-02-10T00:22:12Z<p>Danielrh: /* Making mesh a point sprite */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Making an object a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=586JavascriptGraphicsAPI2010-02-10T00:21:34Z<p>Danielrh: /* Adding/changing mesh property for an object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Making mesh a point sprite===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
<br />
<br />
{<br />
msg:"Sprite",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
sprite:"http://example.com/test.jpg",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:"perpendicular_self"<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self, this vector is the common up vector used to orient all particles in the system.<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=585JavascriptGraphicsAPI2010-02-09T23:41:46Z<p>Danielrh: /* Deprecated API Ideas */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=584JavascriptGraphicsAPI2010-02-09T23:37:24Z<p>Danielrh: /* Intersection callback */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
id:5<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=583JavascriptGraphicsAPI2010-02-09T23:37:15Z<p>Danielrh: /* Requesting intersection */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
id:5<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=582JavascriptGraphicsAPI2010-02-09T23:35:00Z<p>Danielrh: /* Intersection callback */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
normals:[[0,1,0],[.5,0,.86]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=581JavascriptGraphicsAPI2010-02-09T23:30:20Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent DOM element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,parentElement)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early<br />
<br />
=Deprecated API Ideas=<br />
Here we put ideas we had but decided to discard so that they don't come up again as new ideas and may be discussed here and evaluated for re-addition if someone feels strongly they should be included<br />
<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
==Skeleton file formats==<br />
<br />
The reason these were removed is that they are too brittle (it's hard to weigh an wave and walk animation and have the steps not be half as wide) and it's difficult to keep the skeletons out of trouble (i.e. feet through the ground)<br />
so we think thta the physics system in general should send the bone positions and timestamps since it's the arbiter of what intersects what--and it can always read the skeleton file format.<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=579JavascriptGraphicsAPI2010-02-09T06:35:43Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a constructor method that takes in a callback and a parent element and returns a class that has a send(obj) method that takes in serializable objects from other threads that modify graphics state and an optional "destroy" method which cleans up graphics state in the DOM.<br />
<br />
so a sequence of code to construct an graphics system, make an object, and destroy it could look like<br />
gfx= new GLGERenderer(callbackFunction,window)<br />
gfx.send({ msg:"Create", id:"f47ac10b-58cc-4372-a567-0e02b2c3d479", time: 2181298451298491284, pos:[1,2,3], orient:[.5,0,0,.5]})<br />
gfx.destroy();<br />
<br />
<br />
<br />
<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=578JavascriptGraphicsAPI2010-02-09T06:03:05Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a function called InitializeGFX(name,callback)<br />
The function definition should look as follows<br />
InitializeGFX=function(name,callback) {<br />
if (name in GraphicsPlugins) {<br />
GraphicsPlugins[name](callback);<br />
return true;<br />
}else if (name.length==0) {//return an arbitrary one, user has not specified<br />
for (name in GraphicsPlugins) {<br />
GraphicsPlugins[name](callback);<br />
return true;<br />
}<br />
}<br />
return false;<br />
}<br />
<br />
The plugin should also carefully create the list GraphicsPlugins if that list is not there and add itself to the list of graphics plugins<br />
<br />
callback is a function taking a single serializable object and passing that message to the rest of the system as a manner of providing a mechanism for the graphics system to call back with key and mouse events<br />
<br />
calling GraphicsPlugin[name] must create a global method called SendGFX(object) which routes one of the below cross thread message to the graphics subsystem.<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=577JavascriptGraphicsAPI2010-02-09T02:21:30Z<p>Danielrh: /* Experimental/Brainstorming ideas for the API */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a function called InitializeGFX(name,callback)<br />
The function definition should look as follows<br />
InitializeGFX=function(name,callback) {<br />
if (name in GraphicsPlugins) {<br />
GraphicsPlugins[name](callback);<br />
return true;<br />
}<br />
return false;<br />
}<br />
<br />
The plugin should also carefully create the list GraphicsPlugins if that list is not there and add itself to the list of graphics plugins<br />
<br />
callback is a function taking a single serializable object and passing that message to the rest of the system as a manner of providing a mechanism for the graphics system to call back with key and mouse events<br />
<br />
calling GraphicsPlugin[name] must create a global method called SendGFX(object) which routes one of the below cross thread message to the graphics subsystem.<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
I decided to reserve a section of the wiki for sort of bleeding edge ideas of cool features that would be nice to have. I could have put that in the "talk" page, but I think it makes more sense here so that it will get wider exposure. These are meant to be things that would help in drawing real scenes and building real VW systems but that we haven't figured out a good API to yet.<br />
<br />
<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Specifying a terrain for the world==<br />
Would need to be chunked and in some sort of widely readable format---would be nice to be able to tap into google earth for terrain--ideas for how to do this are still very very early</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=576JavascriptGraphicsAPI2010-02-09T02:12:00Z<p>Danielrh: /* Skeleton Management */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a function called InitializeGFX(name,callback)<br />
The function definition should look as follows<br />
InitializeGFX=function(name,callback) {<br />
if (name in GraphicsPlugins) {<br />
GraphicsPlugins[name](callback);<br />
return true;<br />
}<br />
return false;<br />
}<br />
<br />
The plugin should also carefully create the list GraphicsPlugins if that list is not there and add itself to the list of graphics plugins<br />
<br />
callback is a function taking a single serializable object and passing that message to the rest of the system as a manner of providing a mechanism for the graphics system to call back with key and mouse events<br />
<br />
calling GraphicsPlugin[name] must create a global method called SendGFX(object) which routes one of the below cross thread message to the graphics subsystem.<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
<br />
Note that the animation.dae should have annotations for loop-in point and loop-out point within the .dae so that loop can intelligently function<br />
<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
//if not specified this is a hard constraint (i.e. foot is glued to a wall in order to avoid penetrating it)<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=575JavascriptGraphicsAPI2010-02-08T21:58:48Z<p>Danielrh: /* Attaching 3d Text to an Objects */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a function called InitializeGFX(name,callback)<br />
The function definition should look as follows<br />
InitializeGFX=function(name,callback) {<br />
if (name in GraphicsPlugins) {<br />
GraphicsPlugins[name](callback);<br />
return true;<br />
}<br />
return false;<br />
}<br />
<br />
The plugin should also carefully create the list GraphicsPlugins if that list is not there and add itself to the list of graphics plugins<br />
<br />
callback is a function taking a single serializable object and passing that message to the rest of the system as a manner of providing a mechanism for the graphics system to call back with key and mouse events<br />
<br />
calling GraphicsPlugin[name] must create a global method called SendGFX(object) which routes one of the below cross thread message to the graphics subsystem.<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
=Experimental/Brainstorming ideas for the API=<br />
It seems like there should be a manner aside from "embedded iframes" to get art defined in the DOM into the scene graph--perhaps the canvas tag is the way to go here? But maybe that's too webGL specific and won't work for an Ogre port of this<br />
<br />
maybe just text rendering belongs here?<br />
<br />
Anyhow anything below here is purely speculative<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=574JavascriptGraphicsAPI2010-02-08T21:56:32Z<p>Danielrh: /* Attaching 3d Text to an Objects */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a function called InitializeGFX(name,callback)<br />
The function definition should look as follows<br />
InitializeGFX=function(name,callback) {<br />
if (name in GraphicsPlugins) {<br />
GraphicsPlugins[name](callback);<br />
return true;<br />
}<br />
return false;<br />
}<br />
<br />
The plugin should also carefully create the list GraphicsPlugins if that list is not there and add itself to the list of graphics plugins<br />
<br />
callback is a function taking a single serializable object and passing that message to the rest of the system as a manner of providing a mechanism for the graphics system to call back with key and mouse events<br />
<br />
calling GraphicsPlugin[name] must create a global method called SendGFX(object) which routes one of the below cross thread message to the graphics subsystem.<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
<br />
Perhaps the canvas tag is the way to go <br />
<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=573JavascriptGraphicsAPI2010-02-08T21:54:18Z<p>Danielrh: </p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a function called InitializeGFX(name,callback)<br />
The function definition should look as follows<br />
InitializeGFX=function(name,callback) {<br />
if (name in GraphicsPlugins) {<br />
GraphicsPlugins[name](callback);<br />
return true;<br />
}<br />
return false;<br />
}<br />
<br />
The plugin should also carefully create the list GraphicsPlugins if that list is not there and add itself to the list of graphics plugins<br />
<br />
callback is a function taking a single serializable object and passing that message to the rest of the system as a manner of providing a mechanism for the graphics system to call back with key and mouse events<br />
<br />
calling GraphicsPlugin[name] must create a global method called SendGFX(object) which routes one of the below cross thread message to the graphics subsystem.<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}<br />
<br />
==Attaching 3d Text to an Objects==<br />
I'm just brainstorming here: it seems like WebGL has facilities to do this efficiently, but I don't have a good use case except buildnig a rendering system inside a canvas tag or something?<br />
{<br />
msg:"Text",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
text:"This is a test of the emergency broadcast system",<br />
font:"size=+1"<br />
}<br />
{<br />
msg:"DestroyText",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}</div>Danielrhhttps://www.sirikata.com/wiki/index.php?title=JavascriptGraphicsAPI&diff=572JavascriptGraphicsAPI2010-02-08T21:43:41Z<p>Danielrh: /* Adding a particle system to an object */</p>
<hr />
<div>=Rationale for a common API to 3d graphics systems=<br />
<br />
Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:<br />
<br />
In modern engines, graphics framerates should not be tied to physics framerates and networking events and decoding of said events should happen at the correct pace to keep up with the networknig adapter. Graphics, however, is tied to the DOM and therefore must be on the main thread. This forces both networking and physics to be on webworker threads if there is to be any threading.<br />
<br />
These threads need to advertise state changes to the main graphics thread so that the scene graph may be altered at the graphics rate. This requires that the individual physics and networking threads send timestamped events to the graphics system which drive changes to it. <br />
<br />
Since graphics can run at different rates and the updates from the network may be irregular, the graphics (main) thread needs to have a smooth interpolation scheme interpolating the current position with the timestamped updates sent by the network/physics thread(s).<br />
<br />
Below are some example objects that may be sent cross-thread. The objects are listed in JSON format so the type information should be clear from the example.<br />
<br />
=API To Graphics System=<br />
Graphics should provide a function called InitializeGFX(name,callback)<br />
The function definition should look as follows<br />
InitializeGFX=function(name,callback) {<br />
if (name in GraphicsPlugins) {<br />
GraphicsPlugins[name](callback);<br />
return true;<br />
}<br />
return false;<br />
}<br />
<br />
The plugin should also carefully create the list GraphicsPlugins if that list is not there and add itself to the list of graphics plugins<br />
<br />
callback is a function taking a single serializable object and passing that message to the rest of the system as a manner of providing a mechanism for the graphics system to call back with key and mouse events<br />
<br />
calling GraphicsPlugin[name] must create a global method called SendGFX(object) which routes one of the below cross thread message to the graphics subsystem.<br />
<br />
=Cross thread communication from Physics and Networking to graphics=<br />
==Object Management==<br />
===Creating a new graphics object===<br />
<br />
{<br />
msg:"Create"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time: 2181298451298491284,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5]<br />
rotaxis:[0,0,1]<br />
rotvel:.25,<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479",//<-- optional (defaults to empty--toplevel if absent<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Assume root transform otherwise<br />
}<br />
<br />
===Moving a graphics object===<br />
//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?<br />
<br />
{<br />
msg:"Move"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
time:39852398592385,//milliseconds since 1970<br />
pos:[1,2,3],<br />
vel:[.25,0,0],<br />
orient:[.5,0,0,.5],//defaults to (identity) if absent<br />
rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 <br />
rotvel:.25,//defaults to 0 if absent<br />
scale:[1,1,1],//defaults to 1,1,1 if absent<br />
parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to previous state if absent, to clear pass empty string)<br />
parentbone:"Hand"//name of the bone on the parent object that this is attached to. Defaults to previous state if absent, to clear pass empty string<br />
}<br />
<br />
===Destroying a graphics object===<br />
<br />
{<br />
msg:"Destroy"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
==Managing object appearance properties==<br />
===Adding/changing mesh property for an object===<br />
{<br />
msg:"Mesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
mesh:"http://example.com/test.dae",//the mesh should be rescaled to fit inside a unit sphere centered at 0,0,0<br />
billboard:false//defaults to false, if set to true the object will stay aligned with camera<br />
}<br />
<br />
===Removing mesh property for an object===<br />
{<br />
msg:"DestroyMesh",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
===Adding/changing light property for an object===<br />
<br />
{<br />
msg:"Light"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
diffuse_color:[.25,.5,1],<br />
specular_color: [.2,1,.5],<br />
power=1.0: //exponent on the light<br />
ambient_color: [0,0,0],<br />
light_range: 1.0e5<br />
constant_falloff: 0.5,<br />
linear_falloff: 0.2,<br />
quadratic_falloff: 0.1,<br />
cone_inner_radians: 0,<br />
cone_outer_radians: 0,<br />
cone_falloff: 0.5,<br />
type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"<br />
casts_shadow: true<br />
}<br />
<br />
===Removing light property for an object===<br />
{<br />
msg:"DestroyLight"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
==Camera Management==<br />
<br />
===Attaching a camera to an object===<br />
{<br />
msg:"Camera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)<br />
}<br />
<br />
===Detaching a camera from an object===<br />
{<br />
msg:"DestroyCamera"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
===Attach a camera to an object's texture"===<br />
{<br />
msg:AttachCamera",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
texname:"example.png"//overwrites this texture<br />
}<br />
<br />
==Attaching UI elements to graphics objects==<br />
The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.<br />
<br />
The user may specify a 3d location, orientation and scale for a UI dialog to be. The graphics system should do its best to scale and position the UI in the appropriate place, but the UI may be restricted to always face the camera and always be horizontal compared with the bottom of the screen on many system. The UI should not be displayed if it is completely invisible from the camera angle or smaller than 10 pixels.<br />
===Creating/Updating UI Element===<br />
{<br />
msg:"IFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
uri: "http://example.com"<br />
}<br />
===Notification from UI Element===<br />
The iframe should have a parent method called "UISend" which takes a serializable object and which will invoke the callback that was passed into the graphics system with an object like<br />
{<br />
msg: "IFrameCallback"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
argument:{name:"Clicked button",location:[4,5]}<br />
}<br />
<br />
===Destroying UI Element===<br />
{<br />
msg:"DestroyIFrame"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
}<br />
<br />
==Skeleton Management==<br />
===Animating a skeleton based on a time based animation===<br />
{<br />
msg:"Ani",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)<br />
animation:"http://example.com/animation.dae",<br />
loop:false,<br />
weight:1.0 ///how strong this animation should compare with other animations that use the same bones<br />
fadein:2.3 //how many seconds to fade in<br />
}<br />
<br />
===Stopping a skeleton based on a time based animation===<br />
{<br />
msg:"AniStop",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"http://example.com/animation.dae"<br />
fadeout:1.0//how many seconds to fade out<br />
}<br />
<br />
===Streaming some joint locations===<br />
{<br />
msg:"AnimateBone",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
animation:"uniqueAnimationIdentifier",//so this movement can be associated with one animation and blended with others<br />
weight:1.0,//the weight for prospective blending, defaults to 1.0<br />
time:1250120951209510295;//milliseconds since 1970<br />
bone:["ankle","arm"]<br />
pos:[[1,2,3],[2,3,4]]<br />
vel:[[.25,0,0],[0,0,0]]<br />
orient:[[.5,0,0,.5],[1,0,0,0]]<br />
rotaxis:[[0,0,1],[0,1,0]]<br />
rotvel:[.25,0]<br />
}<br />
<br />
==Scene Queries==<br />
===Requesting intersection===<br />
{<br />
msg:"RayTrace",<br />
pos:[2,3,4],<br />
dir:[.24,.33,.5],<br />
multiple:true//if false, only return first hit<br />
infinite:false//if false use length of dir to specify ray length<br />
}<br />
<br />
===Intersection callback===<br />
{<br />
msg:"Intersections",<br />
pos:[[2,3,4],[2.23,3.32,4.49]]<br />
id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",<br />
}<br />
<br />
==Particle System==<br />
===Adding a particle system to an object===<br />
This mimics the ogre interface and we introduce a number of billboard types<br />
point<br />
The default arrangement, this approximates spherical particles and the billboards always fully face the camera. <br />
oriented_common<br />
Particles are oriented around a common, typically fixed direction vector (see common_direction), which acts as their local Y axis. The billboard rotates only around this axis, giving the particle some sense of direction. Good for rainstorms, starfields etc where the particles will traveling in one direction - this is slightly faster than oriented_self (see below). <br />
oriented_self<br />
Particles are oriented around their own direction vector, which acts as their local Y axis. As the particle changes direction, so the billboard reorients itself to face this way. Good for laser fire, fireworks and other 'streaky' particles that should look like they are traveling in their own direction. <br />
perpendicular_common<br />
Particles are perpendicular to a common, typically fixed direction vector (see common_direction), which acts as their local Z axis, and their local Y axis coplanar with common direction and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side material to ensure particles never culled by back-facing. Good for aureolas, rings etc where the particles will perpendicular to the ground - this is slightly faster than perpendicular_self (see below). <br />
perpendicular_self<br />
Particles are perpendicular to their own direction vector, which acts as their local Z axis, and their local Y axis coplanar with their own direction vector and the common up vector (see common_up_vector). The billboard never rotates to face the camera, you might use double-side mater<br />
For further documentation about the properties see<br />
http://www.ogre3d.org/docs/manual/manual_35.html#SEC191<br />
http://www.ogre3d.org/docs/manual/manual_36.html#SEC208<br />
and<br />
<br />
<br />
{ <br />
msg:"ParticleSystem",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
mesh:"http://example.com/billboard.dae"//the mesh should be rescaled to be a 1x1 mesh with <br />
particle_size:[20,20],<br />
cull_each:false<br />
quota:10000<br />
billboard:"oriented_self",<br />
sorted:false//defaults to false--whether the particles should be sorted<br />
local:false//defaults to false--if true rotation of the node after the emission of the particle will rotate it<br />
direction: [0,0,1],///the common direction for oriented_common or perpendicular_common<br />
up: [0,0,1],///Only required if billboard_type is set to perpendicular_self or perpendicular_common, this vector is the common up vector used to orient all particles in the system.<br />
accurate_facing:false//if the facing is set to the camera facing or calculated per billboard<br />
iteration_interval:.125//how often the particles are updated--if set to 0, defaults to framerate<br />
invisibility_timeout:10//how many seconds of being outside the frustum before the system stops updating<br />
}<br />
<br />
{<br />
msg:"DestroyParticleSystem"<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"<br />
}<br />
<br />
<br />
once a system is created, particles need to be emitted from it. There should be a global map of default emitters named ParticleEmitters consisting of at least<br />
"Point","Box","Cylinder","Ellipsoid","Shell","Ring" and the extra attributes are specified in http://www.ogre3d.org/docs/manual/manual_38.html<br />
{<br />
msg:"ParticleEmitter",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
type:"Ring"<br />
angle 15<br />
emission_rate 75<br />
time_to_live:[2.5,3]//range between 2.5 and 3<br />
direction [0, 1, 0]//3d vector<br />
speed:[250,300]//range between 250 and 300<br />
colour_range:[[1 0 0],[0 0 1]]//random color<br />
position:[0,0,0],<br />
repeat_delay:[2.5,5]<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleEmitter",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"Flare"<br />
}<br />
<br />
There may be forces applied to the emitters<br />
and there must be a global map of affectors called ParticleAffector from which the relevent affector is selected consisting of at least<br />
<br />
LinearForce, ColourFader, Scaler, Rotator, ColourInterpolator, ColourImage, DeflectorPlane, DirectionRandomiser<br />
The detailed definitions are contanied at http://www.ogre3d.org/docs/manual/manual_40.html#SEC234<br />
<br />
<br />
<br />
<br />
{<br />
msg:"ParticleAffector",//add or upate a particle emitter<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
type:"LinearForce"<br />
force_vector: [0 -100 0]<br />
force_application: "add"<br />
<br />
}<br />
<br />
{<br />
msg:"RemoveParticleAffector",<br />
id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",<br />
name:"TheForce"<br />
}</div>Danielrh