Package info.ata4.unity.cli.extract.mesh

Source Code of info.ata4.unity.cli.extract.mesh.ObjWriter

/*
** 2014 July 10
**
** The author disclaims copyright to this source code.  In place of
** a legal notice, here is a blessing:
**    May you do good and not evil.
**    May you find forgiveness for yourself and forgive others.
**    May you share freely, never taking more than you give.
*/
package info.ata4.unity.cli.extract.mesh;

import info.ata4.unity.DisUnity;
import info.ata4.unity.engine.Mesh;
import info.ata4.unity.engine.struct.Vector2f;
import info.ata4.unity.engine.struct.Vector3f;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
*
* @author Nico Bergemann <barracuda415 at yahoo.de>
*/
class ObjWriter extends MeshWriter {
   
    private PrintStream ps;
    private List<Vector2f> vts;
    private List<Vector3f> vns;

    ObjWriter(MeshHandler handler) {
        super(handler);
    }
   
    @Override
    public void write(MeshData meshData) throws IOException {
        Mesh mesh = meshData.getMesh();
       
        vns = meshData.getNormals();
        vts = meshData.getUV1();
       
        // use second layer if the first one is unused
        if (vts.isEmpty()) {
            vts = meshData.getUV2();
        }
       
        try (PrintStream ps_ = handler.getPrintStream(mesh.name, "obj")) {
            ps = ps_;
       
            writeComment("Created by " + DisUnity.getSignature());

            // write vertex array
            for (Vector3f v : meshData.getVertices()) {
                writeVertex(v);
            }

            // write normal array
            for (Vector3f vn : vns) {
                writeNormal(vn);
            }

            // write texture coordinate array
            for (Vector2f vt : vts) {
                writeUV(vt);
            }

            writeLine();
            writeObject(mesh.name);
            writeSmooth(1);

            final int subMeshCount = mesh.subMeshes.size();
            final int vertsPerFace = 3;
            for (int i = 0; i < subMeshCount; i++) {
                // write sub-meshes as materials
                if (subMeshCount == 1) {
                    writeUsemtl(mesh.name);
                } else {
                    writeUsemtl(String.format("%s_%d", mesh.name, i));
                }
               
                // write sub-mesh triangles
                List<Integer> subMeshTriangles = meshData.getTriangles().get(i);
                List<Integer> faceTriangles = new ArrayList<>();
               
                for (Integer t : subMeshTriangles) {
                    faceTriangles.add(t);
                   
                    if (faceTriangles.size() == vertsPerFace) {
                        writeFace(faceTriangles);
                        faceTriangles.clear();
                    }
                }

                writeLine();
            }
        }
    }

    private void writeLine() {
        ps.println();
    }

    private void writeComment(String comment) {
        ps.print("# ");
        ps.println(comment);
    }

    private void writeObject(String name) {
        ps.print("g ");
        ps.println(name);
    }

    private void writeSmooth(int smooth) {
        ps.print("s ");
        ps.println(smooth);
    }

    private void writeUsemtl(String material) {
        ps.print("usemtl ");
        ps.println(material);
    }

    private void writeFace(List<Integer> indices) {
        ps.print("f ");
       
        // reverse winding to fix normals after x axis has been flipped
        Collections.reverse(indices);
       
        boolean vt = !vts.isEmpty();
        boolean vn = !vns.isEmpty();
       
        for (int index : indices) {
            // OBJ indices start from 1
            int i = index + 1;
           
            ps.print(i);
           
            if (vt || vn) {
                ps.print('/');

                if (vt) {
                    ps.print(i);
                }

                ps.print('/');

                if (vn) {
                    ps.print(i);
                }
            }
           
            ps.print(' ');
        }
       
        ps.print('\n');
    }

    private void writeVector(String prefix, Vector2f v) {
        ps.print(prefix);
        ps.print(' ');
        ps.print(v.x);
        ps.print(' ');
        ps.print(1 - v.y);
        ps.println();
    }

    private void writeVector(String prefix, Vector3f v) {
        ps.print(prefix);
        ps.print(' ');
        ps.print(-v.x);
        ps.print(' ');
        ps.print(v.y);
        ps.print(' ');
        ps.print(v.z);
        ps.println();
    }

    private void writeVertex(Vector3f v) {
        writeVector("v", v);
    }

    private void writeNormal(Vector3f vn) {
        writeVector("vn", vn);
    }

    private void writeUV(Vector2f vt) {
        writeVector("vt", vt);
    }
}
TOP

Related Classes of info.ata4.unity.cli.extract.mesh.ObjWriter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.