Difference between revisions of "JavascriptGraphicsAPI"

From Sirikata Wiki
Jump to navigation Jump to search
Line 187: Line 187:
  
 
==Scene Queries==
 
==Scene Queries==
===Requesting intersection
+
===Requesting intersection===
 
  {
 
  {
 
   msg:"RayTrace",
 
   msg:"RayTrace",

Revision as of 20:47, 8 February 2010

Argument for a common API to 3d graphics systems

Objects are sent across the thread barrier to alter the current scene graph being displayed--here's why:

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.

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.

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).

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.

API To Graphics System

Graphics should provide a function called InitializeGFX(name,callback) The function definition should look as follows

InitializeGFX=function(name,callback) {
  if (name in GraphicsPlugins) {
     GraphicsPlugins[name](callback);
     return true;
   }
   return false;
}

The plugin should also carefully create the list GraphicsPlugins if that list is not there and add itself to the list of graphics plugins

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

calling GraphicsPlugin[name] must create a global method called SendGFX(object) which routes one of the below cross thread message to the graphics subsystem.

Cross thread communication from Physics and Networking to graphics

Object Management

Creating a new graphics object

{
 msg:"Create"
 id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"
 time: 2181298451298491284,//milliseconds since 1970
 pos:[1,2,3],
 vel:[.25,0,0],
 orient:[.5,0,0,.5]
 rotaxis:[0,0,1]
 rotvel:.25,
 scale:[1,1,1],//defaults to 1,1,1 if absent
 parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to empty--toplevel if absent
}

Moving a graphics object

//should we define that the graphics system has some sort of interp--otherwise velocity may be useless?

{
  msg:"Move"
  id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"
  time:39852398592385,//milliseconds since 1970
  pos:[1,2,3],
  vel:[.25,0,0],
  orient:[.5,0,0,.5],//defaults to (identity) if absent
  rotaxis:[0,0,1],//defaults to 0,0,1 if absent, forcing rotvel to 0 
  rotvel:.25,//defaults to 0 if absent
  scale:[1,1,1],//defaults to 1,1,1 if absent
  parent:"c46ac00b-58cc-4372-a567-0e02b2c3d479"//<-- optional (defaults to toplevel (empty string) if absent
}

Destroying a graphics object

{
   msg:"Destroy"
   id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"
}


Managing object appearance properties

Adding/changing mesh property for an object

{
  msg:"Mesh",
  id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
  mesh:"http://example.com/test.dae"
}

Removing mesh property for an object

{
   msg:"DestroyMesh",
   id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
}

Adding/changing light property for an object

{
  msg:"Light"
  id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"
  diffuse_color:[.25,.5,1],
  specular_color: [.2,1,.5],
  power=1.0: //exponent on the light
  ambient_color: [0,0,0],
  light_range: 1.0e5
  constant_falloff: 0.5,
  linear_falloff: 0.2,
  quadratic_falloff: 0.1,
  cone_inner_radians: 0,
  cone_outer_radians: 0,
  cone_falloff: 0.5,
  type: "POINT",//options include "SPOTLIGHT" or "DIRECTIONAL"
  casts_shadow: true
}

Removing light property for an object

{
    msg:"DestroyLight"
    id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

Camera Management

Attaching a camera to an object

{
   msg:"Camera"
   id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"
   primary:true//whether the camera should be attached to the canvas rendering surface (may be overridden with future calls to Camera)
}

Detaching a camera from an object

{
   msg:"DestroyCamera"
   id:"f47ac10b-58cc-4372-a567-0e02b2c3d479"
}

Attach a camera to an object's texture"

{
  msg:AttachCamera",
  id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
  camid:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
  texname:"example.png"//overwrites this texture
}

Attaching UI elements to graphics objects

The UI will naturally need to be in HTML since that's the best established cross platform, sandboxed UI system.

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.

Creating/Updating UI Element

{
  msg:"IFrame"
  id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
  uri: "http://example.com"
}

Notification from UI Element

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

{
  msg: "IFrameCallback"
  id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
  argument:{name:"Clicked button",location:[4,5]}
}

Destroying UI Element

{
  msg:"DestroyIFrame"
  id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
}

Skeleton Management

Animating a skeleton based on a time based animation

{
   msg:"Ani",
   id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
   time:489192048120984102,///milliseconds since 1970 that the animation should be started from (skip frames if now is later)
   animation:"http://example.com/animation.dae",
   weight:1.0 ///how strong this animation should compare with other animations that use the same bones
}

Stopping a skeleton based on a time based animation

{
   msg:"AniStop",
   id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
   animation:"http://example.com/animation.dae"
}

Streaming some joint locations

{
  msg:"AnimateBone",
  id:"f47ac10b-58cc-4372-a567-0e02b2c3d479",
  time:1250120951209510295;//milliseconds since 1970
  bone:["ankle","arm"]
  pos:[[1,2,3],[2,3,4]]
  vel:[[.25,0,0],[0,0,0]]
  orient:[[.5,0,0,.5],[1,0,0,0]]
  rotaxis:[[0,0,1],[0,1,0]]
  rotvel:[.25,0]
}

Scene Queries

Requesting intersection

{
  msg:"RayTrace",
  pos:[2,3,4],
  dir:[.24,.33,.5],
  multiple_objects:true//if false, only return first hit
  infinitely_long:false//if false use length of dir to specify ray length
}

Intersection callback

{
  msg:"Intersections",
  pos:[[2,3,4],[2.23,3.32,4.49]]
  id:["f47ac10b-58cc-4372-a567-0e02b2c3d479","a33ff133-58dd-2272-dd6a-12aadc31d173",
}