diff options
5 files changed, 73 insertions, 159 deletions
diff --git a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleOffExample.java b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleOffExample.java index be255dc..46e0c29 100644 --- a/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleOffExample.java +++ b/ardor3d-examples/src/main/java/com/ardor3d/example/pipeline/SimpleOffExample.java @@ -36,7 +36,7 @@ public class SimpleOffExample extends ExampleBase { // Load the OFF scene final long time = System.currentTimeMillis(); final OffImporter importer = new OffImporter(); - final OffGeometryStore storage = importer.load("off/vertcube.off"); + final OffGeometryStore storage = importer.load("off/toilet.off"); System.out.println("Importing Took " + (System.currentTimeMillis() - time) + " ms"); final Node model = storage.getScene(); diff --git a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffEdgeInfo.java b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffEdgeInfo.java deleted file mode 100644 index b65ec67..0000000 --- a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffEdgeInfo.java +++ /dev/null @@ -1,50 +0,0 @@ -/** - * Copyright (c) 2008-2014 Ardor Labs, Inc. - * - * This file is part of Ardor3D. - * - * Ardor3D is free software: you can redistribute it and/or modify it - * under the terms of its license which may be found in the accompanying - * LICENSE file or at <http://www.ardor3d.com/LICENSE>. - */ - -package com.ardor3d.extension.model.off; - -import com.ardor3d.math.ColorRGBA; - -public class OffEdgeInfo { - - private Integer index1; - - private Integer index2; - - private ColorRGBA color; - - public OffEdgeInfo() { - super(); - } - - public Integer getIndex1() { - return index1; - } - - public void setIndex1(final Integer index1) { - this.index1 = index1; - } - - public Integer getIndex2() { - return index2; - } - - public void setIndex2(final Integer index2) { - this.index2 = index2; - } - - public ColorRGBA getColor() { - return color; - } - - public void setColor(final ColorRGBA color) { - this.color = color; - } -} diff --git a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffFaceInfo.java b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffFaceInfo.java index 60d24a7..8a2ba2e 100644 --- a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffFaceInfo.java +++ b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffFaceInfo.java @@ -13,14 +13,13 @@ package com.ardor3d.extension.model.off; import java.util.ArrayList; import java.util.List; +import com.ardor3d.math.ColorRGBA; + public class OffFaceInfo { private List<Integer> _vertexIndices; - private List<Integer> _materialIndices; - - // TODO use only vertices indices and colors in faces - private List<Float> _textureCoordinates; + private ColorRGBA _color; public OffFaceInfo() { super(); @@ -37,25 +36,11 @@ public class OffFaceInfo { return _vertexIndices; } - public void addMaterialIndex(final int materialIndex) { - if (_materialIndices == null) { - _materialIndices = new ArrayList<>(); - } - _materialIndices.add(Integer.valueOf(materialIndex)); - } - - public List<Integer> getMaterialIndices() { - return _materialIndices; - } - - public void addTextureCoordinate(final float textureCoordinate) { - if (_textureCoordinates == null) { - _textureCoordinates = new ArrayList<>(); - } - _textureCoordinates.add(Float.valueOf(textureCoordinate)); + public void setColor(final ColorRGBA color) { + _color = color; } - public List<Float> getTextureCoordinates() { - return _textureCoordinates; + public ColorRGBA getColor() { + return _color; } } diff --git a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffGeometryStore.java b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffGeometryStore.java index dce55a7..d884aff 100644 --- a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffGeometryStore.java +++ b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffGeometryStore.java @@ -22,11 +22,9 @@ import com.ardor3d.image.Texture; import com.ardor3d.math.ColorRGBA; import com.ardor3d.math.Vector2; import com.ardor3d.math.Vector3; -import com.ardor3d.math.type.ReadOnlyColorRGBA; import com.ardor3d.renderer.IndexMode; import com.ardor3d.renderer.state.TextureState; import com.ardor3d.scenegraph.IndexBufferData; -import com.ardor3d.scenegraph.Line; import com.ardor3d.scenegraph.Mesh; import com.ardor3d.scenegraph.Node; import com.ardor3d.util.geom.BufferUtils; @@ -39,8 +37,6 @@ public class OffGeometryStore { private int _totalMeshes = 0; - private int _totalLines = 0; - private final OffDataStore _dataStore; private final Node _root; @@ -49,8 +45,6 @@ public class OffGeometryStore { private List<OffFaceInfo> _offFaceInfoList; - private List<OffEdgeInfo> _offEdgeInfoList; - private Texture _texture; private String _textureName; @@ -106,13 +100,6 @@ public class OffGeometryStore { return null; } - void addLine(final OffEdgeInfo edgeInfo) { - if (_offEdgeInfoList == null) { - _offEdgeInfoList = new ArrayList<>(); - } - _offEdgeInfoList.add(edgeInfo); - } - void addFace(final OffFaceInfo faceInfo) { if (_offFaceInfoList == null) { _offFaceInfoList = new ArrayList<>(); @@ -120,71 +107,35 @@ public class OffGeometryStore { _offFaceInfoList.add(faceInfo); } - @SuppressWarnings("null") - void commitObjects() { - if (_offEdgeInfoList != null) { - final String name = "off_line" + _totalLines; - boolean hasColors = false; - final boolean hasNormals = _dataStore.getNormals() != null && !_dataStore.getNormals().isEmpty(); - final int vertexCount = _offEdgeInfoList.size() * 2; - final Vector3[] vertices = new Vector3[vertexCount]; - final Vector3[] normals = hasNormals ? null : new Vector3[vertexCount]; - ReadOnlyColorRGBA[] colors = null; - final IndexBufferData<? extends Buffer> indices = BufferUtils.createIndexBufferData(vertexCount, - vertexCount - 1); - int edgeVertexIndex = 0; - for (final OffEdgeInfo offEdgeInfo : _offEdgeInfoList) { - indices.put(edgeVertexIndex).put(edgeVertexIndex + 1); - vertices[edgeVertexIndex] = _dataStore.getVertices().get(offEdgeInfo.getIndex1()); - vertices[edgeVertexIndex + 1] = _dataStore.getVertices().get(offEdgeInfo.getIndex2()); - if (hasNormals) { - normals[edgeVertexIndex] = _dataStore.getNormals().get(offEdgeInfo.getIndex1()); - normals[edgeVertexIndex + 1] = _dataStore.getNormals().get(offEdgeInfo.getIndex2()); - } - if (offEdgeInfo.getColor() != null) { - if (colors == null) { - colors = new ReadOnlyColorRGBA[vertexCount]; - } - colors[edgeVertexIndex] = offEdgeInfo.getColor(); - colors[edgeVertexIndex + 1] = offEdgeInfo.getColor(); - hasColors = true; + void replaceNullFaceColorsByDefaultFaceColorIfColoredFaces() { + // if there's at least one colored face + if (_offFaceInfoList != null && !_offFaceInfoList.isEmpty() + && _offFaceInfoList.stream().anyMatch((final OffFaceInfo faceInfo) -> faceInfo.getColor() != null)) { + _offFaceInfoList.stream().forEach((final OffFaceInfo faceInfo) -> { + // if a face has no color + if (faceInfo.getColor() == null) { + // sets a default color + faceInfo.setColor(new ColorRGBA(0.666f, 0.666f, 0.666f, 0.666f)); } - edgeVertexIndex += 2; - } - final Line line = new Line(name, vertices, normals, colors, null); - indices.rewind(); - line.getMeshData().setIndices(indices); - final EnumSet<MatchCondition> matchConditions = EnumSet.noneOf(MatchCondition.class); - if (hasNormals) { - matchConditions.add(MatchCondition.Normal); - } - if (hasColors) { - matchConditions.add(MatchCondition.Color); - } - _geometryTool.minimizeVerts(line, matchConditions); - - final TextureState tState = getTextureState(); - if (tState != null) { - line.setRenderState(tState); - } - - line.updateModelBound(); - _totalLines++; - _offEdgeInfoList = null; + }); } + } + + @SuppressWarnings("null") + void commitObjects() { if (_offFaceInfoList != null) { final String name = "off_mesh" + _totalMeshes; final Mesh mesh = new Mesh(name); - boolean hasTexCoordsInFaces = false; - final boolean hasTexCoordsInVertices = _dataStore.getTextureCoordinates() != null + boolean hasColorsInFaces = false; + final boolean hasTexCoords = _dataStore.getTextureCoordinates() != null && !_dataStore.getTextureCoordinates().isEmpty(); final boolean hasNormals = _dataStore.getNormals() != null && !_dataStore.getNormals().isEmpty(); - final boolean hasColors = _dataStore.getColors() != null && !_dataStore.getColors().isEmpty(); + final boolean hasColorsInVertices = _dataStore.getColors() != null && !_dataStore.getColors().isEmpty(); int vertexCount = 0; for (final OffFaceInfo offFaceInfo : _offFaceInfoList) { vertexCount += offFaceInfo.getVertexIndices().size(); - if (offFaceInfo.getTextureCoordinates() != null && !offFaceInfo.getTextureCoordinates().isEmpty()) { - hasTexCoordsInFaces = true; + if (offFaceInfo.getColor() != null) { + hasColorsInFaces = true; } } final FloatBuffer vertices = BufferUtils.createVector3Buffer(vertexCount); @@ -192,10 +143,10 @@ public class OffGeometryStore { vertexCount - 1); final FloatBuffer normals = hasNormals ? BufferUtils.createFloatBuffer(vertices.capacity()) : null; - final FloatBuffer colors = hasColors ? BufferUtils.createFloatBuffer(vertexCount * 4) : null; - final FloatBuffer uvs = hasTexCoordsInFaces || hasTexCoordsInVertices - ? BufferUtils.createFloatBuffer(vertexCount * 2) + final FloatBuffer colors = hasColorsInFaces || hasColorsInVertices + ? BufferUtils.createFloatBuffer(vertexCount * 4) : null; + final FloatBuffer uvs = hasTexCoords ? BufferUtils.createFloatBuffer(vertexCount * 2) : null; int dummyVertexIndex = 0; final List<IndexMode> indexModeList = new ArrayList<>(); @@ -239,20 +190,19 @@ public class OffGeometryStore { final Vector3 normal = _dataStore.getNormals().get(vertexIndex.intValue()); normals.put(normal.getXf()).put(normal.getYf()).put(normal.getZf()); } - if (hasColors) { + if (hasColorsInVertices) { final ColorRGBA color = _dataStore.getColors().get(vertexIndex.intValue()); colors.put(color.getRed()).put(color.getGreen()).put(color.getBlue()).put(color.getAlpha()); } - if (hasTexCoordsInVertices) { + if (hasTexCoords) { final Vector2 texCoords = _dataStore.getTextureCoordinates().get(vertexIndex.intValue()); uvs.put(texCoords.getXf()).put(texCoords.getYf()); } dummyVertexIndex++; } - if (hasTexCoordsInFaces) { - for (final Float texCoord : offFaceInfo.getTextureCoordinates()) { - uvs.put(texCoord); - } + if (hasColorsInFaces) { + final ColorRGBA color = offFaceInfo.getColor(); + colors.put(color.getRed()).put(color.getGreen()).put(color.getBlue()).put(color.getAlpha()); } } } @@ -278,12 +228,12 @@ public class OffGeometryStore { mesh.getMeshData().setNormalBuffer(normals); matchConditions.add(MatchCondition.Normal); } - if (hasColors) { + if (hasColorsInVertices || hasColorsInFaces) { colors.rewind(); mesh.getMeshData().setColorBuffer(colors); matchConditions.add(MatchCondition.Color); } - if (hasTexCoordsInFaces || hasTexCoordsInVertices) { + if (hasTexCoords) { uvs.rewind(); mesh.getMeshData().setTextureBuffer(uvs, 0); matchConditions.add(MatchCondition.UVs); @@ -309,6 +259,5 @@ public class OffGeometryStore { void cleanup() { _offFaceInfoList = null; - _offEdgeInfoList = null; } } diff --git a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffImporter.java b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffImporter.java index 74c44e3..80221fd 100644 --- a/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffImporter.java +++ b/ardor3d-extras/src/main/java/com/ardor3d/extension/model/off/OffImporter.java @@ -445,6 +445,7 @@ public class OffImporter { final int maxExpectedValueCountPerVertexLine = expectedValueCountPerVertexLineExcludingColorValues + offKeyword.getMaxColorValuesPerTuple(); // reads the vertices, normals, colors and/or texture coordinates for each vertex in that order + // FIXME handle other orders for (int vertexIndex = 0; vertexIndex < numberOfVertices.intValue(); vertexIndex++) { // skips comment lines, comments and empty lines do { @@ -482,8 +483,6 @@ public class OffImporter { if (valueList.size() <= maxExpectedValueCountPerVertexLine) { OffImporter.LOGGER.log(Level.INFO, "Coords: " + valueList.stream().map(Number::toString).collect(Collectors.joining(" "))); - // TODO put the values into the data store (vertices, normals, colors and/or texture - // coordinates) if (offKeyword.getVertexValuesPerTuple() == 3) { store.getDataStore().getVertices().add(new Vector3(valueList.get(0).doubleValue(), valueList.get(1).doubleValue(), valueList.get(2).doubleValue())); @@ -513,7 +512,7 @@ public class OffImporter { // nothing to do break; case 1: - // TODO store the color map somewhere + // TODO store the color index somewhere break; case 3: final ColorRGBA rgb = new ColorRGBA(valueList.get(nextIndex).floatValue(), @@ -533,7 +532,6 @@ public class OffImporter { if (valueList.get(nextIndex) instanceof Integer) { rgba.divideLocal(255.0f); } - rgba.setAlpha(1.0f); store.getDataStore().getColors().add(rgba); break; } @@ -597,12 +595,44 @@ public class OffImporter { IntStream.rangeClosed(1, vertexIndexCount).mapToObj(valueList::get) .mapToInt(Number::intValue).forEachOrdered(faceInfo::addVertexIndex); final int colorComponentCount = valueList.size() - vertexIndexCount - 1; - if (0 < colorComponentCount) { - // TODO put the colors into the geometry store + switch (colorComponentCount) { + case 0: + // no declared color + break; + case 1: + // TODO store the color index somewhere + break; + case 3: + final ColorRGBA rgb = new ColorRGBA( + valueList.get(vertexIndexCount + 1).floatValue(), + valueList.get(vertexIndexCount + 2).floatValue(), + valueList.get(vertexIndexCount + 3).floatValue(), 0.0f); + if (valueList.get(vertexIndexCount + 1) instanceof Integer) { + rgb.divideLocal(255.0f); + } + rgb.setAlpha(1.0f); + faceInfo.setColor(rgb); + break; + case 4: + final ColorRGBA rgba = new ColorRGBA( + valueList.get(vertexIndexCount + 1).floatValue(), + valueList.get(vertexIndexCount + 2).floatValue(), + valueList.get(vertexIndexCount + 3).floatValue(), + valueList.get(vertexIndexCount + 4).floatValue()); + if (valueList.get(vertexIndexCount + 1) instanceof Integer) { + rgba.divideLocal(255.0f); + } + faceInfo.setColor(rgba); + break; } store.addFace(faceInfo); } } + /** + * The faces must have a consistent color behavior: either they all have a color or none has a + * color. If some faces are colored and some aren't, it gives them a default color + */ + store.replaceNullFaceColorsByDefaultFaceColorIfColoredFaces(); } catch (final IOException ioe) { throw new Exception("IO Error on line " + parser.lineno(), ioe); } |