/* * Copyright 2013 MovingBlocks * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.terasology.rendering.assets.mesh; import gnu.trove.list.TFloatList; import gnu.trove.list.TIntList; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.terasology.assets.ResourceUrn; import org.terasology.assets.format.AbstractAssetFileFormat; import org.terasology.assets.format.AssetDataFile; import org.terasology.assets.module.annotations.RegisterAssetFileFormat; import org.terasology.rendering.collada.ColladaLoader; import org.terasology.rendering.collada.ColladaParseException; import java.io.BufferedInputStream; import java.io.IOException; import java.util.List; /** * Importer for Collada data exchange model files. Supports mesh data * <p> * The development of this loader was greatly influenced by * http://www.wazim.com/Collada_Tutorial_1.htm * */ @RegisterAssetFileFormat public class ColladaMeshFormat extends AbstractAssetFileFormat<MeshData> { private static final Logger logger = LoggerFactory.getLogger(ColladaMeshFormat.class); public ColladaMeshFormat() { super("dae"); } @Override public MeshData load(ResourceUrn urn, List<AssetDataFile> inputs) throws IOException { logger.info("Loading mesh for " + urn); ColladaLoader loader = new ColladaLoader(); try (BufferedInputStream stream = inputs.get(0).openStream()) { loader.parseMeshData(stream); } catch (ColladaParseException e) { throw new IOException("Error loading collada mesh for " + urn, e); } MeshData data = new MeshData(); TFloatList colorsMesh = data.getColors(); TFloatList verticesMesh = data.getVertices(); TFloatList texCoord0Mesh = data.getTexCoord0(); TFloatList normalsMesh = data.getNormals(); TIntList indicesMesh = data.getIndices(); // Scale vertices coordinates by unitsPerMeter for (int i = 0; i < loader.getVertices().size(); i++) { float originalVertexValue = loader.getVertices().get(i); float adjustedVertexValue = (float) (originalVertexValue * loader.getUnitsPerMeter()); verticesMesh.add(adjustedVertexValue); } colorsMesh.addAll(loader.getColors()); texCoord0Mesh.addAll(loader.getTexCoord0()); normalsMesh.addAll(loader.getNormals()); indicesMesh.addAll(loader.getIndices()); if (data.getVertices() == null) { throw new IOException("No vertices define"); } //if (data.getNormals() == null || data.getNormals().size() != data.getVertices().size()) { // throw new IOException("The number of normals does not match the number of vertices."); //} if (((null == data.getColors()) || (0 == data.getColors().size())) && ((null == data.getTexCoord0()) || (0 == data.getTexCoord0().size()))) { throw new IOException("There must be either texture coordinates or vertex colors provided."); } if ((null != data.getTexCoord0()) && (0 != data.getTexCoord0().size())) { if (data.getTexCoord0().size() / 2 != data.getVertices().size() / 3) { throw new IOException("The number of tex coords (" + data.getTexCoord0().size() / 2 + ") does not match the number of vertices (" + data.getVertices().size() / 3 + ")."); } } if ((null != data.getColors()) && (0 != data.getColors().size())) { if (data.getColors().size() / 4 != data.getVertices().size() / 3) { throw new IOException("The number of vertex colors (" + data.getColors().size() / 4 + ") does not match the number of vertices (" + data.getVertices().size() / 3 + ")."); } } return data; } }