Note that with V2.0.0 of the Maya exporter, the V texture coordinates, with respect to maya, are exported as 1-v. They used to be exported as being -v.
There is now a build of the Aftk (and Nexus) with integrated Maya support (currently only Maya 6.0, although 6.5 will be provided shortly). This means that the Aftk can read .mb and .ma files. Importantly, this does not require a Maya license from the server. However, if writing of .ma and .ma files were to be needed, a license would be needed. For this reason, the current Maya support is read-only.
A mesh can be added to another mesh by calling the AddMesh function of the mesh class. This does not delete the added mesh. The AddMesh will preserve weighting information if present.
Floating point colour values can be packed in to a 32-bit integer by the following global function:
inline U32 ColourRGBAToU32(F32 r, F32 g, F32 b, F32 a)Floating point colours can be recovered using this global function:
inline AftkVector4F32 ColourRGBAFromU32(U32 colour)Note that the vertex colours exported by version 2.0.0 of the Maya exporter are now stored in 32 bits as integers, not 128 bits as floats.
Instead of calling the 'weld mesh components' and 'weld polygon vertex' functions of AftkScene to perform scene-wide mesh welding, you can use the WeldMeshes function, which does both. Similarly, on the mesh class itself, the Weld function will perform welding of all data for an entire mesh.
Nodes in the scene graph can now be accessed using directory-like paths. The path is delimited using pipe characters. For example, consider a scene with a root node named "AftkRoot", which has a child named "child1". The path of the root is "|AftkRoot", and the path of the child is "|AftkRoot|child1". The function GetSceneNodeByPathByFullPath performs the path query, returning the first matching node it finds. You can also search for a path fragment by using the GetSceneNodeByPartialPath function.
The function ClearGeometry on the mesh class allows the erasing of a meshes geometry.
This is one of the biggest additions to this release of the Aftk. Although nobody is set to use it just yet! Essentially, the Aftk now supports 'XRef' nodes, these are like instance nodes, except that the object they instance is potentially offline (not in main memory). Offline objects reside in .a3d scenes on disk. Offline objects can easily be brought online thru an API call, and then work in a similar manner to traditional instances. XRef objects are equivalent to the 'reference' nodes that you see in the Maya outliner after loading a 'reference scene'. The Maya export system supports the automatic creation of .a3d files for each reference scene when exporting a scene that employs references. The scene into which the references were loaded then stores CRC values for the a3d reference files and also the .mb files they originated from. This is to detect changes in the files such that references are only re-exported when necessary.
Fully elaborating on the nature of the Aftk's xref system will not be done here as its not currently needed.
The Aftk class has been removed. Its functionality is now encompassed by the AftkScene class.
If you use the SetVertexDataChannelInfo function of the mesh class to change the data type of a vertex data channel, then the aftk will now delete any existing data in that channel. It will then automatically creating a new channel of the given data type. Previously any existing vertex data was left untouched, causing crashes later on when querying this data.
Build properties can now be queried through the following Aftk class members. See doxygen for more information.
std::string GetBuildStamp() const; std::string GetBuildPC() const; std::string GetSVNRevision() const;
The animation evaluation system for meshes has been updated. A mesh can be evaluated for a given value of x (typically in units of time) by calling its Evaluate function. This updates an internal cache containing the evaluated positions, normals, tangents and binormals for the mesh. This cache can the be queried via the following mesh functions.
AftkPosition3 GetEvaluatedPolygonVertexPosition(U32 polyVertIndex) const; AftkNormal3 GetEvaluatedPolygonVertexNormal(U32 polyVertIndex) const; AftkVector3F32 GetEvaluatedPolygonVertexTangent(U32 uvSet, U32 polyVertIndex) const; AftkVector3F32 GetEvaluatedPolygonVertexBinormal(U32 uvSet, U32 polyVertIndex) const;
Tangent space properties for meshes can now be added explicitly by users.
The arbitrary vertex data system has been improved. A variety of data types can now be used, including all the usual scalar types and some vector types. See doxygen.
The root node of the scene can no longer have any siblings. The Aftk attempts to enforce this relationship automatically. For example, attempting to set a node with siblings as the root node results in a new scene node being created as root. The node with siblings is then parented to this. This hierarchy structure is the same as that of XSI, and allows for more simple hierarchy traversal and manipulation.
The Maya->A3D export plug-in no longer scales exported scenes down by a factor of 100. The Aftk will scale up older A3D files when read in to compensate. This is done by altering the scene transform. The reason for this change is to make A3D object scaling consistent with the scale of objects read from XSI.
Two methods for discrete LOD support have been implemented, see below.
Method 1 - Seperate scene nodes, such as meshes, can be grouped inder a "LOD Group node" (AftkSceneLodGroupNode). The LOD group node contains a table which describes which of its children represent what level of detail. This table also stores the threshold value at which lods are switched. This is the method that Maya uses to provide LOD support.
Method 2 - Discrete LOD support has now been added to the mesh class. This has been implemented by storing separate lists of polygons for each LOD level. In order to create a level of detail, first call SetLodLevelInfo, providing the level of LOD you wish to create, and a structure describing that LOD. This structure includes the name and threshold at which the subsequent LOD activates. Note that LODs should be stored sequentially from highest->lowest detail. Once the LOD description has been added, polygon data can be input in the usual fashion. Note that all polygon functions now accept an argument indicating the LOD level they refer to. Alternatively, the SetLodLevelMesh function can be invoked. This function takes the first LOD level of a given mesh and copies the vertex, polygon and weighting data from that mesh into a specified level of detail on the target mesh. This data can then welded if desired, with the vertex weights being averaged.
Bounds information can be queried for any scene node object, so this includes instances and deformed objects. This bounds information includes bounding box, bounding sphere and centre point information. The local and world space bounds can be provided. The bounds information is cached.
The following functions have been provided for scene graph manipulation, see doxygen for more info:
void ExtractSceneNodeAndChildren(AftkSceneNode* pNode); void ExtractSceneNodeAndReparentChildren(AftkSceneNode* pNode); void DeleteSceneNodeAndReparentChildren(AftkSceneNode* pNode); void DeleteSceneNodeAndChildren(AftkSceneNode* pNode);
Deformed instances (boned instances) are now supported via the AftkSceneMeshBonedInstanceNode class. Deformed instances with LODs are to be used for the PGR3 barriers.
Material and blind data resources are no longer automatically deleted when their reference count reaches zero. Instead, unused resources can be cleaned up by calling the RemoveUnusedMaterialNodess and RemoveUnusedBlindDataNodes functions of AftkScene.
Material and blind data mapping table entries for mesh classes are no longer deleted when a resources mesh-relative
reference count reaches zero. Instead, functions RemoveUnusedMeshPolygonMaterialMappings and
To quickly remove all unused resource information, as mentioned in the above two points, call the Optimise function of AftkScene.
AftkScene's ValidateScene function has been replaced by Validate.
AftkScene's DeleteSceneNode function has been replaced by DeleteSceneNodeAndChildren.
The API for arbitrary vertex data has been changed - see doxygen.
The API for polygon access has changed such that you must specify the level of detail that you are querying.
Some internal work has been undertaken in order to increase performance.
Deleting an instance of a node now correctly decreases the instance reference count for the node that was being instanced
The 'ApplyMatrix' function of the mesh class now transforms tangents and binormals.
No assertion checking is now performed in release builds for increased performance.
Dynamic memory allocation for material, blind data, polygon and polygon vertex members is now handled via a memory pool system. As well as the AFTK faster, this also reduces memory usage. For a 127mb A3D scene, ~275mb of memory is required. This requirement used to be just over 300mb. For debug builds around 400mb was required for the same scene. This has now dropped to around 300mb.
The AFTK had a bug which resulted in tangent space vectors being incorrectly shared across the mesh, making the results unusable. This has now been fixed. Tangent and binormal vectors are no longer implicitly shared upon creation. Instead, they can be shared (via snapping) by calling WeldVertexTangentsAndBinormals on the mesh node.
Tangents and binormals will also be shared by calling the scene's WeldMeshComponents function.
The tangent and binormal related functions of the mesh class now follow the naming scheme GetVertexTangent instead of GetTangent for consistency.
Tangents and binormals are now returned as type AftkNormal3 instead of AftkVector3F32, again for consistency. As the name suggests, these vectors are normalised.
Spot and point lights now have a radius attribute.
When reading a file, the Aftk attempts to secure the file for exclusive read access. Should this fail, an error to that effect is returned.
Similarly, when writing a file, the Aftk attempts to lock the file for exclusive write access. These changes should prevent any problems on HT CPUs, where a program could possibly attempt to read an A3D file half way through it being written out by another process.
Quaternions are now used to interpolate (slerp) rotations within the animation evaluation code.
The 'ImportAnimation' functions of the Aftk and AftkScene classes allow animation to be imported from files on disk and scenes in memory respectively. The import matches scene nodes, by name, within the two scenes and then copies any animation data from animated source nodes into the target scene.
The world matrices for all scene nodes are now cached, instead of being recalculated for every GetWorldMatrix call.
The XSI import code now provides a working progress callback.
On some peoples machines, building the Aftk would result in a large number of XSIFTK.lib linker errors. To fix this, the Aftk no longer links to the XSI-FTK library directly. This must be seperately linked into your application.
The Aftk's internal debug manager is now thread-safe.
Global reference counts could become out of sync with the actual number of times a resource was used.
The way in which materials and blind data are associated with polygons has changed very significantly. The AftkSceneMeshNode class is now derived from a class named AftkSceneMeshRemappableNode. The latter class provides tables that map 16-bit indices to blind data and material resources. So now, all polygons have 16-bit indices into these tables for their material and blind data. For the case of just a simple mesh one can get a polygon's material index, look this up against the mesh's index --> material resource mapping table, and thus end up with the material resource. However, things get more interesting when considering another class derived from AftkSceneMeshRemappableNode, namely the AftkSceneMeshRemappedInstanceNode class.
The AftkSceneMeshRemappedInstanceNode class represents a special instance of a mesh node. Two things are special about this node:
(1) It it implements a mesh interface, allowing it to be queried like a regular mesh.
(2) It provides its own resource mapping tables.
The fact that it contains its own mapping tables allows you to override material and blind data assignments. For example, consider the case where our remapped mesh instance points to a mesh with two polygons. Polygon 1 has a material index of 0, and polygon 2 has a material index of 1. On the source mesh, these indices point to materials Lambert1 and Blinn1 respectively. The remapped instance of the mesh has a different material mapping table however. Such that material index 0 points to Phong1, while material index 1 still points to Blinn1. So you can see, that by providing different material mapping tables, materials can be easily overridden by instances.
All nodes derived from AftkSceneMeshRemappableNode, such as AftkSceneMeshNode, can have UV offset information specified per UV set. These UV offsets may be overrided in the AftkSceneMeshRemappedInstanceNode class.
AftkStatus BuildAnimationHelpers(); AftkStatus EvaulateMatrixPalette(F32 x); AftkPosition3 EvaluatePolygonVertexPosition(U32 instance, const AftkMatrix44& worldMatrix) const; AftkNormal3 EvaluatePolygonVertexNormal(U32 instance, const AftkMatrix44& worldMatrix) const; U32 GetNumVertexWeights() const; const AftkVertexWeight& GetVertexWeight(U32 instance) const; U32 GetNumPaletteMatrices() const; const AftkMatrix44& GetPaletteMatrix(U32 instance) const;
It is now possible to share mesh components individually using the following functions on the AftkSceneMeshNode class.
U32 WeldTextureCoordinates (F32 threshold) U32 WeldVertexNormals (F32 threshold) U32 WeldVertexPositions (F32 threshold)
It's also possible to perform the above operations across all mesh nodes via these functions of the AftkScene class:
U32 WeldMeshComponents (F32 threshold=AFTK_EPSILON, AftkProgressNotification *pProgressCallback=0)
The Aftk now contains functions to share and un-share polygon vertices. In order to maximise sharing is advisable you first weld all of the mesh components as previously described. Note that in the lighting tool, polygon vertices are unshared prior to lighting. For example, think of the consequences of lighting to vertex colours with shared polygon vertices. The same polygon vertex would likely have its colour value overwritten several times, yielding incorrect results.
U32 WeldMeshPolygonVertices (F32 threshold, AftkProgressNotification *pProgressCallback=0) U32 ExpandMeshPolygonVertices (AftkProgressNotification *pProgressCallback=0)
U32 Repair (U32 &vPosRemoved, U32 &normRemoved, U32 &uvRemoved, U32 &pvRemoved, U32 °TrisRemoved)Note, for convenience a function is provided in the AftkScene class which will repair all of the meshes in the scene.
U32 RepairMeshNodes (U32 &vPosRemoved, U32 &normRemoved, U32 &uvRemoved, U32 &pvRemoved, U32 °TrisRemoved, AftkProgressNotification *pProgressCallback=0)
It is now possible to copy a mesh between two Aftk instances. This should be useful for the PGR crowd system, as it will be possible to load an animated character - evaluate the mesh data for a given pose, and then copy this data into a new Aftk instance in order to save out the pose separately.
Cameras are now exported from Maya, and are implemented by the AftkSceneCameraNode class. Please refer to the doxygen documentation for this class.
Fixed memory leak within polygon cluster system.
Bug fixed whereby vertex position welding could skip some vertices.