From 72d169d7e5ef64b7cc4366ea51264a32c0a7f037 Mon Sep 17 00:00:00 2001 From: "rec..om" Date: Mon, 8 Oct 2012 14:53:51 +0000 Subject: [PATCH] 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 --- .../blender/AbstractBlenderLoader.java | 2 +- .../scene/plugins/blender/BlenderContext.java | 20 ++++++++ .../scene/plugins/blender/BlenderLoader.java | 8 +++ .../plugins/blender/cameras/CameraHelper.java | 49 ++++++++++++++++--- .../plugins/blender/objects/ObjectHelper.java | 2 +- 5 files changed, 71 insertions(+), 10 deletions(-) diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/AbstractBlenderLoader.java b/engine/src/blender/com/jme3/scene/plugins/blender/AbstractBlenderLoader.java index 2ad8cf473..057c0548e 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/AbstractBlenderLoader.java +++ b/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; } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java index 144c933a4..fcdb423c7 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java +++ b/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. diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java b/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java index 1482c59c4..2c2cfc81d 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java +++ b/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)); + } } } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/cameras/CameraHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/cameras/CameraHelper.java index ae028ee32..4fc529ff9 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/cameras/CameraHelper.java +++ b/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); } diff --git a/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java b/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java index 44ee463ac..cd1cef744 100644 --- a/engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java +++ b/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 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;