Development log: September 07, 2012

CAVEs and monitor walls with multi-node rendering

Network cluster system

A new Syncker is a scalable multi-node rendering system that makes it easy to create highly immersive CAVE systems or large-scale visualization walls on a computer cluster synchronised over the network in real-time.

Simply connect multiple computers over LAN and turn your monitors into one high-resolution seamless display with a Unigine application running on it at lightning speed. It does not matter if these computers are running on Windows, Linux and Mac OS X at the same time, as Syncker works even across different platforms. Moreover, virtual environments can be of any monitor configuration, since all viewports are fully configurable.

Here the main application is run on Linux and connected to it are computers with Windows 7, Windows 8 and Mac OS X:

Syncker running on one main and four slave computers

Be sure to check the documentation on how to run Syncker and new samples/syncker samples in SDK!

Render

  • Added Ambient light material option for highly optimized rendering of grass, water, leaf and terrain objects. When checked, the world light pass is automatically disabled and objects are rendered only once during the Ambient pass. One rendering pass spared can give a good performance boost in case an object in question has many polygons. Unlike in the previous implementation, shadows are supported. For grass this option also allows to get rid of any light flickering on the edges.
  • Light probes are now faster and do not decrease performance even if there is a bunch of them.
  • Flat now do not change their orientation with Emitter based flag unchecked.
  • Fixed incorrect orientation of environment cube maps.
  • Now it's possible to use any blending options for ObjectWater and ObjectWaterMesh or even create non-transparent water. By default, Scr: one and Dest: src alpha flags are currently used. If you use water nodes in your projects and its blending does not look right, please check its blending options: go to Nodes panel -> Surfaces tab, click Material edit icon and set a proper default value. (Or you can go to *.world file or *.node file and delete <blend> tag for a water node).
  • Decal distance in Render settings now works correctly.
  • Optimized view frustum culling for decals results in performance increase. Check it on a new stress test sample samples/stress/decals_00.
  • Derived materials can override texture options for any custom materials (like wrapping, anisotropy, texture filtering).
  • ObjectWater and ObjectWaterMesh wave parameters can now be controlled via four simple functions: setWaveAngle(), setWaveSpeed(), setWaveLength(), setWaveHeight().
  • No more issues when setting a texture image in run-time for inherited materials via Material::setImageTextureImage() with dynamic flag set to 1. Base materials are not affected in this case.
  • ObjectMeshSkinned can now access bones and vertex weights by a vertex number (ObjectMeshSkinned::getWeights and ObjectMeshSkinned::getBones()).
  • Added support of OpenGL compute shaders. This functionality can be used in custom shaders, if necessary.

Ambient state option for grass in Valley demo

