Member 12721648 Ответов: 1

Java 3D:перемещение частей тела в объектной модели (.obj)


Я изучаю JOGL (Java OpenGL) уже несколько месяцев и сумел загрузить объектную модель, применить текстуры и повернуть объект без какой-либо анимации в реальном времени в настоящее время. Я пытаюсь использовать хэш-таблицу heirarchy или Map для отображения частей объекта, в данном случае я использую Map, но метод .get, похоже, возвращает null. Я все еще изучаю структуру кода, и в настоящее время я не хочу создавать много легко используемых методов, но хочу использовать один единообразный файл .jar для выполнения RotationInterpolator, поведения и, возможно, классов узлов, чтобы заставить мои крылья двигаться.

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Frame;
import java.awt.GraphicsConfiguration;
import java.io.FileNotFoundException;
import java.util.Map;

import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.Material;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3d;
import javax.vecmath.Vector3f;

import com.sun.j3d.loaders.IncorrectFormatException;
import com.sun.j3d.loaders.ParsingErrorException;
import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.objectfile.ObjectFile;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;

public class ObjectInteractive extends Frame {

	private static final long serialVersionUID = 819877942509843369L;

	/*
	 * IN ORDER TO LOAD THE OBJECT MODEL AFTER SEPARATING IT INTO LOOSE PARTS IN
	 * BLENDER, JAVA3D REQUIRES YOU TO OPEN THE OBJECT IN A TEXT EDITOR AND ADD
	 * "#" IN FRONT OF EVERY OBJECT "o". COMMAND F TO SEARCH FOR TEXT "o" AND
	 * ENTER TO CYCLE, UNLESS IT PROVIDES YOU WITH ARROW KEYS. MAKE SURE TO
	 * CHANGE THE FILE EXTENSION BACK TO .obj, ON MAC OS X YOU HAVE TO RIGHT
	 * CLICK>GET INFO
	 * 
	 * eg.
	 * 
	 * o gargoyle <------wrong
	 * 
	 * # o gargoyle <------right
	 */

	{

		GraphicsConfiguration graphicsConfigI = SimpleUniverse
				.getPreferredConfiguration();

		setLayout(new BorderLayout());
		setTitle("Heavy Evil - Act I");
		Canvas3D canvas3DI = new Canvas3D(graphicsConfigI);
		canvas3DI.setSize(1200, 800);
		canvas3DI.setVisible(true);
		canvas3DI.setBackground(Color.BLACK);

		add(canvas3DI);

		ObjectFile loaderI = new ObjectFile(ObjectFile.LOAD_ALL);
		loaderI.setFlags(ObjectFile.RESIZE);

		Shape3D modelI = new Shape3D();
		Scene modelSceneI = null;

		try {
			modelSceneI = loaderI.load("Images/untitled.obj/");
			modelI = (Shape3D) modelSceneI.getSceneGroup().getChild(0);
			modelSceneI.getSceneGroup().removeChild(0);
			modelI.getAppearance().getMaterial();

		} catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (IncorrectFormatException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ParsingErrorException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

		BranchGroup root = modelSceneI.getSceneGroup();
		root.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
		root.setCapability(BranchGroup.ALLOW_CHILDREN_WRITE);

		root.removeAllChildren();

		Color3f light1Color = new Color3f(1.8f, 0.1f, 0.1f);

		BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0),
				100.0);

		Vector3f light1Direction = new Vector3f(2.0f, 12.0f, -12.0f);

		DirectionalLight light1

		= new DirectionalLight(light1Color, light1Direction);

		light1.setInfluencingBounds(bounds);

		root.addChild(light1);

		Transform3D transform = new Transform3D();
		transform.lookAt(new Point3d(0, 0, 4), new Point3d(0, 0, 0),
				new Vector3d(0, 1, 0));
		transform.invert();

		/* Creates rotation transforms for x, y and z axis */
		Transform3D rotateX = new Transform3D();
		Transform3D rotateY = new Transform3D();
		Transform3D rotateZ = new Transform3D();

		rotateX.rotX(30d); // +30 degrees on the X axis
		rotateY.rotY(30d); // +30 degrees on the Y axis
		rotateZ.rotZ(-15d); // or something
		transform.mul(rotateX, rotateY);
		transform.mul(transform, rotateZ);

		root.addChild(modelI);

		@SuppressWarnings("unchecked")
		Map<String, Shape3D> nameMap = modelSceneI.getNamedObjects();

		for (String groups : nameMap.keySet()) {
			System.out.printf("Name: %s\n", groups);
		}

