소스 검색

Optims, fixed vscale for dds textures, fixed coordinate index

Simon Ferquel 10 년 전
부모
커밋
28bced7ba7

+ 23 - 20
Exporters/FBX/BabylonFbxNative/BabylonCamera.cpp

@@ -109,8 +109,10 @@ BabylonCamera::BabylonCamera(BabylonNode& babnode)
 	rotationQuaternion = localTransformAtStart.rotationQuaternion();
 	
 	fov = static_cast<float>(camera->FieldOfViewY * Euler2Rad);
-	minZ = static_cast<float>(camera->FrontPlaneDistance.Get());
-	maxZ = static_cast<float>(camera->BackPlaneDistance.Get());
+	
+	
+	minZ = static_cast<float>(camera->NearPlane.Get());
+	maxZ = static_cast<float>(camera->FarPlane.Get());
 
 	auto hasAnimStack = node->GetScene()->GetSrcObjectCount<FbxAnimStack>() > 0;
 	if (!hasAnimStack){
@@ -128,30 +130,31 @@ BabylonCamera::BabylonCamera(BabylonNode& babnode)
 	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"position", L"position", true, 0, static_cast<int>(animLengthInFrame), true);
 	auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"rotation", L"rotation", true, 0, static_cast<int>(animLengthInFrame), true);
 	auto targetAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"target", L"target", true, 0, static_cast<int>(animLengthInFrame), true);
