Move each application to its own submodule

Removed JOML and Bukkit depednencies for the standalone applications
This commit is contained in:
2026-03-15 15:16:42 -04:00
parent ce8165417b
commit c2aa41fe58
33 changed files with 1204 additions and 177 deletions

View File

@@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<parent>
<artifactId>mc-mesh-application-visualizer</artifactId>
<groupId>com.aaaaahhhhhhh.bananapuncher714</groupId>
<version>0.0.1</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>mc-mesh-application-visualizer-test-4</artifactId>
<version>0.0.1</version>
<build>
<plugins>
<plugin>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
<configuration>
<release>8</release>
</configuration>
</plugin>
<plugin>
<artifactId>maven-jar-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.aaaaahhhhhhh.bananapuncher714.mesh.test.MeshingTest4</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,66 @@
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.aaaaahhhhhhh.bananapuncher714</groupId>
<artifactId>mc-mesh-application-visualizer</artifactId>
<version>0.0.1</version>
</parent>
<artifactId>mc-mesh-application-visualizer-test-4</artifactId>
<version>0.0.1</version>
<dependencies>
<dependency>
<groupId>com.aaaaahhhhhhh.bananapuncher714</groupId>
<artifactId>mc-mesh-core</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>com.aaaaahhhhhhh.bananapuncher714</groupId>
<artifactId>mc-mesh-base</artifactId>
<version>0.0.1</version>
<scope>compile</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-shade-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>shade</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.14.1</version>
<configuration>
<release>8</release>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-jar-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<archive>
<manifest>
<addClasspath>true</addClasspath>
<mainClass>com.aaaaahhhhhhh.bananapuncher714.mesh.test.MeshingTest4</mainClass>
</manifest>
</archive>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,404 @@
package com.aaaaahhhhhhh.bananapuncher714.mesh.test;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import com.aaaaahhhhhhh.bananapuncher714.mesh.Mesh;
import com.aaaaahhhhhhh.bananapuncher714.mesh.Polygon;
import com.aaaaahhhhhhh.bananapuncher714.mesh.Point;
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionRuleWinding;
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple;
import com.aaaaahhhhhhh.bananapuncher714.mesh.region.simple.RegionSimple.GluWindingRule;
import com.aaaaahhhhhhh.bananapuncher714.mesh.base.Facet;
import com.aaaaahhhhhhh.bananapuncher714.mesh.base.MeshBuilder;
import com.aaaaahhhhhhh.bananapuncher714.mesh.base.Plane;
import com.aaaaahhhhhhh.bananapuncher714.mesh.base.Vector3d;
/**
* Mesh chunk data to ply2 format
*/
public class MeshingTest4 {
private static final File BASE = new File( System.getProperty( "user.dir" ) );
private static final File CHUNK_DIR = new File( BASE, "chunks" );
private static final File MODEL_DIR = new File( BASE, "chunk_models" );
public static void main( String[] args ) {
if ( CHUNK_DIR.exists() && CHUNK_DIR.isDirectory() ) {
System.out.println( "Found " + CHUNK_DIR.list().length + " files" );
// Omega mesh time
// omegaMesh( CHUNK_DIR, new File( MODEL_DIR, "omega.ply" ) );
final long allStart = System.currentTimeMillis();
final AtomicInteger index = new AtomicInteger( 0 );
final Collection< File > files = Arrays.asList( CHUNK_DIR.listFiles() );
files.parallelStream().forEach( f -> {
final StringBuilder builder = new StringBuilder();
builder.append( "Meshing file: " + f + "\n" );
final long start = System.currentTimeMillis();
final List< Plane > planes = mesh( f, builder );
savePly2( new File( MODEL_DIR, f.getName() + ".ply" ), planes.parallelStream().flatMap( p -> process( p ).parallelStream().map( p::convert ) ).collect( Collectors.toSet() ) );
final long time = System.currentTimeMillis() - start;
builder.append( "\tTook " + time + "ms\n" );
builder.append( "\tCompleted " + index.incrementAndGet() + "/" + files.size() );
System.out.println( builder.toString() );
} );
System.out.println( "Took a total of " + ( System.currentTimeMillis() - allStart ) );
// for ( int i = 0; i < CHUNK_DIR.listFiles().length; ++i ) {
// final File file = CHUNK_DIR.listFiles()[ i ];
// System.out.println( ( i + 1 ) + "/" + CHUNK_DIR.listFiles().length + ":\tMeshing " + file );
// final long start = System.currentTimeMillis();
// final List< Plane > planes = mesh( file );
// savePly2( new File( MODEL_DIR, file.getName() + ".ply" ), planes.parallelStream().flatMap( p -> process( p ).parallelStream().map( p::convert ) ).collect( Collectors.toSet() ) );
// long time = System.currentTimeMillis() - start;
//
// System.out.println( "\tTook " + time + "ms" );
// }
} else {
System.err.println( "No such directory exists: " + CHUNK_DIR );
}
}
private static void savePly2( final File file, Collection< Facet > facets ) {
file.getParentFile().mkdirs();
if ( file.exists() ) {
file.delete();
}
class VectorRef {
int index;
}
class Triangle {
List< VectorRef > refs = new ArrayList< VectorRef >();
}
Map< Vector3d, VectorRef > vertices = new HashMap< Vector3d, VectorRef >();
Collection< Triangle > triangles = new HashSet< Triangle >();
// Convert each facet to a triangle
for ( final Facet facet : facets ) {
if ( facet.points.size() != 3 ) {
System.out.println( "Warning: Facet is not a triangle!" );
}
final Triangle triangle = new Triangle();
for ( final Vector3d vec : facet.points ) {
VectorRef ref = null;
for ( final Entry< Vector3d, VectorRef > entry : vertices.entrySet() ) {
final Vector3d existingVec = entry.getKey();
if ( existingVec.distanceSquared( vec ) < 1e-8 ) {
ref = entry.getValue();
break;
}
}
if ( ref == null ) {
ref = new VectorRef();
vertices.put( vec, ref );
}
triangle.refs.add( ref );
}
triangles.add( triangle );
}
// Sort the vertices
final List< Entry< Vector3d, VectorRef > > sorted = new ArrayList< Entry< Vector3d, VectorRef > >( vertices.entrySet() );
Collections.sort( sorted, ( aEntry, bEntry ) -> {
final Vector3d a = aEntry.getKey();
final Vector3d b = bEntry.getKey();
final double xDiff = a.getX() - b.getX();
if ( xDiff == 0 ) {
final double yDiff = a.getY() - b.getY();
if ( yDiff == 0 ) {
return Double.compare( a.getZ(), b.getZ() );
} else {
return Double.compare( yDiff, 0 );
}
} else {
return Double.compare( xDiff, 0 );
}
} );
try ( PrintWriter writer = new PrintWriter( file ) ) {
writer.println( "ply" );
writer.println( "format ascii 1.0" );
writer.println( "comment Created by java tess" );
writer.println( "element vertex " + sorted.size() );
writer.println( "property float x" );
writer.println( "property float y" );
writer.println( "property float z" );
writer.println( "element face " + triangles.size() );
writer.println( "element property list uchar uint vertex_indices" );
writer.println( "end_header" );
// Write vertices
for ( int i = 0; i < sorted.size(); ++i ) {
final Entry< Vector3d, VectorRef > entry = sorted.get( i );
entry.getValue().index = i;
final Vector3d vector = entry.getKey();
writer.println( String.format( "%f %f %f", vector.getX(), vector.getY(), vector.getZ() ) );
}
for ( final Triangle triangle : triangles ) {
final StringBuilder builder = new StringBuilder();
builder.append( triangle.refs.size() );
for ( final VectorRef ref : triangle.refs ) {
builder.append( " " );
builder.append( ref.index );
}
writer.println( builder.toString() );
}
System.out.println( "\tWriting " + triangles.size() + " triangles and " + sorted.size() + " vertices to " + file );
} catch ( FileNotFoundException e ) {
e.printStackTrace();
}
}
private static void omegaMesh( final File directory, final File output ) {
final List< AABB > allBoxes = new ArrayList< AABB >();
for ( int i = 0; i < directory.listFiles().length; ++i ) {
final File file = directory.listFiles()[ i ];
System.out.println( ( i + 1 ) + "/" + directory.listFiles().length + ": Getting meshes for: " + file );
allBoxes.addAll( getBoxes( file ) );
}
System.out.println( "Gathered " + allBoxes.size() + " boxes" );
final MeshBuilder builder = new MeshBuilder();
int boxCount = 0;
for ( final AABB box : allBoxes ) {
for ( final Facet facet : generateFacetsFor( box ) ) {
builder.addFacet( facet );
}
if ( ++boxCount % 100_000 == 0 ) {
System.out.println( "Added box " + boxCount + "/" + allBoxes.size() + "\t" + ( boxCount / ( double ) allBoxes.size() ) + "%" );
}
}
System.out.println( "Starting to mesh " + builder.planes.size() + " planes" );
final long start = System.currentTimeMillis();
final AtomicInteger counter = new AtomicInteger();
savePly2( output, builder.planes.parallelStream().flatMap( p -> {
final Stream< Facet > facets = process( p ).parallelStream().map( p::convert );
System.out.println( "Finished " + counter.incrementAndGet() + "/" + builder.planes.size() );
return facets;
} ).collect( Collectors.toSet() ) );
System.out.println( "\tTook " + ( System.currentTimeMillis() - start ) + "ms" );
}
private static Collection< Polygon > process( final Plane plane ) {
if ( plane != null ) {
Mesh< RegionSimple > mesh = new Mesh< RegionSimple >( () -> { return new RegionSimple( GluWindingRule.ODD ); } );
for ( Polygon poly : plane.polygons ) {
mesh.addPolygon( poly, RegionRuleWinding.CLOCKWISE );
}
return mesh.meshify();
} else {
System.out.println( "No data!" );
return Collections.emptySet();
}
}
private static List< Plane > mesh( File file, final StringBuilder stringBuilder ) {
String name = file.getName();
String[] split = name.split( "," );
Point location = new Point( Integer.parseInt( split[ 1 ] ), Integer.parseInt( split[ 2 ] ) );
// First parse the file to get a list of all bounding boxes that we can use
List< AABB > boxes = new ArrayList< AABB >();
try ( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) {
String line;
while ( ( line = reader.readLine() ) != null ) {
if ( !line.isEmpty() ) {
String[] values = line.split( "," );
double minX = Double.parseDouble( values[ 0 ] );
double minY = Double.parseDouble( values[ 1 ] );
double minZ = Double.parseDouble( values[ 2 ] );
double maxX = Double.parseDouble( values[ 3 ] );
double maxY = Double.parseDouble( values[ 4 ] );
double maxZ = Double.parseDouble( values[ 5 ] );
boxes.add( new AABB( minX, minY, minZ, maxX, maxY, maxZ ) );
}
}
} catch ( FileNotFoundException e ) {
e.printStackTrace();
return null;
} catch ( IOException e ) {
e.printStackTrace();
return null;
}
// Now that we have a bunch of bounding boxes, do whatever
MeshBuilder builder = new MeshBuilder();
for ( AABB box : boxes ) {
for ( Facet facet : generateFacetsFor( box ) ) {
builder.addFacet( facet );
}
}
if ( stringBuilder != null ) {
stringBuilder.append( "\tParsing chunk " + location + "\n" );
stringBuilder.append( "\tFound " + boxes.size() + " boxes and " + builder.planes.size() + " planes\n" );
} else {
System.out.println( "\tParsing chunk " + location );
System.out.println( "\tFound " + boxes.size() + " boxes and " + builder.planes.size() + " planes" );
}
return builder.planes;
}
private static List< AABB > getBoxes( final File file ) {
final String name = file.getName();
final String[] split = name.split( "," );
final int chunkX = Integer.parseInt( split[ 1 ] );
final int chunkZ = Integer.parseInt( split[ 2 ] );
final int blockX = chunkX << 4;
final int blockZ = chunkZ << 4;
// First parse the file to get a list of all bounding boxes that we can use
final List< AABB > boxes = new ArrayList< AABB >();
try ( BufferedReader reader = new BufferedReader( new FileReader( file ) ) ) {
String line;
while ( ( line = reader.readLine() ) != null ) {
if ( !line.isEmpty() ) {
String[] values = line.split( "," );
double minX = Double.parseDouble( values[ 0 ] );
double minY = Double.parseDouble( values[ 1 ] );
double minZ = Double.parseDouble( values[ 2 ] );
double maxX = Double.parseDouble( values[ 3 ] );
double maxY = Double.parseDouble( values[ 4 ] );
double maxZ = Double.parseDouble( values[ 5 ] );
boxes.add( new AABB( minX + blockX, minY, minZ + blockZ, maxX + blockX, maxY, maxZ + blockZ ) );
}
}
} catch ( FileNotFoundException e ) {
e.printStackTrace();
return Collections.emptyList();
} catch ( IOException e ) {
e.printStackTrace();
return Collections.emptyList();
}
return boxes;
}
private static List< Facet > generateFacetsFor( AABB box ) {
List< Facet > facets = new ArrayList< Facet >();
Vector3d p1 = new Vector3d( box.xmin, box.ymin, box.zmin );
Vector3d p2 = new Vector3d( box.xmin, box.ymin, box.zmax );
Vector3d p3 = new Vector3d( box.xmin, box.ymax, box.zmin );
Vector3d p4 = new Vector3d( box.xmin, box.ymax, box.zmax );
Vector3d p5 = new Vector3d( box.xmax, box.ymin, box.zmin );
Vector3d p6 = new Vector3d( box.xmax, box.ymin, box.zmax );
Vector3d p7 = new Vector3d( box.xmax, box.ymax, box.zmin );
Vector3d p8 = new Vector3d( box.xmax, box.ymax, box.zmax );
{
Facet facet = new Facet();
facet.points.add( p1 );
facet.points.add( p2 );
facet.points.add( p4 );
facet.points.add( p3 );
facet.normal = new Vector3d( -1, 0, 0 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p5 );
facet.points.add( p6 );
facet.points.add( p8 );
facet.points.add( p7 );
facet.normal = new Vector3d( 1, 0, 0 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p1 );
facet.points.add( p2 );
facet.points.add( p6 );
facet.points.add( p5 );
facet.normal = new Vector3d( 0, -1, 0 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p3 );
facet.points.add( p4 );
facet.points.add( p8 );
facet.points.add( p7 );
facet.normal = new Vector3d( 0, 1, 0 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p1 );
facet.points.add( p3 );
facet.points.add( p7 );
facet.points.add( p5 );
facet.normal = new Vector3d( 0, 0, -1 );
facets.add( facet );
}
{
Facet facet = new Facet();
facet.points.add( p2 );
facet.points.add( p4 );
facet.points.add( p8 );
facet.points.add( p6 );
facet.normal = new Vector3d( 0, 0, 1 );
facets.add( facet );
}
return facets;
}
static class AABB {
double xmin, ymin, zmin;
double xmax, ymax, zmax;
AABB( double xmin, double ymin, double zmin, double xmax, double ymax, double zmax ) {
this.xmin = xmin;
this.ymax = ymin;
this.zmin = zmin;
this.xmax = xmax;
this.ymax = ymax;
this.zmax = zmax;
}
}
}