		for (String gargoyle : nameMap.keySet()) {
			System.out.printf("Name: %s\n", gargoyle);
		}
		for (String wings : nameMap.keySet()) {
			System.out.printf("Name: %s\n", wings);
		}
		for (String box : nameMap.keySet()) {
			System.out.printf("Name: %s\n", box);
		}
		for (String teeth : nameMap.keySet()) {
			System.out.printf("Name: %s\n", teeth);
		}
		for (String eyes : nameMap.keySet()) {
			System.out.printf("Name: %s\n", eyes);
		}
		for (String object : nameMap.keySet()) {
			System.out.printf("Name: %s\n", object);
		}
		for (String bar : nameMap.keySet()) {
			System.out.printf("Name: %s\n", bar);
		}
		for (String hornOther : nameMap.keySet()) {
			System.out.printf("Name: %s\n", hornOther);
		}

		TransformGroup groups = new TransformGroup(transform);
		TransformGroup gargoyle = new TransformGroup();
		TransformGroup teeth = new TransformGroup();
		TransformGroup wings = new TransformGroup();
		TransformGroup eyes = new TransformGroup();
		TransformGroup object = new TransformGroup();
		TransformGroup bar = new TransformGroup();
		TransformGroup box = new TransformGroup();
		TransformGroup hornOther = new TransformGroup();

		object.addChild(nameMap.get("Object01"));
		bar.addChild(nameMap.get("cone"));
		box.addChild(nameMap.get("box"));
		eyes.addChild(nameMap.get("eye_left"));
		eyes.addChild(nameMap.get("eye_right"));
		gargoyle.addChild(nameMap.get("gargoyle"));
		hornOther.addChild(nameMap.get("gargoyle.001"));
		hornOther.addChild(nameMap.get("gargoyle.002"));
		wings.addChild(nameMap.get("gargoyle.003"));
		wings.addChild(nameMap.get("gargoyle.004"));
		teeth.addChild(nameMap.get("gargoyle.005"));
		teeth.addChild(nameMap.get("gargoyle.006"));
		teeth.addChild(nameMap.get("gargoyle.007"));
		teeth.addChild(nameMap.get("gargoyle.008"));
		teeth.addChild(nameMap.get("gargoyle.009"));
		teeth.addChild(nameMap.get("gargoyle.010"));
		teeth.addChild(nameMap.get("gargoyle.011"));
		teeth.addChild(nameMap.get("gargoyle.012"));
		teeth.addChild(nameMap.get("gargoyle.013"));
		teeth.addChild(nameMap.get("gargoyle.014"));
		teeth.addChild(nameMap.get("gargoyle.015"));
		teeth.addChild(nameMap.get("gargoyle.016"));
		teeth.addChild(nameMap.get("gargoyle.017"));
		teeth.addChild(nameMap.get("gargoyle.018"));
		teeth.addChild(nameMap.get("gargoyle.019"));
		teeth.addChild(nameMap.get("gargoyle.020"));
		teeth.addChild(nameMap.get("gargoyle.021"));
		teeth.addChild(nameMap.get("gargoyle.022"));
		teeth.addChild(nameMap.get("gargoyle.023"));
		teeth.addChild(nameMap.get("gargoyle.024"));
		teeth.addChild(nameMap.get("gargoyle.025"));
		teeth.addChild(nameMap.get("gargoyle.026"));
		teeth.addChild(nameMap.get("gargoyle.027"));
		teeth.addChild(nameMap.get("gargoyle.028"));
		teeth.addChild(nameMap.get("gargoyle.029"));
		teeth.addChild(nameMap.get("gargoyle.030"));
		teeth.addChild(nameMap.get("gargoyle.031"));
		teeth.addChild(nameMap.get("gargoyle.032"));
		teeth.addChild(nameMap.get("gargoyle.033"));
		teeth.addChild(nameMap.get("gargoyle.034"));
		teeth.addChild(nameMap.get("gargoyle.035"));
		teeth.addChild(nameMap.get("gargoyle.036"));
		teeth.addChild(nameMap.get("gargoyle.037"));
		teeth.addChild(nameMap.get("gargoyle.038"));
		teeth.addChild(nameMap.get("gargoyle.039"));
		teeth.addChild(nameMap.get("gargoyle.040"));
		teeth.addChild(nameMap.get("gargoyle.041"));
		teeth.addChild(nameMap.get("gargoyle.042"));
		teeth.addChild(nameMap.get("gargoyle.043"));
		teeth.addChild(nameMap.get("gargoyle.044"));
		teeth.addChild(nameMap.get("gargoyle.045"));
		teeth.addChild(nameMap.get("gargoyle.046"));
		teeth.addChild(nameMap.get("gargoyle.047"));
		teeth.addChild(nameMap.get("gargoyle.048"));
		teeth.addChild(nameMap.get("gargoyle.049"));
		teeth.addChild(nameMap.get("gargoyle.050"));
		teeth.addChild(nameMap.get("gargoyle.051"));
		teeth.addChild(nameMap.get("gargoyle.052"));
		teeth.addChild(nameMap.get("gargoyle.053"));
		teeth.addChild(nameMap.get("gargoyle.054"));
		teeth.addChild(nameMap.get("gargoyle.055"));
		teeth.addChild(nameMap.get("gargoyle.056"));