-	
-	for (auto ix = 0; ix < animLengthInFrame; ix++){
-		FbxTime currTime;
-		currTime.SetFrame(startFrame + ix, animTimeMode);
+	if (node->LclRotation.GetCurveNode() || node->LclScaling.GetCurveNode() || node->LclTranslation.GetCurveNode() || camera->InterestPosition.GetCurveNode()) {
+		for (auto ix = 0; 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;
+			babylon_animation_key<babylon_vector3> poskey;
+			babylon_animation_key<babylon_vector4> rotkey;
+			poskey.frame = ix;
+			rotkey.frame = ix;
 
 
-		auto transformAtT = babnode.GetLocal(currTime);
+			auto transformAtT = babnode.GetLocal(currTime);
 
-		poskey.values = transformAtT.translation();
-		rotkey.values = transformAtT.rotationQuaternion();
-		posAnim->appendKey(poskey);
-		rotAnim->appendKey(rotkey);
+			poskey.values = transformAtT.translation();
+			rotkey.values = transformAtT.rotationQuaternion();
+			posAnim->appendKey(poskey);
+			rotAnim->appendKey(rotkey);
 
-		if (lockedTargetId.size() == 0){
+			if (lockedTargetId.size() == 0) {
 
-			babylon_animation_key<babylon_vector3> targetKey;
-			targetKey.frame = ix;
-			targetKey.values = camera->InterestPosition.EvaluateValue(currTime);
-			targetAnim->appendKey(targetKey);
+				babylon_animation_key<babylon_vector3> targetKey;
+				targetKey.frame = ix;
+				targetKey.values = camera->InterestPosition.EvaluateValue(currTime);
+				targetAnim->appendKey(targetKey);
+			}
 		}
 	}
 	if (!posAnim->isConstant()){

+ 21 - 19
Exporters/FBX/BabylonFbxNative/BabylonLight.cpp

@@ -142,25 +142,27 @@ BabylonLight::BabylonLight(BabylonNode & babnode) :
 	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);
-	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 (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()) {

+ 10 - 4
Exporters/FBX/BabylonFbxNative/BabylonMaterial.cpp

@@ -317,15 +317,21 @@ BabylonTexture::BabylonTexture(FbxFileTexture* texture){
 	vOffset = trans.y;
 	uScale = scaling.x;
 	vScale = scaling.y;
-	uAng = rot.x * Euler2Rad;
-	vAng = rot.y * Euler2Rad;
-	wAng = rot.z * Euler2Rad;
+	std::string strFileName = texture->GetFileName();
+	auto lastDot = strFileName.find_last_of('.');
+	auto ext = strFileName.substr(lastDot);
+	if (_stricmp(ext.c_str(), ".dds") == 0) {
+		vScale *= -1;
+	}
+	uAng = static_cast<float>(rot.x * Euler2Rad);
+	vAng = static_cast<float>(rot.y * Euler2Rad);
+	wAng = static_cast<float>(rot.z * Euler2Rad);
 	auto uwrapMode = texture->GetWrapModeU();
 	auto vwrapMode = texture->GetWrapModeV();
 	wrapU = uwrapMode == FbxTexture::eRepeat;
 	wrapV = vwrapMode == FbxTexture::eRepeat;
 
-	
+	uvset = texture->UVSet.Get();
 	
 	
 

+ 1 - 1
Exporters/FBX/BabylonFbxNative/BabylonMaterial.h

@@ -13,7 +13,7 @@ public:
 	
 	 std::wstring name;
 	 std::wstring fullPath;
-
+	 std::string uvset;
 		
 	 float level = 1.0f;
 

+ 48 - 25
Exporters/FBX/BabylonFbxNative/BabylonMesh.cpp

@@ -424,6 +424,7 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 
 	pivotMatrix.SetIdentity();
 	auto fbxNode = node->fbxNode();
+	
 	std::string ansiName = fbxNode->GetName();
 	name(std::wstring(ansiName.begin(), ansiName.end()));
 	id(getNodeId(fbxNode));
@@ -441,35 +442,57 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 	auto startFrame = takeInfo->mLocalTimeSpan.GetStart().GetFrameCount(animTimeMode);
 	auto endFrame = takeInfo->mLocalTimeSpan.GetStop().GetFrameCount(animTimeMode);
 	auto animLengthInFrame = endFrame - startFrame + 1;
-	_visibility = node->fbxNode()->Visibility.Get();
+	_visibility = static_cast<float>(node->fbxNode()->Visibility.Get());
 	auto posAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"position", L"position", true, 0, static_cast<int>(animLengthInFrame), true);
 	auto rotAnim = std::make_shared<BabylonAnimation<babylon_vector4>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"rotationQuaternion", L"rotationQuaternion", true, 0, static_cast<int>(animLengthInFrame), true);
 	auto scaleAnim = std::make_shared<BabylonAnimation<babylon_vector3>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"scaling", L"scaling", true, 0, static_cast<int>(animLengthInFrame), true);
 	auto visibilityAnim = std::make_shared<BabylonAnimation<float>>(BabylonAnimationBase::loopBehavior_Cycle, static_cast<int>(animFrameRate), L"visibility", L"visibility", true, 0, static_cast<int>(animLengthInFrame), true);
-	for (auto ix = 0; ix < animLengthInFrame; ix++){
-		FbxTime currTime;
-		currTime.SetFrame(startFrame + ix, animTimeMode);
-
-		babylon_animation_key<babylon_vector3> poskey;
-		babylon_animation_key<babylon_vector4> rotkey;
-		babylon_animation_key<babylon_vector3> scalekey;
-		babylon_animation_key<float> visibilityKey;
-		poskey.frame = ix;
-		rotkey.frame = ix;
-		scalekey.frame = ix;
-		visibilityKey.frame = ix;
-		auto currTransform = node->GetLocal(currTime);
-		poskey.values = currTransform.translation();
-		rotkey.values = currTransform.rotationQuaternion();
-		scalekey.values = currTransform.scaling();
-		visibilityKey.values = node->fbxNode()->Visibility.EvaluateValue(currTime);
-		posAnim->appendKey(poskey);
-		rotAnim->appendKey(rotkey);
-		scaleAnim->appendKey(scalekey);
-		visibilityAnim->appendKey(visibilityKey);
-
-		
+	auto mesh = fbxNode->GetMesh();
+	_isVisible = fbxNode->Show.Get();
+	
+	auto rotCurveNode = fbxNode->LclRotation.GetCurveNode();
+	auto translateCurveNode = fbxNode->LclTranslation.GetCurveNode();
+	auto scalingCurveNode = fbxNode->LclScaling.GetCurveNode();
+	auto visibilityCurveNode = fbxNode->Visibility.GetCurveNode();
+	if (rotCurveNode || translateCurveNode || scalingCurveNode) {
+		for (auto ix = 0; ix < animLengthInFrame; ix++) {
+			FbxTime currTime;
+			currTime.SetFrame(startFrame + ix, animTimeMode);
+
+			babylon_animation_key<babylon_vector3> poskey;
+			babylon_animation_key<babylon_vector4> rotkey;
+			babylon_animation_key<babylon_vector3> scalekey;
+			poskey.frame = ix;
+			rotkey.frame = ix;
+			scalekey.frame = ix;
+			auto currTransform = node->GetLocal(currTime);
+			poskey.values = currTransform.translation();
+			rotkey.values = currTransform.rotationQuaternion();
+			scalekey.values = currTransform.scaling();
+			posAnim->appendKey(poskey);
+			rotAnim->appendKey(rotkey);
+			scaleAnim->appendKey(scalekey);
+
+
+		}
+	}
+	if (visibilityCurveNode) {
+		for (auto ix = 0; ix < animLengthInFrame; ix++) {
+			FbxTime currTime;
+			currTime.SetFrame(startFrame + ix, animTimeMode);
+
+			babylon_animation_key<float> visibilityKey;
+
+			visibilityKey.frame = ix;
+
+			visibilityKey.values = static_cast<float>(node->fbxNode()->Visibility.EvaluateValue(currTime));
+
+			visibilityAnim->appendKey(visibilityKey);
+
+
+		}
 	}
+	
 	if (!posAnim->isConstant()){
 		animations.push_back(posAnim);
 	}
@@ -482,7 +505,6 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 	if (!visibilityAnim->isConstant()) {
 		animations.push_back(visibilityAnim);
 	}
-	auto mesh = fbxNode->GetMesh();
 	if (!mesh) {
 		return;
 	}
@@ -512,6 +534,7 @@ BabylonMesh::BabylonMesh(BabylonNode* node) :
 			uniqueUVSets.push_back(value);
 		}
 	}
