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
3.0
rec..om 13 years ago
parent 63632afca1
commit 72d169d7e5
  1. 2
      engine/src/blender/com/jme3/scene/plugins/blender/AbstractBlenderLoader.java
  2. 20
      engine/src/blender/com/jme3/scene/plugins/blender/BlenderContext.java
  3. 8
      engine/src/blender/com/jme3/scene/plugins/blender/BlenderLoader.java
  4. 49
      engine/src/blender/com/jme3/scene/plugins/blender/cameras/CameraHelper.java
  5. 2
      engine/src/blender/com/jme3/scene/plugins/blender/objects/ObjectHelper.java

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

@ -73,6 +73,8 @@ public class BlenderContext {
private BlenderKey blenderKey; private BlenderKey blenderKey;
/** The header of the file block. */ /** The header of the file block. */
private DnaBlockData dnaBlockData; private DnaBlockData dnaBlockData;
/** The scene structure. */
private Structure sceneStructure;
/** The input stream of the blend file. */ /** The input stream of the blend file. */
private BlenderInputStream inputStream; private BlenderInputStream inputStream;
/** The asset manager. */ /** The asset manager. */
@ -173,6 +175,24 @@ public class BlenderContext {
public DnaBlockData getDnaBlockData() { public DnaBlockData getDnaBlockData() {
return dnaBlockData; 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. * This method returns the asset manager.

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

@ -1,6 +1,7 @@
package com.jme3.scene.plugins.blender.cameras; package com.jme3.scene.plugins.blender.cameras;
import com.jme3.asset.BlenderKey.FeaturesToLoad; import com.jme3.asset.BlenderKey.FeaturesToLoad;
import com.jme3.math.FastMath;
import com.jme3.renderer.Camera; import com.jme3.renderer.Camera;
import com.jme3.scene.CameraNode; import com.jme3.scene.CameraNode;
import com.jme3.scene.plugins.blender.AbstractBlenderHelper; 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 * an exception is thrown when there are problems with the
* blender file * blender file
*/ */
public CameraNode toCamera(Structure structure) throws BlenderFileException { public CameraNode toCamera(Structure structure, BlenderContext blenderContext) throws BlenderFileException {
if (blenderVersion >= 250) { if (blenderVersion >= 250) {
return this.toCamera250(structure); return this.toCamera250(structure, blenderContext.getSceneStructure());
} else { } else {
return this.toCamera249(structure); return this.toCamera249(structure);
} }
@ -55,13 +56,22 @@ public class CameraHelper extends AbstractBlenderHelper {
* *
* @param structure * @param structure
* camera structure * camera structure
* @param sceneStructure
* scene structure
* @return jme camera object * @return jme camera object
* @throws BlenderFileException * @throws BlenderFileException
* an exception is thrown when there are problems with the * an exception is thrown when there are problems with the
* blender file * blender file
*/ */
private CameraNode toCamera250(Structure structure) throws BlenderFileException { private CameraNode toCamera250(Structure structure, Structure sceneStructure) throws BlenderFileException {
Camera camera = new Camera(DEFAULT_CAM_WIDTH, DEFAULT_CAM_HEIGHT); 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(); int type = ((Number) structure.getFieldValue("type")).intValue();
if (type != 0 && type != 1) { if (type != 0 && type != 1) {
LOGGER.log(Level.WARNING, "Unknown camera type: {0}. Perspective camera is being used!", type); 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 //type==0 - perspective; type==1 - orthographic; perspective is used as default
camera.setParallelProjection(type == 1); 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 clipsta = ((Number) structure.getFieldValue("clipsta")).floatValue();
float clipend = ((Number) structure.getFieldValue("clipend")).floatValue(); float clipend = ((Number) structure.getFieldValue("clipend")).floatValue();
if (type == 0) { 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 { } 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); return new CameraNode(null, camera);
} }

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

Loading…
Cancel
Save