		@SuppressWarnings("unchecked")
		Shape3D wingz = (Shape3D) modelSceneI.getNamedObjects().getOrDefault(
				"gargoyle.003", modelI);

		// NamedObject returns null, need to map Hashtable

		Appearance appear = new Appearance();

		Material mat = new Material();
		mat.setAmbientColor(0f, 0f, 5f);
		mat.setDiffuseColor(0f, 0f, 5f);
		mat.setLightingEnable(true);
		appear.setMaterial(mat);
		wingz.setAppearance(appear);

		/* Add completed scenegraph, Construct the groups */

		groups.addChild(gargoyle);
		gargoyle.addChild(wings);
		gargoyle.addChild(teeth);
		gargoyle.addChild(eyes);
		gargoyle.addChild(object);
		gargoyle.addChild(bar);
		gargoyle.addChild(hornOther);
		gargoyle.addChild(box);

		groups.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		groups.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
		gargoyle.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		gargoyle.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
		gargoyle.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);

		wings.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		wings.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

		teeth.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		eyes.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		object.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		bar.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		hornOther.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
		box.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);

		// INSERT TRANSFORMS OR JAVA VECTOR UTILS

		Vector3d vecs = new Vector3d();
		transform.rotY(0.1d);
		vecs.setZ(3.0d);

		transform.setTranslation(vecs);

		SimpleUniverse universeI = new SimpleUniverse(canvas3DI);
		universeI.getViewingPlatform().setNominalViewingTransform();

		ViewingPlatform viewPlatformI = universeI.getViewingPlatform();

		TransformGroup viewTransformI = viewPlatformI
				.getViewPlatformTransform();

		viewTransformI.setTransform(transform);
		universeI.addBranchGraph(root);

	}

	public static void main(String[] args) {

		ObjectInteractive frameObj = new ObjectInteractive();
		frameObj.setSize(1200, 800);
		frameObj.setVisible(true);

	}

}


Что я уже пробовал:

Я просмотрел объектный файл с помощью текстового редактора и отредактировал все свои отдельные части в соответствии со спецификациями Java 3D, которые должны добавить # перед всеми частями объекта со строкой, которой предшествует "o", пока все ошибки ушли. Все нормально работает. Мой метод getOrDefault всегда применяет текстуру ко всему файлу, поэтому в моем коде что-то не так, где .get неправильно обрабатывает части объекта. Учебники Google и Java3D не имеют никакого смысла, и большинство из них не затрагивают анимацию с использованием сегментов объектных файлов. Я также не уверен, что делают эти циклы for во всяком случае. Их можно использовать для многократного использования сегментов.

Я добавил поведение вращения, наконец, с помощью перетаскивания мыши, но я все еще не могу правильно отобразить крылья и т. д.

OrbitBehavior orbit = new OrbitBehavior(canvas3DI,
				OrbitBehavior.REVERSE_ALL);
orbit.setSchedulingBounds(bounds);
orbit.setRotateEnable(true);
orbit.setRotXFactor(5d);

viewPlatformI.setViewPlatformBehavior(orbit);

1 Ответов

Рейтинг:
0

Patrice T

Вы должны научиться использовать отладчик как можно скорее. Вместо того чтобы гадать, что делает ваш код, пришло время увидеть, как он выполняется, и убедиться, что он делает то, что вы ожидаете.

Отладчик позволяет вам следить за выполнением строка за строкой, проверять переменные, и вы увидите, что есть точка, в которой он перестает делать то, что вы ожидаете.
Отладчик-Википедия, свободная энциклопедия[^]
Освоение отладки в Visual Studio 2010 - руководство для начинающих[^]
http://docs.oracle.com/javase/7/docs/technotes/tools/windows/jdb.html[^]
https://www.jetbrains.com/idea/help/debugging-your-first-java-application.html[^]

Отладчик здесь для того, чтобы показать вам, что делает ваш код, и ваша задача-сравнить его с тем, что он должен делать.