Version 1.5 — 27-Dec-2008
- A new voxel terrain system has been added to the engine, along with several terrain editing tools in the World Editor. More information about these can be found in the wiki article. Support for the old terrain geometry has been removed from the engine, so any old terrain in existing worlds will disappear when opened in the new version of the engine. To preserve the old terrain, select it in the editor under a previous version and convert it to a generic mesh before opening it in the current version of the engine.
- All of the shading systems in the engine have been completely replaced by a new architecture based on shader graphs. Every existing attribute-based material will continue to work just fine, but they are translated into shader graphs internally. The Material Manager still allows materials to be created by configuring a fixed set of material attributes, and this is still the preferred method of creating materials that only use the standard options. Arbitrary custom materials can now be created in the new Shader Editor that's accessible from the Material Manager window. More information about the Shader Editor can be found in its wiki article.
- Both the new Shader Editor and the existing Script Editor have a new tool for creating sections in a graph. A section is simply a rectangular area drawn beneath the graph that can be used to group a set of nodes for organizational purposes—it has absolutely no effect on the function of the graph itself. Each section has a user-configurable title and background color that can be changed by double-clicking on the title bar or by selecting the section and choosing Get Info from the menu (or hitting Ctrl-I).
- Three new script methods have been added that can be used to set scalar, vector, and color parameter values in shader-based materials. These methods allow you to specify a parameter slot number and a new parameter value. When executed, the methods search all of the materials on the target geometry node for Constant Scalar, Constant Vector, and Constant Color processes that use the parameter slot and change the input value for those processes to the new value specified in the script.
- A new tool has been added to the Material page in the World Editor that works like the eyedropper in a painting program. When this tool is clicked on a geometry surface in a scene, the current material is set to the material used on that surface.
- For transition zones having exactly two outgoing direct portals, the ambient light color is now dynamically calculated. The light color is simply a smooth gradient in between the two portals, blending from one zone's ambient light color to the other's. If either zone's ambient light color changes, then the gradient is automatically updated.
- The collision system has been improved in this release. To gain the full benefits of these improvements, it is necessary to rebuild the collision data for geometry nodes in the World Editor. This can be done by selecting all of the geometry nodes, hitting Ctrl-I to open the Node Info window, moving to the Collision tab, and then just clicking OK.
- The engine now recognizes the operating system clipboard under Windows and Mac OS X, so it's possible to copy and paste text between other applications and text boxes inside C4.
- The project files now have a new build target called Server. When this target is selected, the engine builds without any graphics, sound, or input systems so that it can be run on minimal hardware and used as a dedicated server.
- The
kWindowMaximizeflag can now be passed to theWindowconstructor to make it as large as possible upon creation. - If an attempt is made to read strings from a non-existent string table resource, the engine now returns the "<missing>" string in the same way that it already does for missing strings in an existing resource.
- The Time Manager has been modified so that it correctly handles frame rates greater than 1000 fps.
- The quad effect now has a setting for the blend mode that it's rendered with.
- The Panel Controller script functions for getting and setting panel item text now work on editable text items as well as static text items.
- New standard Panel Controller script functions have been added to get and set the texture map shown in an image item.
- The script expression parser now recognizes the words "true" and "false" as boolean literals. These are now treated as keywords and cannot be used as variable names.
- Hexadecimal integer literals using the
0xsyntax are now recognized by the script expression parser. - The box select tool in the World Editor has been reimplemented and is now very precise.
- In the World Editor, double-clicking on a node in the scene graph now opens the Node Info window.
- When importing a geometry node with the Collada Importer, if the transform contains any kind of scale, then the 3×3 portion of the transform (containing the scale and rotation) is now baked into the vertices.
- A voice chat channel can now be enabled and disabled so that it's possible to switch among chat configurations without having to create and/or delete channels.
- A new type of event handler, the
WindowEventHandler, can now be installed in the Interface Manager to receive events pertaining to GUI windows. The types of events posted are (a) a window was added/removed from the GUI, (b) a window's enable or hidden state has changed, and (c) the mouse has moved into or out of a window's content area. - The Input Manager has been modified so that it is possible to receive raw input from only specific classes of devices
while still receiving ordinary OS events for mouse and/or keyboard devices. The
kInputNormalmode that could previously be passed to theInputMgr::SetInputMode()function has been replaced by the three valueskInputMouseActive,kInputKeyboardActive, andkInputGameActive. The "Game" classification includes all devices that are not mice or keyboards. These values can be passed in any combination (through logical OR) to theInputMgr::SetInputMode()function to set the input mode for those classes of device. If eitherkInputMouseActiveorkInputKeyboardActiveis not specified, then you continue to receive OS events for those classes of device. ThekInputAllActivevalue is provided to enable raw input for all devices, equivalent to the old value ofkInputNormal. - The
SetAudioCaptureProc()function has been added to the Audio Capture Manager. This function lets you install a callback procedure that is periodically invoked when new audio data has been captured on the local machine, and it provides a way for the application to intercept the raw sample data. - The configuration file
Engine/engine.cfghas been renamed toEngine/input.cfgsince it only includes commands for binding input controls. - In debug mode, the values used to fill newly allocated memory and just-deallocated memory have been changed
to
0x7FCCCCCCand0x7FDDDDDD, respectively. This was done so that any float-point values read from uninitialized memory would be interpreted as NANs. In the case that a memory block is not a multiple of four bytes in size,0xCCand0xDDare used to fill in the remainder bytes. - In debug mode under Windows, the engine will now display an error message at startup if the working directory does
not point to the location containing the
Datadirectory. - The per-vertex fog option has been removed from the engine. Fog calculations are now always performed at the fragment level.
- The separate specular color option has been removed from light objects.
- The microfacet rendering variable
$renderMicrofacetShadinghas been removed from the engine. Microfacet rendering can no longer be turned off through a flag.
Version 1.4.10 — 25-Jul-2008
- A new cross-platform voice chat system has been added to the engine as the Audio Capture Manager. In a multiplayer game, audio can be captured on each player's machine, compressed using a variable bit-rate algorithm, and distributed through the server to the other players in the game. In the demo game, there are options for enabling or disabling sending and receiving of voice chat, and there's a volume control for received voice chat.
- Each
Playerobject that corresponds to a player in a game is now part of a graph that represents the voice communication channels among all of the players. Voice chat is only sent from player A to player B if there exists a channel starting at player A and ending at player B. A channel is an edge in the player graph encapsulated by theChannelclass. The demo game automatically establishes channels among all players who have enabled voice chat receipt, but more complex arrangements such as team chat can be set up. - It is now possible for a remote portal to span multiple zones so that a single large portal can be used in several zones in cases when a reflective or refractive surface is bigger than a single room. To use this functionality, just add a connector to each zone (other than the portal's owning zone) and link it to the remote portal.
- The S3TC texture compression algorithm built into the engine has been significantly improved in this release, both in terms of image quality and speed.
- Due to some serious limitations in Mac OS 10.4 (Tiger), we will only be supporting Mac OS 10.5 (Leopard) beginning with this release. The Mac project files now require Xcode 3. It's still possible to build the engine under earlier versions of Mac OS X, but it will require making your own project files for Xcode 2 and working around the dynamic loader limitations (for which one solution is to hard-code an absolute installation path for the C4.app bundle).
Build 149 — 8-Jul-2008
- The graphical scripting system in the engine has been replaced with a far more powerful design that supports variables, loops, and conditional execution. All previously existing scripts will continue to run without modification. Details about the new scripting system are too extensive to include here, but they can be found in its wiki article.
- The
Function::Execute()function now takes a pointer to the method that is calling it. This allows the function to set the method's boolean result value in the new scripting system. -
The engine's texture format has been changed in this release. The file extension is still
.tex, and the engine can still read the old format. However, in the next release, the old format will no longer be supported. We have included a conversion utility in this release that will scan yourDatafolder and convert all.texfiles to the new format automatically. All textures that ship with the engine have already been converted.To use the conversion utility, run the engine and type
convtexin the command console. This will convert all.texfiles in yourDatafolder to the new format in place. Be sure that you have a backup copy of your custom textures before running this utility. - The Texture Viewer tool has been renamed to Texture Tool, and all the code that creates textures of any kind
has been moved to this plugin. Generated textures (light projections, shadow maps, environment maps, and
ambient spaces) are now made using the
gentexconsole command. - The ambient space feature has been replaced with a new rendering method for static volumetric ambient occlusion. Ambient spaces are still placed in zones as they were previously, but now they only encode directional occlusion that modulates the ambient light intensity as opposed to encoding the ambient light intensity itself. More ambient lighting capabilities will be added to near-term future releases.
- The
SceneImportPluginclass has been changed slightly so that it's possible for an import plugin to display a dialog before importing a scene. (See the Collada import plugin for an example.) TheSceneImportPlugin::ImportGeometry()function now takes a pointer to the editor window as a parameter, and the importer must call theEditor::ImportScene()function in order to complete the import. - The Collada importer now offers the option to attempt to import texture maps while it is importing a scene.
When this option is turned on, any qualified diffuse map, normal map, gloss map, or emission map specified in a
Collada file will be imported with the Texture Tool using the default settings. A texture map qualifies for
import if its path name contains
/Import/so that the importer recognizes it as being in the C4Importfolder. If the Collada file specifies the wrap modes for a texture map, then they are respected when a texture map is automatically imported. - A Cleanup button has been added to the Material Manager. Clicking this button causes all duplicate materials to be merged into one material. Materials are considered equivalent if they produce the same shaders.
- The
Entityclass has been renamed to theModelclass. To update your code, make the case-sensitive global replacements ofEntitytoModelandentitytomodel. This will have the effect of inadvertently changing the word "identity" as well, so you'll need to also make the replacement ofdmodeltodentityto clean it up. - A new toggle button has been added to the World Editor that turns display of models on and off. Models are no longer displayed as a bounding box.
- A model registration now takes one more parameter that specifies the human-readable model name to be displayed in the World Editor.
- A new multi-zone referencing system has been implemented that generalizes some older techniques used in the engine for transition zones and effects that span multiple zones. Most of this system is internal to the engine and not exposed to higher-level code, but there's one new addition that game programmers need to be aware of. Model nodes have always automatically reparented themselves to the zones that contain them as they move around, but now when a model exits a zone, it also attaches a special reference to the zone that survives until the model's bounding volume has completely left the zone. This allows large models to span multiple zones and to be correctly identified by the visibility determination system. The whole thing is automated, so no code needs to be written to take advantage of this feature.
- The
kEntityAttachedflag, previously used to signify that a model is attached to another model in some way, has been removed from the engine. TheModelclass now determines whether models are attached to other models automatically. - Under Windows, the Sound Manager now uses XAudio2 instead of DirectSound. This should be completely transparent to all higher-level code, but you will need to upgrade to the latest version of DirectX. The engine will only compile with the June 2008 DirectX SDK or later.
- The streaming capabilities in the Sound Manager have been generalized so that it's possible to stream sound data from any kind of source. The method for setting up a streaming wave file has changed—see the wiki article for more information.
- A color scale and bias operation has been added to the post-processing pass. The
World::SetFinalColorTransform()function can be used to specify a scale color S and a bias color B that are applied to the final rendered color C to yield SC + B. The red, green, and blue channels of these colors can be any floating-point values that produce the desired effect. The scale and bias colors only affect rendering of the current world and not the graphical user interface. - The
WorldRenderTask()andInterfaceRenderTask()functions have been added to theApplicationclass. These functions are called once per frame after the world has been rendered and after the graphical user interface has been rendered, respectively. - The Display Manager will now allow any window size to be specified by the
$displayWidthand$displayHeightvariables when running in windowed mode. - The
Nodeclass is now subclassed fromConstructableso that custom node types can be defined and properly deserialized. TheConstructable::InstallConstructor()function is used to install a callback function that constructs custom node subclasses. - Full native support for Xbox 360 controllers under Windows has been added to the Input Manager (using XInput). The demo game code has been updated so that it's possible to play using only the Xbox controller. Better support for DirectInput joysticks has also been added to the Input Manager.
- The movies plugin now allows movies to be played as streams from remote locations. The movie controller and movie panel item now both have check boxes indicating whether the movie name is a URL.
- Movie play position is now synchronized in multiplayer games when new players join.
Build 148 — 13-Mar-2008
- Glow and bloom effects have been added to the post-processing phase of the rendering system. No distinction is made between glow and bloom during post-processing, but the two effects are created by different parts of the shading equations. Glow comes from the emission component's alpha channel, and bloom is determined by the intensity of the specular component. Glow and bloom are enabled on a per-material basis, and each has a checkbox in the Material Manager. (Glow is found under the Ambient tab, and bloom is found under the Specular tab.) Glow and bloom can be enabled or disabled globally in the Graphics Settings dialog.
- A new generic animation controller has been added to the engine. This controller can be attached to an entity node, and it simply plays an animation resource for that entity. The animation controller also exposes play and stop functions that can be called from a script to change animations or stop the current animation.
-
The Material Manager in the World Editor has been largely redesigned. It now always displays every material that is used by a world, and all previews are rendered in real-time. The various material attribute settings have been reorganized into four panes: Diffuse, Specular, Ambient, and Texcoords. The first three panes group attributes by where they appear in the lighting equations, and the Texcoords pane contains everything related to texture coordinate transforms and animation.
The New button now creates an empty material, and a Duplicate button has been added that creates a copy of the currently selected material. A Delete button has been added that removes a material from a world, but only if it is not used by anything. The Import and Export buttons still exist and function as before.
- The World Editor now directly supports plugin modules. The external API is in a rather early state, but it
is possible to create a plugin that displays new tool pages in the editor. World Editor plugins should be
placed inside the
Plugins/Tools/Editor/directory so that they are loaded after the World Editor itself is loaded. Support for import and export plugins has been moved to the World Editor, and the Collada Importer plugin has been modified to work directly with the editor. - Up to four columns of tool pages can now be displayed in the World Editor. How many columns there are, and where they appear, is configured by selecting Editor Settings from the Layout menu. Each of the four available columns can be placed on the left or right side of the viewports when made visible. Pages can be dragged from one column to another.
- By holding in the Control key (Command key on Mac) while clicking on the collapse or close button of a tool page, all pages in the same column can now be collapsed or closed at once. There is a new command in the Page menu that shows all available tool pages.
- In the World Editor, the selection mask will now be automatically updated whenever a new node is drawn so that the node is always selectable right after it is created.
- The Clone Group command in the World Editor has been replaced with the Clone command. Any node can be cloned now, and the result is a new copy of the node that refers to the same object(s).
- The right-click popup menu in the World Editor now contains a Get Info item. Also, the Frame All and Frame Selection items in this menu now work on perspective viewports.
- Editable text elements can now be made read-only by setting the
kEditableTextReadOnlyflag with theSetEditableTextFlags()function. Text can still be selected and copied from a read-only text element, but it cannot be modified by the user. - The Movies plugin now exposes script functions for playing, stopping, pausing, and resuming movie items inside panel effects.
- The Collada Importer now correctly sets the default up direction to the y axis if an imported file does not indicate an up axis.
Build 147 — 25-Feb-2008
- This release is primarily an update that contains the demo shown at GDC.
- A new enemy character, the spider, has been added to the demo game. Its controller is now the simplest example of a controller for a non-player character.
- A world can now be paused by setting the
kWorldPausedflag with theWorld::SetWorldFlags()function. (Care should be taken to avoid clearing other flags by callingWorld::GetWorldFlags()and logically ORing in thekWorldPausedflag.) While this flag is set, controllers and effects are not moved. The demo game now sets this flag when the menu window is displayed in single player mode.
Build 146 — 7-Feb-2008
- With this release, we begin officially supporting the Intel GMA X3000 series of graphics chips under Windows. Some driver issues are currently preventing us from supporting these chips on the Mac.
-
A new post-processing effect has been implemented that enables distortion effects such as heat haze. Any effect can be configured so that it renders into the distortion buffer instead of into the main scene by using the
Effect::SetEffectListIndex()function to set the effect list tokEffectListDistortionand by setting thekShaderDistortionshader flag. TheEffect::SetDistortionState()function has been provided to set all of the necessary state for rendering into the distortion buffer.When an effect is rendered into the distortion buffer, only the red and green channels of the texture color matter, and they encode horizontal and vertical offsets, respectively. A value of 128 in either channel means no offset, while 0 means the largest possible negative offset, and 255 means the largest possible positive offset. Offsets are accumulated in the distortion buffer so that multiple effect nodes can have an additive effect on the amount of distortion visible at a particular point. The alpha channel of the vertex color can be used to modulate the intensity of the offset values after RG decoding. See the
ShimmerSystemclass in the demo game for an example of a particle system that renders heat waves into the distortion buffer. - It is now possible to render effect nodes in the lighting passes so that all of the shading capabilities of
the engine can be applied to the effect. This is accomplished by using the
Effect::SetEffectListIndex()function to set the effect list tokEffectListLight. An effect must have normal and tangent arrays in order to render correctly in the lighting passes. The marking effect has been extended to create these arrays automatically and set the effect list index. To use this functionality, thekMarkingLightflag should be specified when creating a newMarkingDatastructure. The demo game now uses this flag for blood splatters. - The engine now supports a hierarchical relationship among plugins, and it is now possible for a plugin to
depend on the existence of other plugins. The way this works is through the use of subdirectories inside the
Pluginsdirectory. All plugins in a particular directory are loaded before any plugins in the subdirectories of that directory, so if plugin B depends on plugin A, then plugin B should be in a subdirectory inside the directory containing plugin A. - It is no longer necessary to define
C4MODULEwhen compiling the application module or any plugin modules. Instead, the engine project definesC4ENGINEMODULEso that it can be determined that the engine is being compiled as opposed to any other module. - All of the movie code has been moved into a new Movies plugin. All dependencies on QuickTime are now isolated to this plugin, and the plugin can simply be omitted if movie playing capabilities are not needed. The MoviePlayer plugin depends on the Movies plugin.
- A new plugin called Extras has been created that contains functionality that may not be needed by every game, but is general enough to be made available outside the application module. Currently, the Extras plugin includes the rotation controller and the star field particle system. More functionality will be moved to the Extras plugin in the future.
-
New path editing tools have been added to the World Editor. A path is made up of a series of components that can be any of the types linear, elliptical, or Bezier. A linear component is simply a straight line that connects two endpoints, an elliptical component is a 90-degree elliptical arc between two endpoints, and a Bezier component is a single cubic Bezier curve with four control points (two endpoints and two off-curve control points). Paths are created by using the three tools in the Paths page corresponding to linear, elliptical, and Bezier components. Switching among the tools allows the user to add different types of components to the same path. Whenever a single path node is selected, using the path tools will add to that path.
The path tools will snap to the beginning endpoint of the current path so that perfectly closed paths can be created. The snap can be disabled by holding in the Control key (Command key on Mac).
Control points along a curve can be selected with the ordinary selection tools. Shift-clicking adds or subtracts from a selection. A Control-click (Command-click on the Mac) will cause control points along the tangent to be selected in addition to an on-curve control point in a single click. If an off-curve control point is moved for a Bezier component, then it's opposing control point in any adjacent Bezier component is moved in the opposite direction unless it is also selected or the Control key is held in (Command key on Mac).
- Three new geometric primitives based on paths have been added to the engine and are available in the Geometries page inside the World Editor. They are called path tube, path extrusion, and path revolution. Each of these primitives can be created when a path is selected in the editor to define the shape of a tube, the base shape of an extrusion, or the lateral surface shape of a revolution. When creating a tube geometry, you drag out a disk representing the shape of the tube's cross section. When creating an extrusion or revolution, the drawing tools behave like a box and a cylinder, respectively so that you can create geometries with the shape of the path, but at any size.
- A new effect type called a tube effect has been added to the engine. It is similar to the beam effect, except that it follows a path instead of a straight line. The tube effect is drawn as a circular disk representing the cross-sectional shape. The actual effect can only be seen in the perspective view with lighting turned on.
- When a tube (geometry or effect), extrusion, or revolution is created, the path from which it was made is copied into the
geometry or effect node so that the original path is not needed in order to rebuild the node (for example, with different
subdivision settings). A link to the original path is also stored in a built-in connector of type
PATH. When the original path is edited, the node linking to it will not be updated automatically, but any such node can be explicitly rebuilt using the linked path by choosing the Rebuild with New Path command under the Geometry menu. Several improvements have been made to the in-game interface panels and the Panel Editor:
- It is now possible to create and register custom panel items.
- There is a new stock panel item that encapsulates editable text.
- The selection tool in the Panel Editor now functions as a box select tool once the cursor has been dragged a few pixels. The shift key can be used to add to the current selection when dragging out a box.
- It is now possible to modify settings for multiple items simultaneously in the Panel Editor.
- A new mutator called Animate has been implemented which plays frames of animation out of a texture by changing the texture coordinates of an image item. The mutator is configured by specifying the horizontal and vertical grid dimensions for subdividing the texture, the total number of frames, and the frame rate.
- Script method registrations now take only a single name string instead of the two name strings previously taken.
When a script method name is displayed in the Script Editor, lines will automatically be broken at a space, hyphen,
or forward slash, if necessary, or at any newline character (represented by
\n). - In the World Editor, the types of entities, locator markers, and reference markers are now displayed in the Info page for the node to which the gizmo is attached.
- A new command called Bake Transform into Vertices has been added to the Geometry menu in the World Editor. This applies the node transform of a geometry node to each of its vertices, and then sets the node transform to the identity.
- Another new command called Reposition Mesh Origin has been added to the Geometry menu. When this is selected, a dialog appears that lets you select min, center, or max for each of the three axes, where these refer to the bounding box. The node position for each selected mesh will be moved to the specified location, and the vertices of the mesh will be translated the same distance in the opposite direction. This has the effect of moving the object origin without actually moving the world-space vertex positions.
- A new command called Move Viewport Camera to Node has been added to the Node menu. This command moves the camera in all perspective viewports to the position of the selected node and faces it along the node's z-axis. The camera still obeys the ordinary restrictions on the viewport camera, so it will not roll side to side or tilt up or down more than about 83 degrees from the horizontal.
- Another new command called Open Referenced World has been added to the Node menu. This command opens the world resource referenced by each selected reference marker in a separate editor window.
- A new camera speed slider has been added to the Viewports page in the World Editor. This controls the maximum speed of the free camera in the perspective viewports.
- When the Invert Geometry command (Ctrl-Shift-I) is used in the World Editor to invert a primitive geometry node, it will now also flip the "Build inverted" flag from the Get Info dialog automatically. This will cause the geometry to continue rebuilding in the inverted state if it's altered at a later point in time.
- When placing a locator marker in the World Editor, the marker will now keep the identity transform until the mouse has been dragged several pixels away from the click point. This prevents random rotations if the mouse is clicked and released at the same point.
- The Markers page now displays a list of registered locator types. Selecting one of these lets you place a locator in the scene with the registered type already set.
- The Memory Manager has been largely rewritten and there is an enormous performance improvement in general allocation speed.
- Screenshots saved using the
shotcommand are now saved as compressed TGA files (whereas before they were not compressed). - All interface elements now have common functions for getting and setting their sizes. These functions are
GetElementWidth(),GetElementHeight(), andSetElementSize(). Also, the origin for the push button element is now at the left edge of the button at the vertical position for the button text. - When a radio button is selected by the user, it will now automatically unselect all other radio buttons having the same parent element.
- It is no longer necessary to type the full path name when opening a world, texture, or sound using the command line. The top-level virtual directory name should be left off.
- All resource names may now contain the names of system variables, and these will be replaced by the value of
each variable before the Resource Manager tries to locate a resource. The syntax is
($name). For example, if you try to load a resource with the nametextures/($season)/leaves, and the value of the variable$seasonis "summer", then the Resource Manager will load the resource namedtextures/summer/leaves. A resource name may contain any number of variable names. In any case when the right syntax isn't used or the variable doesn't exist, the resource name is not altered. - The Xcode projects for the Mac have been changed significantly. Everything now builds as a dynamic library
instead of a bundle. The engine module also builds as a dynamic library because it's not possible to link
against both an executable and another plugin on the Mac, and this is necessary for plugins that depend
on other plugins. A small executable that contains only the
main()function is now built as a wrapper for the engine module.
Build 145 — 27-Nov-2007
- Implemented a new GUI rendering system. For details, see the wiki article about Creating a GUI Skin.
- Added a radio button interface element as the
RadioButtonElementclass. - Cameras now have a new flag to indicate that they may temporarily move outside their owning zone. This is useful in such cases as a camera mounted on a gun that's attached to a character. A similar flag has existed for lights, and now both flags are exposed in the Get Info dialog.
-
A new concept of “perspective” has been worked into the engine, and this refers to the kind of viewing position the scene is currently being rendered from. There are currently four perspectives defined: direct, reflection, refraction, and camera. The direct perspective pertains to the scene as it is rendered directly from the main camera, the reflection and refraction perspectives pertain to the scene as it is rendered through remote portals, and the camera perspective pertains to the scene as it is rendered through a camera item in an interface panel. Multiple perspectives can be in effect at the same time; for example, the reflection in a water surface seen through a panel camera.
Geometries and fog spaces can now be excluded from each of the four perspectives by setting flags in the Get Info box. (The flags for a geometry appear under the Node tab.) For geometries, the visibility of shadows can also be controlled independently.
- A new flag has been added for remote portals that enables recursive rendering. By default, this flag is off, so a remote portal will not be rendered again if you are already looking through that portal.
- When shadow maps, cube light projections, spot light projections, or ambient space maps are generated, they are now written into the same virtual directory that contains the world resource from which they were generated. Any subdirectory names in the resource path are relative to the top-level virtual directory.
- Added the
GetImportResourceCatalog()function to theSceneImportPluginclass and theGetExportResourceCatalog()function to theSceneExportPluginclass to let the plugins specify what catalog to use for import or export. - Added some resource caching optimizations.
- A lot of work has been done to move the PS3 rendering code to a much lower-level system. The Graphics Manager now minimizes use of the GCM library and instead uses custom code to build command buffers. This allows the C4 rendering code to be as fast as possible, and it gives C4 access to more hardware features than are available to other PS3 games.
Build 144 — 9-Nov-2007
-
The Resource Manager has been redesigned and now supports pack files and a virtual directory hierarchy. All resources are still stored inside the
Datafolder, but the subfolders that previously separated resources by type no longer exist. Resources can now be organized in an arbitrary manner inside theDatafolder. However, the top-level contents of theDatafolder have special meanings.All of the top-level subfolders of the
Datafolder behave as if their contents belonged to a single virtual folder at the root of the resource namespace. These top-level subfolders exist only for external organization and do not participate in the unique identification of any resources. As an example, suppose that there existed two subfoldersData/Interiors/andData/Exteriors/. A resource namedWood.texcould be stored in either subfolder, but it would still be identified only as "Wood" by the Resource Manager. The name of the top-level subfolder is not part of the resource's path. However, if theWood.texresource was placed in an additional subfolder such asData/Exteriors/Forest/, then the name of the resource would be "Forest/Wood". All folder names beneath the top-level subfolders of theDatadirectory are part of the resource name.The resources that ship with C4 have been divided into the following subfolders:
- A
C4folder containing the resources used by the core engine and required by all applications built with C4. - A
Demofolder containing the resources used exclusively by the demo game. - A
Toolsfolder containing the resources used exclusively by the tool plugins. - A
Tutorialfolder containing the resources associated with the tutorials and sample worlds.
Pack files, having the extension
.pak, can also be stored at the top level of theDatadirectory. A pack file is created by using a new tool plugin, the Resource Packer, to pack the contents of a top-level subfolder into a single file. The console commandpack<name> is used to create a pack file, where <name> is the name of a top-level subfolder. For example, the commandpack Demowill create the fileDemo.pakcontaining all of the resources used exclusively by the demo game. Once a pack file has been created, the folder from which it was made can be deleted, and the Resource Manager will fetch resources from the pack file instead. (Pack files actually override ordinary folders.)Some additional miscellaneous notes about the Resource Manager:
- Folders and pack files are the only items allowed at the top level of the
Datadirectory. Other types of files in that location will be ignored. - Resource path names inside pack files are case sensitive.
- QuickTime movies cannot be accessed inside pack files.
- Because concealment is a benefit provided by pack files, there will not be an unpacking tool that would allow
users to easily extract resources from a
.pakfile.
- A
- It is no longer necessary to use the
ModuleResourceclass template when defining a resource type in a game module or plugin module. New resource types should now just inherit from theResourceclass template. However, the resource descriptor is now declared in the subclass. - The
Packable::GetPackSize()andPackable::GetPackTypeCount()functions have been removed from the engine. All overrides of these functions in custom class types should be deleted. These sizes are now calculated automatically by calling thePackable::Pack()andPackable::PackType()functions with a nonwritable data object. - Added a new flag to the script controller that lets you limit concurrent runs of a script to unique activators. That is, with this flag set, only one instance of the script will run for each node that is activating the trigger for the script.
- The C4 Sound Manager has been upgraded on the Mac to use the CoreAudio framework. This should provide greater compatibility with future hardware and OS releases as well as yield better performance.
- Added a new
HashTableclass to the engine utilities. - The
PrimitiveGeometryclass now inherits fromConstructableso that custom primitives can be defined by an application. - A new setting has been added to the Texture Import dialog that allows you to select the channel from which height
data is read when calculating normal maps, horizon maps, and ambient occlusion maps. The command line equivalent
is
-height<n>, where n is an integer between 0 and 3 representing the red, green, blue, or alpha channel, in that order. - Since world resources don't all have to be in the same location any more, the demo game now reads the strings in
the
Data/Demo/game/Worlds.strfile to obtain the list of playable worlds displayed in the New Game and Host Game dialogs. The corresponding.txtfile in theImportdirectory can be edited and re-imported (with theistringcommand) to add or remove worlds from the list. - A new command, Save and Play World, has been added to the World menu in the World Editor. This saves the world being edited, closes the World Editor, and loads the world in the game.
Build 143 — 19-Oct-2007
- Reference markers can now be expanded and collapsed dynamically from code using the
ReferenceMarker::Expand()andReferenceMarker::Collapse()functions. - The
TextElementinterface element class has been rewritten and now combines all of the functionality that was previously spread over four different classes. Several new features have also been added that can be used almost everywhere that text is rendered in the engine, including panel effects. For more information, see the documentation for theTextElementclass. - The
EditableTextElementclass has been expanded to allow multi-line text boxes. This is enabled by setting thekEditableTextMultilineflag with theEditableTextElement::SetEditableTextFlags()function. Multi-line text boxes support all the bells and whistles, including full selection capabilities, copy and paste, mouse wheeling, word wrap, double-click word selection, and smart cursoring. - Made some general improvements to the Panel Editor. One of these is that the text entry box for text items is now a multi-line box.
- The Set Panel Item Text script function has been expanded so that you can choose to append or prepend text in
addition to replacing it altogether. Also added a way to limit the length of the resulting text. An example that
uses this new functionality has been added to the
Samples/Lasersworld. - Added a truncated cone primitive geometry type. This produces a cleaner mesh than intersecting a cone with a box in many cases.
- Some improvements have been made to the CSG code in the World Editor. They can now handle some more topologically complex cases.
- Exposed the GetMillisecondCount() function in the Time Manager. This will return a real-time absolute millisecond count, but with no zero reference. This function should only be used if you know what you're doing. If you have to ask whether it's the right function, then you shouldn't use it.
Build 142 — 9-Oct-2007
- The Tool Manager has been renamed to the Plugin Manager. The
Toolclass is now thePluginclass, theToolMgrclass is now thePluginMgrclass, and the Tools folder is now the Plugins folder. - A new feature has been added to the in-game interface panels that allows an impostor image to be displayed beyond a given distance instead of the set of elements in the panel. This can improve performance considerably when many panels are visible at once. The impostor image will cross-fade with the real panel between two distances that can be set in the Get Info dialog under the Panel tab. An impostor image should be a 2D texture so that mipmapping is supported. It is possible to change the impostor image from a script using the Change Settings method.
- A geometry detail level bias and shader detail level bias have been added to the Get Info dialog for geometry nodes. These are specified in units of fractional detail levels. A value of 1.0 means to use a detail level that's exactly one level lower quality than would normally be selected. Negative values can be used to keep higher detail at farther distances.
- A detail level bias setting has been added to remote portals and panel cameras. This value is added to the detail level that would normally be selected by the engine (in addition to per-geometry detail level biases) and can be used to boost performance when rendering reflections, refractions, or panel cameras.
- A simple
QuadEffectclass has been added to the engine for cases when you just need to render a single billboarded quad. It has a position, radius, color, and texture. It gets rendered in the sorted transparent effect pass. - Calling the
Entity::SetRootAnimator()function now causes the new root animator to be invalidated, so it's no longer necessary to invalidate it through a separate call toAnimator::Invalidate(). - Added settings to the
DoorControllerin the demo game that control the opening speed and closing speed of a door, the time that a door stays open, and whether the door is initially open or closed. - Added a generic rain particle system to the demo game. Also added a new setting to the burning rain particle system that controls what percentage of the rain drops turn into flames. (Note that setting the rain intensity and burning rain percentage too high in combination can result in the flame particle system periodically running out of free particles.)
- Implemented a fallback mechanism for missing fonts. If an attempt to load a nonexistent is made, then the default GUI font is loaded in its place.
- The middle mouse button now pans viewports in the World Editor.
- The Collada Importer now recognizes any empty node whose name begins with
MARKER_as a locator marker. This will prevent an empty leaf node from being deleted during import. When the marker is imported, the first 7 characters are stripped from the beginning of the node's name. - The Graphics Manager now allows three texture quality settings, and this is exposed in the Graphics Settings dialog in the game code. The high quality setting causes the highest-resolution mipmap to be used, and the medium and low quality settings remove the top one or two mipmaps, respectively. Any mipmaps having a resolution higher than that supported by the hardware are also removed.
- Added an icon to the multiplayer game that appears over a player's head when he's typing a chat message.
- Made some adjustments to the weapon code in the demo game so that shots are no longer fired parallel to the line of sight, but instead in a slightly bent direction based on how far away the target in the crosshairs is. This precisely aligns the projectile's destination with the center of the crosshairs.
Build 141 — 3-Oct-2007
- The Info page in the World Editor now displays the number of instances in the scene corresponding to the node for which the gizmo is currently shown. The number of instances is equal to the total number of nodes referencing the same data object.
- When replacing materials on individual surfaces of a geometry that has multiple instances in the scene, the World Editor now enforces the preservation of the material segmentation structure in order to prevent mismatches among the different instances. What this means is that you can't change the number of material slots or the surface-to-material-slot mapping for geometries having multiple instances in the scene. The only consequence of this rule is that attempting to change the material for a set of surfaces on an multiply-instanced geometry may result in the material being applied to more surfaces than are selected.
- Added the Copy Transform and Paste Transform commands to the Edit menu in the World Editor. These commands copy and paste the local node transform corresponding to the node for which the gizmo is currently shown. They do not copy and paste the node size (since that's not part of the transform), but just the position and rotation. The transform clipboard is independent from the main clipboard.
-
Added the Combine Detail Levels and Separate Detail Levels commands to the Geometry menu in the World Editor. These commands allow you to combine multiple geometries into a single geometry with multiple levels of detail, or to separate multiple levels of detail in a single geometry into multiple geometries with a single level of detail.
The Combine Detail Levels command is available when 2–4 geometries are selected. It examines the highest level of detail from each geometry and puts them in order by vertex count. The geometry having the most vertices is designated the primary geometry node, and it continues to exist after the detail levels are combined. The highest level of detail from each geometry is added to the primary geometry as a lower detail level, replacing any lower detail levels that were already there. The geometry data from each input geometry is transformed into the coordinate space for the primary geometry. (Geometries should be manually aligned before combining detail levels.) Input geometries other than the primary geometry are finally deleted.
The Separate Detail Levels command has the opposite function. It takes an input geometry and creates new geometry nodes for each level of detail, removing them from the input geometry. The new geometry nodes are identical to the input geometry, including controller assignment, properties, and connections. However, the collision data will be rebuilt for level 0 if it had been changed.
- The collision detail level is now exposed in the Get Info dialog under the Collision tab. By default, collision detection information is generated for the highest level of detail (level 0) for a geometry. This can now be changed so that collisions occur against a lower level of detail. The advantages to setting a higher-numbered collision detail level (which corresponds to lower geometric level of detail) are that it saves space and it performs a little faster. If the collision detail level is set greater than or equal to the number of geometric detail levels, then the last available level of detail is used.
- A check box called "Reflection" has been added to the Texture Mapping page in the World Editor. Checking this box will cause texture coordinates to be mirrored in the s direction, effectively adding an inversion on top of the reflection in the texture coordinate generation matrix. Mirroring in the t direction can be achieved by rotating 180 degrees after checking the Reflection box.
- An alignment plane popup menu has also been added to the Texture Mapping page. This allows selection of the XY, XZ, or YZ plane as the texcoord generation plane. These are set automatically by many primitive geometries, but may need to be changed for imported geometry to get the desired mapping.
- The default texture used when a texture resource is missing has been changed so that it works better as a
normal map. (The file is
Data/tex/C4/missing.tex.) This texture now looks like a bunch of green Xs on top of a pastel purple background (representing the <0,0,1> normal vector). - The
Constructable::Construct()function has been changed to take a second parameter. Any custom construction functions (for custom objects, properties, controllers, etc.) will need to be altered so that they take a second parameter of typeunsigned longfor additional flags to be passed in. The value of the flags parameter can safely be ignored. - Fixed a crash that would occur only on PowerPC-based Macs when streaming sounds were played.
Build 140 — 27-Sep-2007
-
IMPORTANT: It is particularly important that you backup your resources before installing this build. The World Editor will throw away obsolete information when you open files, and worlds will be saved in an updated format.
After installing build 140, you should open each of your worlds in the World Editor and then immediately save them to automatically update them to the new format. Resource sizes will decrease a bit depending on how many generic meshes each world contains. Models should also be opened in the Model Viewer and then immediately saved to update those as well.
If you have any worlds or models that have not been opened and saved for a very long time, then you should open them and save them in build 139 before installing build 140. Specifically, any resources not saved in build 112 or later need to be opened and saved in build 112–139 before installing build 140. Some very old backwards compatibility mechanisms have been removed from build 140, and this could cause information to be lost if resources aren't first updated in a previous build.
- All geometry building code in the engine has been completed rewritten. The World Editor no longer relies on the existence of a separate source of polygon data for generic meshes, and a lot of support for obsolete mesh operations has been removed. Even though most of this rewrite pertains to internal functionality that is transparent to the user, the completion of this task opens the door for much faster implementation of new geometrical editor features.
- Most of the new geometry building code is concentrated in the
GeometryLevelclass, which represents a single level-of-detail for a geometry object. Non-primitive (generic) geometries are no longer implicitly rebuilt when certain operations are performed on them in the editor. Primitive geometries are rebuilt when they are changed, and they can be explicitly rebuilt by the user. Imported geometries are always generic, and normals for imported geometries are always preserved. Normals can be explicitly recalculated in the editor, however (see next item). -
The Node menu in the World Editor has been split into a Node menu and a Geometry menu. The Geometry menu contains two new commands, Rebuild Primitive and Recalculate Normals.
The Rebuild Primitive command has limited utility in this build, but it will become a lot more useful in future builds when edits have been made to a primitive geometry and you want to restore it to its original state. One present use for this command is to restore natural texture coordinates after they've been altered.
The Recalculate Normals command recalculates all of the normals for selected geometries. This is useful for replacing bad normals on imported geometries. When normals are recalculated, so are the tangents.
- A primitive geometry will no longer remember that it has been inverted by the Invert Geometry command. If a primitive is rebuilt, then the inversion will be lost. There is a new flag in the Get Info dialog for primitive geometries that causes them to be built inverted, and this should be used to permanently invert a primitive.
- The CSG operations (intersection, union, subtraction) in the World Editor have received a major upgrade. They are now capable of handling much more complex geometry, and they generate very clean meshes using some new geometry optimization operations. There are still some precision-related issues with high-density meshes and complex topologies, but the CSG operations can do a lot more than they could before.
- The resize tool has been completely rewritten for generic meshes.
- A new Mesh Tools page has been added to the World Editor. It currently contains only one tool, and that tool
selects individual surfaces on a geometry. (A surface is a group of faces which, as a whole, has a
tangent space domain and material that is independent from other surfaces belonging to the geometry.)
Clicking on a geometry with the surface selection tool will select the surface containing the triangle
that you clicked on. The Shift key can be used to select multiple surfaces, and it's possible to select
surfaces from multiple geometries simultaneously. The highlight color for selected surfaces is given by
the
$surfaceColorsystem variable. - If individual surfaces are selected on a geometry, then the Set Material command in the Geometry menu now replaces materials only on those surfaces, leaving the materials on other surfaces unchanged. If a geometry is selected, but none of its individual surfaces are selected, then the Set Material command replaces the material for all of the geometry's surfaces.
- The Select by Material command in the Edit menu now selects all of the individual surfaces using the current material instead of entire geometries.
-
A new Texture Mapping page has been added to the World Editor. It contains tools for offsetting, rotating, and scaling texture coordinates. It also contains type-in boxes for the texcoord generation transform and popup menus for the coordinates generation modes. This replaces the Texturing tab which used to exist in the Get Info dialog for a geometry node. (The Texturing tab has been removed.)
When an entire geometry is selected, the texture offset, rotate, and scale tools apply to all surfaces of the geometry. If individual surfaces of a geometry are selected, then texture operations only affect the selected surfaces.
The texcoord generation transform information appears when exactly one surface is selected. Two offsets (one for each of the s and t coordinates), two scales, and a single rotation value can be changed by entering new numbers in the text boxes, and the changes take affect immediately. For undo, the Texture Mapping page works like the Transform page: any contiguous sequence of inputs for offset, scale, rotation, or mode is treated as a single undoable action. Also like the Transform page, keyboard focus is ended whenever you click in a viewport, select a standard tool at the top of the editor window, or hit the Escape key.
- Operations that combine multiple geometries into one now generate as many detail levels as the maximum number existing in any of the input geometries. The applies to the Merge Geometry, Intersect Geometry, and Union Geometry commands in the World Editor.
- The
FunnelGeometryprimitive geometry type has been removed from the engine. The same type of shape will be achievable in the World Editor using a revolved path in an upcoming release. Any existing funnel geometries will disappear when a world containing them is opened in this build. To keep the funnels, convert each one to a generic mesh using a previous build. (Select all of them and hit Ctrl-Shift-C in the World Editor.) - Eight flags have been added to the cloth geometry to control which vertices are fixed in position. This is a temporary solution that allows control over whether each of the four corners or four edges of a cloth geometry is fixed. The flags appear in the Get Info dialog under the Geometry tab.
- The utility window that has been called "Graphics" is now called "Stats", and the
grafcommand has been changed tostat. This window now displays four new stats, two for textures and two for sound sources. For textures, the window shows the current number of textures loaded and the total amount of memory used by the textures. For sound sources, the window shows the current number of playing sources and the number of those sources that are currently engaged. (A source is considered playing if it would be audible when you're close enough to it, and it's engaged when you actually are close enough to it for the engine to need to send it through the Sound Manager. - Additional mouse wheel support has been added in various places. In particular, the mouse wheel will now scroll the pages in the World Editor and the materials in the Material Manager.
- Added the
Stop()function to theMethodclass. This function should be called from within the method'sExecute()function to indicate that the method's subnodes should not be executed, effectively stopping execution of the script along the branch containing the method for whichStop()is called. - Added the static
Sleep()andYield()functions to theThreadclass. These functions can be used to temporarily suspend execution of the current thread. - Added the
Complete()function to theThreadclass. This function can be used to poll for the completion of thread execution. - The Textue Importer dialog contains a new check box that causes the green channel of the output texture to be inverted.
This is useful for changing handedness on precomputed normal maps. The command line switch is
-invgreen. - In the World Editor, holding in the Ctrl key (or Cmd key on the Mac) while clicking in the Selection Mask page will now cause the mask buttons for all other node types to be unselected.
- The Memory Manager has been upgraded. It is now safe to allocate or deallocate memory from any thread.
- The
C4SIMDdefine has been removed from the engine. SSE code will now always be compiled, but the engine will only call SSE functions if the processor supports SSE2 instructions.
Build 139 — 21-Aug-2007
- Implemented a workaround for an ATI driver crash that some people have been experiencing.
- Fixed a couple minor bugs in the engine.
Build 138 — 18-Aug-2007
-
A new script method called "Change Settings" has been added to the core scripting system. This method lets a script change the same settings for an object that are displayed in the World Editor's Get Info dialog. Not all of every object's settings are exposed to scripts because there are some things that can't be changed dynamically, but in general, any object setting for which it makes sense to change can now be changed by a script. A single method can change any number of settings from a single settings category (each tab in the Get Info dialog represents a separate category), and each changed setting generates a journaled message that overrides any previous changes to the same setting.
In the Script Editor, once a target has been chosen for the Change Settings method, a list of available categories appears. Clicking on a category causes the settings in that category to be displayed. Initially, all of the settings are in an indeterminant state, meaning that they are not changed by the script method. Modifying a setting causes it to be added to the method. The settings can be put back into the indeterminant state by clicking the Reset button.
- The Change Light Color script method has been removed because it has been subsumed by the Change Settings method.
- The
Function::Execute()function now takes aScriptStateobject as a second parameter so that it's possible to retrieve information about the activator and trigger nodes. - The Script Editor and Panel Editor will now accept the Enter and Escape keys as shortcuts for the OK and Canel buttons. If the Cancel button is clicked, or the Escape key is pressed, and changes have been made, a confirmation dialog is displayed.
- The Script Editor and Panel Editor windows are now resizeable.
- Added the Ticker mutator to the panel effect code. This mutator can be applied to a text item to make the text scroll left or right and be clipped against the edges of the item's bounding box. A new check box in the Panel Editor lets you choose to put the text all on one line, and this must be checked for the Ticker mutator to do anything.
- The Texture Importer tool now supports 8-bit grayscale TGA files.
- Added a rotation menu to the animation import picker in the Model Viewer. This lets you rotate a character by any multiple of 90 degrees and hardwire it into the animation.
- Made several additions to the Collada Importer tool to handle various quirks in the exporters out there.
- Implemented several bug fixes and minor feature requests that aren't listed here.
Build 137 — 4-Aug-2007
-
The Sound Manager has been almost completely rewritten and now includes a much larger set of features. More important than the number of features, though, is the fact that every single feature is available on all platforms and with all sound hardware. The engine no longer contains any support for vendor-specific libraries like EAX and instead uses a custom multi-threaded software audio renderer. This gets rid of all the headaches associated with supporting different hardware, buggy drivers, and poorly designed APIs. Furthermore, it means that the audio experience is identical on all machines, so testing across a wide spectrum of sound hardware is not necessary.
The following list briefly describes the new features in the Sound Manager.
- All sounds can now have any loop count. Previously, spatialized sounds could only play once or loop forever.
- The previously-existing sound classifications (effects, music, voice) have been removed and replaced by registered sound groups. A game module can define any number of sound groups for which the volume can be independently controlled.
- WAV files no longer need to have a sampling rate of 22.05 kHz or 44.1 kHz. The Sound Manager will play WAV files using any frequency.
- The playback frequency of a sound can be changed while it is playing, and the Sound Manager ensures a smooth transition without popping artifacts.
- A Doppler shift can be applied to a sound based on the relative velocity between it and the listener.
- A very precise sound travel delay can be applied based on the distance between a sound and the listener. When a sound is played, this delay is calculated using the current distance to the listener, but the motion of the listener will also be taken into account so that the sound begins playing at the right time.
- Atmospheric absorption can be applied to a sound based on distance from the listener. This attenuates high frequencies so that distant sounds are muffled somewhat.
- The Sound Manager includes a full reverberation model and supports multiple simultaneously active environments.
A new type of space node, an
AcousticsSpacehas been added that defines the size and reflective properties of an acoustics environment. The listener does not need to be in the same environment as a sound in order for the correct reverberation effects to be audible. - The volumes of early reflections can be set on a per-environment and per-sound basis. There is a separate setting for high-frequency attenuation of reflected sound. Each environment also has a reverberation decay time associated with it.
- Directional sounds are now supported. As the listener moves through a sound cone for a directional sound, the volume falls off to the exterior volume at the cone's boundary. The exterior volume and extra high-frequency attenuation are applied outside the sound cone.
- Sounds can be attenuated by obstructions. There are separate obstructive volume settings for the direct path
and for reflected paths. The
AcousticsPropertyhas been updated for the new obstruction settings. - Sounds use a new fall-off model, and there is a new sound permeation system that determines how sounds travel throughout worlds. Sounds will now penetrate much more deeply through different zones, traveling down halls and around corners until they naturally become too faint to be heard.
Some aspects of the new Sound Manager are still a slight bit rough and will get some tweaking in the next few builds. Acoustics environments have been added to a few of the worlds that ship with the engine, but not all of them.
Some additional audio features that will be added to future releases include direct mixing to multi-channel surround sound and a generalized streaming mechanism that will allow plugin decompressors.
-
For various reasons, all C++ exception handling has been removed from the engine. This resulted in significantly smaller binaries, and execution speed should be slightly faster due to the removal of some code and space overhead. If you have a custom project, be sure to turn off support for exception handling in the code generation properties.
As a consequence of there being no exception handling, many error handling mechanisms in the engine had to be reworked. The design pattern for constructors that used to throw exceptions to indicate failure had to be changed to a pattern in which the constructor doesn't really do anything, and a separate initialization function is called. The most prominently affected classes are
File,Sound, andMovie. The constructors for these classes no longer take any parameters. TheFileclass now hasOpen()andClose()functions, and theSoundandMovieclasses now both have aLoad()function. - In the World Editor, the Get Info dialog nows displays settings for all selected nodes simultaneously. Making changes to the settings has an effect on every selected node when the Get Info dialog is closed. Every type of setting can now assume an indeterminant state that is used when values from multiple nodes conflict. If a setting is left in the indeterminant state, then its value is left unchanged for all nodes. The appearance of the indeterminant states are as follows: check boxes show a dash instead of an X, sliders do not show a handle, popup menus show a blank selection, and both color boxes and text boxes are filled with a striped pattern.
-
Several node settings have been moved or changed to work better with the new Get Info dialog:
- The "Do not render through remote portals" setting for geometries has been moved to a subsection under the Node pane because it is a setting for the geometry node and not the geometry object.
- The "Do not share light object data" setting for lights has also been moved to a subsection under the Node pane because it represents a general node flag.
- The "Light is statically confined" setting for lights has been removed. Controllers that make lights move in a small volume now set the confined flag automatically when the "Light is static" flag has been set in the editor.
- The clear color property of the root zone is now exposed as an actual property. This was a property all along, but it was previously shown under the Zone pane instead of the Properties pane.
-
Several upgrades have been made to the weapons code in the demo game:
- Three checkboxes have been added to the Player Settings dialog that control automatic weapon switching. The game can be configured to automatically change weapons when you pick up a new weapon or when you run out of ammo.
- There are new ammo packs for the grenade launcher, rocket launcher, plasma gun, and proton cannon.
- The proton cannon now does a reasonable amount of damage per unit time.
- The code for the Display Settings, Audio Settings, and Control Settings dialogs has been moved to the demo game module.
- Added a new setting type called
PowerTwoSettingthat displays a slider and allows the user to choose a power of two between a minimum and maximum value. - Added a new setting type called
MultiResourceSettingthat displays a text box containing a semicolon-separated list of resources. - The
ResourceSettingandMultiResourceSettingsettings now display the file picker with texture preview when the resource type is a texture map. - The Interface Manager now maintains a global clipboard for text. Copy, cut, and paste are now supported for all editable text boxes, and this is independent of the World Editor's clipboard for nodes.
- The
TypeToStringandStringToTypefunctions have been moved into theTextnamespace. Furthermore,TypeToStringnow returns a string instead of taking a pointer to an array of characters as a parameter. - Added a
SetThreadPriority()function to theThreadclass. - Changed the
Signal::Wait()function so that it takes a timeout parameter. - The engine now ships with a new project called SimpleChar. This project contains a simple example
of an implementation of a subclass of the
CharacterControllerclass and let's you run a character around the world. This game module can be run by changing the$applicNamevariable (in Data/cfg/Variables.cfg) to"SimpleChar". As with the SimpleBall game module, you need to open the console and use theloadcommand to load a world.
Build 136 — 22-May-2007
- There have been several problems with input not responding on the Mac lately. This issue has been traced to behavior changes in some MacOS X HID Manager functions introduced by the latest security updates from Apple. Some users would have started experiencing the problem after upgrading to MacOS 10.4.9, and other users would have seen the problem only after installing security update 2007-004. A workaround has been implemented in the engine, so all input problems on the Mac should now be resolved.
- Added some new optimizations to the shadow culling code that will stop unnecessary shadows from being drawn in some cases.
- Added a new feature to the motion blur effect that uses fast-clearing hardware to initialize the velocity buffer to the correct background velocity when appropriate. This allows motion blur to be applied when the clear color is being used in a world, and it provides a more optimal way to set the velocity of a skybox. There is no case in which this has any additional performance cost.
- Improved the quality of horizon mapping when used in conjunction with parallax mapping.
- Fixed several minor bugs in the world editor and demo game.
Build 135 — 12-May-2007
- Antialiasing has been re-implemented in the engine using the
GL_EXT_framebuffer_multisampleextension. The number of samples per pixel can be set in the Graphics Settings dialog, and the engine supports up to 8 samples when available. - The weapon code in the demo game has received a big upgrade. All weapons now shoot precisely from their barrels. More importantly, the proton cannon is now implemented. When it's fired, the barrel takes a moment to spin up before the beams actually shoot, but the gun has a devastating effect on its target.
- The configuration interface for customizable settings has been completely reworked. It now displays a two-column
scrollable list of settings. Slider-based settings now also accept text entry. The only affect this has on existing
code is that the
TextSettingconstructor no longer takes a width parameter. - There is a new
HeadingSettingclass that lets you insert a section heading into a list of settings. There is a new Transform page in the World Editor that displays the position, rotation, and size of the node for which the gizmo is currently shown. (Remember that the gizmo can be advanced through the selected nodes by pressing Tab.) Entering new data in the Transform page has an immediate effect on the node. All changes to the position and rotation are clumped together for a single undo step, and all changes to the size are clumped together for a separate single undo step. Keyboard focus in the Transform page is ended whenever you click in a viewport, select one of the standard tools at the top of the editor, or hit the Escape key.
The size fields in the Transform page require a little explanation. These aren't to be confused with scales, which are not included in transformation matrices in C4. All objects that have well-defined sizes can express their dimensions using 1–4 measurements. For most primitive geometries, the measurements correspond to the size of the geometry in the x, y, and z directions. The annulus and hole primitives are exceptions where two numbers correspond to the size of the inner boundary, and two numbers correspond to the size of the outer boundary. For things like lights and sound sources, the first size parameter corresponds to the light's range.
- There is a new Info page in the World Editor that displays various kinds of information about the node for which the gizmo is currently shown. Currently, the Info page displays the node name, the controller type, the number of connectors, and the number of properties for every type of node. For geometry nodes, the Info page also displays the vertex count, face count, surface count, material count, and detail level count. More information may be added in a future release.
- There is a new Grid page in the World Editor that contains controls for all grid-related settings. The toggle buttons for showing gridlines, snapping to the grid, and showing the coordinate axes have all been moved to the Grid page. The settings for gridline spacing and grid color have also been moved to the Grid page from their previous home in the Editor Settings dialog. There is a new setting called "major grid" that specifies how many grid squares separate each brighter major gridline. There are also two new buttons that immediately double or halve the gridline spacing.
- The grid snap mechanism in the World Editor has been changed. Instead of being applied to everything, grid snap is now only applied where it makes sense. In general, grid snap is applied when nodes are placed, moved, or resized. Furthermore, grid snap now applies when nodes are moved in the perspective viewport.
-
The motion blur algorithm has been upgraded in several ways. It's now more accurate, and it takes depth gradients into account so that distant objects don't blur together with close objects. Previously, you could see a halo around the weapon in the demo game because the background was moving, but the weapon was stationary with respect to the camera. This no longer happens, and additionally, the spinning barrel of the proton cannon won't blur with the stationary parts of the same gun.
It was not possible to implement the motion blur as nicely on ATI hardware because the ATI drivers do not support derivative instructions in
ARB_fragment_program. So the ability to separate motion blur into different depth layers is limited on ATI hardware, but it's still better in this release than in the previous ones. In particular, the engine can't stop the stationary part of the proton cannon from blurring into the spinning barrel on ATI hardware. Derivative instructions are available on ATI hardware in GLSL, but GLSL has serious limitations that don't exist inARB_fragment_program, such as a lack of shared global variables, that have prevented the engine from using it. - The cursor in an interface panel no longer blurs into the rest of the panel when the camera moves (since it's stationary with respect to the camera). Again, this isn't 100% perfect on ATI hardware for the reasons mentioned above.
- The Script Editor will now automatically assign generic controllers to nodes that are the targets of script methods, but don't already have controllers assigned to them. This removes the extra step that was necessary before in order for a script method to send messages to a node.
- Added a new function called
SetInputManagementModeto the Interface Manager class. PassingkInputManagementManualto this function will stop the Interface Manager from changing the input mode based on whether a window capable of receiving events is currently active. PassingkInputManagementAutomaticto the function will cause the Interface Manager to switch the input mode to gameplay mode whenever all interactive windows are closed.
Build 134 — 14-Apr-2007
- Added a new
PolygonZoneclass that allows a zone to have the shape of an extruded convex polygon. In the World Editor, polygon zones are drawn in a manner similar to portals, in which new vertices can be inserted, and existing vertices can be individually dragged around or removed. The polygonal shape defines the base of the zone, and the height of the zone is controlled by an additional handle at the top center of the zone. - When a node is cloned, links between any pair of its subnodes are now replicated in the cloned subtree. (Any connectors that lead out of the subtree being cloned continue to be cleared in the new copy.) This also affects connectors in referenced worlds, since these worlds are cloned when more than one instance is used in a level. Connectors inside a referenced world will now be replicated in all copies of that world.
- In the World Editor, panel effects are now rendered in the perspective viewport when lighting is enabled. Panels are only shown in their initial state because controllers do not run in the editor.
- Particle systems are now subclassed from the
Configurableclass and can expose settings in the World Editor. If a particle system exposes any settings, then a Particles pane will appear in its Get Info dialog. - Several improvements have been made to the burning rain effect in the demo game. The flames can now be rendered
as particles, so a single particle system is used to render all of the flames at once. The
BurningRainclass also exposes some settings in the editor now. - Added a color setting to the waterfall particle effects in the demo game.
- Added the Select Connected Node command to the Node menu in the World Editor. This command is available when one or more connectors are selected, and it selects the nodes that they are connected to.
- Added virtual functions
BeginRendering()andEndRendering()to theWorldclass. These contain the code previously in theWorld::Render()function that should only be executed once per frame. The render callback function that could be installed in the last build is no longer necessary since it's exact behavior can now be implemented by overriding theWorld::Render()function and executing extra code after calling the base class'sRender()function. Thus, theWorld::SetRenderProc()function has been removed. - The
CompressorandDecompressorclasses now support 64-bit integers for network messages.
Build 133 — 6-Apr-2007
- FBOs are now enabled by default on the Mac. They seem to be working correctly in MacOS 10.4.9.
- The
Systemclass has been removed from the engine, and its functions have been moved to theEngineclass. All occurrences ofSystem::andTheSystem->should be changed toEngine::andTheEngine->, respectively. -
With the intent of reducing the number of steps required to register custom class types, the registration mechanism has been changed a bit. First, for all registration types, it is no longer necessary to explicitly call one of the
Register*()functions. Instead, every registration type automatically registers itself upon construction. Calls to the following functions should simply be removed:RegisterControllerRegisterPropertyRegisterMethodRegisterMutatorRegisterEffectRegisterEntityRegisterFunction
Second, there is a new, slightly different way to declare registrations for controllers, properties, methods, mutators, effects, particle systems, and functions. Instead of declaring a controller registration object as a
ControllerRegistration, you should declare it as aControllerReg<type>template object, wheretypeis the derived type of the custom controller class. For example, the registraton for theRotationControllerclass is declared asControllerReg<RotationController>. The following templates exist for registering various types of custom classes:ControllerReg<type>PropertyReg<type>MethodReg<type>MutatorReg<type>EffectReg<type>ParticleSystemReg<type>FunctionReg<type>
Custom class types registered with these templates no longer need to be constructed explicitly by the application. If you've implemented a function such as
ConstructController, then you can remove any registered types because they will be constructed automatically.The function registration object is a little different in that its constructor takes a pointer to a controller registration as its first parameter. Function registrations for each type of controller are stored in the controller's registration object. There is no longer any need to implement a
ConstructFunction()function in controller classes that define custom functions.Previously, registration objects for controllers, properties, and mutators took a parameter that specified some kind of validation function. These have been removed because the new registration templates can call the validation function for the custom class type directly. When a controller or property subclass defines the
ValidNode()function (as a static member function), then it is automatically called to determine whether the controller or property can be applied to a particular node. Likewise, defining theValidPanelItem()function in a mutator subclass will cause that function to automatically be called to determine what kind of panel item the mutator can be assigned to.Entity and locator registrations still work as they did before since they don't register new subclass types. Continue using the
EntityRegistrationandLocatorRegistrationobjects to register these types. - The perspective viewport in the World Editor can now render with full lighting, reflection, refraction, fog, and some effects. There is a new toggle button at the top of the editor window that switches between full lighting and bright ambient rendering. Geometries, lights, etc., can be moved around with full lighting turned on to see the immediate results of your changes.
- In the scene graph viewport, hidden nodes are now shown in a darker gray color. Nodes belonging to referenced worlds are shown in a reddish color.
- In the World Editor, the Layout page has been renamed to the Viewports page to avoid confusion with a future Layers page.
- The mouse wheel will now work at all times in the World Editor to zoom viewports, even when you're doing something else with the mouse button down.
- Pages in the World Editor can now be displayed on either the left or right side of the window. This can be changed in the Editor Settings dialog accessible from the Layout menu.
-
The World Editor now displays a gizmo for selected nodes that shows the orientation of the node's local axes. The gizmo is shown as three arrows with colors red, green, and blue corresponding to the x-, y-, and z-axes, respectively. The gizmo is shown for one node in the selection at a time, and it can be iterated through the selected nodes by pressing the tab key. When the Select and Move tool is used, an arrowhead on the gizmo can be grabbed in any viewport and used to drag the node along its corresponding axis.
In the next build, the gizmo will also have rotation handles, and it will be possible to display world-space and zone-space axes instead of object-space axes.
- Added a new Particle Systems page to the World Editor. This page displays a list of registered particle systems (see next item) and also contains tools for drawing emitter volumes. Particle systems now have a built-in connector of type EMIT that can be connected to an emitter volume. How the emitter volume is used depends on the particular particle system's implementation. Multiple particle systems can be connected to the same emitter volume.
- Application-defined particle systems can now be registered using the
ParticleSystemReg<>class. Registered particle systems can be placed in a world using the World Editor. - Particle systems can now be fully serialized, meaning that the state of all active particles is saved.
If a custom particle type is defined, then it must implement
PackandUnpackfunctions that save any custom state in addition to the base state saved withParticle::Pack. - Added a new particle style called
kParticleQuadthat causes particles to be drawn as fully oriented quads instead of camera-facing billboards. Particle systems using this style must use theQuadParticlestructure to store particles. Thetransformfield of theQuadParticlestructure specifies the orientation of each particle as a quaternion. - Added the
AddFarthestParticle()function to theParticleSystemclass. This makes the newly added particle the first to render instead of the last, as is the case when theAddParticle()function is called. - Previously, it has been possible to render multiple fog spaces at once as long as they apply to different render targets, but each fog space had to be in a different zone. It is now possible to place multiple fog spaces in a single zone and have them all be considered for rendering (but still only into different render targets). This makes it a lot easier to add fog to areas that already contain a fog space for an underwater volume.
- The
DoorControllernow exposes settings for three different sounds: one that plays when the door has fully opened, one that plays when the door has fully closed, and one that loops while the door is moving in either direction. - The demo game module now defines the variable
$fovto be the field of view for all cameras, in degrees. The game will clamp the value to the range [45,90]. - The String Importer tool will now translate
\t,\n, and\rinto tab, newline, and carriage return, respectively. As usual, a backslash can be obtained by using\\. - The
TextBoxElementinterface class now starts a new line whenever a newline or carriage return character is encountered. The\nis recognized as a newline in the panel editor for text items. - If an attempt is made to load a nonexistent model resource, the engine will now load a stand-in “missing” model instead of throwing an exception. The “missing” model is currently a yellow cylinder.
- The
shotcommand will now pad out screenshot index numbers in filenames to four digits. - Added support for 64-bit integers to the
Stringclass andTextnamespace. - Added a rendering callback to the
Worldclass. TheWorld::SetRenderProc()function sets a callback function that is called right after the entire scene has been rendered insideWorld::Render(), but before the Graphics Manager render target is changed back to the primary surface. This lets you render extra objects directly into the world's render target. - Precached entity models will now be reloaded when a model resource is exported from the World Editor. This removes the need to quit and restart the engine when a model is changed. If the change occurs while clones of the model exist (perhaps because a world is running in the background), then they will not be replaced, but all new instances will use the new model resource.
- The Collada Importer tool has been updated to recognize additional material structures that are output by the 3DS Max exporter.
Build 132 — 14-Feb-2007
- NOTE: A lot of changes have been made to the distribution of source code files among the three code directories in this build. The directories have been renamed to “EngineCode”, “GameCode”, and “ToolCode”, without spaces, so unzipping into an existing installation will result in three new code directories being created with clean groups of files.
- The World Editor has received a massive upgrade, and the existing editor code has been largely reorganized. It is now structured in such a way that custom editor extensions (plugins) will be possible in a near-term release.
- Most of the editor tools have now been organized into palette-like subwindows called “pages”. Pages contain groups of related tools and can be arranged on the left side of the editor window by dragging them around. Pages can also be hidden or collapsed, and invisible pages can be shown by selecting them in the new Page menu. The page state is saved and restored for each world separately.
- Some previously existing editor features have been moved into new pages. The selection mask buttons are now part of the Selection Mask page, and the show/hide items previously in the View menu are now part of the Visibility page.
- The bulk of the manipulator code has been moved out of the engine core and into the World Editor module, and some internal structures have been changed. All saved manipulators will be dumped when worlds are first opened with this build and replaced with new ones. The only impact this has is that certain manipulator state such a node's editor-only visibility state will be reset.
- There is a new page called Layout that controls viewport configuration and manipulator appearance. Several new viewport layouts are now possible, and the type of each viewport can be chosen by right-clicking in the viewport itself. All editor viewports will be reset to default configurations when worlds are opened with this build.
-
A new viewport type has been added to the editor that displays the scene graph hierarchy. Each node is shown with an icon representing its type and either its name or a string describing its type if it doesn't have a name. The collapse boxes in the hierarchy can be used to hide subtrees. Nodes belonging to referenced worlds are shown in a darker color (when referenced world display is on) and cannot be selected.
The node select, rect select, scroll, zoom, and rect zoom tools work in the scene graph viewport in the same way that they do elsewhere. The move tool works as a reparenting tool in the scene graph viewport, allowing you to drag the selection to a new parent node. Nodes cannot be reparented to one of their descendants or to a reference marker, but anything else goes.
The root node can be selected in the scene graph viewport, but it cannot be deleted or reparented.
- The concept of a target group has been removed from the editor because its functionality has been superseded by the reparenting capabilities in the scene graph viewport.
- The World Settings command has been removed from the editor. It simply opened the Get Info dialog for the root node, and this can now be accomplished by selecting the root node directly and hitting Ctrl-I.
- The right-click menu contains two additional items called Frame All and Frame Selection. These center a viewport on either all nodes or just selected nodes and scale so that everything fits into view.
- Most node types are now visible and selectable in the perspective viewport. Lights, sources, markers, and effects are represented by cubic icons whose size can be changed in the Layout page. The volumes covered by triggers, spaces, and effects are also visible.
- The default grid color in the World Editor is now given by the variable
$editorGridColor. - Added a camera placement tool to the World Editor in a new Cameras page. Also, connectors can now be set up so that they can only link to camera nodes.
- Added a new interface panel item that displays an image rendered from another camera in the world. This can be used for things like security camera monitors. To use this panel item, a connector must be assigned to the panel effect node and linked to the target camera. Then the same connector key should be assigned to the camera panel item.
- A new function that changes the connector key for a camera panel item has been added to the panel controller. This lets a script change which camera is used to render an image for a camera panel item.
- Added a new Skybox page that contains a skybox placement tool. A skybox is now added to a world by explicitly placing a skybox node in the root zone. Skyboxes in existing worlds will show up at the world-space origin. Since a skybox is rendered at infinity, the physical location of a skybox node has no effect, but its orientation does affect the angle at which the skybox is rendered. Furthermore, it is now possible to assign a controller to a skybox node so that, for example, it can be rotated or controlled by a script.
- It is now possible to assign a material to a skybox node in the World Editor. Such a material affects how a skybox is rendered in addition to the texture maps assigned to the six skybox faces. Only material attributes that pertain to the ambient lighting equation affect the appearance of a skybox. A material can be removed from a skybox using the new Remove Material command under the Node menu.
- The Change Material Color script method will now affect any material assigned to a skybox.
-
Added a new sound source type that plays ambient sounds. These can be placed in a world to serve as containers for music or environmental sounds. Currently, the physical location of an ambient source has no effect. If an ambient source is playing, it can be heard at the same volume everywhere.
The Get Info dialog for an ambient source lets you assign a list of sound files to play. If the source is streaming, then multiple sounds can be attached to the source, and they will play consecutively without interruption. The same file can be listed more than once.
- Under the texcoord animation pane in the material manager, the texcoord speed is now displayed numerically, and the allowable range of speeds has been increased.
- When geometry is imported into the World Editor, it will now always appear at the same world-space coordinates no matter what zone is currently the target zone. Imported geometry is still added to the current target zone, but it's transform is multiplied by the inverse of the zone's transform to keep it at the location specified in the import file.
- The Remove Transform command has been renamed to Reset Transform to Identity, and a new command called Align Position to Grid has been added to the Node menu in the editor.
- The Texture Viewer and Texture Importer tools have been merged into a single tool module.
- A new checkbox has been added to the Texture Importer that lets you specify that the RGB channels of the
source texture already contain vector information (such as a normal map). Checking this box causes
mipmaps to be generated for vectors instead of colors. This option can be accessed on the command
line using the
-vectorswitch. - The Model Viewer has been integrated into the World Editor tool module. It's likely that the model viewer will eventually be integrated into the editor window itself so that a separate window isn't even necessary.
- The
Constructableclass template has been changed in a couple of ways that make it more flexible in general and slightly simpler in the default case. All installed custom constructor objects (such asConstructor<Controller>) should now encapsulate a function taking a single parameter of type reference toUnpacker. The type to be constructed can be retrieved by calling theGetType()function on theUnpackerobject. See the examples in the game modules. - The polyboard rendering code has been improved so that polyboards viewed near-tangentially look better.
- Panels now render correctly in fog. Fog must be explicitly enabled for panels by checking a new box in the Get Info dialog for a panel effect node.
- New functions have been added to the
Controllerclass calledWake()andSleep(). When a controller is asleep, it does not receive calls to itsMove()function, saving processing time. New script methods for putting controllers to sleep and waking them are now available. - Added a new flag to the script controller that causes a script to loop continuously. If this flag is set, a script will start over when its last method has finished executing.
- When a world is loaded, all nodes now have their world transforms updated before they are preprocessed.
This means that the world transform of a node is valid inside the
Preprocess()function when a world is being loaded. The world transform is not valid insidePreprocess()if this function is called explicitly or indirectly through a call to theAddNewSubnode()function. - The
Node::EnumerateGeometries()function has been updated so that the callback function gets the center and radius of the input sphere. - Added a loop callback to the
Interpolatorclass. This allows you to install a function that is called each time an interpolator loops (such as the frame interpolator for theFrameAnimatorclass). - Modified the
RotationControllerclass in the Game Module. The center of rotation and the rotation axis are now specified by adding connectors of type CENT and AXIS to the controller's target node and connecting them to markers. If the AXIS connector is present and connected to a node, then the difference in the positions of the two markers gives the axis of rotation. If there is no AXIS connector, then the rotation axis is the z-axis. These markers should not be subnodes of the node that is actually moved. - Modified the
DoorControllerclass in the Game Module. The controller should now be applied directly to the node that gets moved (which can be the root node of a bigger tree). Open, closed, and shifted positions are specified by adding connectors of type OPEN, CLOS, and SHFT to the controller's target node and connecting them to markers. The relative positions of the markers (which can actually be any kind of node) tell the controller how to move the door. These markers should not be subnodes of the node that is actually moved. - Added a new enemy character to the Game Module. The AI for the Pumpkinhead is extremely basic for now, but the code demonstrates how an NPC could be added to a game. The Pumpkinhead can be found in the Dungeon level, and he'll come after you with fireballs.
- By fiddling with internal formats, a 75% increase in shadow map rendering speed has been achieved on ATI hardware.
- The C4 Engine now runs on PS3.
Build 131 — 20-Nov-2006
- Implemented an example of a polyboard particle system. The
SpiralHelixEffectclass in the Game Module animates a particle system for which every group of 8 particles forms a ribbon. - Added a workaround to the Collada Importer that would handle apparently erroneous bone weights of zero generated by the ColladaMax 1.06 export plugin.
- Fixed a scale problem that affected Collada exports from 3D Studio MAX. Models that looked mangled before should now import correctly.
- Fixed a problem that could prevent animations from importing correctly.
- Fixed a hardware detection problem that could cause shadow mapping not to render correctly on ATI hardware.
(A hacky workaround has to be used on ATI hardware because
GL_ARB_fragment_program_shadowdoes not function correctly.)
Build 130 — 10-Nov-2006
-
Finished the animation blending system based on a new design. There are three built-in animator subclasses that provide general functionality, and applications can define custom animators for more specific purposes (see next note). Each animator in the tree assigned to an entity targets a range of nodes rooted at a given target node (which is often the entity itself).
The
FrameAnimatorclass is used to play an animation stored in an animation resource. This replaces the functionality that was previously part of theEntityclass. The frame animator is based on time instead of frame number, and its rate can be changed arbitrarily. Control over the playback is accessed through theInterpolatorobject returned by theFrameAnimator::GetFrameInterpolator()function.The
MergeAnimatorclass can be used to combine the outputs of multiple animators. It takes the outputs of all of its subnodes and combines them into a single output. Later subnodes can override the outputs of earlier nodes.The
BlendAnimatorclass blends the outputs of at most two sub-animators. The weight of each animator is controlled through anotherInterpolatorobject that can be retrieved with theAnimator::GetWeightInterpolator()function. Weights are always renormalized by the blend animator, so they don't need to sum to one. - Removed the bone modifier mechanism that was being used to twist the spine of the player as he looked
around. This is now handled by a custom animator called
SpineTwistAnimatorin the game code. - Fixed a bug that could cause a crash on exit when using microfacet shading together with fog.
- Fixed a crash that would occur if you combined dual textures, refraction, and environment mapping in a single material.
Build 129 — 3-Nov-2006
-
Designed and implemented an animation blending system. The
Entityclass can now own a tree ofAnimatorobjects that calculate transforms for the node hierarchy rooted at the entity node. Each animator has its own target root node so that it can be assigned to a subtree of the whole entity. Animators can calculate transforms in any way they wish, and the final transforms output by the root animator are ultimately applied by theEntityclass.NOTE: Some parts of the animation blending system have been intentionally removed from this release because they are being redesigned. The complete system will be included with the next release.
-
Implemented horizon maps. It is now possible, while importing a normal map, to generate two auxiliary textures that contain data about how bumps cast shadows onto themselves. When the “Generate horizon maps” check box is selected in the Texture Importer dialog, two additional textures with suffixes
-h1and-h2are created along with the normal map. Once these exist, horizon mapping can be enabled for a material by selecting the “Apply horizon maps” check box in the General pane of the Material Manager. Horizon maps can only be applied when a single normal map is present in a material, and they use the same texture coordinates as the normal map.There is a new setting in the Graphics Options dialog that enables or disables horizon mapping globally.
- Removed the two-sided and alpha test flags from the
GeometryObjectclass. These rendering flags can now only be set in a material. - Added a new type of particle that can be used for ribbon/trail effects. When the
kParticlePolyboardconstant is specified as a particle's style, then thePolyParticlestructure must be the base structure used in the particle pool. It contains a tangent direction, a texture coordinate, and a flag indicating whether the particle is the last in a single polyboard. If it is not the last, then the polyboard continues to the next particle in the system. If it is the last, then the next particle begins a new polyboard. The radius of a particle controls the width of the polyboard. -
Several big changes have been made to the Message Manager. The
PlayerMgrclass has been removed from the engine and replaced with a system based on events that are passed to handler functions in theApplicationclass.Two new general classes have been defined for distributing information to client machines in a multiplayer game. The
StateSenderclass is used to send initial state when a new client joins a game, and theSnapshotSenderclass is used to send state at fixed intervals during gameplay. - Added a new script function to the
PanelControllerthat activates panel items. This runs the scripts attached to the panel items as if the player had clicked on them. - Removed the
PositionMarkerclass and renamed theLocationMarkerclass toLocatorMarker. All position markers will be converted to locator markers automatically. There was really no need to have two different marker types that essentially mean the same thing. - In the Game Module, the player's weapon is now visible in the first-person view. Both the weapon and the flashlight are now hooked up to a special mount node that the attached to the character. The player's hands do not yet grasp the weapon correctly—we are planning to use IK in a future release to keep the hands in the right place. There are a couple of additional minor issues: projectiles do not yet fire directly out of the weapons, and motion blur around the border of the weapon is not acceptable when the background is in motion. These will both be addressed in a future release.
- The geometry building code now splits vertices along edges that are too sharp to share normals. The Collada Importer now preserves the normal vectors on all imported geometry.
- The Collada Importer now recognizes the custom bump map settings written by 3DS Max.
- The Graphics Manager will now attempt to auto-configure some rendering options. On lower-end graphics chips, some options will be turned off automatically the first time the engine is run.
- Fixed a problem in which some geometries in a zone may not be lit properly if the zone is visible through multiple portals simultaneously and a particular light region doesn't intersect all of the camera regions.
- Made some small changes to the material manager layout. The two-sided flag, alpha










