BabylonCamera::BabylonCamera(BabylonNode& babnode) { auto node = babnode.fbxNode(); std::string ansiName = node->GetName(); name = std::wstring(ansiName.begin(), ansiName.end()); id = getNodeId(node); auto parent = node->GetParent(); if (parent) { parentId = getNodeId(parent); } auto camera = node->GetCamera(); if (!camera) { return; } type = L"FreeCamera"; auto targetNode = node->GetTarget(); if (targetNode) { lockedTargetId = getNodeId(targetNode); } else { target = camera->InterestPosition.Get(); } position = babnode.localTranslate(); rotationQuaternion = babnode.localRotationQuat(); fov = camera->FieldOfViewY * Euler2Rad; minZ = camera->FrontPlaneDistance.Get(); maxZ = camera->BackPlaneDistance.Get(); auto hasAnimStack = node->GetScene()->GetSrcObjectCount<FbxAnimStack>() > 0; if (!hasAnimStack){ return; } auto animStack = node->GetScene()->GetSrcObject<FbxAnimStack>(0); FbxString animStackName = animStack->GetName(); FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName); auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode; auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate(); auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(animTimeMode); auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(animTimeMode); auto animLengthInFrame = endFrame - startFrame + 1; auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"position", L"position", true, 0, animLengthInFrame, true); auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"rotation", L"rotation", true, 0, animLengthInFrame, true); auto targetAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, animFrameRate, L"target", L"target", true, 0, animLengthInFrame, true); for (auto ix = 0ll; ix < animLengthInFrame; ix++){ FbxTime currTime; currTime.SetFrame(startFrame + ix, animTimeMode); babylon_animation_key<babylon_vector3> poskey; babylon_animation_key<babylon_vector4> rotkey; poskey.frame = ix; rotkey.frame = ix; poskey.values = babnode.localTranslate(currTime); rotkey.values = babnode.localRotationQuat(currTime); posAnim->appendKey(poskey); rotAnim->appendKey(rotkey); if (lockedTargetId.size() == 0){ babylon_animation_key<babylon_vector3> targetKey; targetKey.frame = ix; targetKey.values = camera->InterestPosition.EvaluateValue(currTime); targetAnim->appendKey(targetKey); } } if (!posAnim->isConstant()){ animations.push_back(posAnim); } if (!rotAnim->isConstant()){ quatAnimations.push_back(rotAnim); } if (!targetAnim->isConstant()){ animations.push_back(targetAnim); } }
BabylonLight::BabylonLight(BabylonNode & babnode) : diffuse(1, 1, 1), specular(1, 1, 1) { auto node = babnode.fbxNode(); std::string ansiName = node->GetName(); name = std::wstring(ansiName.begin(), ansiName.end()); id = getNodeId(node); auto parent = node->GetParent(); if (parent) { parentId = getNodeId(parent); } auto localTransform = babnode.GetLocal(); position = localTransform.translation(); auto light = node->GetLight(); switch (light->LightType) { case FbxLight::ePoint: type = type_omni; break; case FbxLight::eDirectional: type = type_direct; { FbxDouble3 vDir(0, -1, 0); FbxAMatrix rotM; rotM.SetIdentity(); rotM.SetQ(localTransform.fbxrot()); auto transDir = rotM.MultT(vDir); direction = transDir; } break; case FbxLight::eSpot: type = type_Spot; { FbxDouble3 vDir(0, -1, 0); FbxAMatrix rotM; rotM.SetIdentity(); rotM.SetQ(localTransform.fbxrot()); auto transDir = rotM.MultT(vDir); direction = transDir; exponent = 1; angle = static_cast<float>(light->OuterAngle*Euler2Rad); } break; default: break; } diffuse = light->Color.Get(); intensity = static_cast<float>(light->Intensity.Get() / 100.0); if (light->EnableFarAttenuation.Get()) { range = static_cast<float>(light->FarAttenuationEnd.Get()); } auto hasAnimStack = node->GetScene()->GetSrcObjectCount<FbxAnimStack>() > 0; if (!hasAnimStack) { return; } castShadows = light->CastShadows.Get(); if (castShadows) { shadowGenerator = std::make_shared<BabylonShadowGenerator>(node); } auto animStack = node->GetScene()->GetSrcObject<FbxAnimStack>(0); FbxString animStackName = animStack->GetName(); FbxTakeInfo* takeInfo = node->GetScene()->GetTakeInfo(animStackName); auto animTimeMode = GlobalSettings::Current().AnimationsTimeMode; auto animFrameRate = GlobalSettings::Current().AnimationsFrameRate(); auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(animTimeMode); auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(animTimeMode); auto animLengthInFrame = endFrame - startFrame + 1; auto posAnimName = getNodeId(node); auto dirAnimName = getNodeId(node); posAnimName.append(L"_position"); dirAnimName.append(L"_direction"); auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), posAnimName, L"position", true, 0, static_cast<int>(animLengthInFrame), true); auto dirAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), dirAnimName, L"direction", true, 0, static_cast<int>(animLengthInFrame), true); if (node->LclRotation.GetCurveNode() || node->LclTranslation.GetCurveNode()) { for (auto ix = 0; ix < animLengthInFrame; ix++) { babylon_animation_key<babylon_vector3> key; key.frame = ix; FbxTime currTime; currTime.SetFrame(startFrame + ix, animTimeMode); auto currTransform = babnode.GetLocal(currTime); key.values = currTransform.translation(); posAnim->appendKey(key); if (type == type_direct || type == type_Spot) { babylon_animation_key<babylon_vector3> dirkey; dirkey.frame = ix; FbxDouble3 vDir(0, -1, 0); FbxAMatrix rotM; rotM.SetIdentity(); rotM.SetQ(currTransform.fbxrot()); auto transDir = rotM.MultT(vDir); dirkey.values = transDir; dirAnim->appendKey(dirkey); } } } if (!posAnim->isConstant()) { animations.push_back(posAnim); } if (!dirAnim->isConstant()) { animations.push_back(dirAnim); } }