OBJLoader enhancement: named groups support
This commit is contained in:
parent
6ade1a027e
commit
0f06c14c28
@ -17,6 +17,10 @@ sourceSets {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
testCompile project(':jme3-testdata')
|
||||||
|
}
|
||||||
|
|
||||||
task updateVersionPropertiesFile {
|
task updateVersionPropertiesFile {
|
||||||
def versionFile = file('src/main/resources/com/jme3/system/version.properties')
|
def versionFile = file('src/main/resources/com/jme3/system/version.properties')
|
||||||
def versionFileText = "# THIS IS AN AUTO-GENERATED FILE..\n" +
|
def versionFileText = "# THIS IS AN AUTO-GENERATED FILE..\n" +
|
||||||
|
@ -152,6 +152,7 @@ public class MTLLoader implements AssetLoader {
|
|||||||
material.setFloat("AlphaDiscardThreshold", 0.01f);
|
material.setFloat("AlphaDiscardThreshold", 0.01f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
material.setName(matName);
|
||||||
matList.put(matName, material);
|
matList.put(matName, material);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,10 +66,9 @@ public final class OBJLoader implements AssetLoader {
|
|||||||
protected final ArrayList<Vector3f> verts = new ArrayList<Vector3f>();
|
protected final ArrayList<Vector3f> verts = new ArrayList<Vector3f>();
|
||||||
protected final ArrayList<Vector2f> texCoords = new ArrayList<Vector2f>();
|
protected final ArrayList<Vector2f> texCoords = new ArrayList<Vector2f>();
|
||||||
protected final ArrayList<Vector3f> norms = new ArrayList<Vector3f>();
|
protected final ArrayList<Vector3f> norms = new ArrayList<Vector3f>();
|
||||||
|
|
||||||
protected final ArrayList<Face> faces = new ArrayList<Face>();
|
private final ArrayList<Group> groups = new ArrayList<Group>();
|
||||||
protected final HashMap<String, ArrayList<Face>> matFaces = new HashMap<String, ArrayList<Face>>();
|
|
||||||
|
|
||||||
protected String currentMatName;
|
protected String currentMatName;
|
||||||
protected String currentObjectName;
|
protected String currentObjectName;
|
||||||
|
|
||||||
@ -87,6 +86,16 @@ public final class OBJLoader implements AssetLoader {
|
|||||||
protected String objName;
|
protected String objName;
|
||||||
protected Node objNode;
|
protected Node objNode;
|
||||||
|
|
||||||
|
private static class Group {
|
||||||
|
private String name;
|
||||||
|
private final ArrayList<Face> faces = new ArrayList<Face>();
|
||||||
|
private final HashMap<String, ArrayList<Face>> matFaces = new HashMap<String, ArrayList<Face>>();
|
||||||
|
|
||||||
|
public Group(final String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected static class Vertex {
|
protected static class Vertex {
|
||||||
|
|
||||||
Vector3f v;
|
Vector3f v;
|
||||||
@ -164,8 +173,7 @@ public final class OBJLoader implements AssetLoader {
|
|||||||
verts.clear();
|
verts.clear();
|
||||||
texCoords.clear();
|
texCoords.clear();
|
||||||
norms.clear();
|
norms.clear();
|
||||||
faces.clear();
|
groups.clear();
|
||||||
matFaces.clear();
|
|
||||||
|
|
||||||
vertIndexMap.clear();
|
vertIndexMap.clear();
|
||||||
indexVertMap.clear();
|
indexVertMap.clear();
|
||||||
@ -289,10 +297,17 @@ public final class OBJLoader implements AssetLoader {
|
|||||||
f.verticies[i] = vertList.get(i);
|
f.verticies[i] = vertList.get(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matList != null && matFaces.containsKey(currentMatName)){
|
Group group = groups.get(groups.size() - 1);
|
||||||
matFaces.get(currentMatName).add(f);
|
|
||||||
|
if (currentMatName != null && matList != null && matList.containsKey(currentMatName)){
|
||||||
|
ArrayList<Face> matFaces = group.matFaces.get(currentMatName);
|
||||||
|
if (matFaces == null) {
|
||||||
|
matFaces = new ArrayList<Face>();
|
||||||
|
group.matFaces.put(currentMatName, matFaces);
|
||||||
|
}
|
||||||
|
matFaces.add(f);
|
||||||
}else{
|
}else{
|
||||||
faces.add(f); // faces that belong to the default material
|
group.faces.add(f); // faces that belong to the default material
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -337,13 +352,6 @@ public final class OBJLoader implements AssetLoader {
|
|||||||
} catch (AssetNotFoundException ex){
|
} catch (AssetNotFoundException ex){
|
||||||
logger.log(Level.WARNING, "Cannot locate {0} for model {1}", new Object[]{name, key});
|
logger.log(Level.WARNING, "Cannot locate {0} for model {1}", new Object[]{name, key});
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matList != null){
|
|
||||||
// create face lists for every material
|
|
||||||
for (String matName : matList.keySet()){
|
|
||||||
matFaces.put(matName, new ArrayList<Face>());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected boolean nextStatement(){
|
protected boolean nextStatement(){
|
||||||
@ -387,8 +395,14 @@ public final class OBJLoader implements AssetLoader {
|
|||||||
// specify MTL lib to use for this OBJ file
|
// specify MTL lib to use for this OBJ file
|
||||||
String mtllib = scan.nextLine().trim();
|
String mtllib = scan.nextLine().trim();
|
||||||
loadMtlLib(mtllib);
|
loadMtlLib(mtllib);
|
||||||
}else if (cmd.equals("s") || cmd.equals("g")){
|
}else if (cmd.equals("s")) {
|
||||||
|
logger.log(Level.WARNING, "smoothing groups are not supported, statement ignored: {0}", cmd);
|
||||||
return nextStatement();
|
return nextStatement();
|
||||||
|
}else if (cmd.equals("mg")) {
|
||||||
|
logger.log(Level.WARNING, "merge groups are not supported, statement ignored: {0}", cmd);
|
||||||
|
return nextStatement();
|
||||||
|
}else if (cmd.equals("g")) {
|
||||||
|
groups.add(new Group(scan.nextLine().trim()));
|
||||||
}else{
|
}else{
|
||||||
// skip entire command until next line
|
// skip entire command until next line
|
||||||
logger.log(Level.WARNING, "Unknown statement in OBJ! {0}", cmd);
|
logger.log(Level.WARNING, "Unknown statement in OBJ! {0}", cmd);
|
||||||
@ -565,11 +579,14 @@ public final class OBJLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
|
|
||||||
objNode = new Node(objName + "-objnode");
|
objNode = new Node(objName + "-objnode");
|
||||||
|
|
||||||
|
Group defaultGroupStub = new Group(null);
|
||||||
|
groups.add(defaultGroupStub);
|
||||||
|
|
||||||
if (!(info.getKey() instanceof ModelKey))
|
if (!(info.getKey() instanceof ModelKey))
|
||||||
throw new IllegalArgumentException("Model assets must be loaded using a ModelKey");
|
throw new IllegalArgumentException("Model assets must be loaded using a ModelKey");
|
||||||
|
|
||||||
InputStream in = null;
|
InputStream in = null;
|
||||||
try {
|
try {
|
||||||
in = info.openStream();
|
in = info.openStream();
|
||||||
|
|
||||||
@ -583,25 +600,43 @@ public final class OBJLoader implements AssetLoader {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (matFaces.size() > 0){
|
for (Group group : groups) {
|
||||||
for (Entry<String, ArrayList<Face>> entry : matFaces.entrySet()){
|
if (group == defaultGroupStub) {
|
||||||
ArrayList<Face> materialFaces = entry.getValue();
|
materializeGroup(group, objNode);
|
||||||
if (materialFaces.size() > 0){
|
} else {
|
||||||
Geometry geom = createGeometry(materialFaces, entry.getKey());
|
Node groupNode = new Node(group.name);
|
||||||
|
materializeGroup(group, groupNode);
|
||||||
|
if (groupNode.getQuantity() == 1) {
|
||||||
|
Spatial geom = groupNode.getChild(0);
|
||||||
|
geom.setName(groupNode.getName());
|
||||||
objNode.attachChild(geom);
|
objNode.attachChild(geom);
|
||||||
|
} else if (groupNode.getQuantity() > 1) {
|
||||||
|
objNode.attachChild(groupNode);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}else if (faces.size() > 0){
|
|
||||||
// generate final geometry
|
|
||||||
Geometry geom = createGeometry(faces, null);
|
|
||||||
objNode.attachChild(geom);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (objNode.getQuantity() == 1)
|
if (objNode.getQuantity() == 1)
|
||||||
// only 1 geometry, so no need to send node
|
// only 1 geometry, so no need to send node
|
||||||
return objNode.getChild(0);
|
return objNode.getChild(0);
|
||||||
else
|
else
|
||||||
return objNode;
|
return objNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void materializeGroup(Group group, Node container) throws IOException {
|
||||||
|
if (group.matFaces.size() > 0) {
|
||||||
|
for (Entry<String, ArrayList<Face>> entry : group.matFaces.entrySet()){
|
||||||
|
ArrayList<Face> materialFaces = entry.getValue();
|
||||||
|
if (materialFaces.size() > 0){
|
||||||
|
Geometry geom = createGeometry(materialFaces, entry.getKey());
|
||||||
|
container.attachChild(geom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (group.faces.size() > 0) {
|
||||||
|
// generate final geometry
|
||||||
|
Geometry geom = createGeometry(group.faces, null);
|
||||||
|
container.attachChild(geom);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,106 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2020 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package com.jme3.scene.plugins;
|
||||||
|
|
||||||
|
import com.jme3.asset.AssetInfo;
|
||||||
|
import com.jme3.asset.AssetLoader;
|
||||||
|
import com.jme3.asset.AssetManager;
|
||||||
|
import com.jme3.asset.ModelKey;
|
||||||
|
import com.jme3.scene.Geometry;
|
||||||
|
import com.jme3.scene.Node;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.system.TestUtil;
|
||||||
|
import com.jme3.texture.Image;
|
||||||
|
import org.junit.Before;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
|
||||||
|
public class OBJLoaderTest {
|
||||||
|
private AssetManager assetManager;
|
||||||
|
|
||||||
|
@Before
|
||||||
|
public void init() {
|
||||||
|
assetManager = TestUtil.createAssetManager();
|
||||||
|
// texture loaders are outside of core, so creating stub
|
||||||
|
assetManager.registerLoader(PngLoaderStub.class, "png");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHappyPath() {
|
||||||
|
Node scene = (Node) assetManager.loadModel(new ModelKey("OBJLoaderTest/TwoChairs.obj"));
|
||||||
|
String sceneAsString = toDiffFriendlyString("", scene);
|
||||||
|
System.out.println(sceneAsString);
|
||||||
|
String expectedText = "" +
|
||||||
|
// generated root name (as before named groups support)
|
||||||
|
"TwoChairs-objnode\n" +
|
||||||
|
// unnamed geometry with generated name (as before named groups support).
|
||||||
|
// actually it's partially smoothed, but this fact is ignored.
|
||||||
|
" TwoChairs-geom-0 (material: dot_purple)\n" +
|
||||||
|
// named group as Geometry
|
||||||
|
" Chair 2 (material: dot_purple)\n" +
|
||||||
|
// named group as Geometry
|
||||||
|
" Pillow 2 (material: dot_red)\n" +
|
||||||
|
// named group as node with two dufferent Geometry instances,
|
||||||
|
// because two materials are used (as before named groups support)
|
||||||
|
" Podium\n" +
|
||||||
|
" TwoChairs-geom-3 (material: dot_red)\n" +
|
||||||
|
" TwoChairs-geom-4 (material: dot_blue)\n" +
|
||||||
|
// named group as Geometry
|
||||||
|
" Pillow 1 (material: dot_green)";
|
||||||
|
assertEquals(expectedText, sceneAsString.trim());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String toDiffFriendlyString(String indent, Spatial spatial) {
|
||||||
|
if (spatial instanceof Geometry) {
|
||||||
|
return indent + spatial.getName() + " (material: "+((Geometry) spatial).getMaterial().getName()+")\n";
|
||||||
|
}
|
||||||
|
if (spatial instanceof Node) {
|
||||||
|
StringBuilder s = new StringBuilder();
|
||||||
|
s.append(indent).append(spatial.getName()).append("\n");
|
||||||
|
Node node = (Node) spatial;
|
||||||
|
for (final Spatial child : node.getChildren()) {
|
||||||
|
s.append(toDiffFriendlyString(indent + " ", child));
|
||||||
|
}
|
||||||
|
return s.toString();
|
||||||
|
}
|
||||||
|
return indent + spatial + "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PngLoaderStub implements AssetLoader {
|
||||||
|
@Override
|
||||||
|
public Object load(final AssetInfo assetInfo) {
|
||||||
|
return new Image();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2009-2020 jMonkeyEngine
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* * Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* * Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* * Neither the name of 'jMonkeyEngine' nor the names of its contributors
|
||||||
|
* may be used to endorse or promote products derived from this software
|
||||||
|
* without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||||
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||||
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||||
|
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||||
|
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
||||||
|
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
||||||
|
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||||
|
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
package jme3test.model;
|
||||||
|
|
||||||
|
import com.jme3.app.SimpleApplication;
|
||||||
|
import com.jme3.asset.ModelKey;
|
||||||
|
import com.jme3.collision.CollisionResult;
|
||||||
|
import com.jme3.collision.CollisionResults;
|
||||||
|
import com.jme3.font.BitmapFont;
|
||||||
|
import com.jme3.font.BitmapText;
|
||||||
|
import com.jme3.font.Rectangle;
|
||||||
|
import com.jme3.light.AmbientLight;
|
||||||
|
import com.jme3.math.ColorRGBA;
|
||||||
|
import com.jme3.math.Ray;
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
|
||||||
|
public class TestObjGroupsLoading extends SimpleApplication {
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
TestObjGroupsLoading app = new TestObjGroupsLoading();
|
||||||
|
app.start();
|
||||||
|
}
|
||||||
|
|
||||||
|
private BitmapText pointerDisplay;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleInitApp() {
|
||||||
|
|
||||||
|
// load scene with following structure:
|
||||||
|
// Chair 1 (just mesh without name) and named groups: Chair 2, Pillow 2, Podium
|
||||||
|
Spatial scene = assetManager.loadModel(new ModelKey("OBJLoaderTest/TwoChairs.obj"));
|
||||||
|
// add light to make it visible
|
||||||
|
scene.addLight(new AmbientLight(ColorRGBA.White));
|
||||||
|
// attach scene to the root
|
||||||
|
rootNode.attachChild(scene);
|
||||||
|
|
||||||
|
// configure camera for best scene viewing
|
||||||
|
cam.setLocation(new Vector3f(-3, 4, 3));
|
||||||
|
cam.lookAtDirection(new Vector3f(0, -0.5f, -1), Vector3f.UNIT_Y);
|
||||||
|
flyCam.setMoveSpeed(10);
|
||||||
|
|
||||||
|
// create display to indicate pointed geometry name
|
||||||
|
pointerDisplay = new BitmapText(guiFont);
|
||||||
|
pointerDisplay.setBox(new Rectangle(0, settings.getHeight(), settings.getWidth(), settings.getHeight()/2));
|
||||||
|
pointerDisplay.setAlignment(BitmapFont.Align.Center);
|
||||||
|
pointerDisplay.setVerticalAlignment(BitmapFont.VAlign.Center);
|
||||||
|
guiNode.attachChild(pointerDisplay);
|
||||||
|
|
||||||
|
initCrossHairs();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void simpleUpdate(final float tpf) {
|
||||||
|
|
||||||
|
// ray to the center of the screen from the camera
|
||||||
|
Ray ray = new Ray(cam.getLocation(), cam.getDirection());
|
||||||
|
|
||||||
|
// find object at the center of the screen
|
||||||
|
|
||||||
|
final CollisionResults results = new CollisionResults();
|
||||||
|
rootNode.collideWith(ray, results);
|
||||||
|
|
||||||
|
CollisionResult result = results.getClosestCollision();
|
||||||
|
if (result == null) {
|
||||||
|
pointerDisplay.setText("");
|
||||||
|
} else {
|
||||||
|
// display pointed geometry and it's parents names
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
for (Spatial node = result.getGeometry(); node != null; node = node.getParent()) {
|
||||||
|
if (sb.length() > 0) {
|
||||||
|
sb.append(" < ");
|
||||||
|
}
|
||||||
|
sb.append(node.getName());
|
||||||
|
}
|
||||||
|
pointerDisplay.setText(sb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void initCrossHairs() {
|
||||||
|
guiFont = assetManager.loadFont("Interface/Fonts/Default.fnt");
|
||||||
|
BitmapText ch = new BitmapText(guiFont, false);
|
||||||
|
ch.setSize(guiFont.getCharSet().getRenderedSize() * 2);
|
||||||
|
ch.setText("+"); // crosshairs
|
||||||
|
ch.setLocalTranslation( // center
|
||||||
|
settings.getWidth() / 2 - guiFont.getCharSet().getRenderedSize() / 3 * 2,
|
||||||
|
settings.getHeight() / 2 + ch.getLineHeight() / 2, 0);
|
||||||
|
guiNode.attachChild(ch);
|
||||||
|
}
|
||||||
|
}
|
20
jme3-testdata/src/main/resources/OBJLoaderTest/TwoChairs.mtl
Normal file
20
jme3-testdata/src/main/resources/OBJLoaderTest/TwoChairs.mtl
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
newmtl dot_purple
|
||||||
|
map_Kd -o 0 0 -s 1 1 dot_purple.png
|
||||||
|
Kd 1 1 1
|
||||||
|
d 1
|
||||||
|
|
||||||
|
newmtl dot_red
|
||||||
|
map_Kd -o 0 0 -s 1 1 dot_red.png
|
||||||
|
Kd 1 1 1
|
||||||
|
d 1
|
||||||
|
|
||||||
|
newmtl dot_blue
|
||||||
|
map_Kd -o 0 0 -s 1 1 dot_blue.png
|
||||||
|
Kd 1 1 1
|
||||||
|
d 1
|
||||||
|
|
||||||
|
newmtl dot_green
|
||||||
|
map_Kd -o 0 0 -s 1 1 dot_green.png
|
||||||
|
Kd 1 1 1
|
||||||
|
d 1
|
||||||
|
|
219
jme3-testdata/src/main/resources/OBJLoaderTest/TwoChairs.obj
Normal file
219
jme3-testdata/src/main/resources/OBJLoaderTest/TwoChairs.obj
Normal file
@ -0,0 +1,219 @@
|
|||||||
|
# ProBuilder 4.2.3
|
||||||
|
# https://unity3d.com/unity/features/worldbuilding/probuilder
|
||||||
|
# 5/10/2020 4:30:31 PM
|
||||||
|
|
||||||
|
mtllib ./TwoChairs.mtl
|
||||||
|
o TwoChairs
|
||||||
|
|
||||||
|
v -4 1 0
|
||||||
|
v -5 1 0
|
||||||
|
v -4 2 0
|
||||||
|
v -5 2 0
|
||||||
|
v -5 1 -1
|
||||||
|
v -5 2 -1
|
||||||
|
v -5 1 -1.25
|
||||||
|
v -4 1 -1.25
|
||||||
|
|
||||||
|
s 1
|
||||||
|
v -5 2 -1.25
|
||||||
|
v -4 2 -1.25
|
||||||
|
v -4 1 -1
|
||||||
|
v -4 2 -1
|
||||||
|
v -4 3 -1
|
||||||
|
v -5 3 -1
|
||||||
|
v -4 3 -1.25
|
||||||
|
v -5 3 -1.25
|
||||||
|
s off
|
||||||
|
|
||||||
|
vt 0 0
|
||||||
|
vt -1 0
|
||||||
|
vt 0 1
|
||||||
|
vt -1 1
|
||||||
|
vt 1 0
|
||||||
|
vt 1 1
|
||||||
|
vt -1 -1
|
||||||
|
vt 0 -1
|
||||||
|
vt -1 -1.25
|
||||||
|
vt 0 -1.25
|
||||||
|
vt -1.25 1
|
||||||
|
vt -1.25 0
|
||||||
|
vt 1.25 0
|
||||||
|
vt 1.25 1
|
||||||
|
vt 1 -1
|
||||||
|
vt 1 -1.25
|
||||||
|
vt 0 2
|
||||||
|
vt -1 2
|
||||||
|
vt 1.25 2
|
||||||
|
vt 1 2
|
||||||
|
vt -1.25 2
|
||||||
|
|
||||||
|
vn 0 0 1
|
||||||
|
vn -1 0 0
|
||||||
|
vn 0 0 -1
|
||||||
|
vn 1 0 0
|
||||||
|
vn 0 -1 0
|
||||||
|
vn 0 1 0
|
||||||
|
|
||||||
|
usemtl dot_purple
|
||||||
|
f 3/3/1 4/4/1 2/2/1 1/1/1
|
||||||
|
f 4/3/2 6/4/2 5/2/2 2/1/2
|
||||||
|
f 9/6/3 10/3/3 8/1/3 7/5/3
|
||||||
|
f 12/6/4 3/3/4 1/1/4 11/5/4
|
||||||
|
f 7/9/5 8/10/5 11/8/5 5/7/5
|
||||||
|
f 9/11/2 7/12/2 5/2/2 6/4/2
|
||||||
|
f 8/13/4 10/14/4 12/6/4 11/5/4
|
||||||
|
f 15/10/6 16/16/6 14/15/6 13/8/6
|
||||||
|
f 13/17/1 14/18/1 6/4/1 12/3/1
|
||||||
|
f 15/19/4 13/20/4 12/6/4 10/14/4
|
||||||
|
f 14/18/2 16/21/2 9/11/2 6/4/2
|
||||||
|
f 16/20/3 15/17/3 10/3/3 9/6/3
|
||||||
|
|
||||||
|
g Chair 2
|
||||||
|
v -2 1 0
|
||||||
|
v -3 1 0
|
||||||
|
v -2 2 0
|
||||||
|
v -3 2 0
|
||||||
|
v -3 1 -1
|
||||||
|
v -3 2 -1
|
||||||
|
v -3 1 -1.25
|
||||||
|
v -2 1 -1.25
|
||||||
|
v -3 2 -1.25
|
||||||
|
v -2 2 -1.25
|
||||||
|
v -2 1 -1
|
||||||
|
v -2 2 -1
|
||||||
|
v -2 3 -1
|
||||||
|
v -3 3 -1
|
||||||
|
v -2 3 -1.25
|
||||||
|
v -3 3 -1.25
|
||||||
|
|
||||||
|
vt 0 0
|
||||||
|
vt -1 0
|
||||||
|
vt 0 1
|
||||||
|
vt -1 1
|
||||||
|
vt 1 0
|
||||||
|
vt 1 1
|
||||||
|
vt -1 -1
|
||||||
|
vt 0 -1
|
||||||
|
vt -1 -1.25
|
||||||
|
vt 0 -1.25
|
||||||
|
vt -1.25 1
|
||||||
|
vt -1.25 0
|
||||||
|
vt 1.25 0
|
||||||
|
vt 1.25 1
|
||||||
|
vt 1 -1
|
||||||
|
vt 1 -1.25
|
||||||
|
vt 0 2
|
||||||
|
vt -1 2
|
||||||
|
vt 1.25 2
|
||||||
|
vt 1 2
|
||||||
|
vt -1.25 2
|
||||||
|
|
||||||
|
vn 0 0 1
|
||||||
|
vn -1 0 0
|
||||||
|
vn 0 0 -1
|
||||||
|
vn 1 0 0
|
||||||
|
vn 0 -1 0
|
||||||
|
vn 0 1 0
|
||||||
|
|
||||||
|
usemtl dot_purple
|
||||||
|
f 19/24/7 20/25/7 18/23/7 17/22/7
|
||||||
|
f 20/24/8 22/25/8 21/23/8 18/22/8
|
||||||
|
f 25/27/9 26/24/9 24/22/9 23/26/9
|
||||||
|
f 28/27/10 19/24/10 17/22/10 27/26/10
|
||||||
|
f 23/30/11 24/31/11 27/29/11 21/28/11
|
||||||
|
f 25/32/8 23/33/8 21/23/8 22/25/8
|
||||||
|
f 24/34/10 26/35/10 28/27/10 27/26/10
|
||||||
|
f 31/31/12 32/37/12 30/36/12 29/29/12
|
||||||
|
f 29/38/7 30/39/7 22/25/7 28/24/7
|
||||||
|
f 31/40/10 29/41/10 28/27/10 26/35/10
|
||||||
|
f 30/39/8 32/42/8 25/32/8 22/25/8
|
||||||
|
f 32/41/9 31/38/9 26/24/9 25/27/9
|
||||||
|
|
||||||
|
g Pillow 2
|
||||||
|
v -2 2 0
|
||||||
|
v -3 2 0
|
||||||
|
v -2 2 -1
|
||||||
|
v -3 2 -1
|
||||||
|
|
||||||
|
vt 0 0
|
||||||
|
vt 1 0
|
||||||
|
vt 0 -1
|
||||||
|
vt 1 -1
|
||||||
|
|
||||||
|
vn 0 1 0
|
||||||
|
|
||||||
|
usemtl dot_red
|
||||||
|
f 35/45/13 36/46/13 34/44/13 33/43/13
|
||||||
|
|
||||||
|
g Podium
|
||||||
|
v -1 0 1.5
|
||||||
|
v -6 0 1.5
|
||||||
|
v -1 1 1.5
|
||||||
|
v -6 1 1.5
|
||||||
|
v -6 0 -2
|
||||||
|
v -6 1 -2
|
||||||
|
v -1 0 -2
|
||||||
|
v -1 1 -2
|
||||||
|
|
||||||
|
vt -1 0
|
||||||
|
vt -6 0
|
||||||
|
vt -1 1
|
||||||
|
vt -6 1
|
||||||
|
vt 1.5 0
|
||||||
|
vt -2 0
|
||||||
|
vt 1.5 1
|
||||||
|
vt -2 1
|
||||||
|
vt 6 0
|
||||||
|
vt 1 0
|
||||||
|
vt 6 1
|
||||||
|
vt 1 1
|
||||||
|
|
||||||
|
s 1
|
||||||
|
vt 2 0
|
||||||
|
vt -1.5 0
|
||||||
|
vt 2 1
|
||||||
|
vt -1.5 1
|
||||||
|
vt 1 1.5
|
||||||
|
vt 6 1.5
|
||||||
|
vt 1 -2
|
||||||
|
vt 6 -2
|
||||||
|
vt -1 -2
|
||||||
|
vt -6 -2
|
||||||
|
vt -1 1.5
|
||||||
|
vt -6 1.5
|
||||||
|
s off
|
||||||
|
|
||||||
|
vn 0 0 1
|
||||||
|
vn 0 0.7071068 0.7071068
|
||||||
|
vn -1 0 0
|
||||||
|
vn 0 0 -1
|
||||||
|
vn 1 0 0
|
||||||
|
vn 0 1 0
|
||||||
|
vn 0 -1 0
|
||||||
|
|
||||||
|
usemtl dot_red
|
||||||
|
f 39/49/15 40/50/15 38/48/14 37/47/14
|
||||||
|
f 40/53/16 42/54/16 41/52/16 38/51/16
|
||||||
|
f 42/57/17 44/58/17 43/56/17 41/55/17
|
||||||
|
f 44/61/18 39/62/18 37/60/18 43/59/18
|
||||||
|
f 37/69/20 38/70/20 41/68/20 43/67/20
|
||||||
|
|
||||||
|
usemtl dot_blue
|
||||||
|
f 44/65/19 42/66/19 40/64/15 39/63/15
|
||||||
|
|
||||||
|
g Pillow 1
|
||||||
|
v -4 2 0
|
||||||
|
v -5 2 0
|
||||||
|
v -4 2 -1
|
||||||
|
v -5 2 -1
|
||||||
|
|
||||||
|
vt 0 0
|
||||||
|
vt 1 0
|
||||||
|
vt 0 -1
|
||||||
|
vt 1 -1
|
||||||
|
|
||||||
|
vn 0 1 0
|
||||||
|
|
||||||
|
usemtl dot_green
|
||||||
|
f 47/73/21 48/74/21 46/72/21 45/71/21
|
||||||
|
|
BIN
jme3-testdata/src/main/resources/OBJLoaderTest/dot_blue.png
Normal file
BIN
jme3-testdata/src/main/resources/OBJLoaderTest/dot_blue.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 143 B |
BIN
jme3-testdata/src/main/resources/OBJLoaderTest/dot_green.png
Normal file
BIN
jme3-testdata/src/main/resources/OBJLoaderTest/dot_green.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 142 B |
BIN
jme3-testdata/src/main/resources/OBJLoaderTest/dot_purple.png
Normal file
BIN
jme3-testdata/src/main/resources/OBJLoaderTest/dot_purple.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 143 B |
BIN
jme3-testdata/src/main/resources/OBJLoaderTest/dot_red.png
Normal file
BIN
jme3-testdata/src/main/resources/OBJLoaderTest/dot_red.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 142 B |
Loading…
x
Reference in New Issue
Block a user