Files
ReplayModCinematic/src/main/java/com/replaymod/render/blend/data/DMesh.java
2018-03-04 16:28:29 +01:00

301 lines
12 KiB
Java

package com.replaymod.render.blend.data;
import org.blender.dna.CustomData;
import org.blender.dna.CustomDataLayer;
import org.blender.dna.Image;
import org.blender.dna.MEdge;
import org.blender.dna.MFace;
import org.blender.dna.MLoop;
import org.blender.dna.MLoopCol;
import org.blender.dna.MLoopUV;
import org.blender.dna.MPoly;
import org.blender.dna.MTexPoly;
import org.blender.dna.MVert;
import org.blender.dna.Material;
import org.blender.dna.Mesh;
import org.cakelab.blender.io.block.BlockCodes;
import org.cakelab.blender.nio.CArrayFacade;
import org.cakelab.blender.nio.CPointer;
import org.lwjgl.util.vector.Vector2f;
import org.lwjgl.util.vector.Vector3f;
//#if MC>=10904
import net.minecraft.util.math.Vec3i;
//#else
//$$ import net.minecraft.util.Vec3i;
//#endif
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
public class DMesh {
public final DId id = new DId(BlockCodes.ID_ME);
public final List<Vertex> vertices = new ArrayList<>();
public final List<Edge> edges = new ArrayList<>();
public final List<Face> faces = new ArrayList<>();
public final List<Loop> loops = new ArrayList<>();
public final List<Poly> polys = new ArrayList<>();
public final List<DMaterial> materials = new ArrayList<>();
public CPointer<Mesh> serialize(Serializer serializer) throws IOException {
return serializer.maybeMajor(this, id, Mesh.class, () -> {
List<CPointer<Material>> materials = new ArrayList<>();
List<CPointer<Image>> images = new ArrayList<>();
for (DMaterial material : this.materials) {
materials.add(material.serialize(serializer));
images.add(material.textures.isEmpty() ? null : material.textures.get(0).texture.image.serialize(serializer));
}
return mesh -> {
mesh.setDrawflag(3 /* Edges & Faces */);
CArrayFacade<CPointer<Material>> mat = serializer.writeDataPArray(Material.class, materials.size(), materials::get);
mesh.setMat(mat);
mesh.setTotcol((short) materials.size());
if (!vertices.isEmpty()) {
CArrayFacade<MVert> mVerts = serializer.writeData(MVert.class, vertices.size(),
(i, mVert) -> vertices.get(i).serialize(mVert));
CustomDataLayer vDataLayer = serializer.writeData(CustomDataLayer.class);
vDataLayer.setType(0 /* CD_MVERT */);
vDataLayer.setData(mVerts.cast(Object.class));
CustomData vData = mesh.getVdata();
vData.setMaxlayer(1);
vData.setTotlayer(1);
vData.setLayers(vDataLayer.__io__addressof());
mesh.setMvert(mVerts);
mesh.setTotvert(vertices.size());
}
if (!edges.isEmpty()) {
CArrayFacade<MEdge> mEdges = serializer.writeData(MEdge.class, edges.size(),
(i, mEdge) -> edges.get(i).serialize(mEdge));
CustomDataLayer eDataLayer = serializer.writeData(CustomDataLayer.class);
eDataLayer.setType(3 /* CD_MEDGE */);
eDataLayer.setData(mEdges.cast(Object.class));
CustomData eData = mesh.getEdata();
eData.setMaxlayer(1);
eData.setTotlayer(1);
eData.setLayers(eDataLayer.__io__addressof());
mesh.setMedge(mEdges);
mesh.setTotedge(edges.size());
mesh.setMface(serializer.writeData(MFace.class, faces.size(),
(i, mFace) -> faces.get(i).serialize(mFace)));
mesh.setTotface(faces.size());
}
if (!loops.isEmpty()) {
CArrayFacade<MLoop> mLoops = serializer.writeData(MLoop.class, loops.size(),
(i, mLoop) -> loops.get(i).serialize(mLoop));
CArrayFacade<MLoopUV> mLoopUVs = serializer.writeData(MLoopUV.class, loops.size(),
(i, mLoopUV) -> loops.get(i).serialize(mLoopUV));
CArrayFacade<MLoopCol> mLoopCols = serializer.writeData(MLoopCol.class, loops.size(),
(i, mLoopCol) -> loops.get(i).serialize(mLoopCol));
CArrayFacade<CustomDataLayer> dataLayers = serializer.writeData(CustomDataLayer.class, 3);
int i = 0;
CustomDataLayer luvDataLayer = dataLayers.get(i++);
luvDataLayer.setType(16 /* CD_MLOOPUV */);
luvDataLayer.setData(mLoopUVs.cast(Object.class));
CustomDataLayer lcolDataLayer = dataLayers.get(i++);
lcolDataLayer.setType(17 /* CD_MLOOPCOL */);
lcolDataLayer.setData(mLoopCols.cast(Object.class));
CustomDataLayer lDataLayer = dataLayers.get(i++);
lDataLayer.setType(26 /* CD_MLOOP */);
lDataLayer.setData(mLoops.cast(Object.class));
CustomData lData = mesh.getLdata();
lData.setMaxlayer(i);
lData.setTotlayer(i);
lData.setLayers(dataLayers);
mesh.setMloop(mLoops);
mesh.setMloopuv(mLoopUVs);
mesh.setTotloop(loops.size());
}
if (!polys.isEmpty()) {
CArrayFacade<MPoly> mPolys = serializer.writeData(MPoly.class, polys.size(),
(i, mPoly) -> polys.get(i).serialize(mPoly));
CArrayFacade<MTexPoly> mTexPolys = serializer.writeData(MTexPoly.class, polys.size(),
(i, mTexPoly) -> mTexPoly.setTpage(images.get(polys.get(i).materialSlot)));
CArrayFacade<CustomDataLayer> dataLayers = serializer.writeData(CustomDataLayer.class, mTexPolys != null ? 2 : 1);
int i = 0;
if (mTexPolys != null) {
CustomDataLayer pTexDataLayer = dataLayers.get(i++);
pTexDataLayer.getName().fromString("UVMap");
pTexDataLayer.setType(15 /* CD_MTEXPOLY */);
pTexDataLayer.setData(mTexPolys.cast(Object.class));
}
CustomDataLayer pDataLayer = dataLayers.get(i++);
pDataLayer.setType(25 /* CD_MPOLY */);
pDataLayer.setData(mPolys.cast(Object.class));
CustomData pData = mesh.getPdata();
pData.setMaxlayer(i);
pData.setTotlayer(i);
pData.setLayers(dataLayers);
mesh.setMpoly(mPolys);
mesh.setMtpoly(mTexPolys);
mesh.setTotpoly(polys.size());
}
};
});
}
public void addTriangle(DMesh.Vertex v1, DMesh.Vertex v2, DMesh.Vertex v3,
Vector2f uv1, Vector2f uv2, Vector2f uv3,
int c1, int c2, int c3,
int materialSlot) {
int vOffset = vertices.size();
int eOffset = edges.size();
int lOffset = loops.size();
vertices.add(v1);
vertices.add(v2);
vertices.add(v3);
edges.add(new Edge(vOffset , vOffset + 1));
edges.add(new Edge(vOffset + 1, vOffset + 2));
edges.add(new Edge(vOffset + 2, vOffset ));
loops.add(new Loop(vOffset , eOffset , uv1.x, uv1.y, c1));
loops.add(new Loop(vOffset + 1, eOffset + 1, uv2.x, uv2.y, c2));
loops.add(new Loop(vOffset + 2, eOffset + 2, uv3.x, uv3.y, c3));
polys.add(new Poly(lOffset, 3, materialSlot));
}
public void addQuad(DMesh.Vertex v1, DMesh.Vertex v2, DMesh.Vertex v3, DMesh.Vertex v4,
Vector2f uv1, Vector2f uv2, Vector2f uv3, Vector2f uv4,
int c1, int c2, int c3, int c4,
int materialSlot) {
int vOffset = vertices.size();
int eOffset = edges.size();
int lOffset = loops.size();
vertices.add(v1);
vertices.add(v2);
vertices.add(v3);
vertices.add(v4);
edges.add(new Edge(vOffset , vOffset + 1));
edges.add(new Edge(vOffset + 1, vOffset + 2));
edges.add(new Edge(vOffset + 2, vOffset + 3));
edges.add(new Edge(vOffset + 3, vOffset ));
loops.add(new Loop(vOffset , eOffset , uv1.x, uv1.y, c1));
loops.add(new Loop(vOffset + 1, eOffset + 1, uv2.x, uv2.y, c2));
loops.add(new Loop(vOffset + 2, eOffset + 2, uv3.x, uv3.y, c3));
loops.add(new Loop(vOffset + 3, eOffset + 3, uv4.x, uv4.y, c4));
polys.add(new Poly(lOffset, 4, materialSlot));
}
public static class Vertex {
public Vector3f pos;
public Vec3i norm = Vec3i.NULL_VECTOR;
public Vertex(float x, float y, float z) {
this.pos = new Vector3f(x, y, z);
}
public void serialize(MVert mVert) throws IOException {
CArrayFacade<Float> pos = mVert.getCo();
pos.set(0, this.pos.x);
pos.set(1, this.pos.y);
pos.set(2, this.pos.z);
CArrayFacade<Short> norm = mVert.getNo();
norm.set(0, (short) this.norm.getX());
norm.set(1, (short) this.norm.getY());
norm.set(2, (short) this.norm.getZ());
}
}
public static class Edge {
public int v1, v2;
public Edge(int v1, int v2) {
this.v1 = v1;
this.v2 = v2;
}
public void serialize(MEdge mEdge) throws IOException {
mEdge.setV1(v1);
mEdge.setV2(v2);
}
}
public static class Loop {
public int vertex, edge;
public float u, v;
public int col;
public Loop(int vertex, int edge,
float u, float v,
int col) {
this.vertex = vertex;
this.edge = edge;
this.u = u;
this.v = v;
this.col = col;
}
public void serialize(MLoop mLoop) throws IOException {
mLoop.setV(vertex);
mLoop.setE(edge);
}
public void serialize(MLoopUV mLoop) throws IOException {
CArrayFacade<Float> uv = mLoop.getUv();
uv.set(0, u);
uv.set(1, v);
}
public void serialize(MLoopCol mLoop) throws IOException {
mLoop.setR((byte) ((col ) & 0xff));
mLoop.setG((byte) ((col >> 8) & 0xff));
mLoop.setB((byte) ((col >> 16) & 0xff));
mLoop.setA((byte) ((col >> 24) & 0xff));
}
}
public static class Poly {
public int loopStart, size;
public short materialSlot;
public Poly(int loopStart, int size, int materialSlot) {
this.loopStart = loopStart;
this.size = size;
this.materialSlot = (short) materialSlot;
}
public void serialize(MPoly mPoly) throws IOException {
mPoly.setLoopstart(loopStart);
mPoly.setTotloop(size);
mPoly.setMat_nr(materialSlot);
}
}
public static class Face {
public int v1, v2, v3, v4;
public Face(int v1, int v2, int v3, int v4) {
this.v1 = v1;
this.v2 = v2;
this.v3 = v3;
this.v4 = v4;
}
public void serialize(MFace mFace) throws IOException {
mFace.setV1(v1);
mFace.setV2(v2);
mFace.setV3(v3);
mFace.setV4(v4);
}
}
}