+	uvsets = uniqueUVSets;
 	bool hasUv = uniqueUVSets.size() > 0;
 	bool hasUv2 = uniqueUVSets.size() > 1;
 	bool hasUv3 = uniqueUVSets.size() > 2;

+ 1 - 0
Exporters/FBX/BabylonFbxNative/BabylonMesh.h

@@ -56,6 +56,7 @@ private:
 	bool _applyFog;
 	int _alphaIndex;
 public:
+	std::vector<std::string> uvsets;
 	const std::wstring& id(){ return _id; }
 	const std::wstring& parentId(){ return _parentId; }
 	const std::wstring& materialId(){ return _materialId; }

+ 47 - 11
Exporters/FBX/FbxExporter/FbxExporter.cpp

@@ -52,7 +52,33 @@ std::string wstringToUtf8(const std::wstring& src){
 	return result;
 }
 
-
+void fixupTextureCoordinateIndices(BabylonMaterial& mat, BabylonMesh& mesh) {
+	std::vector<std::shared_ptr<BabylonTexture>> textures;
+	if (mat.ambientTexture) {
+		textures.push_back(mat.ambientTexture);
+	}
+	if (mat.diffuseTexture) {
+		textures.push_back(mat.diffuseTexture);
+	}
+	if (mat.specularTexture) {
+		textures.push_back(mat.specularTexture);
+	}
+	if (mat.emissiveTexture) {
+		textures.push_back(mat.emissiveTexture);
+	}
+	if (mat.reflectionTexture) {
+		textures.push_back(mat.reflectionTexture);
+	}
+	if (mat.bumpTexture) {
+		textures.push_back(mat.bumpTexture);
+	}
+	for (auto& tex : textures) {
+		auto found = std::find(mesh.uvsets.begin(), mesh.uvsets.end(), tex->uvset);
+		if (found != mesh.uvsets.end()) {
+			tex->coordinatesIndex = static_cast<int>(found - mesh.uvsets.begin());
+		}
+	}
+}
 void exploreMeshes(BabylonScene& scene, BabylonNode& node, bool skipEmptyNodes) {
 	if (node.nodeType() == BabylonNodeType::Skeleton && node.hasOnlySkeletonDescendants()) {
 		return;
@@ -67,25 +93,30 @@ void exploreMeshes(BabylonScene& scene, BabylonNode& node, bool skipEmptyNodes)
 	case BabylonNodeType::Mesh:
 	case BabylonNodeType::Skeleton:
 	{
+
+		scene.meshes().emplace_back(&node);
+		auto& mesh = scene.meshes()[scene.meshes().size() - 1];
 		auto matCount = node.fbxNode()->GetMaterialCount();
 		BabylonMultiMaterial multiMat;
 		for (auto i = 0; i < matCount; ++i) {
 			auto mat = node.fbxNode()->GetMaterial(i);
 			if (mat) {
-				BabylonMaterial babMat(mat);
-				auto id = babMat.id;
-				multiMat.materials.push_back(id);
+
+				auto id = getMaterialId(mat);
 				auto existing = std::find_if(scene.materials().begin(), scene.materials().end(), [id](const BabylonMaterial& e) {
 					return e.id == id;
 				});
 				if (existing == scene.materials().end()) {
+					auto babMat = BabylonMaterial(mat);
+					fixupTextureCoordinateIndices(babMat, mesh);
 					scene.materials().push_back(babMat);
 				}
+
+				multiMat.materials.push_back(id);
+				
 			}
 		}
 
-		scene.meshes().emplace_back(&node);
-		auto& mesh = scene.meshes()[scene.meshes().size() - 1];
 		if (mesh.associatedSkeleton){
 			mesh.associatedSkeleton->id = static_cast<int>(scene.skeletons().size()+1);
 			mesh.skeletonId(static_cast<int>(scene.skeletons().size()+1));
@@ -93,10 +124,15 @@ void exploreMeshes(BabylonScene& scene, BabylonNode& node, bool skipEmptyNodes)
 		}
 		if (multiMat.materials.size() > 0) {
 			auto& mesh = scene.meshes()[scene.meshes().size() - 1];
-			multiMat.id = mesh.id();
-			multiMat.name = mesh.name();
-			mesh.materialId(multiMat.id);
-			scene.multiMaterials().push_back(multiMat);
+			/*if (multiMat.materials.size() == 1) {
+				mesh.materialId(multiMat.materials[0]);
+			}
+			else {*/
+				multiMat.id = mesh.id();
+				multiMat.name = mesh.name();
+				mesh.materialId(multiMat.id);
+				scene.multiMaterials().push_back(multiMat);
+			//}
 		}
 	}
 	break;
@@ -311,7 +347,7 @@ int _tmain(int argc, _TCHAR* argv[])
 	wOutputPath.erase(lastDot);
 	wOutputPath.append(L".babylon");
 	DeleteFile(wOutputPath.c_str());
-	std::wofstream stream(wOutputPath);
+	std::ofstream stream(wOutputPath);
 	json.serialize(stream);
 	stream.flush();
 	return 0;