Selaa lähdekoodia

Fix Blender importer to use camera dimensions and field of view.

See forum discussion: http://jmonkeyengine.org/groups/contribution-depot-jme3/forum/topic/patch-fix-blender-camera-loader-fovaspect/


git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@9857 75d07b2b-3a1a-0410-a2c5-0572b91ccdca
rec..om 13 vuotta sitten
vanhempi
commit
72d169d7e5

+ 1 - 1
engine/src/blender/com/jme3/scene/plugins/blender/AbstractBlenderLoader.java

@@ -106,7 +106,7 @@ import com.jme3.scene.plugins.blender.objects.ObjectHelper;
 	public CameraNode toCamera(Structure structure) throws BlenderFileException {
 		CameraHelper cameraHelper = blenderContext.getHelper(CameraHelper.class);
 		if (cameraHelper.shouldBeLoaded(structure, blenderContext)) {
-			return cameraHelper.toCamera(structure);
+			return cameraHelper.toCamera(structure, blenderContext);
 		}
 		return null;
 	}

+ 20 - 0
engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java

@@ -73,6 +73,8 @@ public class BlenderContext {
 	private BlenderKey							blenderKey;
 	/** The header of the file block. */
 	private DnaBlockData						dnaBlockData;
+	/** The scene structure. */
+	private Structure						sceneStructure;
 	/** The input stream of the blend file. */
 	private BlenderInputStream					inputStream;
 	/** The asset manager. */
@@ -173,6 +175,24 @@ public class BlenderContext {
 	public DnaBlockData getDnaBlockData() {
 		return dnaBlockData;
 	}
+	/**
+	 * This method sets the scene structure data.
+	 * 
+	 * @param sceneStructure
+	 *            the scene structure data
+	 */
+	public void setSceneStructure(Structure sceneStructure) {
+		this.sceneStructure = sceneStructure;
+	}
+
+	/**
+	 * This method returns the scene structure data.
+	 * 
+	 * @return the scene structure data
+	 */
+	public Structure getSceneStructure() {
+		return sceneStructure;
+	}
 
 	/**
 	 * This method returns the asset manager.

+ 8 - 0
engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java

@@ -209,11 +209,19 @@ public class BlenderLoader extends AbstractBlenderLoader {
 		blenderContext.putHelper(ParticlesHelper.class, new ParticlesHelper(inputStream.getVersionNumber(), blenderKey.isFixUpAxis()));
 
 		// reading the blocks (dna block is automatically saved in the blender context when found)
+		FileBlockHeader sceneFileBlock = null;
 		do {
 			fileBlock = new FileBlockHeader(inputStream, blenderContext);
 			if (!fileBlock.isDnaBlock()) {
 				blocks.add(fileBlock);
+				// save the scene's file block
+				if (fileBlock.getCode() == FileBlockHeader.BLOCK_SC00) {
+					sceneFileBlock = fileBlock;
+				}
 			}
 		} while (!fileBlock.isLastBlock());
+		if (sceneFileBlock != null) {
+			blenderContext.setSceneStructure(sceneFileBlock.getStructure(blenderContext));
+        }
 	}
 }

+ 41 - 8
engine/src/blender/com/jme3/scene/plugins/blender/cameras/CameraHelper.java

@@ -1,6 +1,7 @@
 package com.jme3.scene.plugins.blender.cameras;
 
 import com.jme3.asset.BlenderKey.FeaturesToLoad;
+import com.jme3.math.FastMath;
 import com.jme3.renderer.Camera;
 import com.jme3.scene.CameraNode;
 import com.jme3.scene.plugins.blender.AbstractBlenderHelper;
@@ -42,9 +43,9 @@ public class CameraHelper extends AbstractBlenderHelper {
 	 *             an exception is thrown when there are problems with the
 	 *             blender file
 	 */
-    public CameraNode toCamera(Structure structure) throws BlenderFileException {
+    public CameraNode toCamera(Structure structure, BlenderContext blenderContext) throws BlenderFileException {
     	if (blenderVersion >= 250) {
-            return this.toCamera250(structure);
+            return this.toCamera250(structure, blenderContext.getSceneStructure());
         } else {
         	return this.toCamera249(structure);
         }
@@ -55,13 +56,22 @@ public class CameraHelper extends AbstractBlenderHelper {
 	 * 
 	 * @param structure
 	 *            camera structure
+	 * @param sceneStructure
+	 *            scene structure
 	 * @return jme camera object
 	 * @throws BlenderFileException
 	 *             an exception is thrown when there are problems with the
 	 *             blender file
 	 */
-    private CameraNode toCamera250(Structure structure) throws BlenderFileException {
-        Camera camera = new Camera(DEFAULT_CAM_WIDTH, DEFAULT_CAM_HEIGHT);
+    private CameraNode toCamera250(Structure structure, Structure sceneStructure) throws BlenderFileException {
+        int width = DEFAULT_CAM_WIDTH;
+        int height = DEFAULT_CAM_HEIGHT;
+        if (sceneStructure != null) {
+            Structure renderData = (Structure)sceneStructure.getFieldValue("r");
+            width = ((Number)renderData.getFieldValue("xsch")).shortValue();
+            height = ((Number)renderData.getFieldValue("ysch")).shortValue();
+        }
+        Camera camera = new Camera(width, height);
         int type = ((Number) structure.getFieldValue("type")).intValue();
         if (type != 0 && type != 1) {
             LOGGER.log(Level.WARNING, "Unknown camera type: {0}. Perspective camera is being used!", type);
@@ -69,15 +79,38 @@ public class CameraHelper extends AbstractBlenderHelper {
         }
         //type==0 - perspective; type==1 - orthographic; perspective is used as default
         camera.setParallelProjection(type == 1);
-        float aspect = 0;
+        float aspect = width / (float)height;
+        float fovY; // Vertical field of view in degrees
         float clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
         float clipend = ((Number) structure.getFieldValue("clipend")).floatValue();
         if (type == 0) {
-            aspect = ((Number) structure.getFieldValue("lens")).floatValue();
+            // Convert lens MM to vertical degrees in fovY, see Blender rna_Camera_angle_get()
+            // Default sensor size prior to 2.60 was 32.
+            float sensor = 32.0f;
+            boolean sensorVertical = false;
+            Number sensorFit = (Number)structure.getFieldValue("sensor_fit");
+            if (sensorFit != null) {
+                // If sensor_fit is vert (2), then sensor_y is used
+                sensorVertical = sensorFit.byteValue() == 2;
+                String sensorName = "sensor_x";
+                if (sensorVertical) {
+                    sensorName = "sensor_y";
+                }
+                sensor = ((Number) structure.getFieldValue(sensorName)).floatValue();
+            }
+            float focalLength = ((Number) structure.getFieldValue("lens")).floatValue();
+            float fov = 2.0f * FastMath.atan((sensor / 2.0f) / focalLength);
+            if (sensorVertical) {
+                fovY = fov * FastMath.RAD_TO_DEG;
+            } else {
+                // Convert fov from horizontal to vertical
+                fovY = 2.0f * FastMath.atan(FastMath.tan(fov / 2.0f) / aspect) * FastMath.RAD_TO_DEG;
+            }
         } else {
-            aspect = ((Number) structure.getFieldValue("ortho_scale")).floatValue();
+            // This probably is not correct.
+            fovY = ((Number) structure.getFieldValue("ortho_scale")).floatValue();
         }
-        camera.setFrustumPerspective(45, aspect, clipsta, clipend);
+        camera.setFrustumPerspective(fovY, aspect, clipsta, clipend);
         return new CameraNode(null, camera);
     }
     

+ 1 - 1
engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java

@@ -207,7 +207,7 @@ public class ObjectHelper extends AbstractBlenderHelper {
 					if(pCamera.isNotNull()) {
 						CameraHelper cameraHelper = blenderContext.getHelper(CameraHelper.class);
 						List<Structure> camerasArray = pCamera.fetchData(blenderContext.getInputStream());
-						CameraNode camera = cameraHelper.toCamera(camerasArray.get(0));
+						CameraNode camera = cameraHelper.toCamera(camerasArray.get(0), blenderContext);
 						camera.setName(name);
 						camera.setLocalTransform(t);
 						result = camera;