2012-03-23 02:28:46 +00:00
//
// KRResource+fbx.cpp
// KREngine
//
// Created by Kearwood Gilbert on 12-03-22.
// Copyright (c) 2012 Kearwood Software. All rights reserved.
//
2013-01-11 03:21:19 +00:00
# include "KREngine-common.h"
2013-04-04 12:50:53 -07:00
# include <boost/tokenizer.hpp>
# include <boost/lexical_cast.hpp>
2012-03-23 02:28:46 +00:00
# include <fbxsdk.h>
# include "KRResource.h"
2013-01-09 22:37:23 +00:00
# include "KRMesh.h"
2012-03-28 21:58:55 +00:00
# include "KRMaterial.h"
2012-04-05 23:09:41 +00:00
# include "KRLight.h"
# include "KRPointLight.h"
# include "KRDirectionalLight.h"
# include "KRSpotLight.h"
2012-04-12 00:43:53 +00:00
# include "KRNode.h"
# include "KRScene.h"
2012-11-29 21:28:49 +00:00
# include "KRQuaternion.h"
2012-12-07 08:22:20 +00:00
# include "KRBone.h"
2013-10-06 18:56:23 -07:00
# include "KRLocator.h"
2012-12-20 01:23:57 +00:00
# include "KRBundle.h"
2013-01-09 22:37:23 +00:00
# include "KRModel.h"
2013-04-04 12:50:53 -07:00
# include "KRLODGroup.h"
2012-12-20 01:53:09 +00:00
# include "KRCollider.h"
2012-03-23 02:28:46 +00:00
# ifdef IOS_REF
# undef IOS_REF
# define IOS_REF (*(pSdkManager->GetIOSettings()))
# endif
2013-11-23 12:16:31 -08:00
void InitializeSdkObjects ( FbxManager * & pSdkManager , FbxScene * & pScene ) ;
void DestroySdkObjects ( FbxManager * pSdkManager ) ;
bool LoadScene ( FbxManager * pSdkManager , FbxDocument * pScene , const char * pFilename ) ;
2012-12-01 02:03:18 +00:00
KRAnimation * LoadAnimation ( KRContext & context , FbxAnimStack * pAnimStack ) ;
2012-12-07 00:20:06 +00:00
KRAnimationCurve * LoadAnimationCurve ( KRContext & context , FbxAnimCurve * pAnimCurve ) ;
2012-12-01 02:03:18 +00:00
KRAnimationLayer * LoadAnimationLayer ( KRContext & context , FbxAnimLayer * pAnimLayer ) ;
2013-11-23 12:16:31 -08:00
void LoadNode ( FbxScene * pFbxScene , KRNode * parent_node , FbxGeometryConverter * pGeometryConverter , FbxNode * pNode ) ;
2012-12-01 02:03:18 +00:00
//void BakeNode(KFbxNode* pNode);
2013-05-06 14:06:29 -07:00
void LoadMaterial ( KRContext & context , FbxSurfaceMaterial * pMaterial ) ;
2013-11-23 12:16:31 -08:00
void LoadMesh ( KRContext & context , FbxScene * pFbxScene , FbxGeometryConverter * pGeometryConverter , FbxMesh * pSourceMesh ) ;
KRNode * LoadMesh ( KRNode * parent_node , FbxScene * pFbxScene , FbxGeometryConverter * pGeometryConverter , FbxNode * pNode ) ;
KRNode * LoadLight ( KRNode * parent_node , FbxNode * pNode ) ;
KRNode * LoadSkeleton ( KRNode * parent_node , FbxScene * pScene , FbxNode * pNode ) ;
KRNode * LoadLocator ( KRNode * parent_node , FbxScene * pScene , FbxNode * pNode ) ;
KRNode * LoadCamera ( KRNode * parent_node , FbxNode * pNode ) ;
2012-12-07 08:22:20 +00:00
std : : string GetFbxObjectName ( FbxObject * obj ) ;
2012-03-23 02:28:46 +00:00
2012-11-29 21:28:49 +00:00
const float KRAKEN_FBX_ANIMATION_FRAMERATE = 30.0f ; // FINDME - This should be configurable
2012-12-07 00:20:06 +00:00
2012-12-07 08:22:20 +00:00
std : : string GetFbxObjectName ( FbxObject * obj )
2012-12-07 00:20:06 +00:00
{
2013-10-06 18:56:23 -07:00
bool is_locator = false ;
2013-11-23 12:16:31 -08:00
FbxNode * node = FbxCast < FbxNode > ( obj ) ;
2013-10-06 18:56:23 -07:00
if ( node ) {
2013-11-23 12:16:31 -08:00
FbxNodeAttribute : : EType attribute_type = ( node - > GetNodeAttribute ( ) - > GetAttributeType ( ) ) ;
if ( attribute_type = = FbxNodeAttribute : : eNull ) {
FbxNull * pSourceNull = ( FbxNull * ) node - > GetNodeAttribute ( ) ;
if ( pSourceNull - > Look . Get ( ) = = FbxNull : : eCross ) {
2013-10-06 18:56:23 -07:00
is_locator = true ;
}
}
}
2012-12-07 08:22:55 +00:00
// Object names from FBX files are now concatenated with the FBX numerical ID to ensure that they are unique
// TODO - This should be updated to only add a prefix or suffix if needed to make the name unique
2013-10-06 18:56:23 -07:00
if ( is_locator ) {
// We do not rename locators
return std : : string ( obj - > GetName ( ) ) ;
2013-11-23 12:16:31 -08:00
} else if ( strncmp ( obj - > GetName ( ) , " so_ " , 3 ) = = 0 ) {
// An so_ prefix indicates that this is a "Scriptable Object" that should not have the name decorated;
return obj - > GetName ( ) ;
2013-10-06 18:56:23 -07:00
} else if ( strcmp ( obj - > GetName ( ) , " default_camera " ) = = 0 ) {
2013-05-24 12:20:47 -07:00
// There is currently support for rendering from only one camera, "default_camera". We don't translate this node's name, so that animations can drive the camera
return " default_camera " ;
} else {
std : : stringstream st ;
st < < " fbx_ " ;
st < < obj - > GetUniqueID ( ) ;
if ( strlen ( obj - > GetName ( ) ) ! = 0 ) {
st < < " _ " ;
st < < obj - > GetName ( ) ;
}
return st . str ( ) ;
2012-12-07 00:20:06 +00:00
}
}
2013-05-06 14:06:29 -07:00
void KRResource : : LoadFbx ( KRContext & context , const std : : string & path )
2012-03-23 02:28:46 +00:00
{
2012-09-05 18:14:08 +00:00
KRScene * pScene = new KRScene ( context , KRResource : : GetFileBase ( path ) ) ;
2013-05-06 14:06:29 -07:00
context . getSceneManager ( ) - > add ( pScene ) ;
2012-04-12 00:43:53 +00:00
2013-11-23 12:16:31 -08:00
FbxManager * lSdkManager = NULL ;
FbxScene * pFbxScene = NULL ;
2012-03-23 02:28:46 +00:00
bool lResult ;
2012-11-30 00:32:03 +00:00
FbxGeometryConverter * pGeometryConverter = NULL ;
2012-03-23 02:28:46 +00:00
// Prepare the FBX SDK.
2012-04-12 00:43:53 +00:00
InitializeSdkObjects ( lSdkManager , pFbxScene ) ;
2012-03-23 02:28:46 +00:00
// Initialize Geometry Converter
2012-11-30 00:32:03 +00:00
pGeometryConverter = new FbxGeometryConverter ( lSdkManager ) ;
2012-03-23 02:28:46 +00:00
// Load the scene.
2012-04-12 00:43:53 +00:00
lResult = LoadScene ( lSdkManager , pFbxScene , path . c_str ( ) ) ;
2012-03-23 02:28:46 +00:00
2013-11-23 12:16:31 -08:00
FbxNode * pNode = pFbxScene - > GetRootNode ( ) ;
2012-03-23 02:28:46 +00:00
2013-05-13 13:16:25 -07:00
// ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====----
/*
2012-12-01 02:03:18 +00:00
printf ( " Baking pivots... \n " ) ;
2013-05-13 13:16:25 -07:00
2012-12-01 02:03:18 +00:00
if ( pNode ) {
pNode - > ResetPivotSetAndConvertAnimation ( ) ;
}
2013-05-13 13:16:25 -07:00
*/
2013-04-04 16:09:29 -07:00
2012-12-20 01:23:57 +00:00
// ----====---- Import Animation Layers ----====----
printf ( " \n Loading animations... \n " ) ;
2012-12-07 00:20:06 +00:00
int animation_count = pFbxScene - > GetSrcObjectCount < FbxAnimStack > ( ) ;
2012-12-02 09:31:01 +00:00
for ( int i = 0 ; i < animation_count ; i + + ) {
2012-12-20 01:23:57 +00:00
FbxAnimStack * animation = pFbxScene - > GetSrcObject < FbxAnimStack > ( i ) ;
printf ( " Animation %i of %i: %s \n " , i + 1 , animation_count , animation - > GetName ( ) ) ;
KRAnimation * new_animation = LoadAnimation ( context , animation ) ;
2013-01-11 03:21:19 +00:00
if ( new_animation ) {
context . getAnimationManager ( ) - > addAnimation ( new_animation ) ;
}
2012-12-07 00:20:06 +00:00
}
// ----====---- Import Animation Curves ----====----
2012-12-20 01:23:57 +00:00
printf ( " \n Loading animation curves... \n " ) ;
2012-12-07 00:20:06 +00:00
int curve_count = pFbxScene - > GetSrcObjectCount < FbxAnimCurve > ( ) ;
for ( int i = 0 ; i < curve_count ; i + + ) {
2012-12-20 01:23:57 +00:00
FbxAnimCurve * curve = pFbxScene - > GetSrcObject < FbxAnimCurve > ( i ) ;
printf ( " Animation Curve %i of %i: %s \n " , i + 1 , curve_count , curve - > GetName ( ) ) ;
KRAnimationCurve * new_curve = LoadAnimationCurve ( context , curve ) ;
2013-12-02 17:44:55 -08:00
//***** curves 1, 2, and 3 are x, y, z translation .. the first point holds the key frame in centimeters
// POSSIBLE UPGRADE .. grab the key frame and output it as the start location to the kranimation file
2013-01-11 03:21:19 +00:00
if ( new_curve ) {
2013-12-03 16:04:15 -08:00
printf ( " Adding a curve \n " ) ;
2013-01-11 03:21:19 +00:00
context . getAnimationCurveManager ( ) - > addAnimationCurve ( new_curve ) ;
}
2013-12-02 17:44:55 -08:00
}
2012-12-02 09:31:01 +00:00
2013-05-06 12:58:57 -07:00
// ----====---- Import Materials ----====----
int material_count = pFbxScene - > GetSrcObjectCount < FbxSurfaceMaterial > ( ) ;
printf ( " \n Loading materials... \n " ) ;
for ( int i = 0 ; i < material_count ; i + + ) {
FbxSurfaceMaterial * material = pFbxScene - > GetSrcObject < FbxSurfaceMaterial > ( i ) ;
printf ( " Material %i of %i: %s \n " , i + 1 , material_count , material - > GetName ( ) ) ;
2013-05-06 14:06:29 -07:00
LoadMaterial ( context , material ) ;
2013-05-06 12:58:57 -07:00
}
2012-12-20 01:23:57 +00:00
// ----====---- Import Meshes ----====----
int mesh_count = pFbxScene - > GetSrcObjectCount < FbxMesh > ( ) ;
printf ( " \n Loading meshes... \n " ) ;
for ( int i = 0 ; i < mesh_count ; i + + ) {
FbxMesh * mesh = pFbxScene - > GetSrcObject < FbxMesh > ( i ) ;
printf ( " Mesh %i of %i: %s \n " , i + 1 , mesh_count , mesh - > GetNode ( ) - > GetName ( ) ) ;
2013-05-24 12:20:47 -07:00
LoadMesh ( context , pFbxScene , pGeometryConverter , mesh ) ;
2012-03-23 02:28:46 +00:00
}
2012-12-20 01:23:57 +00:00
// ----====---- Import Textures ----====----
int texture_count = pFbxScene - > GetSrcObjectCount < FbxFileTexture > ( ) ;
printf ( " \n Loading textures... \n " ) ;
for ( int i = 0 ; i < texture_count ; i + + ) {
FbxFileTexture * texture = pFbxScene - > GetSrcObject < FbxFileTexture > ( i ) ;
const char * file_name = texture - > GetFileName ( ) ;
printf ( " Texture %i of %i: %s \n " , i + 1 , texture_count , ( KRResource : : GetFileBase ( file_name ) + " . " + KRResource : : GetFileExtension ( file_name ) ) . c_str ( ) ) ;
context . loadResource ( file_name ) ;
}
2013-04-04 16:09:29 -07:00
// ----====---- Import Scene Graph Nodes ----====----
printf ( " \n Loading scene graph... \n " ) ;
if ( pNode )
{
for ( int i = 0 ; i < pNode - > GetChildCount ( ) ; i + + )
{
2013-05-06 14:06:29 -07:00
LoadNode ( pFbxScene , pScene - > getRootNode ( ) , pGeometryConverter , pNode - > GetChild ( i ) ) ;
2013-04-04 16:09:29 -07:00
}
}
2012-12-07 00:20:06 +00:00
2013-01-24 13:52:26 -08:00
2012-12-20 01:23:57 +00:00
2013-05-06 14:06:29 -07:00
DestroySdkObjects ( lSdkManager ) ;
2012-03-23 02:28:46 +00:00
}
2013-11-23 12:16:31 -08:00
void InitializeSdkObjects ( FbxManager * & pSdkManager , FbxScene * & pScene )
2012-03-23 02:28:46 +00:00
{
// The first thing to do is to create the FBX SDK manager which is the
// object allocator for almost all the classes in the SDK.
2013-11-23 12:16:31 -08:00
pSdkManager = FbxManager : : Create ( ) ;
2012-03-23 02:28:46 +00:00
if ( ! pSdkManager )
{
printf ( " Unable to create the FBX SDK manager \n " ) ;
exit ( 0 ) ;
}
// create an IOSettings object
2013-11-23 12:16:31 -08:00
FbxIOSettings * ios = FbxIOSettings : : Create ( pSdkManager , IOSROOT ) ;
2012-03-23 02:28:46 +00:00
pSdkManager - > SetIOSettings ( ios ) ;
// Load plugins from the executable directory
2013-11-23 12:16:31 -08:00
FbxString lPath = FbxGetApplicationDirectory ( ) ;
# if TARGET_OS_WIN32
FbxString lExtension = " dll " ;
# elif TARGET_OS_MAC
FbxString lExtension = " dylib " ;
# elif TARGET_OS_UNIX
FbxString lExtension = " so " ;
# elif
# error Unsupported Platform
2012-03-23 02:28:46 +00:00
# endif
pSdkManager - > LoadPluginsDirectory ( lPath . Buffer ( ) , lExtension . Buffer ( ) ) ;
// Create the entity that will hold the scene.
2013-11-23 12:16:31 -08:00
pScene = FbxScene : : Create ( pSdkManager , " " ) ;
2012-03-23 02:28:46 +00:00
}
2013-11-23 12:16:31 -08:00
void DestroySdkObjects ( FbxManager * pSdkManager )
2012-03-23 02:28:46 +00:00
{
// Delete the FBX SDK manager. All the objects that have been allocated
// using the FBX SDK manager and that haven't been explicitly destroyed
// are automatically destroyed at the same time.
if ( pSdkManager ) pSdkManager - > Destroy ( ) ;
pSdkManager = NULL ;
}
2013-11-23 12:16:31 -08:00
bool LoadScene ( FbxManager * pSdkManager , FbxDocument * pScene , const char * pFilename )
2012-03-23 02:28:46 +00:00
{
int lFileMajor , lFileMinor , lFileRevision ;
int lSDKMajor , lSDKMinor , lSDKRevision ;
//int lFileFormat = -1;
2012-12-01 02:03:18 +00:00
int lAnimStackCount ;
2012-03-23 02:28:46 +00:00
bool lStatus ;
char lPassword [ 1024 ] ;
// Get the file version number generate by the FBX SDK.
2013-11-23 12:16:31 -08:00
FbxManager : : GetFileFormatVersion ( lSDKMajor , lSDKMinor , lSDKRevision ) ;
2012-03-23 02:28:46 +00:00
// Create an importer.
2013-11-23 12:16:31 -08:00
FbxImporter * lImporter = FbxImporter : : Create ( pSdkManager , " " ) ;
2012-03-23 02:28:46 +00:00
// Initialize the importer by providing a filename.
const bool lImportStatus = lImporter - > Initialize ( pFilename , - 1 , pSdkManager - > GetIOSettings ( ) ) ;
lImporter - > GetFileVersion ( lFileMajor , lFileMinor , lFileRevision ) ;
if ( ! lImportStatus )
{
2013-11-23 12:16:31 -08:00
FbxStatus & status = lImporter - > GetStatus ( ) ;
2012-03-23 02:28:46 +00:00
printf ( " Call to KFbxImporter::Initialize() failed. \n " ) ;
2013-11-23 12:16:31 -08:00
printf ( " Error returned: %s \n \n " , status . GetErrorString ( ) ) ;
2012-03-23 02:28:46 +00:00
2013-11-23 12:16:31 -08:00
if ( status . GetCode ( ) = = FbxStatus : : EStatusCode : : eInvalidFileVersion )
2012-03-23 02:28:46 +00:00
{
printf ( " FBX version number for this FBX SDK is %d.%d.%d \n " , lSDKMajor , lSDKMinor , lSDKRevision ) ;
printf ( " FBX version number for file %s is %d.%d.%d \n \n " , pFilename , lFileMajor , lFileMinor , lFileRevision ) ;
}
return false ;
}
printf ( " FBX version number for this FBX SDK is %d.%d.%d \n " , lSDKMajor , lSDKMinor , lSDKRevision ) ;
2012-11-29 21:28:49 +00:00
if ( ! lImporter - > IsFBX ( ) ) {
printf ( " ERROR Unrecognized FBX File \n " ) ;
return false ;
}
printf ( " FBX version number for file %s is %d.%d.%d \n \n " , pFilename , lFileMajor , lFileMinor , lFileRevision ) ;
// From this point, it is possible to access animation stack information without
// the expense of loading the entire file.
printf ( " Animation Stack Information \n " ) ;
lAnimStackCount = lImporter - > GetAnimStackCount ( ) ;
printf ( " Number of Animation Stacks: %d \n " , lAnimStackCount ) ;
printf ( " Current Animation Stack: \" %s \" \n " , lImporter - > GetActiveAnimStackName ( ) . Buffer ( ) ) ;
printf ( " \n " ) ;
2012-03-23 02:28:46 +00:00
2012-11-29 21:28:49 +00:00
// Set the import states. By default, the import states are always set to
// true. The code below shows how to change these states.
IOS_REF . SetBoolProp ( IMP_FBX_MATERIAL , true ) ;
IOS_REF . SetBoolProp ( IMP_FBX_TEXTURE , true ) ;
IOS_REF . SetBoolProp ( IMP_FBX_LINK , true ) ;
IOS_REF . SetBoolProp ( IMP_FBX_SHAPE , true ) ;
IOS_REF . SetBoolProp ( IMP_FBX_GOBO , true ) ;
IOS_REF . SetBoolProp ( IMP_FBX_ANIMATION , true ) ;
IOS_REF . SetBoolProp ( IMP_FBX_GLOBAL_SETTINGS , true ) ;
2012-03-23 02:28:46 +00:00
// Import the scene.
lStatus = lImporter - > Import ( pScene ) ;
2013-11-23 12:16:31 -08:00
if ( lStatus = = false & & lImporter - > GetStatus ( ) . GetCode ( ) = = FbxStatus : : EStatusCode : : ePasswordError )
2012-03-23 02:28:46 +00:00
{
printf ( " Please enter password: " ) ;
lPassword [ 0 ] = ' \0 ' ;
scanf ( " %s " , lPassword ) ;
2013-11-23 12:16:31 -08:00
FbxString lString ( lPassword ) ;
2012-03-23 02:28:46 +00:00
IOS_REF . SetStringProp ( IMP_FBX_PASSWORD , lString ) ;
IOS_REF . SetBoolProp ( IMP_FBX_PASSWORD_ENABLE , true ) ;
lStatus = lImporter - > Import ( pScene ) ;
2013-11-23 12:16:31 -08:00
if ( lStatus = = false & & lImporter - > GetStatus ( ) . GetCode ( ) = = FbxStatus : : EStatusCode : : ePasswordError )
2012-03-23 02:28:46 +00:00
{
printf ( " \n Password is wrong, import aborted. \n " ) ;
}
}
2012-12-01 02:03:18 +00:00
// // ----====---- Start: Bake pivots into transforms, as Kraken doesn't support them directly ----====----
//
// printf("Baking pivots...\n");
// KFbxNode* pNode = ((KFbxScene*)pScene)->GetRootNode();
//// BakeNode(pNode);
//
// for(i = 0; i < lAnimStackCount; i++)
// {
// KFbxTakeInfo* lTakeInfo = lImporter->GetTakeInfo(i);
//
// printf(" Animation: \"%s\"\n", lTakeInfo->mName.Buffer());
//
// //pNode->ConvertPivotAnimationRecursive(lTakeInfo->mName.Buffer(), KFbxNode::eDestinationPivot, KRAKEN_FBX_ANIMATION_FRAMERATE);
// pNode->ResetPivotSetAndConvertAnimation();
//
// }
//// pNode->ConvertPivotAnimationRecursive(NULL, KFbxNode::eDestinationPivot, KRAKEN_FBX_ANIMATION_FRAMERATE);
//// pNode->UpdatePropertiesFromPivotsAndLimits();
//
// // ----====---- End: Bake pivots into transforms, as Kraken doesn't support them directly ----====----
// // ----====---- Bake pivots into transforms, as Kraken doesn't support them directly ----====----
//
// printf("Baking pivots...\n");
// KFbxNode* pNode = ((KFbxScene*)pScene)->GetRootNode();
// if(pNode) {
// pNode->ResetPivotSetAndConvertAnimation();
// }
2012-11-29 21:28:49 +00:00
2012-03-23 02:28:46 +00:00
// Destroy the importer.
lImporter - > Destroy ( ) ;
return lStatus ;
}
2012-12-01 02:03:18 +00:00
KRAnimation * LoadAnimation ( KRContext & context , FbxAnimStack * pAnimStack )
{
printf ( " Loading animation: \" %s \" \n " , pAnimStack - > GetName ( ) ) ;
KRAnimation * new_animation = new KRAnimation ( context , pAnimStack - > GetName ( ) ) ;
int cLayers = pAnimStack - > GetMemberCount < FbxAnimLayer > ( ) ;
2012-12-07 01:49:17 +00:00
new_animation - > setDuration ( pAnimStack - > LocalStop . Get ( ) . GetSecondDouble ( ) ) ;
2012-12-01 02:03:18 +00:00
for ( int iLayer = 0 ; iLayer < cLayers ; iLayer + + ) {
new_animation - > addLayer ( LoadAnimationLayer ( context , pAnimStack - > GetMember < FbxAnimLayer > ( iLayer ) ) ) ;
2012-11-29 21:28:49 +00:00
}
2012-12-01 02:03:18 +00:00
return new_animation ;
2012-11-29 21:28:49 +00:00
}
2012-12-07 00:20:06 +00:00
KRAnimationCurve * LoadAnimationCurve ( KRContext & context , FbxAnimCurve * pAnimCurve )
{
2012-12-07 08:22:20 +00:00
std : : string name = GetFbxObjectName ( pAnimCurve ) ;
2012-12-07 00:20:06 +00:00
printf ( " Loading animation curve: \" %s \" \n " , name . c_str ( ) ) ;
FbxTimeSpan time_span ;
if ( ! pAnimCurve - > GetTimeInterval ( time_span ) ) {
printf ( " ERROR: Failed to get time interval. \n " ) ;
return NULL ;
}
2013-08-31 19:22:37 -07:00
float dest_frame_rate = 30.0f ; // FINDME, TODO - This needs to be dynamic
int frame_start = time_span . GetStart ( ) . GetSecondDouble ( ) * dest_frame_rate ;
int frame_count = ( time_span . GetStop ( ) . GetSecondDouble ( ) * dest_frame_rate ) - frame_start ;
2012-12-07 00:20:06 +00:00
2013-12-02 17:44:55 -08:00
printf ( " animation start %d and frame count %d \n " , frame_start , frame_count ) ;
2012-12-07 00:20:06 +00:00
KRAnimationCurve * new_curve = new KRAnimationCurve ( context , name ) ;
2013-08-31 19:22:37 -07:00
new_curve - > setFrameRate ( dest_frame_rate ) ;
2012-12-07 00:20:06 +00:00
new_curve - > setFrameStart ( frame_start ) ;
new_curve - > setFrameCount ( frame_count ) ;
// Resample animation curve
int last_frame = 0 ; // Used by FBX sdk for faster keyframe searches
for ( int frame_number = 0 ; frame_number < frame_count ; frame_number + + ) {
2013-08-31 19:22:37 -07:00
float frame_seconds = ( frame_start + frame_number ) / dest_frame_rate ;
2012-12-07 00:20:06 +00:00
FbxTime frame_time ;
frame_time . SetSecondDouble ( frame_seconds ) ;
float frame_value = pAnimCurve - > Evaluate ( frame_time , & last_frame ) ;
2013-12-02 17:44:55 -08:00
// printf(" Frame %i / %i: %.6f\n", frame_number, frame_count, frame_value);
if ( 0 = = frame_number ) printf ( " Value at starting key frame = %3.3f \n " , frame_value ) ;
new_curve - > setValue ( frame_number + frame_start , frame_value ) ;
// BUG FIX Dec 2, 2013 .. changed frame_number to frame_number+frame_start
// setValue(frame_number, frame_value) clamps the frame_number range between frame_start : frame_start+frame_count
2012-12-07 00:20:06 +00:00
}
return new_curve ;
}
2012-12-01 02:03:18 +00:00
KRAnimationLayer * LoadAnimationLayer ( KRContext & context , FbxAnimLayer * pAnimLayer )
{
KRAnimationLayer * new_layer = new KRAnimationLayer ( context ) ;
new_layer - > setName ( pAnimLayer - > GetName ( ) ) ;
2012-12-02 09:31:01 +00:00
new_layer - > setWeight ( pAnimLayer - > Weight . Get ( ) / 100.0f ) ;
2012-12-01 02:03:18 +00:00
switch ( pAnimLayer - > BlendMode . Get ( ) ) {
case FbxAnimLayer : : eBlendAdditive :
new_layer - > setBlendMode ( KRAnimationLayer : : KRENGINE_ANIMATION_BLEND_MODE_ADDITIVE ) ;
break ;
case FbxAnimLayer : : eBlendOverride :
new_layer - > setBlendMode ( KRAnimationLayer : : KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE ) ;
break ;
case FbxAnimLayer : : eBlendOverridePassthrough :
new_layer - > setBlendMode ( KRAnimationLayer : : KRENGINE_ANIMATION_BLEND_MODE_OVERRIDE_PASSTHROUGH ) ;
break ;
}
switch ( pAnimLayer - > RotationAccumulationMode . Get ( ) ) {
case FbxAnimLayer : : eRotationByLayer :
new_layer - > setRotationAccumulationMode ( KRAnimationLayer : : KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_LAYER ) ;
break ;
case FbxAnimLayer : : eRotationByChannel :
new_layer - > setRotationAccumulationMode ( KRAnimationLayer : : KRENGINE_ANIMATION_ROTATION_ACCUMULATION_BY_CHANNEL ) ;
break ;
}
switch ( pAnimLayer - > ScaleAccumulationMode . Get ( ) ) {
case FbxAnimLayer : : eScaleAdditive :
new_layer - > setScaleAccumulationMode ( KRAnimationLayer : : KRENGINE_ANIMATION_SCALE_ACCUMULATION_ADDITIVE ) ;
break ;
case FbxAnimLayer : : eScaleMultiply :
new_layer - > setScaleAccumulationMode ( KRAnimationLayer : : KRENGINE_ANIMATION_SCALE_ACCUMULATION_MULTIPLY ) ;
break ;
}
2012-12-02 09:31:01 +00:00
2012-12-01 02:03:18 +00:00
return new_layer ;
}
//
//void BakeNode(KFbxNode *pNode) {
//
// pNode->SetPivotState(KFbxNode::eSourcePivot, KFbxNode::ePivotActive);
// pNode->SetPivotState(KFbxNode::eDestinationPivot, KFbxNode::ePivotActive);
2012-12-12 09:32:53 +00:00
//
2012-12-01 02:03:18 +00:00
// // Pass the current value to the source pivot.
//// * - Rotation offset (Roff)
//// * - Rotation pivot (Rp)
//// * - Pre-rotation (Rpre)
//// * - Post-rotation (Rpost)
//// * - Scaling offset (Soff)
//// * - Scaling pivot (Sp)
//// * - Geometric translation (Gt)
//// * - Geometric rotation (Gr)
//// * - Geometric scaling (Gs)
// /*
// pNode->SetPostRotation(KFbxNode::eSourcePivot, pNode->PostRotation.Get());
// pNode->SetPreRotation(KFbxNode::eSourcePivot, pNode->PreRotation.Get());
// pNode->SetRotationOffset(KFbxNode::eSourcePivot, pNode->RotationOffset.Get());
// pNode->SetScalingOffset(KFbxNode::eSourcePivot, pNode->ScalingOffset.Get());
// pNode->SetRotationPivot(KFbxNode::eSourcePivot, pNode->RotationPivot.Get());
// pNode->SetScalingPivot(KFbxNode::eSourcePivot, pNode->ScalingPivot.Get());
// pNode->SetGeometricRotation(KFbxNode::eSourcePivot, pNode->GeometricRotation.Get());
// pNode->SetGeometricTranslation(KFbxNode::eSourcePivot, pNode->GeometricTranslation.Get());
// pNode->SetGeometricScaling(KFbxNode::eSourcePivot, pNode->GeometricScaling.Get());
// pNode->SetRotationOrder(KFbxNode::eSourcePivot, pNode->RotationOrder.Get());
// */
//
// // We want to set all these to 0 and bake them into the transforms.
// KFbxVector4 lZero(0.0, 0.0, 0.0);
// KFbxVector4 lOne(1.0, 1.0, 1.0);
// pNode->SetPostRotation(KFbxNode::eDestinationPivot, lZero);
// pNode->SetPreRotation(KFbxNode::eDestinationPivot, lZero);
// pNode->SetRotationOffset(KFbxNode::eDestinationPivot, lZero);
// pNode->SetScalingOffset(KFbxNode::eDestinationPivot, lZero);
// pNode->SetRotationPivot(KFbxNode::eDestinationPivot, lZero);
// pNode->SetScalingPivot(KFbxNode::eDestinationPivot, lZero);
// pNode->SetGeometricRotation(KFbxNode::eDestinationPivot, lZero);
// pNode->SetGeometricTranslation(KFbxNode::eDestinationPivot, lZero);
// pNode->SetGeometricScaling(KFbxNode::eDestinationPivot, lOne);
// pNode->SetRotationOrder(KFbxNode::eDestinationPivot, eEULER_XYZ);
//
//
// /*
// FbxVector4 lZero(0,0,0);
// FbxVector4 lOne(1,1,1);
// pNode->SetPivotState(FbxNode::eSourcePivot, FbxNode::ePivotActive);
// pNode->SetPivotState(FbxNode::eDestinationPivot, FbxNode::ePivotActive);
//
// EFbxRotationOrder lRotationOrder;
// pNode->GetRotationOrder(FbxNode::eSourcePivot , lRotationOrder);
// pNode->SetRotationOrder(FbxNode::eDestinationPivot , lRotationOrder);
//
// //For cameras and lights (without targets) let's compensate the postrotation.
// if( pNode->GetCamera() || pNode->GetLight() )
// {
// if( !pNode->GetTarget() )
// {
// FbxVector4 lRV(90, 0, 0);
// if( pNode->GetCamera() )
// lRV.Set(0, 90, 0);
//
// FbxVector4 prV = pNode->GetPostRotation(FbxNode::eSourcePivot);
// FbxAMatrix lSourceR;
// FbxAMatrix lR(lZero, lRV, lOne);
// FbxVector4 res = prV;
//
// // Rotation order don't affect post rotation, so just use the default XYZ order
// FbxRotationOrder rOrder;
// rOrder.V2M(lSourceR, res);
//
// lR = lSourceR * lR;
// rOrder.M2V(res, lR);
// prV = res;
// pNode->SetPostRotation(FbxNode::eSourcePivot, prV);
// pNode->SetRotationActive(true);
// }
//
// // Point light do not need to be adjusted (since they radiate in all the directions).
// if( pNode->GetLight() && pNode->GetLight()->LightType.Get() == FbxLight::ePoint )
// {
// pNode->SetPostRotation(FbxNode::eSourcePivot, FbxVector4(0,0,0,0));
// }
// }
// // apply Pre rotations only on bones / end of chains
// if( pNode->GetNodeAttribute() && pNode->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eSkeleton
// || (pNode->GetMarker() && pNode->GetMarker()->GetType() == FbxMarker::eEffectorFK)
// || (pNode->GetMarker() && pNode->GetMarker()->GetType() == FbxMarker::eEffectorIK) )
// {
// if( pNode->GetRotationActive() )
// {
// pNode->SetPreRotation(FbxNode::eDestinationPivot, pNode->GetPreRotation(FbxNode::eSourcePivot));
// }
//
// // No pivots on bones
// pNode->SetRotationPivot(FbxNode::eDestinationPivot, lZero);
// pNode->SetScalingPivot(FbxNode::eDestinationPivot, lZero);
// pNode->SetRotationOffset(FbxNode::eDestinationPivot,lZero);
// pNode->SetScalingOffset(FbxNode::eDestinationPivot, lZero);
// }
// else
// {
// // any other type: no pre-rotation support but...
// pNode->SetPreRotation(FbxNode::eDestinationPivot, lZero);
//
// // support for rotation and scaling pivots.
// pNode->SetRotationPivot(FbxNode::eDestinationPivot, pNode->GetRotationPivot(FbxNode::eSourcePivot));
// pNode->SetScalingPivot(FbxNode::eDestinationPivot, pNode->GetScalingPivot(FbxNode::eSourcePivot));
// // Rotation and scaling offset are supported
// pNode->SetRotationOffset(FbxNode::eDestinationPivot, pNode->GetRotationOffset(FbxNode::eSourcePivot));
// pNode->SetScalingOffset(FbxNode::eDestinationPivot, pNode->GetScalingOffset(FbxNode::eSourcePivot));
// //
// // If we don't "support" scaling pivots, we can simply do:
// // pNode->SetRotationPivot(FbxNode::eDestinationPivot, lZero);
// // pNode->SetScalingPivot(FbxNode::eDestinationPivot, lZero);
// }
// */
//
// // Bake child nodes
// for(int i = 0; i < pNode->GetChildCount(); i++)
// {
// BakeNode(pNode->GetChild(i));
// }
//}
2013-11-23 12:16:31 -08:00
void LoadNode ( FbxScene * pFbxScene , KRNode * parent_node , FbxGeometryConverter * pGeometryConverter , FbxNode * pNode ) {
FbxVector4 lTmpVector ;
2012-11-29 21:28:49 +00:00
pNode - > UpdatePropertiesFromPivotsAndLimits ( ) ;
2012-12-07 08:22:20 +00:00
2013-04-04 17:53:39 -07:00
FbxSystemUnit system_unit = pFbxScene - > GetGlobalSettings ( ) . GetSystemUnit ( ) ;
2012-11-29 21:28:49 +00:00
// Transform = T * Roff * Rp * Rpre * R * Rpost * inverse(Rp) * Soff * Sp * S * inverse(Sp)
2012-12-02 09:31:01 +00:00
2013-12-03 16:04:15 -08:00
int node_has_n_points = 0 ; // this will be 3 if the node_frame_key_position is complete after the import animated properties loop
KRVector3 node_key_frame_position = KRVector3 ( 0.0 , 0.0 , 0.0 ) ;
// ADDED 3, 2013 by Peter to store the key frame (start location) of an animation
// the x, y, z translation position of the animation will be extracted from the curves
// as they are added to the animation layer in the loop below ..
2012-12-02 10:58:59 +00:00
// Import animated properties
int animation_count = pFbxScene - > GetSrcObjectCount < FbxAnimStack > ( ) ;
for ( int i = 0 ; i < animation_count ; i + + ) {
// FbxAnimStack* pAnimStack = FbxCast<FbxAnimStack>(pFbxScene->GetSrcObject(FBX_TYPE(FbxAnimStack), i));
FbxAnimStack * pAnimStack = pFbxScene - > GetSrcObject < FbxAnimStack > ( i ) ;
KRAnimation * pAnimation = parent_node - > getContext ( ) . getAnimationManager ( ) - > getAnimation ( pAnimStack - > GetName ( ) ) ;
2013-01-09 22:59:33 +00:00
if ( pAnimation ) {
2013-12-03 16:04:15 -08:00
int cLayers = pAnimStack - > GetMemberCount < FbxAnimLayer > ( ) ;
2013-01-09 22:59:33 +00:00
for ( int iLayer = 0 ; iLayer < cLayers ; iLayer + + ) {
FbxAnimLayer * pFbxAnimLayer = pAnimStack - > GetMember < FbxAnimLayer > ( iLayer ) ;
// float weight = pFbxAnimLayer->Weight.Get();
KRAnimationLayer * pAnimationLayer = pAnimation - > getLayer ( pFbxAnimLayer - > GetName ( ) ) ;
FbxAnimCurve * pAnimCurve = pNode - > LclRotation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_X ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_ROTATE_X ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > LclRotation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Y ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_ROTATE_Y ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > LclRotation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Z ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_ROTATE_Z ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > LclTranslation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_X ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_TRANSLATE_X ) ;
2013-12-03 16:04:15 -08:00
KRAnimationCurve * curve = new_attribute - > getCurve ( ) ;
node_key_frame_position . x = curve - > getValue ( curve - > getFrameStart ( ) ) ;
node_has_n_points + + ;
// ADDED Dec 3, 2013 by Peter to extract start location key frame
pAnimationLayer - > addAttribute ( new_attribute ) ;
2013-01-09 22:59:33 +00:00
}
pAnimCurve = pNode - > LclTranslation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Y ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Y ) ;
2013-12-03 16:04:15 -08:00
KRAnimationCurve * curve = new_attribute - > getCurve ( ) ;
node_key_frame_position . y = curve - > getValue ( curve - > getFrameStart ( ) ) ;
node_has_n_points + + ;
// ADDED Dec 3, 2013 by Peter to extract start location key frame
2013-01-09 22:59:33 +00:00
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > LclTranslation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Z ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_TRANSLATE_Z ) ;
2013-12-03 16:04:15 -08:00
KRAnimationCurve * curve = new_attribute - > getCurve ( ) ;
node_key_frame_position . z = curve - > getValue ( curve - > getFrameStart ( ) ) ;
node_has_n_points + + ;
// ADDED Dec 3, 2013 by Peter to extract start location key frame
2013-01-09 22:59:33 +00:00
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > LclScaling . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_X ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_SCALE_X ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > LclScaling . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Y ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_SCALE_Y ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > LclScaling . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Z ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_SCALE_Z ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
2013-05-24 12:20:47 -07:00
pAnimCurve = pNode - > PreRotation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_X ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_X ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > PreRotation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Y ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Y ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > PreRotation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Z ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_PRE_ROTATION_Z ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > PostRotation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_X ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_X ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > PostRotation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Y ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Y ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > PostRotation . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Z ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_POST_ROTATION_Z ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > RotationPivot . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_X ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_X ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > RotationPivot . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Y ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Y ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > RotationPivot . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Z ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_ROTATION_PIVOT_Z ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > ScalingPivot . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_X ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_X ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > ScalingPivot . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Y ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Y ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > ScalingPivot . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Z ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_SCALE_PIVOT_Z ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > RotationOffset . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_X ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_X ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > RotationOffset . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Y ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Y ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > RotationOffset . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Z ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_ATTRIBUTE_ROTATE_OFFSET_Z ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > ScalingOffset . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_X ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_SCALE_OFFSET_X ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > ScalingOffset . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Y ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_SCALE_OFFSET_Y ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
pAnimCurve = pNode - > ScalingOffset . GetCurve ( pFbxAnimLayer , FBXSDK_CURVENODE_COMPONENT_Z ) ;
if ( pAnimCurve ) {
KRAnimationAttribute * new_attribute = new KRAnimationAttribute ( parent_node - > getContext ( ) ) ;
new_attribute - > setCurveName ( GetFbxObjectName ( pAnimCurve ) ) ;
new_attribute - > setTargetName ( GetFbxObjectName ( pNode ) ) ;
new_attribute - > setTargetAttribute ( KRNode : : KRENGINE_NODE_SCALE_OFFSET_Z ) ;
pAnimationLayer - > addAttribute ( new_attribute ) ;
}
2012-12-02 10:58:59 +00:00
}
}
}
2013-12-03 16:04:15 -08:00
2013-11-23 12:16:31 -08:00
FbxDouble3 local_rotation = pNode - > LclRotation . Get ( ) ; // pNode->GetGeometricRotation(KFbxNode::eSourcePivot);
FbxDouble3 local_translation = pNode - > LclTranslation . Get ( ) ; // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot);
FbxDouble3 local_scale = pNode - > LclScaling . Get ( ) ; // pNode->GetGeometricScaling(KFbxNode::eSourcePivot);
2012-09-13 20:09:19 +00:00
2013-05-24 12:20:47 -07:00
bool rotation_active = pNode - > RotationActive . Get ( ) ;
2013-11-23 12:16:31 -08:00
FbxDouble3 post_rotation = pNode - > PostRotation . Get ( ) ;
FbxDouble3 pre_rotation = pNode - > PreRotation . Get ( ) ;
FbxDouble3 rotation_offset = pNode - > RotationOffset . Get ( ) ;
FbxDouble3 scaling_offset = pNode - > ScalingOffset . Get ( ) ;
FbxDouble3 rotation_pivot = pNode - > RotationPivot . Get ( ) ;
FbxDouble3 scaling_pivot = pNode - > ScalingPivot . Get ( ) ;
FbxDouble3 geometric_rotation = pNode - > GeometricRotation . Get ( ) ;
FbxDouble3 geometric_translation = pNode - > GeometricTranslation . Get ( ) ;
FbxDouble3 geometric_scaling = pNode - > GeometricScaling . Get ( ) ;
EFbxRotationOrder rotation_order = pNode - > RotationOrder . Get ( ) ;
2012-12-01 02:03:18 +00:00
2013-11-23 12:16:31 -08:00
FbxVector4 lZero ( 0.0 , 0.0 , 0.0 ) ;
FbxVector4 lOne ( 1.0 , 1.0 , 1.0 ) ;
2012-12-01 02:03:18 +00:00
assert ( geometric_rotation = = lZero ) ;
assert ( geometric_translation = = lZero ) ;
assert ( geometric_scaling = = lOne ) ;
assert ( rotation_order = = eEulerXYZ ) ;
2013-12-03 16:04:15 -08:00
// FINDME - node_key_frame_position contains the key frame (start location) for an animation node
// node_has_n_points
// node_key_frame_position
if ( 3 = = node_has_n_points )
printf ( " key frame at %2.3f, %2.3f, %2.3f \n " ,
node_key_frame_position . x ,
node_key_frame_position . y ,
node_key_frame_position . z ) ;
//
// The animation curve data is output to the KRNode::KRENGINE_NODE_ATTRIBUTE_TRANSLATE_ X, Y, Z attribute targets
// The actor scripts 'move' command modifies the node's world translations using setWorldTranslation()
//
// QUESTION - where should we store the key frame within the node to make sure it is output into the KRBundle ??
// do we store it as node_local or store it as the world translation? or somewhere else ??
//
2012-12-02 10:58:59 +00:00
2012-11-29 21:28:49 +00:00
KRVector3 node_translation = KRVector3 ( local_translation [ 0 ] , local_translation [ 1 ] , local_translation [ 2 ] ) ; // T * Roff * Rp
2012-12-01 02:03:18 +00:00
KRVector3 node_rotation = KRVector3 ( local_rotation [ 0 ] , local_rotation [ 1 ] , local_rotation [ 2 ] ) / 180.0 * M_PI ;
2012-11-29 21:28:49 +00:00
KRVector3 node_scale = KRVector3 ( local_scale [ 0 ] , local_scale [ 1 ] , local_scale [ 2 ] ) ;
2013-05-13 13:16:25 -07:00
KRVector3 node_rotation_offset = KRVector3 ( rotation_offset [ 0 ] , rotation_offset [ 1 ] , rotation_offset [ 2 ] ) ;
KRVector3 node_scaling_offset = KRVector3 ( scaling_offset [ 0 ] , scaling_offset [ 1 ] , scaling_offset [ 2 ] ) ;
KRVector3 node_rotation_pivot = KRVector3 ( rotation_pivot [ 0 ] , rotation_pivot [ 1 ] , rotation_pivot [ 2 ] ) ;
KRVector3 node_scaling_pivot = KRVector3 ( scaling_pivot [ 0 ] , scaling_pivot [ 1 ] , scaling_pivot [ 2 ] ) ;
2013-05-24 12:20:47 -07:00
KRVector3 node_pre_rotation , node_post_rotation ;
if ( rotation_active ) {
node_pre_rotation = KRVector3 ( pre_rotation [ 0 ] , pre_rotation [ 1 ] , pre_rotation [ 2 ] ) / 180.0 * M_PI ;
node_post_rotation = KRVector3 ( post_rotation [ 0 ] , post_rotation [ 1 ] , post_rotation [ 2 ] ) / 180.0 * M_PI ;
} else {
node_pre_rotation = KRVector3 : : Zero ( ) ;
node_post_rotation = KRVector3 : : Zero ( ) ;
}
2013-05-13 13:16:25 -07:00
2012-12-01 02:03:18 +00:00
// printf(" Local Translation: %f %f %f\n", local_translation[0], local_translation[1], local_translation[2]);
// printf(" Local Rotation: %f %f %f\n", local_rotation[0], local_rotation[1], local_rotation[2]);
// printf(" Local Scaling: %f %f %f\n", local_scale[0], local_scale[1], local_scale[2]);
2012-11-03 02:57:35 +00:00
2013-11-23 12:16:31 -08:00
FbxNodeAttribute : : EType attribute_type = ( pNode - > GetNodeAttribute ( ) - > GetAttributeType ( ) ) ;
if ( attribute_type = = FbxNodeAttribute : : eLODGroup ) {
2013-04-04 12:50:53 -07:00
std : : string name = GetFbxObjectName ( pNode ) ;
FbxLODGroup * fbx_lod_group = ( FbxLODGroup * ) pNode - > GetNodeAttribute ( ) ; // FbxCast<FbxLODGroup>(pNode);
2013-04-08 21:40:53 -07:00
bool use_world_space_units = fbx_lod_group - > WorldSpace . Get ( ) ;
2013-04-04 12:50:53 -07:00
float group_min_distance = 0.0f ;
float group_max_distance = 0.0f ;
if ( fbx_lod_group - > MinMaxDistance . Get ( ) ) {
group_min_distance = fbx_lod_group - > MinDistance . Get ( ) ;
group_max_distance = fbx_lod_group - > MinDistance . Get ( ) ;
}
2013-04-04 16:09:29 -07:00
2013-04-08 21:40:53 -07:00
KRAABB reference_bounds ;
2013-04-04 12:50:53 -07:00
// Create a lod_group node for each fbx child node
int child_count = pNode - > GetChildCount ( ) ;
for ( int i = 0 ; i < child_count ; i + + )
{
float min_distance = 0 ;
float max_distance = 0 ; // 0 for max_distance means infinity
FbxLODGroup : : EDisplayLevel display_level ;
fbx_lod_group - > GetDisplayLevel ( i , display_level ) ;
switch ( display_level ) {
case FbxLODGroup : : eUseLOD :
if ( i > 0 ) {
FbxDistance d ;
fbx_lod_group - > GetThreshold ( i - 1 , d ) ;
2013-04-04 17:53:39 -07:00
min_distance = d . valueAs ( system_unit ) ;
2013-04-04 12:50:53 -07:00
}
if ( i < child_count - 1 ) {
FbxDistance d ;
fbx_lod_group - > GetThreshold ( i , d ) ;
2013-04-04 17:53:39 -07:00
max_distance = d . valueAs ( system_unit ) ;
2013-04-04 12:50:53 -07:00
}
break ;
case FbxLODGroup : : eShow :
// We leave min_distance and max_distance as 0's, which effectively makes the LOD group always visible
break ;
case FbxLODGroup : : eHide :
min_distance = - 1 ;
max_distance = - 1 ;
// LOD Groups with -1 for both min_distance and max_distance will never be displayed; import in case that the distance values are to be modified by scripting at runtime
break ;
}
if ( group_min_distance ! = 0.0f & & min_distance ! = - 1 ) {
if ( min_distance < group_min_distance ) min_distance = group_min_distance ;
}
if ( group_max_distance ! = 0.0f & & max_distance ! = - 1 ) {
if ( max_distance = = 0.0f ) {
max_distance = group_max_distance ;
} else if ( max_distance > group_max_distance ) {
max_distance = group_max_distance ;
2012-11-03 02:57:35 +00:00
}
}
2013-04-04 12:50:53 -07:00
KRLODGroup * new_node = new KRLODGroup ( parent_node - > getScene ( ) , name + " _lodlevel " + boost : : lexical_cast < string > ( i + 1 ) ) ;
new_node - > setMinDistance ( min_distance ) ;
new_node - > setMaxDistance ( max_distance ) ;
new_node - > setLocalRotation ( node_rotation ) ;
new_node - > setLocalTranslation ( node_translation ) ;
new_node - > setLocalScale ( node_scale ) ;
2013-05-13 13:16:25 -07:00
new_node - > setRotationOffset ( node_rotation_offset ) ;
new_node - > setScalingOffset ( node_scaling_offset ) ;
new_node - > setRotationPivot ( node_rotation_pivot ) ;
new_node - > setScalingPivot ( node_scaling_pivot ) ;
new_node - > setPreRotation ( node_pre_rotation ) ;
new_node - > setPostRotation ( node_post_rotation ) ;
2013-04-08 21:40:53 -07:00
new_node - > setUseWorldUnits ( use_world_space_units ) ;
2013-04-04 12:50:53 -07:00
parent_node - > addChild ( new_node ) ;
2013-05-06 14:06:29 -07:00
LoadNode ( pFbxScene , new_node , pGeometryConverter , pNode - > GetChild ( i ) ) ;
2013-04-04 16:09:29 -07:00
if ( i = = 0 ) {
// Calculate reference point using the bounding box center from the highest quality LOD level
2013-04-08 21:40:53 -07:00
reference_bounds = new_node - > getBounds ( ) ;
2013-04-04 16:09:29 -07:00
}
2013-04-08 21:40:53 -07:00
new_node - > setReference ( KRAABB ( reference_bounds . min , reference_bounds . max , new_node - > getInverseModelMatrix ( ) ) ) ;
2012-11-03 02:57:35 +00:00
}
2013-04-04 12:50:53 -07:00
} else {
KRNode * new_node = NULL ;
switch ( attribute_type ) {
2013-11-23 12:16:31 -08:00
case FbxNodeAttribute : : eMesh :
2013-05-24 12:20:47 -07:00
new_node = LoadMesh ( parent_node , pFbxScene , pGeometryConverter , pNode ) ;
2013-12-02 17:44:55 -08:00
// KRNode *LoadMesh parses the "collider names" and then alters the attributes (NFB HACK)
2013-04-04 12:50:53 -07:00
break ;
2013-11-23 12:16:31 -08:00
case FbxNodeAttribute : : eLight :
2013-05-06 14:06:29 -07:00
new_node = LoadLight ( parent_node , pNode ) ;
2013-04-04 12:50:53 -07:00
break ;
2013-11-23 12:16:31 -08:00
case FbxNodeAttribute : : eSkeleton :
2013-05-24 12:20:47 -07:00
new_node = LoadSkeleton ( parent_node , pFbxScene , pNode ) ;
2013-04-04 12:50:53 -07:00
break ;
2013-10-06 18:56:23 -07:00
2013-11-23 12:16:31 -08:00
case FbxNodeAttribute : : eCamera :
2013-05-06 14:06:29 -07:00
new_node = LoadCamera ( parent_node , pNode ) ;
2013-04-04 12:50:53 -07:00
break ;
default :
{
2013-10-06 18:56:23 -07:00
bool is_locator = false ;
2013-11-23 12:16:31 -08:00
if ( attribute_type = = FbxNodeAttribute : : eNull ) {
FbxNull * pSourceNull = ( FbxNull * ) pNode - > GetNodeAttribute ( ) ;
if ( pSourceNull - > Look . Get ( ) = = FbxNull : : eCross ) {
2013-10-06 18:56:23 -07:00
is_locator = true ;
2013-04-04 12:50:53 -07:00
}
2013-10-06 18:56:23 -07:00
}
if ( is_locator ) {
new_node = LoadLocator ( parent_node , pFbxScene , pNode ) ;
} else {
if ( pNode - > GetChildCount ( ) > 0 ) {
// Create an empty node, for inheritence of transforms
std : : string name = GetFbxObjectName ( pNode ) ;
/*
if ( min_distance = = 0.0f & & max_distance = = 0.0f ) {
// Regular node for grouping children together under one transform
new_node = new KRNode ( parent_node - > getScene ( ) , name ) ;
} else {
*/
// LOD Enabled group node
KRLODGroup * lod_group = new KRLODGroup ( parent_node - > getScene ( ) , name ) ;
lod_group - > setMinDistance ( 0.0f ) ;
lod_group - > setMaxDistance ( 0.0f ) ;
new_node = lod_group ;
2013-04-04 12:50:53 -07:00
}
}
}
break ;
}
2013-12-03 16:04:15 -08:00
// this is a KRNode
2013-04-04 12:50:53 -07:00
if ( new_node ! = NULL ) {
new_node - > setLocalRotation ( node_rotation ) ;
new_node - > setLocalTranslation ( node_translation ) ;
new_node - > setLocalScale ( node_scale ) ;
2013-05-13 13:16:25 -07:00
new_node - > setRotationOffset ( node_rotation_offset ) ;
new_node - > setScalingOffset ( node_scaling_offset ) ;
new_node - > setRotationPivot ( node_rotation_pivot ) ;
new_node - > setScalingPivot ( node_scaling_pivot ) ;
new_node - > setPreRotation ( node_pre_rotation ) ;
new_node - > setPostRotation ( node_post_rotation ) ;
2013-04-04 12:50:53 -07:00
parent_node - > addChild ( new_node ) ;
2013-12-03 16:04:15 -08:00
2013-04-04 12:50:53 -07:00
// Load child nodes
for ( int i = 0 ; i < pNode - > GetChildCount ( ) ; i + + )
{
2013-05-06 14:06:29 -07:00
LoadNode ( pFbxScene , new_node , pGeometryConverter , pNode - > GetChild ( i ) ) ;
2013-04-04 12:50:53 -07:00
}
}
2012-03-23 02:28:46 +00:00
}
}
2013-05-06 14:06:29 -07:00
void LoadMaterial ( KRContext & context , FbxSurfaceMaterial * pMaterial ) {
2012-12-20 01:23:57 +00:00
//printf(" %s: %i - %i\n", pMaterial->GetName(), mat_vertex_start, mat_vertex_count + mat_vertex_start - 1);
// ----====---- Output Material File ----====----
KRMaterial * new_material = new KRMaterial ( context , pMaterial - > GetName ( ) ) ;
2013-01-23 12:43:43 -08:00
std : : string name = pMaterial - > GetName ( ) ;
2013-01-24 13:52:26 -08:00
if ( boost : : starts_with ( name , " ab_reflect_ " ) ) {
2013-01-23 12:43:43 -08:00
new_material - > setAlphaMode ( KRMaterial : : KRMATERIAL_ALPHA_MODE_BLENDONESIDE ) ;
2013-01-24 13:52:26 -08:00
size_t underscore_pos = name . find ( ' _ ' , 11 ) ;
2013-01-23 12:43:43 -08:00
new_material - > setReflectionCube ( name . substr ( 11 , underscore_pos - 11 ) ) ;
} else if ( boost : : starts_with ( name , " reflect_ " ) ) {
2013-01-24 13:52:26 -08:00
size_t underscore_pos = name . find ( ' _ ' , 8 ) ;
2013-01-23 12:43:43 -08:00
new_material - > setReflectionCube ( name . substr ( 8 , underscore_pos - 8 ) ) ;
} else if ( boost : : starts_with ( name , " at_ " ) ) {
new_material - > setAlphaMode ( KRMaterial : : KRMATERIAL_ALPHA_MODE_TEST ) ;
} else if ( boost : : starts_with ( name , " ab_ " ) ) {
new_material - > setAlphaMode ( KRMaterial : : KRMATERIAL_ALPHA_MODE_BLENDONESIDE ) ;
} else if ( boost : : starts_with ( name , " ab2_ " ) ) {
2013-01-24 13:52:26 -08:00
new_material - > setAlphaMode ( KRMaterial : : KRMATERIAL_ALPHA_MODE_BLENDTWOSIDE ) ;
2013-01-23 12:43:43 -08:00
}
2012-12-20 01:23:57 +00:00
FbxPropertyT < FbxDouble3 > lKFbxDouble3 ;
FbxPropertyT < FbxDouble > lKFbxDouble1 ;
2013-11-23 12:16:31 -08:00
if ( pMaterial - > GetClassId ( ) . Is ( FbxSurfacePhong : : ClassId ) ) {
2012-12-20 01:23:57 +00:00
// We found a Phong material.
// Ambient Color
lKFbxDouble3 = ( ( FbxSurfacePhong * ) pMaterial ) - > Ambient ;
new_material - > setAmbient ( KRVector3 ( lKFbxDouble3 . Get ( ) [ 0 ] , lKFbxDouble3 . Get ( ) [ 1 ] , lKFbxDouble3 . Get ( ) [ 2 ] ) ) ;
// Diffuse Color
2013-11-23 12:16:31 -08:00
lKFbxDouble3 = ( ( FbxSurfacePhong * ) pMaterial ) - > Diffuse ;
2012-12-20 01:23:57 +00:00
new_material - > setDiffuse ( KRVector3 ( lKFbxDouble3 . Get ( ) [ 0 ] , lKFbxDouble3 . Get ( ) [ 1 ] , lKFbxDouble3 . Get ( ) [ 2 ] ) ) ;
// Specular Color (unique to Phong materials)
2013-11-23 12:16:31 -08:00
lKFbxDouble3 = ( ( FbxSurfacePhong * ) pMaterial ) - > Specular ;
2012-12-20 01:23:57 +00:00
new_material - > setSpecular ( KRVector3 ( lKFbxDouble3 . Get ( ) [ 0 ] , lKFbxDouble3 . Get ( ) [ 1 ] , lKFbxDouble3 . Get ( ) [ 2 ] ) ) ;
// Emissive Color
//lKFbxDouble3 =((KFbxSurfacePhong *) pMaterial)->Emissive;
2013-05-06 19:33:51 -07:00
/*
2012-12-20 01:23:57 +00:00
// Transparency
lKFbxDouble1 = ( ( KFbxSurfacePhong * ) pMaterial ) - > TransparencyFactor ;
2013-05-01 17:54:48 -07:00
new_material - > setTransparency ( 1.0f - lKFbxDouble1 . Get ( ) ) ;
2013-05-06 19:33:51 -07:00
*/
2012-12-20 01:23:57 +00:00
// Shininess
2013-11-23 12:16:31 -08:00
lKFbxDouble1 = ( ( FbxSurfacePhong * ) pMaterial ) - > Shininess ;
2012-12-20 01:23:57 +00:00
new_material - > setShininess ( lKFbxDouble1 . Get ( ) ) ;
2013-05-06 19:33:51 -07:00
/*
2012-12-20 01:23:57 +00:00
// Specular Factor
lKFbxDouble1 = ( ( KFbxSurfacePhong * ) pMaterial ) - > SpecularFactor ;
double specular_factor = lKFbxDouble1 . Get ( ) ;
2013-05-06 19:33:51 -07:00
*/
// Transparency Color
2013-11-23 12:16:31 -08:00
lKFbxDouble3 = ( ( FbxSurfacePhong * ) pMaterial ) - > TransparentColor ;
2013-05-06 19:33:51 -07:00
new_material - > setTransparency ( 1.0f - ( lKFbxDouble3 . Get ( ) [ 0 ] + lKFbxDouble3 . Get ( ) [ 1 ] + lKFbxDouble3 . Get ( ) [ 2 ] ) / 3.0f ) ;
2012-12-20 01:23:57 +00:00
// Reflection factor
2013-11-23 12:16:31 -08:00
lKFbxDouble1 = ( ( FbxSurfacePhong * ) pMaterial ) - > ReflectionFactor ;
2012-12-20 01:23:57 +00:00
// Reflection color
2013-11-23 12:16:31 -08:00
lKFbxDouble3 = ( ( FbxSurfacePhong * ) pMaterial ) - > Reflection ;
2012-12-20 01:23:57 +00:00
// We modulate Relection color by reflection factor, as we only have one "reflection color" variable in Kraken
new_material - > setReflection ( KRVector3 ( lKFbxDouble3 . Get ( ) [ 0 ] * lKFbxDouble1 . Get ( ) , lKFbxDouble3 . Get ( ) [ 1 ] * lKFbxDouble1 . Get ( ) , lKFbxDouble3 . Get ( ) [ 2 ] * lKFbxDouble1 . Get ( ) ) ) ;
2013-11-23 12:16:31 -08:00
} else if ( pMaterial - > GetClassId ( ) . Is ( FbxSurfaceLambert : : ClassId ) ) {
2012-12-20 01:23:57 +00:00
// We found a Lambert material.
// Ambient Color
2013-11-23 12:16:31 -08:00
lKFbxDouble3 = ( ( FbxSurfaceLambert * ) pMaterial ) - > Ambient ;
2012-12-20 01:23:57 +00:00
new_material - > setAmbient ( KRVector3 ( lKFbxDouble3 . Get ( ) [ 0 ] , lKFbxDouble3 . Get ( ) [ 1 ] , lKFbxDouble3 . Get ( ) [ 2 ] ) ) ;
// Diffuse Color
2013-11-23 12:16:31 -08:00
lKFbxDouble3 = ( ( FbxSurfaceLambert * ) pMaterial ) - > Diffuse ;
2012-12-20 01:23:57 +00:00
new_material - > setDiffuse ( KRVector3 ( lKFbxDouble3 . Get ( ) [ 0 ] , lKFbxDouble3 . Get ( ) [ 1 ] , lKFbxDouble3 . Get ( ) [ 2 ] ) ) ;
// Emissive
//lKFbxDouble3 =((KFbxSurfaceLambert *)pMaterial)->Emissive;
2013-05-06 19:33:51 -07:00
/*
2012-12-20 01:23:57 +00:00
// Opacity
lKFbxDouble1 = ( ( KFbxSurfaceLambert * ) pMaterial ) - > TransparencyFactor ;
2013-05-01 17:54:48 -07:00
new_material - > setTransparency ( 1.0f - lKFbxDouble1 . Get ( ) ) ;
2013-05-06 19:33:51 -07:00
*/
// Transparency Color
2013-11-23 12:16:31 -08:00
lKFbxDouble3 = ( ( FbxSurfaceLambert * ) pMaterial ) - > TransparentColor ;
2013-05-06 19:33:51 -07:00
new_material - > setTransparency ( 1.0f - ( lKFbxDouble3 . Get ( ) [ 0 ] + lKFbxDouble3 . Get ( ) [ 1 ] + lKFbxDouble3 . Get ( ) [ 2 ] ) / 3.0f ) ;
2012-12-20 01:23:57 +00:00
} else {
printf ( " Error! Unable to convert material: %s " , pMaterial - > GetName ( ) ) ;
}
2013-11-23 12:16:31 -08:00
FbxProperty pProperty ;
2012-12-20 01:23:57 +00:00
// Diffuse Map Texture
2013-11-23 12:16:31 -08:00
pProperty = pMaterial - > FindProperty ( FbxSurfaceMaterial : : sDiffuse ) ;
if ( pProperty . GetSrcObjectCount ( FbxLayeredTexture : : ClassId ) > 0 ) {
2012-12-20 01:23:57 +00:00
printf ( " Warning! Layered textures not supported. \n " ) ;
}
2013-11-23 12:16:31 -08:00
int texture_count = pProperty . GetSrcObjectCount ( FbxTexture : : ClassId ) ;
2012-12-20 01:23:57 +00:00
if ( texture_count > 1 ) {
printf ( " Error! Multiple diffuse textures not supported. \n " ) ;
} else if ( texture_count = = 1 ) {
2013-11-23 12:16:31 -08:00
FbxTexture * pTexture = FbxCast < FbxTexture > ( pProperty . GetSrcObject ( FbxTexture : : ClassId , 0 ) ) ;
2012-12-20 01:23:57 +00:00
assert ( ! pTexture - > GetSwapUV ( ) ) ;
assert ( pTexture - > GetCroppingTop ( ) = = 0 ) ;
assert ( pTexture - > GetCroppingLeft ( ) = = 0 ) ;
assert ( pTexture - > GetCroppingRight ( ) = = 0 ) ;
assert ( pTexture - > GetCroppingBottom ( ) = = 0 ) ;
2013-11-23 12:16:31 -08:00
assert ( pTexture - > GetWrapModeU ( ) = = FbxTexture : : eRepeat ) ;
assert ( pTexture - > GetWrapModeV ( ) = = FbxTexture : : eRepeat ) ;
2012-12-20 01:23:57 +00:00
assert ( pTexture - > GetRotationU ( ) = = 0.0f ) ;
assert ( pTexture - > GetRotationV ( ) = = 0.0f ) ;
assert ( pTexture - > GetRotationW ( ) = = 0.0f ) ;
2013-11-23 12:16:31 -08:00
FbxFileTexture * pFileTexture = FbxCast < FbxFileTexture > ( pTexture ) ;
2012-12-20 01:23:57 +00:00
if ( pFileTexture ) {
new_material - > setDiffuseMap ( KRResource : : GetFileBase ( pFileTexture - > GetFileName ( ) ) , KRVector2 ( pTexture - > GetScaleU ( ) , pTexture - > GetScaleV ( ) ) , KRVector2 ( pTexture - > GetTranslationU ( ) , pTexture - > GetTranslationV ( ) ) ) ;
}
}
// Specular Map Texture
2013-11-23 12:16:31 -08:00
pProperty = pMaterial - > FindProperty ( FbxSurfaceMaterial : : sSpecular ) ;
if ( pProperty . GetSrcObjectCount ( FbxLayeredTexture : : ClassId ) > 0 ) {
2012-12-20 01:23:57 +00:00
printf ( " Warning! Layered textures not supported. \n " ) ;
}
2013-11-23 12:16:31 -08:00
texture_count = pProperty . GetSrcObjectCount ( FbxTexture : : ClassId ) ;
2012-12-20 01:23:57 +00:00
if ( texture_count > 1 ) {
printf ( " Error! Multiple specular textures not supported. \n " ) ;
} else if ( texture_count = = 1 ) {
2013-11-23 12:16:31 -08:00
FbxTexture * pTexture = FbxCast < FbxTexture > ( pProperty . GetSrcObject ( FbxTexture : : ClassId , 0 ) ) ;
FbxFileTexture * pFileTexture = FbxCast < FbxFileTexture > ( pTexture ) ;
2012-12-20 01:23:57 +00:00
if ( pFileTexture ) {
new_material - > setSpecularMap ( KRResource : : GetFileBase ( pFileTexture - > GetFileName ( ) ) , KRVector2 ( pTexture - > GetScaleU ( ) , pTexture - > GetScaleV ( ) ) , KRVector2 ( pTexture - > GetTranslationU ( ) , pTexture - > GetTranslationV ( ) ) ) ;
}
}
// Normal Map Texture
2013-11-23 12:16:31 -08:00
pProperty = pMaterial - > FindProperty ( FbxSurfaceMaterial : : sNormalMap ) ;
if ( pProperty . GetSrcObjectCount ( FbxLayeredTexture : : ClassId ) > 0 ) {
2012-12-20 01:23:57 +00:00
printf ( " Warning! Layered textures not supported. \n " ) ;
}
texture_count = pProperty . GetSrcObjectCount < FbxTexture > ( ) ;
if ( texture_count > 1 ) {
printf ( " Error! Multiple normal map textures not supported. \n " ) ;
} else if ( texture_count = = 1 ) {
2013-11-23 12:16:31 -08:00
FbxTexture * pTexture = pProperty . GetSrcObject < FbxTexture > ( 0 ) ;
FbxFileTexture * pFileTexture = FbxCast < FbxFileTexture > ( pTexture ) ;
2012-12-20 01:23:57 +00:00
if ( pFileTexture ) {
new_material - > setNormalMap ( KRResource : : GetFileBase ( pFileTexture - > GetFileName ( ) ) , KRVector2 ( pTexture - > GetScaleU ( ) , pTexture - > GetScaleV ( ) ) , KRVector2 ( pTexture - > GetTranslationU ( ) , pTexture - > GetTranslationV ( ) ) ) ;
}
}
2013-05-06 12:58:57 -07:00
// Only save unique materials
KRMaterial * found_material = context . getMaterialManager ( ) - > getMaterial ( new_material - > getName ( ) ) ;
if ( found_material = = NULL ) {
context . getMaterialManager ( ) - > add ( new_material ) ;
} else {
delete new_material ;
}
2012-12-20 01:23:57 +00:00
}
2013-05-24 12:20:47 -07:00
2013-11-23 12:16:31 -08:00
void LoadMesh ( KRContext & context , FbxScene * pFbxScene , FbxGeometryConverter * pGeometryConverter , FbxMesh * pSourceMesh ) {
FbxMesh * pMesh = pGeometryConverter - > TriangulateMesh ( pSourceMesh ) ;
2012-03-23 02:28:46 +00:00
2013-05-24 12:20:47 -07:00
KRMesh : : mesh_info mi ;
mi . format = KRMesh : : KRENGINE_MODEL_FORMAT_TRIANGLES ;
2012-12-12 09:32:53 +00:00
2013-05-24 12:20:47 -07:00
typedef struct {
2012-12-12 22:15:09 +00:00
float weights [ KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX ] ;
int bone_indexes [ KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX ] ;
2013-05-24 12:20:47 -07:00
} control_point_weight_info_t ;
int control_point_count = pMesh - > GetControlPointsCount ( ) ;
2013-11-23 12:16:31 -08:00
FbxVector4 * control_points = pMesh - > GetControlPoints ( ) ;
2012-12-12 09:32:53 +00:00
2013-05-24 12:20:47 -07:00
control_point_weight_info_t * control_point_weights = new control_point_weight_info_t [ control_point_count ] ;
2012-12-12 09:32:53 +00:00
for ( int control_point = 0 ; control_point < control_point_count ; control_point + + ) {
2012-12-12 22:15:09 +00:00
for ( int i = 0 ; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX ; i + + ) {
2012-12-12 09:32:53 +00:00
control_point_weights [ control_point ] . weights [ i ] = 0.0f ;
control_point_weights [ control_point ] . bone_indexes [ i ] = 0 ;
}
2012-12-20 01:23:57 +00:00
2012-12-12 09:32:53 +00:00
}
bool too_many_bone_weights = false ;
// Collect the top 4 bone weights per vertex ...
2012-12-10 21:09:14 +00:00
int skin_count = pMesh - > GetDeformerCount ( FbxDeformer : : eSkin ) ;
2012-12-12 09:32:53 +00:00
int target_bone_index = 0 ;
2012-12-10 21:09:14 +00:00
for ( int skin_index = 0 ; skin_index < skin_count ; skin_index + + ) {
FbxSkin * skin = ( FbxSkin * ) pMesh - > GetDeformer ( skin_index , FbxDeformer : : eSkin ) ;
2012-12-12 09:32:53 +00:00
int cluster_count = skin - > GetClusterCount ( ) ;
printf ( " Found skin with %i clusters. \n " , cluster_count ) ;
for ( int cluster_index = 0 ; cluster_index < cluster_count ; cluster_index + + ) {
FbxCluster * cluster = skin - > GetCluster ( cluster_index ) ;
if ( cluster - > GetLinkMode ( ) ! = FbxCluster : : eNormalize ) {
printf ( " Warning! link mode not supported. \n " ) ;
}
std : : string bone_name = GetFbxObjectName ( cluster - > GetLink ( ) ) ;
2013-05-24 12:20:47 -07:00
mi . bone_names . push_back ( bone_name ) ;
/*
FbxMatrix fbx_bind_pose_matrix ;
KRMat4 bind_pose ;
PoseList pose_list ;
FbxArray < int > pose_indices ;
if ( FbxPose : : GetBindPoseContaining ( pFbxScene , cluster - > GetLink ( ) , pose_list , pose_indices ) ) {
fbx_bind_pose_matrix = ( * pose_list ) [ 0 ] . GetMatrix ( pose_indices [ 0 ] ) ;
bind_pose = KRMat4 (
KRVector3 ( fbx_bind_pose_matrix . GetColumn ( 0 ) . mData ) ,
KRVector3 ( fbx_bind_pose_matrix . GetColumn ( 1 ) . mData ) ,
KRVector3 ( fbx_bind_pose_matrix . GetColumn ( 2 ) . mData ) ,
KRVector3 ( fbx_bind_pose_matrix . GetColumn ( 3 ) . mData )
) ;
fprintf ( stderr , " Found bind pose(s)! \n " ) ;
}
*/
FbxAMatrix link_matrix ;
cluster - > GetTransformLinkMatrix ( link_matrix ) ;
mi . bone_bind_poses . push_back ( KRMat4 (
KRVector3 ( link_matrix . GetColumn ( 0 ) . mData ) ,
KRVector3 ( link_matrix . GetColumn ( 1 ) . mData ) ,
KRVector3 ( link_matrix . GetColumn ( 2 ) . mData ) ,
KRVector3 ( link_matrix . GetColumn ( 3 ) . mData )
) ) ;
2012-12-12 09:32:53 +00:00
int cluster_control_point_count = cluster - > GetControlPointIndicesCount ( ) ;
2013-05-24 12:20:47 -07:00
for ( int cluster_control_point = 0 ; cluster_control_point < cluster_control_point_count ; cluster_control_point + + ) {
int control_point = cluster - > GetControlPointIndices ( ) [ cluster_control_point ] ;
control_point_weight_info_t & weight_info = control_point_weights [ control_point ] ;
float bone_weight = cluster - > GetControlPointWeights ( ) [ cluster_control_point ] ;
2012-12-12 22:15:09 +00:00
if ( bone_weight > weight_info . weights [ KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1 ] ) {
if ( weight_info . weights [ KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1 ] ! = 0.0f ) {
2012-12-12 09:32:53 +00:00
too_many_bone_weights = true ;
}
2012-12-12 22:15:09 +00:00
weight_info . weights [ KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1 ] = bone_weight ;
weight_info . bone_indexes [ KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 1 ] = target_bone_index ;
2013-05-13 13:16:25 -07:00
for ( int bone_index = KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX - 2 ; bone_index > = 0 ; bone_index - - ) {
2012-12-12 09:32:53 +00:00
if ( bone_weight > weight_info . weights [ bone_index ] ) {
weight_info . weights [ bone_index + 1 ] = weight_info . weights [ bone_index ] ;
weight_info . bone_indexes [ bone_index + 1 ] = weight_info . bone_indexes [ bone_index ] ;
weight_info . weights [ bone_index ] = bone_weight ;
weight_info . bone_indexes [ bone_index ] = target_bone_index ;
}
}
} else {
too_many_bone_weights = true ;
}
}
target_bone_index + + ;
}
2012-12-10 21:09:14 +00:00
}
2012-12-12 09:32:53 +00:00
if ( too_many_bone_weights ) {
2012-12-12 22:15:09 +00:00
printf ( " WARNING! - Clipped bone weights to limit of %i per vertex (selecting largest weights and re-normalizing). \n " , KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX ) ;
2012-12-12 09:32:53 +00:00
}
// Normalize bone weights
2013-05-24 12:20:47 -07:00
if ( mi . bone_names . size ( ) > 0 ) {
2012-12-12 09:32:53 +00:00
for ( int control_point_index = 0 ; control_point_index < control_point_count ; control_point_index + + ) {
2013-05-24 12:20:47 -07:00
control_point_weight_info_t & weight_info = control_point_weights [ control_point_index ] ;
2012-12-12 09:32:53 +00:00
float total_weights = 0.0f ;
2012-12-12 22:15:09 +00:00
for ( int i = 0 ; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX ; i + + ) {
2012-12-12 09:32:53 +00:00
total_weights + = weight_info . weights [ i ] ;
}
if ( total_weights = = 0.0f ) total_weights = 1.0f ; // Prevent any divisions by zero
2012-12-12 22:15:09 +00:00
for ( int i = 0 ; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX ; i + + ) {
2012-12-12 09:32:53 +00:00
weight_info . weights [ i ] = weight_info . weights [ i ] / total_weights ;
}
}
}
2012-03-23 02:28:46 +00:00
int polygon_count = pMesh - > GetPolygonCount ( ) ;
2012-03-28 19:06:23 +00:00
int uv_count = pMesh - > GetElementUVCount ( ) ;
int normal_count = pMesh - > GetElementNormalCount ( ) ;
int tangent_count = pMesh - > GetElementTangentCount ( ) ;
2012-03-28 19:34:52 +00:00
int elementmaterial_count = pMesh - > GetElementMaterialCount ( ) ;
2012-12-20 01:23:57 +00:00
int material_count = pSourceMesh - > GetNode ( ) - > GetMaterialCount ( ) ; // FINDME, TODO - To support instancing, material names should be stored in the instance rather than the mesh
2012-03-23 02:28:46 +00:00
2013-05-24 12:20:47 -07:00
// std::vector<std::vector<float> > bone_weights;
// std::vector<std::vector<int> > bone_indexes;
//
// std::vector<KRVector3> vertices;
// std::vector<KRVector2> uva;
// std::vector<KRVector2> uvb;
// std::vector<KRVector3> normals;
// std::vector<KRVector3> tangents;
// std::vector<int> submesh_lengths;
// std::vector<int> submesh_starts;
// std::vector<std::string> material_names;
2012-03-23 02:28:46 +00:00
2012-03-28 19:06:23 +00:00
int dest_vertex_id = 0 ;
2012-12-20 01:23:57 +00:00
2013-05-06 12:58:57 -07:00
bool need_tangents = false ;
2012-03-28 19:34:52 +00:00
for ( int iMaterial = 0 ; iMaterial < material_count ; iMaterial + + ) {
2013-11-23 12:16:31 -08:00
FbxSurfaceMaterial * pMaterial = pSourceMesh - > GetNode ( ) - > GetMaterial ( iMaterial ) ;
2013-05-06 12:58:57 -07:00
KRMaterial * material = context . getMaterialManager ( ) - > getMaterial ( pMaterial - > GetName ( ) ) ;
if ( material ) {
if ( material - > needsVertexTangents ( ) ) {
need_tangents = true ;
}
}
2012-03-28 19:34:52 +00:00
int source_vertex_id = 0 ;
int mat_vertex_count = 0 ;
int mat_vertex_start = dest_vertex_id ;
for ( int iPolygon = 0 ; iPolygon < polygon_count ; iPolygon + + ) {
int lPolygonSize = pMesh - > GetPolygonSize ( iPolygon ) ;
if ( lPolygonSize ! = 3 ) {
source_vertex_id + = lPolygonSize ;
printf ( " Warning - Poly with %i vertices found. Expecting only triangles. " , lPolygonSize ) ;
} else {
// ----====---- Read SubMesh / Material Mapping ----====----
int iNewMaterial = - 1 ;
for ( int l = 0 ; l < elementmaterial_count ; l + + )
{
2012-11-30 00:32:03 +00:00
FbxGeometryElementMaterial * leMat = pMesh - > GetElementMaterial ( l ) ;
2012-03-28 19:34:52 +00:00
if ( leMat ) {
2012-11-30 00:32:03 +00:00
if ( leMat - > GetReferenceMode ( ) = = FbxGeometryElement : : eIndex | | leMat - > GetReferenceMode ( ) = = FbxGeometryElement : : eIndexToDirect ) {
2012-03-28 19:34:52 +00:00
int new_id = leMat - > GetIndexArray ( ) . GetAt ( iPolygon ) ;
if ( new_id > = 0 ) {
iNewMaterial = new_id ;
}
2012-03-28 19:06:23 +00:00
}
}
}
2012-03-28 19:34:52 +00:00
if ( iMaterial = = iNewMaterial ) {
// ----====---- Read Vertex-level Attributes ----====----
for ( int iVertex = 0 ; iVertex < 3 ; iVertex + + ) {
// ----====---- Read Vertex Position ----====----
int lControlPointIndex = pMesh - > GetPolygonVertex ( iPolygon , iVertex ) ;
2013-11-23 12:16:31 -08:00
FbxVector4 v = control_points [ lControlPointIndex ] ;
2013-05-24 12:20:47 -07:00
mi . vertices . push_back ( KRVector3 ( v [ 0 ] , v [ 1 ] , v [ 2 ] ) ) ;
2012-03-28 19:34:52 +00:00
2013-05-24 12:20:47 -07:00
if ( mi . bone_names . size ( ) > 0 ) {
control_point_weight_info_t & weight_info = control_point_weights [ lControlPointIndex ] ;
2012-12-12 09:32:53 +00:00
std : : vector < int > vertex_bone_indexes ;
std : : vector < float > vertex_bone_weights ;
2012-12-12 22:15:09 +00:00
for ( int i = 0 ; i < KRENGINE_MAX_BONE_WEIGHTS_PER_VERTEX ; i + + ) {
2012-12-12 09:32:53 +00:00
vertex_bone_indexes . push_back ( weight_info . bone_indexes [ i ] ) ;
vertex_bone_weights . push_back ( weight_info . weights [ i ] ) ;
}
2013-05-24 12:20:47 -07:00
mi . bone_indexes . push_back ( vertex_bone_indexes ) ;
mi . bone_weights . push_back ( vertex_bone_weights ) ;
2012-12-12 09:32:53 +00:00
}
2012-04-05 20:12:39 +00:00
KRVector2 new_uva = KRVector2 ( 0.0 , 0.0 ) ;
KRVector2 new_uvb = KRVector2 ( 0.0 , 0.0 ) ;
2012-03-28 19:34:52 +00:00
// ----====---- Read UVs ----====----
2012-04-05 20:12:39 +00:00
2013-11-23 12:16:31 -08:00
FbxStringList uvNames ;
2012-04-05 20:12:39 +00:00
pMesh - > GetUVSetNames ( uvNames ) ;
if ( uv_count > = 1 ) {
const char * setName = uvNames [ 0 ] . Buffer ( ) ;
2013-11-23 12:16:31 -08:00
FbxVector2 uv ;
bool unmapped = false ;
if ( pMesh - > GetPolygonVertexUV ( iPolygon , iVertex , setName , uv , unmapped ) ) {
2013-12-02 17:44:55 -08:00
// **** this is where the assert used to happen
2013-11-27 00:10:29 -08:00
if ( ! unmapped ) {
new_uva = KRVector2 ( uv [ 0 ] , uv [ 1 ] ) ;
}
2012-04-05 20:12:39 +00:00
}
2013-05-24 12:20:47 -07:00
mi . uva . push_back ( new_uva ) ;
2012-04-05 20:12:39 +00:00
}
if ( uv_count > = 2 ) {
const char * setName = uvNames [ 1 ] . Buffer ( ) ;
2013-11-23 12:16:31 -08:00
FbxVector2 uv ;
bool unmapped = false ;
if ( pMesh - > GetPolygonVertexUV ( iPolygon , iVertex , setName , uv , unmapped ) ) {
2013-11-27 00:10:29 -08:00
if ( ! unmapped ) {
new_uvb = KRVector2 ( uv [ 0 ] , uv [ 1 ] ) ;
}
2012-04-05 20:12:39 +00:00
}
2013-05-24 12:20:47 -07:00
mi . uvb . push_back ( new_uvb ) ;
2012-12-20 01:23:57 +00:00
}
2012-03-28 23:34:39 +00:00
2012-03-28 19:34:52 +00:00
// ----====---- Read Normals ----====----
2012-03-28 23:34:39 +00:00
2013-11-23 12:16:31 -08:00
FbxVector4 new_normal ;
2012-03-28 23:34:39 +00:00
if ( pMesh - > GetPolygonVertexNormal ( iPolygon , iVertex , new_normal ) ) {
2013-05-24 12:20:47 -07:00
mi . normals . push_back ( KRVector3 ( new_normal [ 0 ] , new_normal [ 1 ] , new_normal [ 2 ] ) ) ;
2012-03-28 19:06:23 +00:00
}
2012-03-28 19:34:52 +00:00
2012-03-28 23:34:39 +00:00
2012-03-28 19:34:52 +00:00
// ----====---- Read Tangents ----====----
for ( int l = 0 ; l < tangent_count ; + + l )
{
2013-11-23 12:16:31 -08:00
FbxVector4 new_tangent ;
2012-11-30 00:32:03 +00:00
FbxGeometryElementTangent * leTangent = pMesh - > GetElementTangent ( l ) ;
2012-03-28 19:34:52 +00:00
2012-11-30 00:32:03 +00:00
if ( leTangent - > GetMappingMode ( ) = = FbxGeometryElement : : eByPolygonVertex ) {
2012-03-28 19:34:52 +00:00
switch ( leTangent - > GetReferenceMode ( ) ) {
2012-11-30 00:32:03 +00:00
case FbxGeometryElement : : eDirect :
2012-03-28 23:34:39 +00:00
new_tangent = leTangent - > GetDirectArray ( ) . GetAt ( lControlPointIndex ) ;
2012-03-28 19:34:52 +00:00
break ;
2012-11-30 00:32:03 +00:00
case FbxGeometryElement : : eIndexToDirect :
2012-03-28 19:34:52 +00:00
{
2012-03-28 23:34:39 +00:00
int id = leTangent - > GetIndexArray ( ) . GetAt ( lControlPointIndex ) ;
2012-03-28 19:34:52 +00:00
new_tangent = leTangent - > GetDirectArray ( ) . GetAt ( id ) ;
}
break ;
default :
break ; // other reference modes not shown here!
}
2012-03-28 19:06:23 +00:00
}
2012-03-28 19:34:52 +00:00
if ( l = = 0 ) {
2013-05-24 12:20:47 -07:00
mi . tangents . push_back ( KRVector3 ( new_tangent [ 0 ] , new_tangent [ 1 ] , new_tangent [ 2 ] ) ) ;
2012-03-28 19:34:52 +00:00
}
2012-03-28 19:06:23 +00:00
}
2012-03-28 19:34:52 +00:00
2012-12-20 01:23:57 +00:00
2012-03-28 19:34:52 +00:00
source_vertex_id + + ;
dest_vertex_id + + ;
mat_vertex_count + + ;
2012-03-28 19:06:23 +00:00
}
}
}
2012-03-23 02:28:46 +00:00
}
2012-03-28 19:34:52 +00:00
2012-03-28 21:58:55 +00:00
2012-03-28 19:34:52 +00:00
if ( mat_vertex_count ) {
2012-03-28 21:58:55 +00:00
// ----====---- Output last material / submesh details ----====----
2013-05-24 12:20:47 -07:00
mi . submesh_starts . push_back ( mat_vertex_start ) ;
mi . submesh_lengths . push_back ( mat_vertex_count ) ;
mi . material_names . push_back ( pMaterial - > GetName ( ) ) ;
2012-03-28 19:34:52 +00:00
}
2012-03-23 02:28:46 +00:00
}
2012-03-28 19:06:23 +00:00
2012-12-20 01:23:57 +00:00
delete control_point_weights ;
2012-03-28 19:06:23 +00:00
2013-01-09 22:37:23 +00:00
KRMesh * new_mesh = new KRMesh ( context , pSourceMesh - > GetNode ( ) - > GetName ( ) ) ;
2013-05-24 12:20:47 -07:00
new_mesh - > LoadData ( mi , true , need_tangents ) ;
2013-04-04 16:09:29 -07:00
context . getModelManager ( ) - > addModel ( new_mesh ) ;
2012-12-20 01:23:57 +00:00
}
2013-11-23 12:16:31 -08:00
KRNode * LoadMesh ( KRNode * parent_node , FbxScene * pFbxScene , FbxGeometryConverter * pGeometryConverter , FbxNode * pNode ) {
2012-12-20 01:23:57 +00:00
std : : string name = GetFbxObjectName ( pNode ) ;
2012-11-02 20:50:45 +00:00
2013-11-23 12:16:31 -08:00
FbxMesh * pSourceMesh = ( FbxMesh * ) pNode - > GetNodeAttribute ( ) ;
2012-12-20 01:23:57 +00:00
2013-01-09 22:37:23 +00:00
if ( KRMesh : : GetLODCoverage ( pNode - > GetName ( ) ) = = 100 ) {
2012-11-02 20:50:45 +00:00
// If this is the full detail model, add an instance of it to the scene file
std : : string light_map = pNode - > GetName ( ) ;
light_map . append ( " _lightmap " ) ;
2013-12-03 16:04:15 -08:00
//FINDME - THIS IS WHERE THE collider in house names are parsed and handled .. and then the collider_<ack> names are done
// in CircaViewController.mm postLoadSetup .. with the addition of KRAKEN_COLLIDER_INTERACTABLE the postLoadSetup is redundant.
2013-12-02 17:44:55 -08:00
//
2013-01-09 22:37:23 +00:00
// FINDME, HACK - Until we have a GUI, we're using prefixes to select correct object type
2012-12-20 01:53:09 +00:00
const char * node_name = pNode - > GetName ( ) ;
2013-01-09 22:37:23 +00:00
if ( strncmp ( node_name , " physics_collider_ " , strlen ( " physics_collider_ " ) ) = = 0 ) {
return new KRCollider ( parent_node - > getScene ( ) , GetFbxObjectName ( pNode ) , pSourceMesh - > GetNode ( ) - > GetName ( ) , KRAKEN_COLLIDER_PHYSICS , 0.0f ) ;
} else if ( strncmp ( node_name , " audio_collider_ " , strlen ( " audio_collider_ " ) ) = = 0 ) {
return new KRCollider ( parent_node - > getScene ( ) , GetFbxObjectName ( pNode ) , pSourceMesh - > GetNode ( ) - > GetName ( ) , KRAKEN_COLLIDER_AUDIO , 1.0f ) ;
2013-12-03 16:04:15 -08:00
} else if ( 0 = = strncmp ( node_name , " collider_so_ " , strlen ( " collider_so_ " ) ) ) {
// ADDED Dec 3, 2013 by Peter to handle the scene object colliders that are layerMask 'Interactable' (16)
return new KRCollider ( parent_node - > getScene ( ) , GetFbxObjectName ( pNode ) , pSourceMesh - > GetNode ( ) - > GetName ( ) , KRAKEN_COLLIDER_INTERACTABLE , 1.0f ) ;
2013-01-09 22:37:23 +00:00
} else if ( strncmp ( node_name , " collider_ " , strlen ( " collider_ " ) ) = = 0 ) {
return new KRCollider ( parent_node - > getScene ( ) , GetFbxObjectName ( pNode ) , pSourceMesh - > GetNode ( ) - > GetName ( ) , KRAKEN_COLLIDER_PHYSICS | KRAKEN_COLLIDER_AUDIO , 1.0f ) ;
2012-12-20 01:53:09 +00:00
} else {
2013-01-09 22:37:23 +00:00
return new KRModel ( parent_node - > getScene ( ) , GetFbxObjectName ( pNode ) , pSourceMesh - > GetNode ( ) - > GetName ( ) , light_map , 0.0f , true , false ) ;
2012-12-20 01:53:09 +00:00
}
2012-11-03 02:57:35 +00:00
} else {
return NULL ;
2012-11-02 20:50:45 +00:00
}
2012-11-03 02:57:35 +00:00
2012-03-23 02:28:46 +00:00
}
2013-11-23 12:16:31 -08:00
KRNode * LoadSkeleton ( KRNode * parent_node , FbxScene * pFbxScene , FbxNode * pNode ) {
2012-12-07 08:22:20 +00:00
std : : string name = GetFbxObjectName ( pNode ) ;
KRBone * new_bone = new KRBone ( parent_node - > getScene ( ) , name . c_str ( ) ) ;
2013-05-24 12:20:47 -07:00
//static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray<int>& pIndex);
// PoseList pose_list;
// FbxArray<int> pose_indices;
// if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) {
// fprintf(stderr, "Found bind pose(s)!\n");
// }
2012-12-07 08:22:20 +00:00
return new_bone ;
}
2013-11-23 12:16:31 -08:00
KRNode * LoadLocator ( KRNode * parent_node , FbxScene * pFbxScene , FbxNode * pNode ) {
2013-10-06 18:56:23 -07:00
std : : string name = GetFbxObjectName ( pNode ) ;
2013-12-02 17:44:55 -08:00
//**** INTERUPT THE NODE STUFF IN HERE
// we can parse the name, look for our special naming conventions, and then route stuff
// either through to the normal locator block within the scene, or we can dump it out
// to another destination .. a script file, an xml file, whatever we need.
//****
2013-12-03 16:04:15 -08:00
//**** HACK A BIT TO FIND OUT HOW IT WORKS
const char * node_name = pNode - > GetName ( ) ;
2013-12-05 15:54:28 -08:00
FbxDouble3 local_translation = pNode - > LclTranslation . Get ( ) ; // pNode->GetGeometricTranslation(KFbxNode::eSourcePivot);
KRVector3 node_translation = KRVector3 ( local_translation [ 0 ] , local_translation [ 1 ] , local_translation [ 2 ] ) ;
2013-12-03 16:04:15 -08:00
// if(strncmp(node_name, "physics_collider_", strlen("physics_collider_")) == 0) {
// // example hard coded compare
// }
//
// Place all the zone markers at listening (head) height
//
// <room#> is a number with the letter 'H' (hotel) or 'A' (alley) at the end of it
//
// KRReverbZone .. see CircaActorStep_CreateReverbZone::execute
// RZcorner_<room#> .. with no meta data
// RZpoint_<room#> .. with meta data locRadius
//
// KRAmbientZone .. see CircaActorStep_CreateAmbientZone::execute
// AZcorner_<sound#> .. all ambient sounds will be numbered somewhere in a master sound list file
// AZpoint_<sound#> .. with meta data locRadius
//
// KRModel .. see CircaActorStep_CreateDummyProp::execute
// AN_<prop point name> .. an audio prop location that can be referenced by name in a trigger script
//
// QUESTION - should we do AN_<sound #>_<prop point name>
// and then trigger the sound by activating the prop point (i.e. the sound file is already associated with the point)
// but the dummy prop doesn't have anywhere to store the sound file name
//
// This is how it's done in the actor files ..
//
// create_ambient_zone entrance_ambient_zone entrance 99.0728 2.9885 -35.3381 10.0 10.0 10.0 0.25 p1_s1.0_1_traffic_general_loop 1.0
// create_reverb_zone telegraph_office_reverb_zone telegraph_office -53.3345 3.58721 58.2977 20.0 20.0 20.0 0.25 reverb_telegraph 1.0
//
// create_prop telegraph_radio dummyprop 94.371559 4.400661 31.469673 0.05
// - creates a reference point that the radio sound is 'located at' later in the script
2013-12-05 15:54:28 -08:00
// create_node mitchell_phone 22.7842 18.7481 9.1446
2013-12-03 16:04:15 -08:00
//
// TO BE ADDED
//
// bool GetDoubleProperty(const char **match_list, double &value);
// pass in a c-string array of case insensitive property names that are all treated as identical
// return true if the property is found
// i.e. if(GetDoubleProperty({"locradius","radius",NULL}, value)) ..
//
// TO BE ADDED
//
// bool ParseLocator(FbxNode* pNode);
// returns true is we should add the locator to the scene and false otherwise
// parses the locator and either returns it to be added to the scene or sends it somewhere else
// somewhere else would be: ambient_zone, reverb_zone, dummy_prop
//
FbxProperty myprop = pNode - > FindProperty ( " locRadius " , true ) ; // (name, is_case_sensitive)
if ( myprop . IsValid ( ) ) {
printf ( " locRadius found! \n " ) ;
FbxDataType pdt = myprop . GetPropertyDataType ( ) ;
EFbxType ptype = pdt . GetType ( ) ;
if ( eFbxDouble = = ptype ) {
double radius = myprop . Get < FbxDouble > ( ) ;
printf ( " The radius is %3.4f \n " , radius ) ;
}
}
// FbxProperty p = GetFirstProperty();
// p = GetNextProperty(p);
// if (p.IsValid()) ..
// FbxDataType pdt = p.GetPropertyDataType();
// EFbxType = pdt.GetType(); // this is an enumerated type
// FbxString pname = p.GetName();
// const char * s = p.GetNameAsCStr(); // owned by the fbx library
//**** END OF HACK
2013-12-02 17:44:55 -08:00
2013-10-06 18:56:23 -07:00
KRLocator * new_locator = new KRLocator ( parent_node - > getScene ( ) , name . c_str ( ) ) ;
//static bool GetBindPoseContaining(FbxScene* pScene, FbxNode* pNode, PoseList& pPoseList, FbxArray<int>& pIndex);
// PoseList pose_list;
// FbxArray<int> pose_indices;
// if(FbxPose::GetBindPoseContaining(pFbxScene, pNode, pose_list, pose_indices)) {
// fprintf(stderr, "Found bind pose(s)!\n");
// }
return new_locator ;
}
2013-11-23 12:16:31 -08:00
KRNode * LoadCamera ( KRNode * parent_node , FbxNode * pNode ) {
2012-12-20 22:08:41 +00:00
FbxCamera * camera = ( FbxCamera * ) pNode - > GetNodeAttribute ( ) ;
const char * szName = pNode - > GetName ( ) ;
KRCamera * new_camera = new KRCamera ( parent_node - > getScene ( ) , szName ) ;
return new_camera ;
}
2013-11-23 12:16:31 -08:00
KRNode * LoadLight ( KRNode * parent_node , FbxNode * pNode ) {
2012-04-12 00:43:53 +00:00
const GLfloat PI = 3.14159265 ;
const GLfloat d2r = PI * 2 / 360 ;
2012-11-30 00:32:03 +00:00
FbxLight * pLight = ( FbxLight * ) pNode - > GetNodeAttribute ( ) ;
2012-04-05 23:09:41 +00:00
const char * szName = pNode - > GetName ( ) ;
2012-04-06 01:07:23 +00:00
2012-11-30 00:32:03 +00:00
FbxDouble3 light_color = pLight - > Color . Get ( ) ;
FbxDouble light_intensity = pLight - > Intensity . Get ( ) ;
FbxDouble light_hotspot = pLight - > InnerAngle . Get ( ) ; // light inner cone angle (in degrees). Also know as the HotSpot
FbxDouble light_coneangle = pLight - > OuterAngle . Get ( ) ; // light outer cone angle (in degrees). Also known as the Falloff
2013-11-23 12:16:31 -08:00
FbxLight : : EDecayType light_decaytype = pLight - > DecayType . Get ( ) ; // decay type
2012-11-30 00:32:03 +00:00
FbxDouble light_decaystart = pLight - > DecayStart . Get ( ) ; // decay start distance
2012-04-06 01:07:23 +00:00
// KFbxLight::eNONE - does not attenuate with distance
// KFbxLight::eLINEAR - attenuation of 1/d
// KFbxLight::eQUADRATIC - attenuation of 1/d^2
2012-11-29 21:28:49 +00:00
// KFbxLight::eCUBIC - attenuation of
2012-04-12 00:43:53 +00:00
KRLight * new_light = NULL ;
2012-04-05 23:09:41 +00:00
switch ( pLight - > LightType . Get ( ) ) {
2013-11-23 12:16:31 -08:00
case FbxLight : : ePoint :
2012-04-12 00:43:53 +00:00
{
2012-09-05 18:14:08 +00:00
KRPointLight * l = new KRPointLight ( parent_node - > getScene ( ) , szName ) ;
2012-04-12 00:43:53 +00:00
new_light = l ;
}
2012-04-05 23:09:41 +00:00
break ;
2013-11-23 12:16:31 -08:00
case FbxLight : : eDirectional :
2012-04-12 00:43:53 +00:00
{
2012-09-05 18:14:08 +00:00
KRDirectionalLight * l = new KRDirectionalLight ( parent_node - > getScene ( ) , szName ) ;
2012-04-12 00:43:53 +00:00
new_light = l ;
}
2012-04-05 23:09:41 +00:00
break ;
2013-11-23 12:16:31 -08:00
case FbxLight : : eSpot :
2012-04-12 00:43:53 +00:00
{
2012-09-05 18:14:08 +00:00
KRSpotLight * l = new KRSpotLight ( parent_node - > getScene ( ) , szName ) ;
2012-04-12 00:43:53 +00:00
l - > setInnerAngle ( light_hotspot * d2r ) ;
l - > setOuterAngle ( light_coneangle * d2r ) ;
new_light = l ;
}
2012-04-05 23:09:41 +00:00
break ;
2013-11-23 12:16:31 -08:00
case FbxLight : : eVolume :
case FbxLight : : eArea :
2012-04-05 23:09:41 +00:00
// Not supported yet
break ;
}
2012-04-12 00:43:53 +00:00
if ( new_light ) {
new_light - > setColor ( KRVector3 ( light_color [ 0 ] , light_color [ 1 ] , light_color [ 2 ] ) ) ;
new_light - > setIntensity ( light_intensity ) ;
new_light - > setDecayStart ( light_decaystart ) ;
}
2012-11-03 02:57:35 +00:00
return new_light ;
2012-04-12 00:43:53 +00:00
2012-04-05 23:09:41 +00:00
}