Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions .github/workflows/gradle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ jobs:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v6
- name: Set up JDK 17
uses: actions/setup-java@v3
uses: actions/setup-java@v5
with:
java-version: '17'
distribution: 'temurin'
Expand All @@ -34,9 +34,9 @@ jobs:
- name: Build with Gradle
uses: gradle/gradle-build-action@67421db6bd0bf253fb4bd25b31ebb98943c375e1
with:
arguments: shadowJar
arguments: build
- name: Upload Nightly Build
uses: actions/upload-artifact@v3
uses: actions/upload-artifact@v6
if: success()
with:
name: skript-particle-nightly
Expand Down
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,7 @@
/build/
/.git/
/src/test/skriptparticle/
CLAUDE.md
/.claude
/shapes-lib/build
/skript-particle/build
1 change: 1 addition & 0 deletions gradle.properties
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
version = 1.4.0
jomlVersion = 1.10.5
2 changes: 1 addition & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1-bin.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
3 changes: 2 additions & 1 deletion settings.gradle
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
rootProject.name = 'skript-particle'
rootProject.name = 'skript-particle-root'
include 'shapes-lib', 'skript-particle'
17 changes: 17 additions & 0 deletions shapes-lib/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
plugins {
id 'java-library'
}

group = 'com.sovdee'

repositories {
mavenCentral()
}

dependencies {
api "org.joml:joml:${jomlVersion}"
}

java {
toolchain.languageVersion.set(JavaLanguageVersion.of(21))
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
package com.sovdee.shapes.sampling;

import com.sovdee.shapes.shapes.Shape;
import org.joml.Quaterniond;
import org.joml.Vector3d;

import java.util.Comparator;
import java.util.LinkedHashSet;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;

/**
* Default implementation of {@link PointSampler} with hash-based caching.
*/
public class DefaultPointSampler implements PointSampler {

private SamplingStyle style = SamplingStyle.OUTLINE;
private double density = 0.25;
private Comparator<Vector3d> ordering;
private final UUID uuid;
private DrawContext drawContext;

// Cache
private Set<Vector3d> cachedPoints = new LinkedHashSet<>();
private CacheState lastState;
private boolean needsUpdate = false;

public DefaultPointSampler() {
this.uuid = UUID.randomUUID();
this.lastState = new CacheState(style, 0, 1.0, 0, density, 0);
}

@Override
public Set<Vector3d> getPoints(Shape shape) {
return getPoints(shape, shape.getOrientation());
}

@Override
public Set<Vector3d> getPoints(Shape shape, Quaterniond orientation) {
CacheState state = new CacheState(style, orientation.hashCode(),
shape.getScale(), shape.getOffset().hashCode(), density, shape.getVersion());
if (shape.isDynamic() || needsUpdate || !state.equals(lastState) || cachedPoints.isEmpty()) {
Set<Vector3d> points = (ordering != null) ? new TreeSet<>(ordering) : new LinkedHashSet<>();

shape.beforeSampling(density);
switch (style) {
case OUTLINE -> shape.generateOutline(points, density);
case SURFACE -> shape.generateSurface(points, density);
case FILL -> shape.generateFilled(points, density);
}
shape.afterSampling(points);

for (Vector3d point : points) {
orientation.transform(point);
point.mul(shape.getScale());
point.add(shape.getOffset());
}
cachedPoints = points;
lastState = state;
needsUpdate = false;
}
return cachedPoints;
}

public void markDirty() {
needsUpdate = true;
}

@Override
public SamplingStyle getStyle() { return style; }

@Override
public void setStyle(SamplingStyle style) {
this.style = style;
this.needsUpdate = true;
}

@Override
public double getDensity() { return density; }

@Override
public void setDensity(double density) {
this.density = Math.max(density, Shape.EPSILON);
this.needsUpdate = true;
}

@Override
public Comparator<Vector3d> getOrdering() { return ordering; }

@Override
public void setOrdering(Comparator<Vector3d> ordering) {
this.ordering = ordering;
this.needsUpdate = true;
}

@Override
public UUID getUUID() { return uuid; }

@Override
public DrawContext getDrawContext() { return drawContext; }

@Override
public void setDrawContext(DrawContext context) { this.drawContext = context; }

@Override
public DefaultPointSampler clone() {
try {
DefaultPointSampler copy = (DefaultPointSampler) super.clone();
// Don't share the cache
copy.cachedPoints = new LinkedHashSet<>();
copy.needsUpdate = true;
if (drawContext != null)
copy.drawContext = drawContext.copy();
return copy;
} catch (CloneNotSupportedException e) {
throw new AssertionError(e);
}
}

private record CacheState(SamplingStyle style, int orientationHash, double scale,
int offsetHash, double density, long shapeVersion) {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package com.sovdee.shapes.sampling;

/**
* Client-provided rendering metadata. Implementations are opaque to the library.
*/
public interface DrawContext {
DrawContext copy();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package com.sovdee.shapes.sampling;

import com.sovdee.shapes.shapes.Shape;
import org.joml.Quaterniond;
import org.joml.Vector3d;

import java.util.Comparator;
import java.util.Set;
import java.util.UUID;

/**
* Responsible for sampling points from a {@link Shape}'s geometry.
* Manages sampling configuration (style, density, ordering) and caching.
*/
public interface PointSampler extends Cloneable {

SamplingStyle getStyle();
void setStyle(SamplingStyle style);

double getDensity();
void setDensity(double density);

Comparator<Vector3d> getOrdering();
void setOrdering(Comparator<Vector3d> ordering);

UUID getUUID();

DrawContext getDrawContext();
void setDrawContext(DrawContext context);

/**
* Samples points from the given shape using the shape's own orientation.
*/
Set<Vector3d> getPoints(Shape shape);

/**
* Samples points from the given shape using the given orientation.
*/
Set<Vector3d> getPoints(Shape shape, Quaterniond orientation);

/**
* Computes and sets the density to achieve approximately the given particle count.
*/
default void setParticleCount(Shape shape, int count) {
setDensity(shape.computeDensity(getStyle(), count));
}

PointSampler clone();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.sovdee.shapes.sampling;

/**
* Determines how a shape's geometry is sampled into points.
*/
public enum SamplingStyle {
OUTLINE,
SURFACE,
FILL;

@Override
public String toString() {
return name().toLowerCase();
}
}
Loading
Loading