The Virtual Environment system allows you to simulate a virtual world inside of your simulation. It uses ODE http://ode.org/ to run a physically accurate simulation of the dynamics of the bodies in the environment. Read the ODE manual on the ode wiki from that link if you plan to do any extensive work with this -- everything drives off of that.
- X = horizontal dimension (positive = right, negative = left)
- Y = vertical dimension (positive = up, negative = down)
- Z = depth dimension (positive = toward you, negative = away from you)
The Init function configures the ODE engine according to the objects you have setup in your VEWorld. This is an essential step to start the physics simulator.
The Step' function then runs one time step of physics simulation in ODE, and updates the current positions etc of the objects according to what ODE computed (calling GetFromODE function on each object). The current information is updated in the cur_* fields on the VEBody objects, so you can see where everything is at..
It is important to appreciate that there are no less than three independent sets of state associated with the virtual environment:
- The objects in the VEWorld, which provides the main interface that you the user experience, in terms of configuration and inspection.
- The ODE state that is initialized and updated by the VEWorld -- this ODE state configuration only happens explicitly with a call to Init, or if you update the cur_* values on a VEBody and call CurToODE -- typically, you just call Init, and then Step and let the physics take over (at which point the ODE state drives the VEWorld object state), but it is also possible to intervene and reposition things at any point you want.
- The 3D visualization of the VEWorld objects provided in the 3D Viewer panel (need to make a New View) of the VEWorld object to get one of these in the first place -- importantly, when making new objects or changing major properties (e.g., shape) of objects, this 3D visualization also requires that the VEWorld Init button be pressed to re-initialize the display to match what you have now selected. All the changes that can be made safely to the gui display are made (e.g., updating the current location, rotation, etc). Note that the gui always tracks the current (cur_*) values.
IMPORTANT: when you are configuring your environment, any addition of new objects or change of shape or joint type requires that you do VEWorld.Init() (Init button at bottom of view control panel or VEWorld edit dialog). This reconfigures both the underlying physics and the 3D visualization thereof. In particular, the 3D visualization will not track changes you make to the VE objects until you have pressed Init.
See 3d Animation for instructions on creating a simple animation of your program's output.
See the demo/virt_env/ve_arm.proj (usually in /usr/local/share/Emergent) for an example project that uses this technology to simulate a virtual arm reaching for objects.
Use in Programs
Generally, you'll want to make a VEWorld object in the objs group of a Program, and then add a call to VEWorld.Init() (MethodCall) in the init_code, and in the prog_code have a for loop (ForLoop) or some other kind of looping construct to update the ODE physics over some appropriate number of time steps, calling VEWorld.Step() at each point in the loop.
To make it so you can hit the Program Step button and have it single-step the physics, just add a stop/step (StopStepPoint) item after the Step method call in the program (this also causes the GUI display to update at each Step, so you get smoother looking visualization, at a small cost in overall performance).
IMPORTANT: You'll need to set the OBJS_UPDT_GUI flag in the Program flags, and also make sure that the updt_display flag is set in VEWorld.
Sub-types used in VE
- VEObject -- container for individual body and joint elements that compose an overall virtual object (e.g., an arm has at least 2 body components and 2 joints).
- VEBody -- basic rigid body object, with position, rotation, velocity, mass, etc -- has shape, color, texture, and can load an Open Inventor 3d object file -- this is the basic building-block element for dynamic objects that move in the world.
- VEJoint-- a joint joins two bodies and imposes constraints on movement
- VESpace -- contains static elements of the environment (ground, walls, etc) -- use multiple spaces if there are spatially separated complex spaces (e.g., multiple different rooms) -- optimizes performance.
- VEStatic -- one static body -- e.g., one wall -- has position, shape, color, etc as in the VEBody, but does not get updated by the physics -- completely static.
- VECamera -- put these somewhere (e.g., on the eyeballs of a robot) to get the view from that location in the scene. You must also "register" the cameras you want to use in the VEWorld object by selecting them for the camera fields.
- VELight -- adds some local illumination in the scene, in addition to the overhead "sunlight" -- also must be registered in the VEWorld
- VETexture -- holds bitmap image files that can be used to apply textures to surfaces of objects -- adds a lot of realism. These are created and managed at a global level and then can be selected for multiple different individual objects, for greater efficiency.
- taQuaternion -- this is the core rotation class used -- very handy for offline computations of 3D rotations that you might want to make.