Physics

  • 2D or even 1D physics is now easily possible. Added BodyRigid::setLinearScale()/setAngularScale() functions that set a multiplier for linear and angular velocities per axis. If one of vec3 values is set to 0, movement along this axis will be restricted. For example, for 2D physics with movement restricted to a X axis, set the body's linear scale to (0,1,1) and the angular scale to (1,0,0). See a modified sample samples/physics/reverse_01.
  • Body can be easily moved and oriented via setPosition(), setRotation() and setDirection() without having to deal with a transformation matrix. (These functions are similar to node's ones.)
  • Fixed an issue with incorrect default joint axis created for cylindrical, prismatic and hinge joints.

GUI

  • Added functions for all WidgetSprite* widgets to change the internal render buffer size (and accordingly, widget size) in real-time. Previously this option was available only in constructors.
  • Fixed a crash in WidgetDialogFile when attempting to browse files up the disk root folder level.
  • Added support of 3d coordinates for vertices in WidgetCanvas. See a new sample samples/widgets/canvas_02.

Flash

  • Improved automatic texture atlas generation (now it's smaller in size).
  • Ensured correct rendering of nine-slice grid on rectangular shapes with a texture in all cases.
  • Fixed an issue with onEnterFrame() actions: now they are called immediately after MovieClip is created.
  • MovieClip can be safely deleted, if necessary.
  • Fixed incorrect creation of single-element arrays.
  • Mouse is correctly handled inside areas hidden by a clipping mask.
  • Texts are now always correctly scaled and resized.

Network

  • Now it's even posiible create a FPS network game only using UnigineScript. Socket class can be created for TCP and UDP protocols (added type flag in the constructor: SOCKET_STREAM and SOCKET_DGRAM respectively).
  • Added Buffer::compress()/decompress() functions to compress and decompress buffer data in run-time using gzip.
  • Added Stream::readStream()/writeStream() functions to copy files, buffers and sockets directly into one byte stream. These functions are more memory efficient than Stream::read()/write().

UnigineScript

  • Fixed an over-optimization issue for floating point values. Now even values that differ by less than EPSILON are correctly handled as two different values.

C++ API

  • Added UnigineWorld class to access engine.world functionality from C++ side.
  • Added UnigineWorld::getNodes() function to get all nodes in the world (as well as created via scripts).
  • Added UnigineBuffer::compress()/decompress() functions to compress and decompress buffer data in run-time using gzip.
  • Added UnigineStream::readStream()/writeStream() functions to conveniently copy files, buffers and sockets directly into one byte stream.
  • UnigineSocket class can be created for TCP and UDP protocols (added type flag in the constructor).
  • When constructed, the engine correctly changes a data directory if an external path is specified.
  • C++ API functions return smart Ptr pointers instead of raw ones.

Mobile platforms

  • Added new texture compression formats for OpenGL ES 3.0-compatible hardware:
    • ETC2 (better color compression quality than ETC1, but no alpha)
    • ETC5 (the same, but with alpha stored in EAC1 format)
    • EAC1 (single channel texture compression for storing gray-scale values)
    • EAC2 (two channel texture compression, for example, for normal maps)
  • iOS application now creates a depth stencil texture for the depth buffer (it's used for correct handling of Flash movie masks in WidgetFlash and WidgetVBox instances with stencil flag).
  • Removed artifacts with texture filtering and precision issues on mobile GPUs that support for different precision on the hardware level.
  • Telnet terminal can now be available in release Android and iOS builds if they are created via scons or build.py with terminal flag set to 1.

Tools

  • Added MeshSkinned functions to control weights and bones into USC Interpreter (setter function MeshSkinned::setBones() to set bones for a vertex and MeshSkinned::setWeights() to set weights for a given vertex and corresponding getters: MeshSkinned::getBones() and MeshSkinned::getWeights()).
  • In Archiver backslashes are automatically replaced by forward slashes to avoid any issues when working under Linux with UNG achieves created in Windows.
  • Fixed a bug with MeshViewer panels (Surfaces, Materials, Bones) in ResourceEditor.
  • Fixed a bug with ImageView tool running on a new Mac OS X 10.8 version.
  • Validator generates no unused resource error if a NodeReference is used only in WorldCluster and WorldClutter.
  • Improved the quality of DXT5 alpha compression (though the speed of compression has decreased).
  • Added VCXProj generator for WindowsRT.

High-Level Systems

  • Tracker is now fully compatible with double precision builds.
  • ObjectWater wave parameters are now available in Tracker.
  • New Unigine::Widgets::Widget::isChild() function checks if a given widget is a child of the widget that called this function.
  • Added Unigine::Widgets::Widget::setCallbackAccel() function to handle hot key combinations.
  • Added Unigine::Widgets::Widget::setPosition() function that correctly sets positions for widgets both in internal and external (created via Interface plugin) GUIs.
  • Fixed a small bug with hiding of Interface plugin windows in Linux. Now the window state changes to hidden immediately.
  • Vertical synchronization is disabled for Interface plugin in Linux which fixes an issue with a performance drop on NVIDIA drivers.
  • Added a new core/scripts/projection.h script to divide the view frustum into multiple viewports. Additional compensation for monitor angle and bezel is supported. See samples/render/viewport_01 and samples/render/viewport_02 for examples. This script is also used for monitor walls (AppWall), 3D stereo rendered across several monitors (NVIDIA 3D Surround) and new Syncker.

Other

  • Object::getIntersection() now returns an intersected triangle (a triangle number is the last value in the return array).
  • Node::getNodeReference() function renamed to Node::getPossessor(). Now this function can return NodeReference, WorldCluster or WorldClutter if they are a container for the given node.
  • Added engine.filesystem.isPackageFile() function to check if a file is present in a package and engine.filesystem.getPackageFileName() to get its name.
  • Added Thread profiler that shows information on pathfinding and sound usage. It can be enabled via show_profiler 5 console command.
  • Fixed incorrect abbreviation used for megabytes (Mb changed to MB).
  • Fixed incorrect parsing of backslashes in XML (now slashes can be safely used for all resources stored into XML files, such as node names and data, material names, properties, etc.)
  • Fixed a bug occurring after deleting and adding a new root node for NodeReference. Now the position of the new root can be safely reset to zero and this does not affect the position of the node reference itself.