3ds Max Data Exchange Interface (3DXI)and COLLADA
Bernard LefebvreAUTODESK - Media and Entertainment
Dev. Tech. Support
Overview3DXI – High Level API for 3ds Max SDK
Goals and Targets Interface Scope Overview Flexibility and Customization
COLLADA - Digital Asset Exchange Schema Goals and Guidelines Library types
3DXI in COLLADA Export plug-in How things work together Data round-trip demonstration
3DXI - High Level APIfor 3ds Max SDK
3DXI (formerly known as IGame) was introduced as a set of interfaces for rapid data extraction
Dual target Allow novice 3ds Max developers to extract
data with minimal effort Allow for the gradual adoption of 3DXI within
existing pipelines
3DXI: Goals and Targets
M&E is devoting R&D resources to maintain and expand 3DXI Short term goal:
Complete the set of entities exposed when parsing the scene graph
Mid term goal: Incorporate import capabilities to the API
Long term goal: Become a standard API for data exchange in
and out of 3ds Max
3DXI: Goals and Targets
3DXI: Interface Scope Overview
Provides unified Scene traversal and Object enumeration
Well defined data containers for top level Nodes and Materials interfaces with list of their children
class IGameScene{virtual bool InitialiseIGame(bool selected = false)=0;
};
3DXI: Interface Scope Overview
Built-in Conversion System Coordinate System Conversions (3ds
Max, OpenGL, DirectX, custom)
IGameConversionManager * cm = GetConversionManager();
cm->SetCoordSystem(IGameConversionManager::IGAME_D3D);
Access to 3ds Max elementsGeometry, Spline, Lights and Cameras, Helper
Objects
Modifiers, Skin Deformers, Materials, Textures (including Bitmap)
Controllers, Constraints, IK Chain, Bipeds
Object Parameter Containers Paramblocks, Custom Attributes, MXS plugins, Custom
Node Data
3DXI: Interface Scope Overview
3DXI: Interface Scope Overview
Mesh AccessAll Vertex Colors, Alpha, Illumination,
Normals, Texture Coordinates, Binormals, and Tangents are accessed directly
Vertex normals calculated based on the smoothing group of the face
Support for Mesh and MNMesh (N-sided polygons)
3DXI: Interface Scope Overview
AnimationAccess to TCB, Euler Controllers,
Constraints and Biped systemsOption for key sampling for parametric
controllers
3DXI: Interface Scope Overview
DirectX EffectsDirectX 9 Shader Material
supported directly via IGameMaterial
3DXI: Interface Scope Overview
IGameFX – main interface to D3D effect, compliant with HLSL COLLADA FX (1.4.0)
IGameFXProperty – interface for individual parameter (property), can be extracted to general IGameProperty
IGameFXTechnique – interface for technique information
IGameFXPass – interface for pass information
IGameFXFunction – access to function’s data
3DXI: Interface Scope Overview Graphical Class Hierarchy
IExportEntity
IGameConstraint
IGameModifier
IGameObject
IGameMaterial
IGameTexture Map
IGameUVGen
IGameGenMod
IGameMorpher
IGameSkin
IGameGenObject
IGameLight
IGameCamera
IGameMesh
IGameIKChain
IGameSpline
IGameXRefObject
IGameSupportObject
IGameScene
IGameNode
IGameControl
IGameKey
IGameFX
FaceEx
IPropertyContainer
IGameConversionManager
IGameProperty
3DXI: Interface Scope OverviewCode Example: Simplification
Extracting key frame data from controller (3ds Max SDK):
Control * cont = node->GetTMController()->GetPositionController()if (!cont)
return;IKeyControl * ikc = GetKeyControlInterface(cont);// TCB point3if (ikc && (cont->ClassID()== Class_ID(TCBINTERP_POINT3_CLASS_ID, 0))){
for (int i=0; i<ikc->GetNumKeys(); i++) {ITCBPoint3Key key;ikc->GetKey(i, &key);// process data
}}
3DXI: Interface Scope OverviewCode Example: Simplification
The same data in 3DXI can be extracted as:
IGameKeyTab poskeys;IGameControl * gameControl = gameNode->GetIGameControl();
if (!gameControl) return; gameControl->GetTCBKeys(poskeys,IGAME_POS));// process data
3DXI: Flexibility and Customization
Ability to fit into existing pluginsAll the major 3DXI classes provide access to
the underlying 3ds Max object:
INode * node = gameNode->GetMaxNode();
Object * obj = gameObject->GetMaxObject();
Mesh * mesh = gameMesh->GetMaxMesh();
Mtl* mat = gameMaterial->GetMaxMaterial();
Conversion from INode* to IGameNode*:
IGameNode * gameNode = GetIGameInterface()->GetIGameNode(node);
3DXI: Flexibility and Customization
Object properties are stored in different containers
IParamBlock, IParamBlock2, Custom Attributes, MXS plugins
3DXI collects all properties from different 3ds Max containers automatically
3DXI: Flexibility and Customization
And provides an interface to extract them by index or by name (as the name known to MAXScript)
IGameObject * obj = gameNode->GetIGameObject();switch(obj->GetIGameType()){ case IGameObject::IGAME_LIGHT: { IGameLight * light = (IGameLight*)obj; IGameProperty * prop =
GetIPropertyContainer()->QueryProperty(_T("color")); Point3 pvalue; if (prop) // property can be NULL, if name not found
prop->GetPropertyValue(pvalue);
}}
3DXI: Flexibility and Customization
If you use User Defined Properties: XML defined in IGameProp.xml
<ExportUserData><UserProperty><id>101</id><simplename>MyString</simplename><keyName>IGameTestString</keyName><type>string</type></UserProperty></ExportUserData>
Extract Custom Property
IGameObject * obj = gameNode->GetIGameObject();IGameSupportObject * hO = (IGameSupportObject*)obj;IPropertyContainer * cc = hO->GetIPropertyContainer();IGameProperty * prop = cc->QueryProperty(101);TCHAR * buf;if(prop)
prop->GetPropertyValue(buf);
3DXI: Flexibility and Customization Example of IGameProperty advantage
for lights: Omni - is paramblock based Skylight – is paramblock2 based Mr_Area_Omni – is scripted plugin
A single way to access property:
IGameProperty * prop =cc->QueryProperty(_T(“Multiplier"));
COLLADA-
Digital Asset Exchange Schema
COLLADA: Goals and Guidelines
COLLADA - An open Digital Asset Exchange (XML) Schema for the interactive 3D industry
Driven by Sony Computer Entertainment , Inc.
Current version is 1.4.0 https://collada.org http://www.khronos.org/
collada/
COLLADA: Goals and Guidelines COLLADA is not a game engine format Goals:
To liberate digital assets from proprietary binary formats into XML open-source format
No binary data within XML Shema Flexibility and Scalability
To provide a standard common format for digital content users
XML Schema, Specification, and API
To be a basis for common data exchange between 3D applications
User’s quote: “The days of game developers writing custom export plug-ins for modeling packages are, from what we've seen, over”
COLLADA 1.4New features.
COLLADA FX Cross-platform standard shader and effects
definition written in XML. Targets:
High-end systems running OpenGL Shading Language (GLSL) and Cg (HLSL coming),
Resource-constrained systems (OpenGL ES 1.x profile).
COLLADA Physics Rigid Body Dynamics, Rag Dolls, Contraints,
Collision Volumes. Enables data interchange between Ageia
(Novodex), Havok, Meqon, ODE and other game physics middleware
COLLADA: Library types library_animations, library_animation_clips library_geometries library_controllers library_nodes library_materials, library_images library_cameras, library_lights library_visual_scenes
library_effects
library_physics_models library_physics_materials, library_force_fields library_physics_scenes
COLLADA: Library typesExample of <animation> created by 3ds Max COLLADA exporter
<animation id="ColladaAnim.max_animation"> <animation id="Box01-Translate"> <source id="Box01-Translate-X-time"> <float_array id="Box01-Translate-X-time-array" count="2">0
3.333333</float_array> <technique_common> <accessor source="#Box01-Translate-X-time-array" count="2"> <param name="TIME" type="float"></param> </accessor> </technique_common> </source> <source id="Box01-Translate-X-value"> <float_array id="Box01-Translate-X-value-array" count="2">0
100.000000</float_array> <technique_common> <accessor source="#Box01-Translate-X-value-array" count="2"> <param name="TRANS.X" type="float"></param> </accessor> </technique_common> </source>
COLLADA: Library typesExample of <animation> (Continue)
<source id="Box01-Translate-X-interp"> <Name_array id="Box01-Translate-X-interp-array" count="2">BEZIER
BEZIER</Name_array> <technique_common> <accessor source="#Box01-Translate-X-interp-array" count="2"> <param
name="TRANS.X" type="Name"></param> </accessor> </technique_common></source><source id="Box01-Translate-X-intgt"> <float_array id="Box01-Translate-X-intgt-array" count="2">-0 -0</float_array> <technique_common> <accessor source="#Box01-Translate-X-intgt-array" count="2"> <param
name="TRANS.X" type="float"></param> </accessor> </technique_common></source><source id="Box01-Translate-X-outtgt"> <float_array id="Box01-Translate-X-outtgt-array" count="2">0 0</float_array> <technique_common> <accessor source="#Box01-Translate-X-outtgt-array" count="2"> <param name="TRANS.X" type="float"></param> </accessor> </technique_common></source>
COLLADA: Library types
Example of <animation> (Continue)
<sampler id="Box01-Translate-X-sampler"> <input semantic="INPUT"
source="#Box01-Translate-X-time"></input> <input semantic="OUTPUT"
source="#Box01-Translate-X-value"></input> <input semantic="INTERPOLATION" source="#Box01-Translate-X-
interp"></input> <input semantic="IN_TANGENT" source="#Box01-Translate-X-
intgt"></input> <input semantic="OUT_TANGENT" source="#Box01-Translate-X-
outtgt"></input> </sampler> <channel source="#Box01-Translate-X-sampler"
target="Box01/Trans.X"></channel> </animation> </animation>
COLLADA: Library typesExample of <mesh> element exported by 3ds Max COLLADA exporter
<geometry id="Box01-obj" name="Box01"> <mesh> <source id="Box01-obj-position"> <float_array id="Box01-obj-position-array" count="24">-15.000000 -15.000000 0 15.000000 -
15.000000 0 -15.000000 15.000000 0 15.000000 15.000000 0 -15.000000 -15.000000 30.000000 15.000000 -15.000000 30.000000 -15.000000 15.000000 30.000000 15.000000 15.000000 30.000000</float_array>
<technique_common> <accessor source="#Box01-obj-position-array" count="8" stride="3"> <param name="X" type="float"></param> <param name="Y" type="float"></param> <param name="Z" type="float"></param> </accessor> </technique_common> </source> <source id="Box01-obj-normal"> <float_array id="Box01-obj-normal-array" count="72">0 0 -1.000000 0 0 -1.000000 0 0 -
1.000000 0 0-1.000000 0 0 1.000000 0 0 1.000000 0 0 1.000000 0 0 1.000000 0 -1.000000 0 0 -1.000000 0 0 -1.000000 0 0 -1.000000 0 1.000000 0 0 1.000000 0 0 1.000000 0 0 1.000000 0 0 0 1.000000 0 0 1.000000 0 0 1.000000 0 0 1.000000 0 -1.000000 0 0 -1.000000 0 0 -1.000000 0 0 -1.000000 0 0</float_array>
<technique_common> <accessor source="#Box01-obj-normal-array" count="24" stride="3"> <param name="X" type="float"></param> <param name="Y" type="float"></param> <param name="Z" type="float"></param> </accessor> </technique_common> </source>
COLLADA: Library typesExample of <mesh> (Continue) <source id="Box01-obj-mapchan-1"> <float_array id="Box01-obj-mapchan-1-array" count="36">0 0 0 1.000000 0 0 0 1.000000
0 1.000000 1.000000 0 0 0 0 1.000000 0 0 0 1.000000 0 1.000000 1.000000 0 0 0 0 1.000000 0 0 0 1.000000 0 1.000000 1.000000 0</float_array>
<technique_common> <accessor source="#Box01-obj-mapchan-1-array" count="12" stride="3"> <param name="S" type="float"></param> <param name="T" type="float"></param> <param name="R" type="float"></param> </accessor> </technique_common> </source> <vertices id="Box01-obj-vertex"> <input semantic="POSITION" source="#Box01-obj-position"></input> </vertices> <polylist material="ColorMaterial_14782296" count="6"> <input semantic="VERTEX" source="#Box01-obj-vertex" offset="0"></input> <input semantic="NORMAL" source="#Box01-obj-normal" offset="1"></input> <input semantic="TEXCOORD" source="#Box01-obj-mapchan-1" offset="2"
set="1"></input> <vcount>4 4 4 4 4 4 </vcount> <p>0 0 0 2 1 2 3 2 3 1 3 1 4 4 4 5 5 5 7 6 7 6 7 6 0 8 8 1 9 9 5 10 11 4 11 10 1 12 12 3 13
13 7 14 15 5 15 14 3 16 16 2 17 17 6 18 19 7 19 18 2 20 20 0 21 21 4 22 23 6 23 22 </p> </polylist> </mesh></geometry>
COLLADA: external references.
<library_visual_scenes> <visual_scene id="Animation_max" name="Animation_max"> <node id="MyGeometry" sid="MyGeometry"
name="MyGeometry"> <translate sid="Trans">3.01744 7.61249 0 </translate> <rotate sid="RotZ">0 0 1 41.2879</rotate> <rotate sid="RotY">0 1 0 -32.6151</rotate> <rotate sid="RotX">1 0 0 -25.3289</rotate> <instance_geometry
url="./SourceGeometry.dae#MyGeometry-obj"> </instance_geometry>
</node> </visual_scene> </library_visual_scenes>
3DXI in COLLADA Export plug-in
3DXI for COLLADA M&E is fully
committed to COLLADA
COLLADA Exporter and Importer effort by Feeling Software, Inc. Personal thanks to Guillaume Laforte
3ds Max Exchange plugins for COLLADA support version 1.4.0
For 3ds Max 7 and 3ds Max 8.
3DXI for COLLADA 3DXI in action
All code snippets are taken from 3ds Max COLLADA exporter
//starting pointint ColladaExporter::DoExport(const TCHAR* name, ExpInterface* ei,
Interface* i, BOOL suppressPrompts, DWORD options){
IGameScene* pIgame = GetIGameInterface(); pIgame->InitialiseIGame(bool(options & SCENE_EXPORT_SELECTED));}
Entire scene traversal happening here All root nodes and materials (including their
children) are enumerated
3DXI for COLLADA 3DXI in action
All code snippets are taken from 3ds Max COLLADA exporter
//Create <material::effect> LibraryIGameMaterial* mat = pIgame->GetRootMaterial(i); //for all scene mtlsIGameFX* gameFX = mat->GetIGameFX();if(!gameFX) return; //not a DX Material
const TCHAR* fxFilename = gameFX->GetEffectFileName();
int np = gameFX->GetNumberOfProperties();for (int j = 0; j < np; j++){ IGameFXProperty* fxp = gameFX->GetIGameFXProperty(j); IGameProperty* property = fxp->GetIGameProperty(); // access to IGameProperty
if (fxp->GetPropertyUsage() == IGameFXProperty::IGAMEFX_LIGHT) IGameNode* lightNode = fxp->GetBindingNode(); // bound light node
}int nt = gameFX->GetNumberOfTechniques(), i = 0;do{ IGameFXTechnique* fxTechnique = gameFX->GetIGameFXTechnique(i); for (int j = 0; j < fxTechnique->GetNumberOfPasses(); j++) IGameFXPass* pass = fxTechnique->GetIGameFXPass(j);}while (++i < nt);
3DXI for COLLADA
3DXI in actionAll code snippets are taken from 3ds Max
COLLADA exporter
//extract Object dataIGameNode *node = pIgame->GetTopLevelNode(i); //for all scene nodesIGameObject* object = node->GetIGameObject();switch (object->GetIGameType()){ case IGameObject::IGAME_LIGHT: AddLightObject(node, object); break; case IGameObject::IGAME_CAMERA: AddCameraObject(node, object); break; case IGameObject::IGAME_MESH: AddMeshObject(node, object); break;}
Object properties are collected into IGamePropertyContainer at this point.
3DXI for COLLADA 3DXI in action – Access Mesh
All code snippets are taken from 3ds Max COLLADA exporter
//export MeshIGameObject* object = node->GetIGameObject();IGameMesh* mesh = (IGameMesh*) obj;mesh->InitializeData();// mesh vertex positionsfor (int i = 0; i < mesh->GetNumberOfVerts(); i++){
Point3 vert; mesh->GetVertex(i, vert, exporterOptions->ExportObjectSpace());
}// mesh normalsfor (int i = 0; i < mesh->GetNumberOfNormals(); i++){
Point3 n; mesh->GetNormal(i,n, exporterOptions->ExportObjectSpace());
}// mesh tangents and binormals for a channelint chan = 1;for (int i = 0; i < mesh->GetNumberOfTangents() ; i++){
Point3 t,b; t = mesh->GetTangent(i,chan); b = mesh->GetBinormal(i,chan);
}// mesh texture vertices for a channelfor (int i = 0; i < mesh->GetNumberOfMapVerts(chan); i++){
Point3 tv; mesh->GetMapVertex(chan, i, tv);
}
For mesh all data (vertices, normals, map channels, binrormals, etc) collected/calculated. FaceEx* structure is stored per face basis
3DXI for COLLADA
Data round-trip demonstration Mesh model textured, skinned with
animated biped as a rig
3DXI Resources
http://beta.discreet.com
http://sparks.autodesk.com
https://collada.org/public_forum
On the DVD:
3DXIHelp.chm (maxsdk\help)
3DXI Headers (maxsdk\include\IGame)
COLLADA Exporter and Importer (maxsdk\samples\Collada)
Questions ?
Top Related