mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-23 03:17:53 +01:00
Merge pull request #240 from IThundxr/feat/multi-loader-1.21
Port to 1.21.1
This commit is contained in:
commit
1a89f36130
128 changed files with 1434 additions and 1747 deletions
14
.github/workflows/build.yml
vendored
14
.github/workflows/build.yml
vendored
|
@ -3,7 +3,7 @@ name: Build
|
||||||
on: [ workflow_dispatch, pull_request, push ]
|
on: [ workflow_dispatch, pull_request, push ]
|
||||||
|
|
||||||
env:
|
env:
|
||||||
JAVA_VERSION: 17
|
JAVA_VERSION: 21
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
|
@ -43,13 +43,15 @@ jobs:
|
||||||
path: |
|
path: |
|
||||||
common/build/libs/
|
common/build/libs/
|
||||||
fabric/build/libs/
|
fabric/build/libs/
|
||||||
forge/build/libs/
|
neoforge/build/libs/
|
||||||
|
vanillinFabric/build/libs/
|
||||||
|
vanillinNeoForge/build/libs/
|
||||||
|
|
||||||
test:
|
test:
|
||||||
strategy:
|
strategy:
|
||||||
fail-fast: false
|
fail-fast: false
|
||||||
matrix:
|
matrix:
|
||||||
loader: [ forge, fabric ]
|
loader: [ neoforge, fabric ]
|
||||||
needs: build
|
needs: build
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
|
@ -63,15 +65,15 @@ jobs:
|
||||||
|
|
||||||
- name: Setup Environment Variables
|
- name: Setup Environment Variables
|
||||||
run: |
|
run: |
|
||||||
echo "MOD_VERSION=$(grep '^mod_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ')" >> "$GITHUB_ENV"
|
|
||||||
echo "MINECRAFT_VERSION=$(grep '^minecraft_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ')" >> "$GITHUB_ENV"
|
echo "MINECRAFT_VERSION=$(grep '^minecraft_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ')" >> "$GITHUB_ENV"
|
||||||
echo "FABRIC_API_VERSION=$(grep '^fabric_api_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ' | sed 's/+.*//')" >> "$GITHUB_ENV"
|
echo "FABRIC_API_VERSION=$(grep '^fabric_api_version =' gradle.properties | cut -d'=' -f2 | tr -d ' ' | sed 's/+.*//')" >> "$GITHUB_ENV"
|
||||||
|
|
||||||
- name: Move Test Mod and Flywheel into run/mods
|
- name: Move Test Mod and Flywheel into run/mods
|
||||||
|
# We don't want to recreate the jar name formatting so glob everything over then remove the sources and javadoc jars
|
||||||
run: |
|
run: |
|
||||||
mkdir -p run/mods
|
mkdir -p run/mods
|
||||||
cp ${{ matrix.loader }}/build/libs/flywheel-${{ matrix.loader }}-${{ env.MINECRAFT_VERSION }}-${{ env.MOD_VERSION }}.jar run/mods
|
cp ${{ matrix.loader }}/build/libs/*.jar run/mods
|
||||||
cp ${{ matrix.loader }}/build/libs/flywheel-${{ matrix.loader }}-${{ env.MINECRAFT_VERSION }}-${{ env.MOD_VERSION }}-testmod.jar run/mods
|
rm -f run/mods/*-sources.jar run/mods/*-javadoc.jar
|
||||||
|
|
||||||
# Lock to a specific commit, it would be bad if the tag is re-pushed with unwanted changes
|
# Lock to a specific commit, it would be bad if the tag is re-pushed with unwanted changes
|
||||||
- name: Run the MC client
|
- name: Run the MC client
|
||||||
|
|
|
@ -39,8 +39,8 @@ repositories {
|
||||||
}
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
compileOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-api-${minecraft_version}:${flywheel_version}")
|
compileOnly fg.deobf("dev.engine_room.flywheel:flywheel-neoforge-api-${minecraft_version}:${flywheel_version}")
|
||||||
runtimeOnly fg.deobf("dev.engine_room.flywheel:flywheel-forge-${minecraft_version}:${flywheel_version}")
|
runtimeOnly fg.deobf("dev.engine_room.flywheel:flywheel-neoforge-${minecraft_version}:${flywheel_version}")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
`${flywheel_version}` gets replaced by the version of Flywheel you want to use, eg. `1.0.0-beta`
|
`${flywheel_version}` gets replaced by the version of Flywheel you want to use, eg. `1.0.0-beta`
|
||||||
|
|
|
@ -8,8 +8,8 @@ plugins {
|
||||||
repositories {
|
repositories {
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven("https://maven.minecraftforge.net/") {
|
maven("https://maven.neoforged.net/releases/") {
|
||||||
name = "MinecraftForge"
|
name = "NeoForged"
|
||||||
}
|
}
|
||||||
maven("https://maven.architectury.dev/") {
|
maven("https://maven.architectury.dev/") {
|
||||||
name = "Architectury"
|
name = "Architectury"
|
||||||
|
|
|
@ -13,10 +13,6 @@ open class JarSetExtension(private val project: Project) {
|
||||||
return JarTaskSet.create(project, name, *sourceSetSet)
|
return JarTaskSet.create(project, name, *sourceSetSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun outgoing(name: String, vararg sourceSetSet: SourceSet): JarTaskSet {
|
|
||||||
return JarTaskSet.create(project, name, *sourceSetSet).also { it.createOutgoingConfiguration() }
|
|
||||||
}
|
|
||||||
|
|
||||||
val mainSet: JarTaskSet by lazy {
|
val mainSet: JarTaskSet by lazy {
|
||||||
val jarTask = project.tasks.named<Jar>("jar")
|
val jarTask = project.tasks.named<Jar>("jar")
|
||||||
val remapJarTask = project.tasks.named<RemapJarTask>("remapJar")
|
val remapJarTask = project.tasks.named<RemapJarTask>("remapJar")
|
||||||
|
|
|
@ -23,11 +23,11 @@ import org.gradle.language.jvm.tasks.ProcessResources
|
||||||
class JarTaskSet(
|
class JarTaskSet(
|
||||||
private val project: Project,
|
private val project: Project,
|
||||||
private val name: String,
|
private val name: String,
|
||||||
private val jar: TaskProvider<Jar>,
|
val jar: TaskProvider<Jar>,
|
||||||
private val sources: TaskProvider<Jar>,
|
val sources: TaskProvider<Jar>,
|
||||||
private val javadocJar: TaskProvider<Jar>,
|
val javadocJar: TaskProvider<Jar>,
|
||||||
private val remapJar: TaskProvider<RemapJarTask>,
|
val remapJar: TaskProvider<RemapJarTask>,
|
||||||
private val remapSources: TaskProvider<RemapSourcesJarTask>
|
val remapSources: TaskProvider<RemapSourcesJarTask>
|
||||||
) {
|
) {
|
||||||
|
|
||||||
fun publish(artifactId: String) {
|
fun publish(artifactId: String) {
|
||||||
|
@ -41,10 +41,21 @@ class JarTaskSet(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
fun outgoing(name: String) {
|
||||||
* Create a new configuration that can be consumed by other projects, and export the base jar.
|
outgoingRemapJar("${name}Remap")
|
||||||
*/
|
outgoingJar("${name}Dev")
|
||||||
fun createOutgoingConfiguration() {
|
}
|
||||||
|
|
||||||
|
fun outgoingRemapJar(name: String) {
|
||||||
|
val config = project.configurations.register(name) {
|
||||||
|
isCanBeConsumed = true
|
||||||
|
isCanBeResolved = false
|
||||||
|
}
|
||||||
|
|
||||||
|
project.artifacts.add(config.name, remapJar)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun outgoingJar(name: String) {
|
||||||
val config = project.configurations.register(name) {
|
val config = project.configurations.register(name) {
|
||||||
isCanBeConsumed = true
|
isCanBeConsumed = true
|
||||||
isCanBeResolved = false
|
isCanBeResolved = false
|
||||||
|
|
|
@ -1,30 +1,18 @@
|
||||||
package dev.engine_room.gradle.platform
|
package dev.engine_room.gradle.platform
|
||||||
|
|
||||||
import dev.engine_room.gradle.jarset.JarTaskSet
|
|
||||||
import net.fabricmc.loom.api.LoomGradleExtensionAPI
|
import net.fabricmc.loom.api.LoomGradleExtensionAPI
|
||||||
import net.fabricmc.loom.task.RemapJarTask
|
import net.fabricmc.loom.task.RemapJarTask
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.Task
|
import org.gradle.api.Task
|
||||||
import org.gradle.api.tasks.SourceSet
|
import org.gradle.api.tasks.SourceSet
|
||||||
import org.gradle.api.tasks.SourceSetContainer
|
|
||||||
import org.gradle.api.tasks.compile.JavaCompile
|
|
||||||
import org.gradle.api.tasks.javadoc.Javadoc
|
|
||||||
import org.gradle.jvm.tasks.Jar
|
import org.gradle.jvm.tasks.Jar
|
||||||
import org.gradle.kotlin.dsl.*
|
import org.gradle.kotlin.dsl.assign
|
||||||
import org.gradle.language.jvm.tasks.ProcessResources
|
import org.gradle.kotlin.dsl.named
|
||||||
|
import org.gradle.kotlin.dsl.register
|
||||||
|
import org.gradle.kotlin.dsl.the
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.properties.ReadWriteProperty
|
|
||||||
import kotlin.reflect.KProperty
|
|
||||||
|
|
||||||
open class PlatformExtension(val project: Project) {
|
open class PlatformExtension(val project: Project) {
|
||||||
var commonProject: Project by DependentProject(this.project)
|
|
||||||
|
|
||||||
var modArtifactId: String = "flywheel-${project.name}-${project.property("artifact_minecraft_version")}"
|
|
||||||
|
|
||||||
var apiArtifactId: String = "flywheel-${project.name}-api-${project.property("artifact_minecraft_version")}"
|
|
||||||
|
|
||||||
private val commonSourceSets: SourceSetContainer by lazy { commonProject.the<SourceSetContainer>() }
|
|
||||||
|
|
||||||
fun setupLoomMod(vararg sourceSets: SourceSet) {
|
fun setupLoomMod(vararg sourceSets: SourceSet) {
|
||||||
project.the<LoomGradleExtensionAPI>().mods.maybeCreate("main").apply {
|
project.the<LoomGradleExtensionAPI>().mods.maybeCreate("main").apply {
|
||||||
sourceSets.forEach(::sourceSet)
|
sourceSets.forEach(::sourceSet)
|
||||||
|
@ -56,52 +44,6 @@ open class PlatformExtension(val project: Project) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun compileWithCommonSourceSets(vararg sourceSets: SourceSet) {
|
|
||||||
project.tasks.apply {
|
|
||||||
withType<JavaCompile>().configureEach {
|
|
||||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets.forEach {
|
|
||||||
val commonSourceSet = commonSourceSets.named(it.name).get()
|
|
||||||
|
|
||||||
named<JavaCompile>(it.compileJavaTaskName).configure {
|
|
||||||
source(commonSourceSet.allJava)
|
|
||||||
}
|
|
||||||
named<ProcessResources>(it.processResourcesTaskName).configure {
|
|
||||||
from(commonSourceSet.resources)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setupFatJar(vararg sourceSets: SourceSet) {
|
|
||||||
project.tasks.apply {
|
|
||||||
val extraSourceSets = sourceSets.filter { it.name != "main" }.toList()
|
|
||||||
val commonSources = sourceSets.map { commonSourceSets.named(it.name).get() }
|
|
||||||
|
|
||||||
named<Jar>("jar").configure {
|
|
||||||
extraSourceSets.forEach { from(it.output) }
|
|
||||||
|
|
||||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
named<Javadoc>("javadoc").configure {
|
|
||||||
commonSources.forEach { source(it.allJava) }
|
|
||||||
extraSourceSets.forEach { source(it.allJava) }
|
|
||||||
|
|
||||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
named<Jar>("sourcesJar").configure {
|
|
||||||
commonSources.forEach { from(it.allJava) }
|
|
||||||
extraSourceSets.forEach { from(it.allJava) }
|
|
||||||
|
|
||||||
JarTaskSet.excludeDuplicatePackageInfos(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setupTestMod(sourceSet: SourceSet) {
|
fun setupTestMod(sourceSet: SourceSet) {
|
||||||
project.tasks.apply {
|
project.tasks.apply {
|
||||||
val testModJar = register<Jar>("testModJar") {
|
val testModJar = register<Jar>("testModJar") {
|
||||||
|
@ -124,20 +66,4 @@ open class PlatformExtension(val project: Project) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DependentProject(private val thisProject: Project) : ReadWriteProperty<Any?, Project> {
|
|
||||||
private var value: Project? = null
|
|
||||||
|
|
||||||
override fun getValue(thisRef: Any?, property: KProperty<*>): Project {
|
|
||||||
return value ?: throw IllegalStateException("Property ${property.name} should be initialized before get.")
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setValue(thisRef: Any?, property: KProperty<*>, value: Project) {
|
|
||||||
this.value = value
|
|
||||||
thisProject.evaluationDependsOn(value.path)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun toString(): String =
|
|
||||||
"NotNullProperty(${if (value != null) "value=$value" else "value not initialized yet"})"
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,182 @@
|
||||||
|
package dev.engine_room.gradle.subproject
|
||||||
|
|
||||||
|
import net.fabricmc.loom.api.LoomGradleExtensionAPI
|
||||||
|
import org.gradle.api.JavaVersion
|
||||||
|
import org.gradle.api.Project
|
||||||
|
import org.gradle.api.plugins.BasePluginExtension
|
||||||
|
import org.gradle.api.plugins.JavaPluginExtension
|
||||||
|
import org.gradle.api.publish.PublishingExtension
|
||||||
|
import org.gradle.api.publish.tasks.GenerateModuleMetadata
|
||||||
|
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
||||||
|
import org.gradle.api.tasks.compile.JavaCompile
|
||||||
|
import org.gradle.api.tasks.javadoc.Javadoc
|
||||||
|
import org.gradle.jvm.tasks.Jar
|
||||||
|
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
||||||
|
import org.gradle.kotlin.dsl.*
|
||||||
|
import org.gradle.language.jvm.tasks.ProcessResources
|
||||||
|
|
||||||
|
open class SubprojectExtension(val project: Project) {
|
||||||
|
fun init(archiveBase: String, group: String, version: String) {
|
||||||
|
setBaseProperties(archiveBase, group, version)
|
||||||
|
setupJava()
|
||||||
|
addRepositories()
|
||||||
|
setupLoom()
|
||||||
|
setupDependencies()
|
||||||
|
configureTasks()
|
||||||
|
setupPublishing()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setBaseProperties(archiveBase: String, group: String, version: String) {
|
||||||
|
val dev = System.getenv("RELEASE")?.contentEquals("false", true) ?: true
|
||||||
|
val buildNumber = System.getenv("BUILD_NUMBER")
|
||||||
|
|
||||||
|
val versionSuffix = if (dev && buildNumber != null) "-${buildNumber}" else ""
|
||||||
|
|
||||||
|
project.group = project.property(group) as String
|
||||||
|
project.version = "${project.property(version)}${versionSuffix}"
|
||||||
|
|
||||||
|
project.the<BasePluginExtension>().apply {
|
||||||
|
archivesName = "${archiveBase}-${project.property("artifact_minecraft_version")}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupLoom() {
|
||||||
|
val loom = project.the<LoomGradleExtensionAPI>()
|
||||||
|
loom.silentMojangMappingsLicense()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupJava() {
|
||||||
|
val java_version: String by project
|
||||||
|
|
||||||
|
project.the<JavaPluginExtension>().apply {
|
||||||
|
val javaVersion = JavaVersion.toVersion(java_version)
|
||||||
|
sourceCompatibility = javaVersion
|
||||||
|
targetCompatibility = javaVersion
|
||||||
|
|
||||||
|
toolchain.languageVersion = JavaLanguageVersion.of(java_version)
|
||||||
|
|
||||||
|
withSourcesJar()
|
||||||
|
withJavadocJar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun addRepositories() {
|
||||||
|
project.repositories.apply {
|
||||||
|
mavenCentral()
|
||||||
|
maven("https://maven.parchmentmc.org") {
|
||||||
|
name = "ParchmentMC"
|
||||||
|
}
|
||||||
|
maven("https://maven.tterrag.com/") {
|
||||||
|
name = "tterrag maven"
|
||||||
|
}
|
||||||
|
maven("https://www.cursemaven.com") {
|
||||||
|
name = "CurseMaven"
|
||||||
|
content {
|
||||||
|
includeGroup("curse.maven")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
maven("https://api.modrinth.com/maven") {
|
||||||
|
name = "Modrinth"
|
||||||
|
content {
|
||||||
|
includeGroup("maven.modrinth")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UnstableApiUsage")
|
||||||
|
private fun setupDependencies() {
|
||||||
|
project.dependencies.apply {
|
||||||
|
val minecraft_version: String by project
|
||||||
|
val parchment_minecraft_version: String by project
|
||||||
|
val parchment_version: String by project
|
||||||
|
val loom = project.the<LoomGradleExtensionAPI>()
|
||||||
|
|
||||||
|
add("minecraft", "com.mojang:minecraft:${minecraft_version}")
|
||||||
|
|
||||||
|
add("mappings", loom.layered {
|
||||||
|
officialMojangMappings()
|
||||||
|
parchment("org.parchmentmc.data:parchment-${parchment_minecraft_version}:${parchment_version}@zip")
|
||||||
|
})
|
||||||
|
|
||||||
|
add("api", "com.google.code.findbugs:jsr305:3.0.2")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun configureTasks() {
|
||||||
|
val java_version: String by project
|
||||||
|
|
||||||
|
project.tasks.apply {
|
||||||
|
// make builds reproducible
|
||||||
|
withType<AbstractArchiveTask>().configureEach {
|
||||||
|
isPreserveFileTimestamps = false
|
||||||
|
isReproducibleFileOrder = true
|
||||||
|
}
|
||||||
|
|
||||||
|
// module metadata is often broken on multi-platform projects
|
||||||
|
withType<GenerateModuleMetadata>().configureEach {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
|
|
||||||
|
withType<JavaCompile>().configureEach {
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
options.release = Integer.parseInt(java_version)
|
||||||
|
options.compilerArgs.add("-Xdiags:verbose")
|
||||||
|
}
|
||||||
|
|
||||||
|
withType<Jar>().configureEach {
|
||||||
|
from("${project.rootDir}/LICENSE.md") {
|
||||||
|
into("META-INF")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
withType<Javadoc>().configureEach {
|
||||||
|
options.optionFiles(project.rootProject.file("javadoc-options.txt"))
|
||||||
|
options.encoding = "UTF-8"
|
||||||
|
}
|
||||||
|
|
||||||
|
val replaceProperties = processResourcesExpandProperties.associateWith { project.property(it) as String }
|
||||||
|
|
||||||
|
withType<ProcessResources>().configureEach {
|
||||||
|
inputs.properties(replaceProperties)
|
||||||
|
|
||||||
|
filesMatching(processResourcesExpandFiles) {
|
||||||
|
expand(replaceProperties)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun setupPublishing() {
|
||||||
|
project.the<PublishingExtension>().repositories.apply {
|
||||||
|
maven("file://${project.rootProject.projectDir}/mcmodsrepo")
|
||||||
|
|
||||||
|
if (project.hasProperty("mavendir")) {
|
||||||
|
maven(project.rootProject.file(project.property("mavendir") as String))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val processResourcesExpandFiles = listOf("pack.mcmeta", "fabric.mod.json", "META-INF/neoforge.mods.toml")
|
||||||
|
|
||||||
|
val processResourcesExpandProperties = listOf(
|
||||||
|
"mod_license",
|
||||||
|
"mod_sources",
|
||||||
|
"mod_issues",
|
||||||
|
"mod_homepage",
|
||||||
|
"flywheel_id",
|
||||||
|
"flywheel_name",
|
||||||
|
"flywheel_description",
|
||||||
|
"flywheel_version",
|
||||||
|
"vanillin_id",
|
||||||
|
"vanillin_name",
|
||||||
|
"vanillin_version",
|
||||||
|
"vanillin_description",
|
||||||
|
"flywheel_maven_version_range",
|
||||||
|
"flywheel_semver_version_range",
|
||||||
|
"minecraft_semver_version_range",
|
||||||
|
"minecraft_maven_version_range",
|
||||||
|
"fabric_api_version_range",
|
||||||
|
"neoforge_version_range",
|
||||||
|
)
|
|
@ -3,183 +3,14 @@ package dev.engine_room.gradle.subproject
|
||||||
import dev.engine_room.gradle.jarset.JarSetExtension
|
import dev.engine_room.gradle.jarset.JarSetExtension
|
||||||
import dev.engine_room.gradle.nullability.PackageInfosExtension
|
import dev.engine_room.gradle.nullability.PackageInfosExtension
|
||||||
import dev.engine_room.gradle.transitive.TransitiveSourceSetsExtension
|
import dev.engine_room.gradle.transitive.TransitiveSourceSetsExtension
|
||||||
import net.fabricmc.loom.api.LoomGradleExtensionAPI
|
|
||||||
import org.gradle.api.JavaVersion
|
|
||||||
import org.gradle.api.Plugin
|
import org.gradle.api.Plugin
|
||||||
import org.gradle.api.Project
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.plugins.BasePluginExtension
|
|
||||||
import org.gradle.api.plugins.JavaPluginExtension
|
|
||||||
import org.gradle.api.publish.PublishingExtension
|
|
||||||
import org.gradle.api.publish.tasks.GenerateModuleMetadata
|
|
||||||
import org.gradle.api.tasks.bundling.AbstractArchiveTask
|
|
||||||
import org.gradle.api.tasks.compile.JavaCompile
|
|
||||||
import org.gradle.api.tasks.javadoc.Javadoc
|
|
||||||
import org.gradle.jvm.tasks.Jar
|
|
||||||
import org.gradle.jvm.toolchain.JavaLanguageVersion
|
|
||||||
import org.gradle.kotlin.dsl.*
|
|
||||||
import org.gradle.language.jvm.tasks.ProcessResources
|
|
||||||
|
|
||||||
class SubprojectPlugin: Plugin<Project> {
|
class SubprojectPlugin: Plugin<Project> {
|
||||||
override fun apply(project: Project) {
|
override fun apply(project: Project) {
|
||||||
project.extensions.create("defaultPackageInfos", PackageInfosExtension::class.java, project)
|
project.extensions.create("defaultPackageInfos", PackageInfosExtension::class.java, project)
|
||||||
project.extensions.create("transitiveSourceSets", TransitiveSourceSetsExtension::class.java, project)
|
project.extensions.create("transitiveSourceSets", TransitiveSourceSetsExtension::class.java, project)
|
||||||
project.extensions.create("jarSets", JarSetExtension::class.java, project)
|
project.extensions.create("jarSets", JarSetExtension::class.java, project)
|
||||||
|
project.extensions.create("subproject", SubprojectExtension::class.java, project)
|
||||||
setBaseProperties(project)
|
|
||||||
setupJava(project)
|
|
||||||
addRepositories(project)
|
|
||||||
setupLoom(project)
|
|
||||||
setupDependencies(project)
|
|
||||||
configureTasks(project)
|
|
||||||
setupPublishing(project)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setBaseProperties(project: Project) {
|
|
||||||
val dev = System.getenv("RELEASE")?.contentEquals("false", true) ?: true
|
|
||||||
val buildNumber = System.getenv("BUILD_NUMBER")
|
|
||||||
|
|
||||||
val versionSuffix = if (dev && buildNumber != null) "-${buildNumber}" else ""
|
|
||||||
|
|
||||||
project.group = project.property("group") as String
|
|
||||||
project.version = "${project.property("mod_version")}${versionSuffix}"
|
|
||||||
|
|
||||||
project.the<BasePluginExtension>().apply {
|
|
||||||
archivesName = "flywheel-${project.name}-${project.property("artifact_minecraft_version")}"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun setupLoom(project: Project) {
|
|
||||||
val loom = project.the<LoomGradleExtensionAPI>()
|
|
||||||
loom.silentMojangMappingsLicense()
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupJava(project: Project) {
|
|
||||||
val java_version: String by project
|
|
||||||
|
|
||||||
project.the<JavaPluginExtension>().apply {
|
|
||||||
val javaVersion = JavaVersion.toVersion(java_version)
|
|
||||||
sourceCompatibility = javaVersion
|
|
||||||
targetCompatibility = javaVersion
|
|
||||||
|
|
||||||
toolchain.languageVersion = JavaLanguageVersion.of(java_version)
|
|
||||||
|
|
||||||
withSourcesJar()
|
|
||||||
withJavadocJar()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun addRepositories(project: Project) {
|
|
||||||
project.repositories.apply {
|
|
||||||
mavenCentral()
|
|
||||||
maven("https://maven.parchmentmc.org") {
|
|
||||||
name = "ParchmentMC"
|
|
||||||
}
|
|
||||||
maven("https://maven.tterrag.com/") {
|
|
||||||
name = "tterrag maven"
|
|
||||||
}
|
|
||||||
maven("https://www.cursemaven.com") {
|
|
||||||
name = "CurseMaven"
|
|
||||||
content {
|
|
||||||
includeGroup("curse.maven")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
maven("https://api.modrinth.com/maven") {
|
|
||||||
name = "Modrinth"
|
|
||||||
content {
|
|
||||||
includeGroup("maven.modrinth")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("UnstableApiUsage")
|
|
||||||
private fun setupDependencies(project: Project) {
|
|
||||||
project.dependencies.apply {
|
|
||||||
val minecraft_version: String by project
|
|
||||||
val parchment_minecraft_version: String by project
|
|
||||||
val parchment_version: String by project
|
|
||||||
val loom = project.the<LoomGradleExtensionAPI>()
|
|
||||||
|
|
||||||
add("minecraft", "com.mojang:minecraft:${minecraft_version}")
|
|
||||||
|
|
||||||
add("mappings", loom.layered {
|
|
||||||
officialMojangMappings()
|
|
||||||
parchment("org.parchmentmc.data:parchment-${parchment_minecraft_version}:${parchment_version}@zip")
|
|
||||||
})
|
|
||||||
|
|
||||||
add("api", "com.google.code.findbugs:jsr305:3.0.2")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun configureTasks(project: Project) {
|
|
||||||
val java_version: String by project
|
|
||||||
|
|
||||||
project.tasks.apply {
|
|
||||||
// make builds reproducible
|
|
||||||
withType<AbstractArchiveTask>().configureEach {
|
|
||||||
isPreserveFileTimestamps = false
|
|
||||||
isReproducibleFileOrder = true
|
|
||||||
}
|
|
||||||
|
|
||||||
// module metadata is often broken on multi-platform projects
|
|
||||||
withType<GenerateModuleMetadata>().configureEach {
|
|
||||||
enabled = false
|
|
||||||
}
|
|
||||||
|
|
||||||
withType<JavaCompile>().configureEach {
|
|
||||||
options.encoding = "UTF-8"
|
|
||||||
options.release = Integer.parseInt(java_version)
|
|
||||||
options.compilerArgs.add("-Xdiags:verbose")
|
|
||||||
}
|
|
||||||
|
|
||||||
withType<Jar>().configureEach {
|
|
||||||
from("${project.rootDir}/LICENSE.md") {
|
|
||||||
into("META-INF")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
withType<Javadoc>().configureEach {
|
|
||||||
options.optionFiles(project.rootProject.file("javadoc-options.txt"))
|
|
||||||
options.encoding = "UTF-8"
|
|
||||||
}
|
|
||||||
|
|
||||||
val replaceProperties = processResourcesExpandProperties.associateWith { project.property(it) as String }
|
|
||||||
|
|
||||||
withType<ProcessResources>().configureEach {
|
|
||||||
inputs.properties(replaceProperties)
|
|
||||||
|
|
||||||
filesMatching(processResourcesExpandFiles) {
|
|
||||||
expand(replaceProperties)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun setupPublishing(project: Project) {
|
|
||||||
project.the<PublishingExtension>().repositories.apply {
|
|
||||||
maven("file://${project.rootProject.projectDir}/mcmodsrepo")
|
|
||||||
|
|
||||||
if (project.hasProperty("mavendir")) {
|
|
||||||
maven(project.rootProject.file(project.property("mavendir") as String))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val processResourcesExpandFiles = listOf("pack.mcmeta", "fabric.mod.json", "META-INF/mods.toml")
|
|
||||||
|
|
||||||
val processResourcesExpandProperties = listOf(
|
|
||||||
"mod_id",
|
|
||||||
"mod_name",
|
|
||||||
"mod_description",
|
|
||||||
"mod_license",
|
|
||||||
"mod_sources",
|
|
||||||
"mod_issues",
|
|
||||||
"mod_homepage",
|
|
||||||
"mod_version",
|
|
||||||
"minecraft_semver_version_range",
|
|
||||||
"minecraft_maven_version_range",
|
|
||||||
"fabric_api_version_range",
|
|
||||||
"forge_version_range",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,15 @@
|
||||||
package dev.engine_room.gradle.transitive
|
package dev.engine_room.gradle.transitive
|
||||||
|
|
||||||
|
import dev.engine_room.gradle.jarset.JarTaskSet
|
||||||
|
import org.gradle.api.Project
|
||||||
import org.gradle.api.tasks.SourceSet
|
import org.gradle.api.tasks.SourceSet
|
||||||
|
import org.gradle.api.tasks.SourceSetContainer
|
||||||
|
import org.gradle.api.tasks.compile.JavaCompile
|
||||||
|
import org.gradle.api.tasks.javadoc.Javadoc
|
||||||
|
import org.gradle.jvm.tasks.Jar
|
||||||
|
import org.gradle.kotlin.dsl.named
|
||||||
|
import org.gradle.kotlin.dsl.the
|
||||||
|
import org.gradle.language.jvm.tasks.ProcessResources
|
||||||
|
|
||||||
class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsExtension, private val sourceSet: SourceSet) {
|
class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsExtension, private val sourceSet: SourceSet) {
|
||||||
internal val compileSourceSets = mutableSetOf<SourceSet>()
|
internal val compileSourceSets = mutableSetOf<SourceSet>()
|
||||||
|
@ -19,14 +28,21 @@ class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsEx
|
||||||
rootRuntime()
|
rootRuntime()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun compile(vararg sourceSets: SourceSet) {
|
fun compileClasspath(vararg sourceSets: SourceSet) {
|
||||||
compileSourceSets += sourceSets
|
compileSourceSets += sourceSets
|
||||||
for (sourceSet in sourceSets) {
|
for (sourceSet in sourceSets) {
|
||||||
this.sourceSet.compileClasspath += sourceSet.output
|
this.sourceSet.compileClasspath += sourceSet.output
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun runtime(vararg sourceSets: SourceSet) {
|
fun compileClasspath(project: Project, vararg sourceSets: String) {
|
||||||
|
val externalSourceSets = project.the<SourceSetContainer>()
|
||||||
|
for (name in sourceSets) {
|
||||||
|
this.sourceSet.compileClasspath += externalSourceSets.getByName(name).output
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun runtimeClasspath(vararg sourceSets: SourceSet) {
|
||||||
runtimeSourceSets += sourceSets
|
runtimeSourceSets += sourceSets
|
||||||
for (sourceSet in sourceSets) {
|
for (sourceSet in sourceSets) {
|
||||||
this.sourceSet.runtimeClasspath += sourceSet.output
|
this.sourceSet.runtimeClasspath += sourceSet.output
|
||||||
|
@ -34,7 +50,107 @@ class TransitiveSourceSetConfigurator(private val parent: TransitiveSourceSetsEx
|
||||||
}
|
}
|
||||||
|
|
||||||
fun implementation(vararg sourceSets: SourceSet) {
|
fun implementation(vararg sourceSets: SourceSet) {
|
||||||
compile(*sourceSets)
|
compileClasspath(*sourceSets)
|
||||||
runtime(*sourceSets)
|
runtimeClasspath(*sourceSets)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun from(otherProject: Project) {
|
||||||
|
from(otherProject, sourceSet.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun from(otherProject: Project, vararg names: String) {
|
||||||
|
|
||||||
|
val otherSourceSets = otherProject.the<SourceSetContainer>()
|
||||||
|
|
||||||
|
from(*names.map { otherSourceSets.getByName(it) }.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun from(vararg sourceSets: SourceSet) {
|
||||||
|
parent.project.tasks.apply {
|
||||||
|
named<JavaCompile>(sourceSet.compileJavaTaskName).configure {
|
||||||
|
sourceSets.forEach { source(it.allJava) }
|
||||||
|
|
||||||
|
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||||
|
}
|
||||||
|
named<ProcessResources>(sourceSet.processResourcesTaskName).configure {
|
||||||
|
sourceSets.forEach { from(it.resources) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bundleFrom(otherProject: Project) {
|
||||||
|
bundleFrom(otherProject, sourceSet.name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bundleFrom(otherProject: Project, vararg names: String) {
|
||||||
|
val otherSourceSets = otherProject.the<SourceSetContainer>()
|
||||||
|
|
||||||
|
bundleFrom(*names.map { otherSourceSets.getByName(it) }.toTypedArray())
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bundleFrom(vararg sourceSets: SourceSet) {
|
||||||
|
from(*sourceSets)
|
||||||
|
// The external sourceSets will be included in the jar by default since we bring it into the java compile task,
|
||||||
|
// however we need to make sure that the javadoc and sources jars also include the external sourceSets
|
||||||
|
bundleJavadocAndSources(*sourceSets)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bundleOutput(vararg sourceSets: SourceSet) {
|
||||||
|
bundleJavadocAndSources(*sourceSets)
|
||||||
|
|
||||||
|
parent.project.tasks.apply {
|
||||||
|
named<Jar>(sourceSet.jarTaskName).configure {
|
||||||
|
sourceSets.forEach { from(it.output) }
|
||||||
|
|
||||||
|
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun bundleJavadocAndSources(vararg sourceSets: SourceSet) {
|
||||||
|
parent.project.tasks.apply {
|
||||||
|
named<Javadoc>(sourceSet.javadocTaskName).configure {
|
||||||
|
sourceSets.forEach { source(it.allJava) }
|
||||||
|
|
||||||
|
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
named<Jar>(sourceSet.sourcesJarTaskName).configure {
|
||||||
|
sourceSets.forEach { from(it.allJava) }
|
||||||
|
|
||||||
|
JarTaskSet.excludeDuplicatePackageInfos(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun outgoing() {
|
||||||
|
outgoingClasses()
|
||||||
|
outgoingResources()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun outgoingResources() {
|
||||||
|
val project = parent.project
|
||||||
|
val exportResources = project.configurations.register("${sourceSet.name}Resources") {
|
||||||
|
isCanBeResolved = false
|
||||||
|
isCanBeConsumed = true
|
||||||
|
}
|
||||||
|
val processResources = project.tasks.named<ProcessResources>(sourceSet.processResourcesTaskName).get()
|
||||||
|
|
||||||
|
project.artifacts.add(exportResources.name, processResources.destinationDir) {
|
||||||
|
builtBy(processResources)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun outgoingClasses() {
|
||||||
|
val project = parent.project
|
||||||
|
val exportClasses = project.configurations.register("${sourceSet.name}Classes") {
|
||||||
|
isCanBeResolved = false
|
||||||
|
isCanBeConsumed = true
|
||||||
|
}
|
||||||
|
|
||||||
|
val compileTask = project.tasks.named<JavaCompile>(sourceSet.compileJavaTaskName).get()
|
||||||
|
project.artifacts.add(exportClasses.name, compileTask.destinationDirectory) {
|
||||||
|
builtBy(compileTask)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import org.gradle.api.Project
|
||||||
import org.gradle.api.file.FileCollection
|
import org.gradle.api.file.FileCollection
|
||||||
import org.gradle.api.tasks.SourceSet
|
import org.gradle.api.tasks.SourceSet
|
||||||
|
|
||||||
open class TransitiveSourceSetsExtension(private val project: Project) {
|
open class TransitiveSourceSetsExtension(val project: Project) {
|
||||||
var compileClasspath: FileCollection? = null
|
var compileClasspath: FileCollection? = null
|
||||||
var runtimeClasspath: FileCollection? = null
|
var runtimeClasspath: FileCollection? = null
|
||||||
|
|
||||||
|
|
|
@ -6,49 +6,55 @@ plugins {
|
||||||
id("flywheel.subproject")
|
id("flywheel.subproject")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subproject.init("flywheel-common", "flywheel_group", "flywheel_version")
|
||||||
|
|
||||||
val api = sourceSets.create("api")
|
val api = sourceSets.create("api")
|
||||||
val lib = sourceSets.create("lib")
|
val lib = sourceSets.create("lib")
|
||||||
val backend = sourceSets.create("backend")
|
val backend = sourceSets.create("backend")
|
||||||
val stubs = sourceSets.create("stubs")
|
val stubs = sourceSets.create("stubs")
|
||||||
val main = sourceSets.getByName("main")
|
val main = sourceSets.getByName("main")
|
||||||
|
val vanillin = sourceSets.create("vanillin")
|
||||||
|
|
||||||
transitiveSourceSets {
|
transitiveSourceSets {
|
||||||
compileClasspath = main.compileClasspath
|
compileClasspath = main.compileClasspath
|
||||||
|
|
||||||
sourceSet(api) {
|
sourceSet(api) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
|
outgoingClasses()
|
||||||
}
|
}
|
||||||
sourceSet(lib) {
|
sourceSet(lib) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
compile(api)
|
compileClasspath(api)
|
||||||
|
outgoing()
|
||||||
}
|
}
|
||||||
sourceSet(backend) {
|
sourceSet(backend) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
compile(api, lib)
|
compileClasspath(api, lib)
|
||||||
|
outgoing()
|
||||||
}
|
}
|
||||||
sourceSet(stubs) {
|
sourceSet(stubs) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
|
outgoingClasses()
|
||||||
}
|
}
|
||||||
sourceSet(main) {
|
sourceSet(main) {
|
||||||
compile(api, lib, backend, stubs)
|
compileClasspath(api, lib, backend)
|
||||||
|
outgoing()
|
||||||
}
|
}
|
||||||
sourceSet(sourceSets.getByName("test")) {
|
sourceSet(sourceSets.getByName("test")) {
|
||||||
implementation(api, lib, backend)
|
implementation(api, lib, backend)
|
||||||
}
|
}
|
||||||
|
sourceSet(vanillin) {
|
||||||
|
rootCompile()
|
||||||
|
compileClasspath(api, lib)
|
||||||
|
outgoing()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultPackageInfos {
|
defaultPackageInfos {
|
||||||
sources(api, lib, backend, main)
|
sources(api, lib, backend, main, vanillin)
|
||||||
}
|
}
|
||||||
|
|
||||||
jarSets {
|
jarSets {
|
||||||
// For sharing with other subprojects.
|
|
||||||
outgoing("commonApiOnly", api)
|
|
||||||
outgoing("commonLib", lib)
|
|
||||||
outgoing("commonBackend", backend)
|
|
||||||
outgoing("commonStubs", stubs)
|
|
||||||
outgoing("commonImpl", main)
|
|
||||||
|
|
||||||
// For publishing.
|
// For publishing.
|
||||||
create("api", api, lib).apply {
|
create("api", api, lib).apply {
|
||||||
addToAssemble()
|
addToAssemble()
|
||||||
|
@ -77,6 +83,9 @@ jarSets {
|
||||||
dependencies {
|
dependencies {
|
||||||
modCompileOnly("net.fabricmc:fabric-loader:${property("fabric_loader_version")}")
|
modCompileOnly("net.fabricmc:fabric-loader:${property("fabric_loader_version")}")
|
||||||
|
|
||||||
|
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric")
|
||||||
|
modCompileOnly("maven.modrinth:iris:${property("iris_version")}-fabric")
|
||||||
|
|
||||||
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
|
testImplementation("org.junit.jupiter:junit-jupiter:5.8.1")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,6 @@ public final class Flywheel {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ResourceLocation rl(String path) {
|
public static ResourceLocation rl(String path) {
|
||||||
return new ResourceLocation(ID, path);
|
return ResourceLocation.fromNamespaceAndPath(ID, path);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,6 @@ package dev.engine_room.flywheel.api;
|
||||||
|
|
||||||
import org.joml.Matrix4fc;
|
import org.joml.Matrix4fc;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
|
@ -16,7 +14,7 @@ public interface RenderContext {
|
||||||
|
|
||||||
RenderBuffers buffers();
|
RenderBuffers buffers();
|
||||||
|
|
||||||
PoseStack stack();
|
Matrix4fc modelView();
|
||||||
|
|
||||||
Matrix4fc projection();
|
Matrix4fc projection();
|
||||||
|
|
||||||
|
|
|
@ -15,11 +15,48 @@ public interface InstanceType<I extends Instance> {
|
||||||
*/
|
*/
|
||||||
I create(InstanceHandle handle);
|
I create(InstanceHandle handle);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The native memory layout of this instance type.
|
||||||
|
*
|
||||||
|
* <p>This layout determines what fields are made available to the instance type's shaders
|
||||||
|
* as well as determining how the fields are arranged in memory.
|
||||||
|
*
|
||||||
|
* @return The layout of this instance type.
|
||||||
|
*/
|
||||||
Layout layout();
|
Layout layout();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The writer of this instance type.
|
||||||
|
*
|
||||||
|
* <p>The writer of an InstanceType is responsible for translating java instance objects
|
||||||
|
* into contiguous native memory. The instance writer must write to the given pointer
|
||||||
|
* according to the layout of this instance type.
|
||||||
|
*
|
||||||
|
* <p>It is undefined behavior to write outside the half closed range
|
||||||
|
* {@code [ptr, ptr + layout().byteSize())}.
|
||||||
|
*
|
||||||
|
* @return The writer for this instance type.
|
||||||
|
*/
|
||||||
InstanceWriter<I> writer();
|
InstanceWriter<I> writer();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <p>The vertex shader of an InstanceType is responsible for transforming vertices from mesh
|
||||||
|
* space to world space in whatever way the instance type requires.
|
||||||
|
*
|
||||||
|
* @return The vertex shader for this instance type.
|
||||||
|
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||||
|
*/
|
||||||
ResourceLocation vertexShader();
|
ResourceLocation vertexShader();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The cull shader of this instance type.
|
||||||
|
*
|
||||||
|
* <p>The cull shader of an InstanceType is responsible for transforming bounding spheres from mesh
|
||||||
|
* space to world space, such that a mesh contained by the input bounding sphere and transformed
|
||||||
|
* by the vertex shader would be contained by the output bounding sphere.
|
||||||
|
*
|
||||||
|
* @return The cull shader for this instance type.
|
||||||
|
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||||
|
*/
|
||||||
ResourceLocation cullShader();
|
ResourceLocation cullShader();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,12 @@ package dev.engine_room.flywheel.api.material;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shader that decides what colors should be discarded in the fragment shader.
|
||||||
|
*/
|
||||||
public interface CutoutShader {
|
public interface CutoutShader {
|
||||||
|
/**
|
||||||
|
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||||
|
*/
|
||||||
ResourceLocation source();
|
ResourceLocation source();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,12 @@ package dev.engine_room.flywheel.api.material;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shader that controls the fog effect on a material.
|
||||||
|
*/
|
||||||
public interface FogShader {
|
public interface FogShader {
|
||||||
|
/**
|
||||||
|
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||||
|
*/
|
||||||
ResourceLocation source();
|
ResourceLocation source();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,12 @@ package dev.engine_room.flywheel.api.material;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A shader that controls the GPU-based light on a material.
|
||||||
|
*/
|
||||||
public interface LightShader {
|
public interface LightShader {
|
||||||
|
/**
|
||||||
|
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||||
|
*/
|
||||||
ResourceLocation source();
|
ResourceLocation source();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,17 @@ package dev.engine_room.flywheel.api.material;
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A vertex and fragment shader pair that can be attached to a material.
|
||||||
|
*/
|
||||||
public interface MaterialShaders {
|
public interface MaterialShaders {
|
||||||
|
/**
|
||||||
|
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||||
|
*/
|
||||||
ResourceLocation vertexSource();
|
ResourceLocation vertexSource();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @apiNote {@code flywheel/} is implicitly prepended to the {@link ResourceLocation}'s path.
|
||||||
|
*/
|
||||||
ResourceLocation fragmentSource();
|
ResourceLocation fragmentSource();
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,10 @@ public class InstancedDraw {
|
||||||
return deleted;
|
return deleted;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public MeshPool.PooledMesh mesh() {
|
||||||
|
return mesh;
|
||||||
|
}
|
||||||
|
|
||||||
public void render(TextureBuffer buffer) {
|
public void render(TextureBuffer buffer) {
|
||||||
if (mesh.isInvalid()) {
|
if (mesh.isInvalid()) {
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -64,6 +64,9 @@ public class InstancedRenderStage {
|
||||||
|
|
||||||
uploadMaterialUniform(program, material);
|
uploadMaterialUniform(program, material);
|
||||||
|
|
||||||
|
program.setUInt("_flw_vertexOffset", drawCall.mesh()
|
||||||
|
.baseVertex());
|
||||||
|
|
||||||
MaterialRenderState.setup(material);
|
MaterialRenderState.setup(material);
|
||||||
|
|
||||||
Samplers.INSTANCE_BUFFER.makeActive();
|
Samplers.INSTANCE_BUFFER.makeActive();
|
||||||
|
|
|
@ -14,6 +14,7 @@ public enum DebugMode implements StringRepresentable {
|
||||||
LIGHT_COLOR,
|
LIGHT_COLOR,
|
||||||
OVERLAY,
|
OVERLAY,
|
||||||
DIFFUSE,
|
DIFFUSE,
|
||||||
|
MODEL_ID,
|
||||||
;
|
;
|
||||||
|
|
||||||
public static final Codec<DebugMode> CODEC = StringRepresentable.fromEnum(DebugMode::values);
|
public static final Codec<DebugMode> CODEC = StringRepresentable.fromEnum(DebugMode::values);
|
||||||
|
|
|
@ -73,7 +73,7 @@ public final class FrameUniforms extends UniformWriter {
|
||||||
var camY = (float) (cameraPos.y - renderOrigin.getY());
|
var camY = (float) (cameraPos.y - renderOrigin.getY());
|
||||||
var camZ = (float) (cameraPos.z - renderOrigin.getZ());
|
var camZ = (float) (cameraPos.z - renderOrigin.getZ());
|
||||||
|
|
||||||
VIEW.set(context.stack().last().pose());
|
VIEW.set(context.modelView());
|
||||||
VIEW.translate(-camX, -camY, -camZ);
|
VIEW.translate(-camX, -camY, -camZ);
|
||||||
PROJECTION.set(context.projection());
|
PROJECTION.set(context.projection());
|
||||||
VIEW_PROJECTION.set(context.viewProjection());
|
VIEW_PROJECTION.set(context.viewProjection());
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class ShaderSources {
|
||||||
}
|
}
|
||||||
|
|
||||||
private static ResourceLocation locationWithoutFlywheelPrefix(ResourceLocation loc) {
|
private static ResourceLocation locationWithoutFlywheelPrefix(ResourceLocation loc) {
|
||||||
return new ResourceLocation(loc.getNamespace(), loc.getPath()
|
return ResourceLocation.fromNamespaceAndPath(loc.getNamespace(), loc.getPath()
|
||||||
.substring(SHADER_DIR.length()));
|
.substring(SHADER_DIR.length()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ in vec2 _flw_crumblingTexCoord;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _FLW_DEBUG
|
#ifdef _FLW_DEBUG
|
||||||
flat in uint _flw_instanceID;
|
flat in uvec2 _flw_ids;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
out vec4 _flw_outputColor;
|
out vec4 _flw_outputColor;
|
||||||
|
@ -79,7 +79,7 @@ void _flw_main() {
|
||||||
color = vec4(flw_vertexNormal * .5 + .5, 1.);
|
color = vec4(flw_vertexNormal * .5 + .5, 1.);
|
||||||
break;
|
break;
|
||||||
case 2u:
|
case 2u:
|
||||||
color = _flw_id2Color(_flw_instanceID);
|
color = _flw_id2Color(_flw_ids.x);
|
||||||
break;
|
break;
|
||||||
case 3u:
|
case 3u:
|
||||||
color = vec4(vec2((flw_fragLight * 15.0 + 0.5) / 16.), 0., 1.);
|
color = vec4(vec2((flw_fragLight * 15.0 + 0.5) / 16.), 0., 1.);
|
||||||
|
@ -93,6 +93,9 @@ void _flw_main() {
|
||||||
case 6u:
|
case 6u:
|
||||||
color = vec4(vec3(diffuseFactor), 1.);
|
color = vec4(vec3(diffuseFactor), 1.);
|
||||||
break;
|
break;
|
||||||
|
case 7u:
|
||||||
|
color = _flw_id2Color(_flw_ids.y);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -72,10 +72,10 @@ mat3 _flw_normalMatrix;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef _FLW_DEBUG
|
#ifdef _FLW_DEBUG
|
||||||
flat out uint _flw_instanceID;
|
flat out uvec2 _flw_ids;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
|
void _flw_main(in FlwInstance instance, in uint stableInstanceID, in uint modelID) {
|
||||||
_flw_layoutVertex();
|
_flw_layoutVertex();
|
||||||
flw_instanceVertex(instance);
|
flw_instanceVertex(instance);
|
||||||
flw_materialVertex();
|
flw_materialVertex();
|
||||||
|
@ -96,6 +96,6 @@ void _flw_main(in FlwInstance instance, in uint stableInstanceID) {
|
||||||
gl_Position = flw_viewProjection * flw_vertexPos;
|
gl_Position = flw_viewProjection * flw_vertexPos;
|
||||||
|
|
||||||
#ifdef _FLW_DEBUG
|
#ifdef _FLW_DEBUG
|
||||||
_flw_instanceID = stableInstanceID;
|
_flw_ids = uvec2(stableInstanceID, modelID);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,5 +51,5 @@ void main() {
|
||||||
|
|
||||||
FlwInstance instance = _flw_unpackInstance(instanceIndex);
|
FlwInstance instance = _flw_unpackInstance(instanceIndex);
|
||||||
|
|
||||||
_flw_main(instance, instanceIndex);
|
_flw_main(instance, instanceIndex, draw.vertexOffset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,8 @@ uniform mat4 _flw_modelMatrixUniform;
|
||||||
uniform mat3 _flw_normalMatrixUniform;
|
uniform mat3 _flw_normalMatrixUniform;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
uniform uint _flw_vertexOffset;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
_flw_unpackMaterialProperties(_flw_packedMaterial.y, flw_material);
|
_flw_unpackMaterialProperties(_flw_packedMaterial.y, flw_material);
|
||||||
|
|
||||||
|
@ -20,5 +22,5 @@ void main() {
|
||||||
_flw_normalMatrix = _flw_normalMatrixUniform;
|
_flw_normalMatrix = _flw_normalMatrixUniform;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
_flw_main(instance, uint(gl_InstanceID));
|
_flw_main(instance, uint(gl_InstanceID), _flw_vertexOffset);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "dev.engine_room.flywheel.backend.mixin",
|
"package": "dev.engine_room.flywheel.backend.mixin",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_21",
|
||||||
"refmap": "backend-flywheel.refmap.json",
|
"refmap": "backend-flywheel.refmap.json",
|
||||||
"client": [
|
"client": [
|
||||||
"AbstractClientPlayerAccessor",
|
"AbstractClientPlayerAccessor",
|
||||||
|
|
|
@ -21,7 +21,7 @@ public interface FlwLibLink {
|
||||||
|
|
||||||
Map<String, ModelPart> getModelPartChildren(ModelPart part);
|
Map<String, ModelPart> getModelPartChildren(ModelPart part);
|
||||||
|
|
||||||
void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha);
|
void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, int color);
|
||||||
|
|
||||||
Deque<PoseStack.Pose> getPoseStack(PoseStack stack);
|
Deque<PoseStack.Pose> getPoseStack(PoseStack stack);
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,13 @@ package dev.engine_room.flywheel.lib.internal;
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
import org.jetbrains.annotations.UnknownNullability;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.internal.DependencyInjection;
|
import dev.engine_room.flywheel.api.internal.DependencyInjection;
|
||||||
|
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.client.resources.model.ModelManager;
|
import net.minecraft.client.resources.model.ModelManager;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
public interface FlwLibXplat {
|
public interface FlwLibXplat {
|
||||||
FlwLibXplat INSTANCE = DependencyInjection.load(FlwLibXplat.class, "dev.engine_room.flywheel.impl.FlwLibXplatImpl");
|
FlwLibXplat INSTANCE = DependencyInjection.load(FlwLibXplat.class, "dev.engine_room.flywheel.impl.FlwLibXplatImpl");
|
||||||
|
@ -19,9 +17,9 @@ public interface FlwLibXplat {
|
||||||
@UnknownNullability
|
@UnknownNullability
|
||||||
BakedModel getBakedModel(ModelManager modelManager, ResourceLocation location);
|
BakedModel getBakedModel(ModelManager modelManager, ResourceLocation location);
|
||||||
|
|
||||||
BakedModelBuilder createBakedModelBuilder(BakedModel bakedModel);
|
SimpleModel buildBakedModelBuilder(BakedModelBuilder builder);
|
||||||
|
|
||||||
BlockModelBuilder createBlockModelBuilder(BlockState state);
|
SimpleModel buildBlockModelBuilder(BlockModelBuilder builder);
|
||||||
|
|
||||||
MultiBlockModelBuilder createMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions);
|
SimpleModel buildMultiBlockModelBuilder(MultiBlockModelBuilder builder);
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,7 +53,7 @@ public final class ModelUtil {
|
||||||
if (renderType == Sheets.translucentCullBlockSheet() || renderType == Sheets.translucentItemSheet()) {
|
if (renderType == Sheets.translucentCullBlockSheet() || renderType == Sheets.translucentItemSheet()) {
|
||||||
return Materials.CUTOUT_BLOCK;
|
return Materials.CUTOUT_BLOCK;
|
||||||
}
|
}
|
||||||
if (renderType == RenderType.glint() || renderType == RenderType.glintDirect()) {
|
if (renderType == RenderType.glint() || renderType == RenderType.glintTranslucent()) {
|
||||||
return Materials.GLINT;
|
return Materials.GLINT;
|
||||||
}
|
}
|
||||||
if (renderType == RenderType.entityGlint() || renderType == RenderType.entityGlintDirect()) {
|
if (renderType == RenderType.entityGlint() || renderType == RenderType.entityGlintDirect()) {
|
||||||
|
|
|
@ -20,9 +20,9 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
* method with the same parameters will return the same object.
|
* method with the same parameters will return the same object.
|
||||||
*/
|
*/
|
||||||
public final class Models {
|
public final class Models {
|
||||||
private static final RendererReloadCache<BlockState, Model> BLOCK_STATE = new RendererReloadCache<>(it -> BlockModelBuilder.create(it)
|
private static final RendererReloadCache<BlockState, Model> BLOCK_STATE = new RendererReloadCache<>(it -> new BlockModelBuilder(it)
|
||||||
.build());
|
.build());
|
||||||
private static final RendererReloadCache<PartialModel, Model> PARTIAL = new RendererReloadCache<>(it -> BakedModelBuilder.create(it.get())
|
private static final RendererReloadCache<PartialModel, Model> PARTIAL = new RendererReloadCache<>(it -> new BakedModelBuilder(it.get())
|
||||||
.build());
|
.build());
|
||||||
private static final RendererReloadCache<TransformedPartial<?>, Model> TRANSFORMED_PARTIAL = new RendererReloadCache<>(TransformedPartial::create);
|
private static final RendererReloadCache<TransformedPartial<?>, Model> TRANSFORMED_PARTIAL = new RendererReloadCache<>(TransformedPartial::create);
|
||||||
|
|
||||||
|
@ -88,7 +88,7 @@ public final class Models {
|
||||||
private Model create() {
|
private Model create() {
|
||||||
var stack = new PoseStack();
|
var stack = new PoseStack();
|
||||||
transformer.accept(key, stack);
|
transformer.accept(key, stack);
|
||||||
return BakedModelBuilder.create(partial.get())
|
return new BakedModelBuilder(partial.get())
|
||||||
.poseStack(stack)
|
.poseStack(stack)
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,21 +2,20 @@ package dev.engine_room.flywheel.lib.model.baked;
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.Material;
|
import dev.engine_room.flywheel.api.material.Material;
|
||||||
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
||||||
|
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
@ApiStatus.NonExtendable
|
public final class BakedModelBuilder {
|
||||||
public abstract class BakedModelBuilder {
|
|
||||||
final BakedModel bakedModel;
|
final BakedModel bakedModel;
|
||||||
@Nullable
|
@Nullable
|
||||||
BlockAndTintGetter level;
|
BlockAndTintGetter level;
|
||||||
|
@ -27,14 +26,10 @@ public abstract class BakedModelBuilder {
|
||||||
@Nullable
|
@Nullable
|
||||||
BiFunction<RenderType, Boolean, Material> materialFunc;
|
BiFunction<RenderType, Boolean, Material> materialFunc;
|
||||||
|
|
||||||
BakedModelBuilder(BakedModel bakedModel) {
|
public BakedModelBuilder(BakedModel bakedModel) {
|
||||||
this.bakedModel = bakedModel;
|
this.bakedModel = bakedModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BakedModelBuilder create(BakedModel bakedModel) {
|
|
||||||
return FlwLibXplat.INSTANCE.createBakedModelBuilder(bakedModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BakedModelBuilder level(BlockAndTintGetter level) {
|
public BakedModelBuilder level(BlockAndTintGetter level) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
return this;
|
return this;
|
||||||
|
@ -55,5 +50,11 @@ public abstract class BakedModelBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract SimpleModel build();
|
public SimpleModel build() {
|
||||||
|
if (materialFunc == null) {
|
||||||
|
materialFunc = ModelUtil::getMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlwLibXplat.INSTANCE.buildBakedModelBuilder(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,20 +2,19 @@ package dev.engine_room.flywheel.lib.model.baked;
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.Material;
|
import dev.engine_room.flywheel.api.material.Material;
|
||||||
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
||||||
|
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
import net.minecraft.world.level.block.state.BlockState;
|
||||||
|
|
||||||
@ApiStatus.NonExtendable
|
public final class BlockModelBuilder {
|
||||||
public abstract class BlockModelBuilder {
|
|
||||||
final BlockState state;
|
final BlockState state;
|
||||||
@Nullable
|
@Nullable
|
||||||
BlockAndTintGetter level;
|
BlockAndTintGetter level;
|
||||||
|
@ -24,14 +23,10 @@ public abstract class BlockModelBuilder {
|
||||||
@Nullable
|
@Nullable
|
||||||
BiFunction<RenderType, Boolean, Material> materialFunc;
|
BiFunction<RenderType, Boolean, Material> materialFunc;
|
||||||
|
|
||||||
BlockModelBuilder(BlockState state) {
|
public BlockModelBuilder(BlockState state) {
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BlockModelBuilder create(BlockState state) {
|
|
||||||
return FlwLibXplat.INSTANCE.createBlockModelBuilder(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
public BlockModelBuilder level(BlockAndTintGetter level) {
|
public BlockModelBuilder level(BlockAndTintGetter level) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
return this;
|
return this;
|
||||||
|
@ -47,5 +42,11 @@ public abstract class BlockModelBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract SimpleModel build();
|
public SimpleModel build() {
|
||||||
|
if (materialFunc == null) {
|
||||||
|
materialFunc = ModelUtil::getMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlwLibXplat.INSTANCE.buildBlockModelBuilder(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@ import java.nio.ByteBuffer;
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.MeshData;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.lib.memory.MemoryBlock;
|
import dev.engine_room.flywheel.lib.memory.MemoryBlock;
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleQuadMesh;
|
import dev.engine_room.flywheel.lib.model.SimpleQuadMesh;
|
||||||
|
@ -16,15 +16,15 @@ final class MeshHelper {
|
||||||
private MeshHelper() {
|
private MeshHelper() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static SimpleQuadMesh blockVerticesToMesh(BufferBuilder.RenderedBuffer buffer, @Nullable String meshDescriptor) {
|
public static SimpleQuadMesh blockVerticesToMesh(MeshData data, @Nullable String meshDescriptor) {
|
||||||
BufferBuilder.DrawState drawState = buffer.drawState();
|
MeshData.DrawState drawState = data.drawState();
|
||||||
int vertexCount = drawState.vertexCount();
|
int vertexCount = drawState.vertexCount();
|
||||||
long srcStride = drawState.format().getVertexSize();
|
long srcStride = drawState.format().getVertexSize();
|
||||||
|
|
||||||
VertexView vertexView = new NoOverlayVertexView();
|
VertexView vertexView = new NoOverlayVertexView();
|
||||||
long dstStride = vertexView.stride();
|
long dstStride = vertexView.stride();
|
||||||
|
|
||||||
ByteBuffer src = buffer.vertexBuffer();
|
ByteBuffer src = data.vertexBuffer();
|
||||||
MemoryBlock dst = MemoryBlock.mallocTracked((long) vertexCount * dstStride);
|
MemoryBlock dst = MemoryBlock.mallocTracked((long) vertexCount * dstStride);
|
||||||
long srcPtr = MemoryUtil.memAddress(src);
|
long srcPtr = MemoryUtil.memAddress(src);
|
||||||
long dstPtr = dst.ptr();
|
long dstPtr = dst.ptr();
|
||||||
|
|
|
@ -2,20 +2,19 @@ package dev.engine_room.flywheel.lib.model.baked;
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
import java.util.function.BiFunction;
|
||||||
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.Material;
|
import dev.engine_room.flywheel.api.material.Material;
|
||||||
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
||||||
|
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||||
import net.minecraft.client.renderer.RenderType;
|
import net.minecraft.client.renderer.RenderType;
|
||||||
import net.minecraft.core.BlockPos;
|
import net.minecraft.core.BlockPos;
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
import net.minecraft.world.level.BlockAndTintGetter;
|
||||||
|
|
||||||
@ApiStatus.NonExtendable
|
public final class MultiBlockModelBuilder {
|
||||||
public abstract class MultiBlockModelBuilder {
|
|
||||||
final BlockAndTintGetter level;
|
final BlockAndTintGetter level;
|
||||||
final Iterable<BlockPos> positions;
|
final Iterable<BlockPos> positions;
|
||||||
@Nullable
|
@Nullable
|
||||||
|
@ -24,15 +23,11 @@ public abstract class MultiBlockModelBuilder {
|
||||||
@Nullable
|
@Nullable
|
||||||
BiFunction<RenderType, Boolean, Material> materialFunc;
|
BiFunction<RenderType, Boolean, Material> materialFunc;
|
||||||
|
|
||||||
MultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
public MultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
||||||
this.level = level;
|
this.level = level;
|
||||||
this.positions = positions;
|
this.positions = positions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static MultiBlockModelBuilder create(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
|
||||||
return FlwLibXplat.INSTANCE.createMultiBlockModelBuilder(level, positions);
|
|
||||||
}
|
|
||||||
|
|
||||||
public MultiBlockModelBuilder poseStack(PoseStack poseStack) {
|
public MultiBlockModelBuilder poseStack(PoseStack poseStack) {
|
||||||
this.poseStack = poseStack;
|
this.poseStack = poseStack;
|
||||||
return this;
|
return this;
|
||||||
|
@ -48,5 +43,11 @@ public abstract class MultiBlockModelBuilder {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract SimpleModel build();
|
public SimpleModel build() {
|
||||||
|
if (materialFunc == null) {
|
||||||
|
materialFunc = ModelUtil::getMaterial;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FlwLibXplat.INSTANCE.buildMultiBlockModelBuilder(this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,67 +26,46 @@ class TransformingVertexConsumer implements VertexConsumer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer vertex(double x, double y, double z) {
|
public VertexConsumer addVertex(float x, float y, float z) {
|
||||||
Matrix4f matrix = poseStack.last().pose();
|
Matrix4f matrix = poseStack.last().pose();
|
||||||
float fx = (float) x;
|
delegate.addVertex(
|
||||||
float fy = (float) y;
|
MatrixMath.transformPositionX(matrix, x, y, z),
|
||||||
float fz = (float) z;
|
MatrixMath.transformPositionY(matrix, x, y, z),
|
||||||
delegate.vertex(
|
MatrixMath.transformPositionZ(matrix, x, y, z));
|
||||||
MatrixMath.transformPositionX(matrix, fx, fy, fz),
|
|
||||||
MatrixMath.transformPositionY(matrix, fx, fy, fz),
|
|
||||||
MatrixMath.transformPositionZ(matrix, fx, fy, fz));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer color(int red, int green, int blue, int alpha) {
|
public VertexConsumer setColor(int red, int green, int blue, int alpha) {
|
||||||
delegate.color(red, green, blue, alpha);
|
delegate.setColor(red, green, blue, alpha);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer uv(float u, float v) {
|
public VertexConsumer setUv(float u, float v) {
|
||||||
delegate.uv(u, v);
|
delegate.setUv(u, v);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer overlayCoords(int u, int v) {
|
public VertexConsumer setUv1(int u, int v) {
|
||||||
delegate.overlayCoords(u, v);
|
delegate.setUv1(u, v);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer uv2(int u, int v) {
|
public VertexConsumer setUv2(int u, int v) {
|
||||||
delegate.uv2(u, v);
|
delegate.setUv2(u, v);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer normal(float x, float y, float z) {
|
public VertexConsumer setNormal(float x, float y, float z) {
|
||||||
Matrix3f matrix = poseStack.last().normal();
|
Matrix3f matrix = poseStack.last().normal();
|
||||||
float fx = (float) x;
|
delegate.setNormal(
|
||||||
float fy = (float) y;
|
MatrixMath.transformNormalX(matrix, x, y, z),
|
||||||
float fz = (float) z;
|
MatrixMath.transformNormalY(matrix, x, y, z),
|
||||||
delegate.normal(
|
MatrixMath.transformNormalZ(matrix, x, y, z));
|
||||||
MatrixMath.transformNormalX(matrix, fx, fy, fz),
|
|
||||||
MatrixMath.transformNormalY(matrix, fx, fy, fz),
|
|
||||||
MatrixMath.transformNormalZ(matrix, fx, fy, fz));
|
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void endVertex() {
|
|
||||||
delegate.endVertex();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void defaultColor(int red, int green, int blue, int alpha) {
|
|
||||||
delegate.defaultColor(red, green, blue, alpha);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unsetDefaultColor() {
|
|
||||||
delegate.unsetDefaultColor();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -74,7 +74,7 @@ public final class MeshTree {
|
||||||
}
|
}
|
||||||
|
|
||||||
VertexWriter vertexWriter = objects.vertexWriter;
|
VertexWriter vertexWriter = objects.vertexWriter;
|
||||||
FlwLibLink.INSTANCE.compileModelPart(modelPart, IDENTITY_POSE, vertexWriter, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 1.0F, 1.0F, 1.0F, 1.0F);
|
FlwLibLink.INSTANCE.compileModelPart(modelPart, IDENTITY_POSE, vertexWriter, LightTexture.FULL_BRIGHT, OverlayTexture.NO_OVERLAY, 0xFFFFFFFF);
|
||||||
MemoryBlock data = vertexWriter.copyDataAndReset();
|
MemoryBlock data = vertexWriter.copyDataAndReset();
|
||||||
|
|
||||||
VertexView vertexView = new PosTexNormalVertexView();
|
VertexView vertexView = new PosTexNormalVertexView();
|
||||||
|
|
|
@ -14,34 +14,42 @@ class VertexWriter implements VertexConsumer {
|
||||||
private MemoryBlock data;
|
private MemoryBlock data;
|
||||||
|
|
||||||
private int vertexCount;
|
private int vertexCount;
|
||||||
private boolean filledPosition;
|
private boolean filledTexture = true;
|
||||||
private boolean filledTexture;
|
private boolean filledNormal = true;
|
||||||
private boolean filledNormal;
|
|
||||||
|
|
||||||
public VertexWriter() {
|
public VertexWriter() {
|
||||||
data = MemoryBlock.malloc(128 * STRIDE);
|
data = MemoryBlock.malloc(128 * STRIDE);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer vertex(double x, double y, double z) {
|
public VertexConsumer addVertex(float x, float y, float z) {
|
||||||
if (!filledPosition) {
|
endLastVertex();
|
||||||
long ptr = vertexPtr();
|
vertexCount++;
|
||||||
MemoryUtil.memPutFloat(ptr, (float) x);
|
|
||||||
MemoryUtil.memPutFloat(ptr + 4, (float) y);
|
long byteSize = vertexCount * STRIDE;
|
||||||
MemoryUtil.memPutFloat(ptr + 8, (float) z);
|
long capacity = data.size();
|
||||||
filledPosition = true;
|
if (byteSize > capacity) {
|
||||||
|
data = data.realloc(capacity * 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
filledTexture = false;
|
||||||
|
filledNormal = false;
|
||||||
|
|
||||||
|
long ptr = vertexPtr();
|
||||||
|
MemoryUtil.memPutFloat(ptr, x);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 4, y);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 8, z);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer color(int red, int green, int blue, int alpha) {
|
public VertexConsumer setColor(int red, int green, int blue, int alpha) {
|
||||||
// ignore color
|
// ignore color
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer uv(float u, float v) {
|
public VertexConsumer setUv(float u, float v) {
|
||||||
if (!filledTexture) {
|
if (!filledTexture) {
|
||||||
long ptr = vertexPtr();
|
long ptr = vertexPtr();
|
||||||
MemoryUtil.memPutFloat(ptr + 12, u);
|
MemoryUtil.memPutFloat(ptr + 12, u);
|
||||||
|
@ -52,19 +60,19 @@ class VertexWriter implements VertexConsumer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer overlayCoords(int u, int v) {
|
public VertexConsumer setUv1(int u, int v) {
|
||||||
// ignore overlay
|
// ignore overlay
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer uv2(int u, int v) {
|
public VertexConsumer setUv2(int u, int v) {
|
||||||
// ignore light
|
// ignore light
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer normal(float x, float y, float z) {
|
public VertexConsumer setNormal(float x, float y, float z) {
|
||||||
if (!filledNormal) {
|
if (!filledNormal) {
|
||||||
long ptr = vertexPtr();
|
long ptr = vertexPtr();
|
||||||
MemoryUtil.memPutByte(ptr + 20, DataPacker.packNormI8(x));
|
MemoryUtil.memPutByte(ptr + 20, DataPacker.packNormI8(x));
|
||||||
|
@ -75,44 +83,27 @@ class VertexWriter implements VertexConsumer {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public void endVertex() {
|
|
||||||
if (!filledPosition || !filledTexture || !filledNormal) {
|
|
||||||
throw new IllegalStateException("Not filled all elements of the vertex");
|
|
||||||
}
|
|
||||||
|
|
||||||
filledPosition = false;
|
|
||||||
filledTexture = false;
|
|
||||||
filledNormal = false;
|
|
||||||
vertexCount++;
|
|
||||||
|
|
||||||
long byteSize = (vertexCount + 1) * STRIDE;
|
|
||||||
long capacity = data.size();
|
|
||||||
if (byteSize > capacity) {
|
|
||||||
data = data.realloc(capacity * 2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void defaultColor(int red, int green, int blue, int alpha) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void unsetDefaultColor() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private long vertexPtr() {
|
private long vertexPtr() {
|
||||||
return data.ptr() + vertexCount * STRIDE;
|
return data.ptr() + (vertexCount - 1) * STRIDE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void endLastVertex() {
|
||||||
|
if (vertexCount != 0) {
|
||||||
|
if (!filledTexture || !filledNormal) {
|
||||||
|
throw new IllegalStateException("Missing elements in vertex");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public MemoryBlock copyDataAndReset() {
|
public MemoryBlock copyDataAndReset() {
|
||||||
|
endLastVertex();
|
||||||
|
|
||||||
MemoryBlock dataCopy = MemoryBlock.mallocTracked(vertexCount * STRIDE);
|
MemoryBlock dataCopy = MemoryBlock.mallocTracked(vertexCount * STRIDE);
|
||||||
data.copyTo(dataCopy);
|
data.copyTo(dataCopy);
|
||||||
|
|
||||||
vertexCount = 0;
|
vertexCount = 0;
|
||||||
filledPosition = false;
|
filledTexture = true;
|
||||||
filledTexture = false;
|
filledNormal = true;
|
||||||
filledNormal = false;
|
|
||||||
|
|
||||||
return dataCopy;
|
return dataCopy;
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ public final class ResourceUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Same as {@link ResourceLocation#ResourceLocation(String)}, but defaults to Flywheel namespace.
|
* Same as {@link ResourceLocation#parse(String)}, but defaults to Flywheel namespace.
|
||||||
*/
|
*/
|
||||||
public static ResourceLocation parseFlywheelDefault(String location) {
|
public static ResourceLocation parseFlywheelDefault(String location) {
|
||||||
String namespace = Flywheel.ID;
|
String namespace = Flywheel.ID;
|
||||||
|
@ -30,7 +30,7 @@ public final class ResourceUtil {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return new ResourceLocation(namespace, path);
|
return ResourceLocation.fromNamespaceAndPath(namespace, path);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,8 +8,8 @@ public final class VertexTransformations {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void retexture(MutableVertexList vertexList, int index, TextureAtlasSprite sprite) {
|
public static void retexture(MutableVertexList vertexList, int index, TextureAtlasSprite sprite) {
|
||||||
vertexList.u(index, sprite.getU(vertexList.u(index) * 16));
|
vertexList.u(index, sprite.getU(vertexList.u(index)));
|
||||||
vertexList.v(index, sprite.getV(vertexList.v(index) * 16));
|
vertexList.v(index, sprite.getV(vertexList.v(index)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void retexture(MutableVertexList vertexList, TextureAtlasSprite sprite) {
|
public static void retexture(MutableVertexList vertexList, TextureAtlasSprite sprite) {
|
||||||
|
|
|
@ -42,7 +42,7 @@ import net.minecraft.world.phys.shapes.VoxelShape;
|
||||||
* The shadow will be cast on blocks at most {@code min(radius, 2 * strength)} blocks below the entity.</p>
|
* The shadow will be cast on blocks at most {@code min(radius, 2 * strength)} blocks below the entity.</p>
|
||||||
*/
|
*/
|
||||||
public final class ShadowComponent implements EntityComponent {
|
public final class ShadowComponent implements EntityComponent {
|
||||||
private static final ResourceLocation SHADOW_TEXTURE = new ResourceLocation("textures/misc/shadow.png");
|
private static final ResourceLocation SHADOW_TEXTURE = ResourceLocation.withDefaultNamespace("textures/misc/shadow.png");
|
||||||
private static final Material SHADOW_MATERIAL = SimpleMaterial.builder()
|
private static final Material SHADOW_MATERIAL = SimpleMaterial.builder()
|
||||||
.texture(SHADOW_TEXTURE)
|
.texture(SHADOW_TEXTURE)
|
||||||
.mipmap(false)
|
.mipmap(false)
|
||||||
|
|
|
@ -6,7 +6,6 @@ import org.slf4j.LoggerFactory;
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
import dev.engine_room.flywheel.api.Flywheel;
|
||||||
import dev.engine_room.flywheel.backend.FlwBackend;
|
import dev.engine_room.flywheel.backend.FlwBackend;
|
||||||
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
import dev.engine_room.flywheel.impl.registry.IdRegistryImpl;
|
||||||
import dev.engine_room.flywheel.vanilla.VanillaVisuals;
|
|
||||||
|
|
||||||
public final class FlwImpl {
|
public final class FlwImpl {
|
||||||
public static final Logger LOGGER = LoggerFactory.getLogger(Flywheel.ID);
|
public static final Logger LOGGER = LoggerFactory.getLogger(Flywheel.ID);
|
||||||
|
@ -23,9 +22,6 @@ public final class FlwImpl {
|
||||||
|
|
||||||
// backend
|
// backend
|
||||||
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
|
FlwBackend.init(FlwConfig.INSTANCE.backendConfig());
|
||||||
|
|
||||||
// vanilla
|
|
||||||
VanillaVisuals.init();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void freezeRegistries() {
|
public static void freezeRegistries() {
|
||||||
|
|
|
@ -13,8 +13,4 @@ public interface FlwImplXplat {
|
||||||
String getVersionStr();
|
String getVersionStr();
|
||||||
|
|
||||||
FlwConfig getConfig();
|
FlwConfig getConfig();
|
||||||
|
|
||||||
boolean useSodium0_6Compat();
|
|
||||||
|
|
||||||
boolean useIrisCompat();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -34,8 +34,8 @@ public class FlwLibLinkImpl implements FlwLibLink {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, float red, float green, float blue, float alpha) {
|
public void compileModelPart(ModelPart part, PoseStack.Pose pose, VertexConsumer consumer, int light, int overlay, int color) {
|
||||||
((ModelPartAccessor) (Object) part).flywheel$compile(pose, consumer, light, overlay, red, green, blue, alpha);
|
((ModelPartAccessor) (Object) part).flywheel$compile(pose, consumer, light, overlay, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -5,7 +5,6 @@ import dev.engine_room.flywheel.impl.FlwImplXplat;
|
||||||
public enum CompatMod {
|
public enum CompatMod {
|
||||||
EMBEDDIUM("embeddium"),
|
EMBEDDIUM("embeddium"),
|
||||||
IRIS("iris"),
|
IRIS("iris"),
|
||||||
OCULUS("oculus"),
|
|
||||||
SODIUM("sodium");
|
SODIUM("sodium");
|
||||||
|
|
||||||
public final String id;
|
public final String id;
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
package dev.engine_room.flywheel.impl.compat;
|
package dev.engine_room.flywheel.impl.compat;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.impl.FlwImpl;
|
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||||
import dev.engine_room.flywheel.impl.FlwImplXplat;
|
|
||||||
import net.irisshaders.iris.api.v0.IrisApi;
|
import net.irisshaders.iris.api.v0.IrisApi;
|
||||||
|
|
||||||
public final class IrisCompat {
|
public final class IrisCompat {
|
||||||
public static final boolean ACTIVE = FlwImplXplat.INSTANCE.useIrisCompat();
|
public static final boolean ACTIVE = CompatMod.IRIS.isLoaded;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if (ACTIVE) {
|
if (ACTIVE) {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
import dev.engine_room.flywheel.api.visualization.BlockEntityVisualizer;
|
||||||
import dev.engine_room.flywheel.impl.FlwImpl;
|
import dev.engine_room.flywheel.impl.FlwImpl;
|
||||||
import dev.engine_room.flywheel.impl.FlwImplXplat;
|
|
||||||
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
||||||
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderHandler;
|
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderHandler;
|
||||||
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderPredicate;
|
import net.caffeinemc.mods.sodium.api.blockentity.BlockEntityRenderPredicate;
|
||||||
|
@ -12,11 +11,11 @@ import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
import net.minecraft.world.level.block.entity.BlockEntityType;
|
||||||
|
|
||||||
public final class SodiumCompat {
|
public final class SodiumCompat {
|
||||||
public static final boolean USE_0_6_COMPAT = FlwImplXplat.INSTANCE.useSodium0_6Compat();
|
public static final boolean ACTIVE = CompatMod.SODIUM.isLoaded;
|
||||||
|
|
||||||
static {
|
static {
|
||||||
if (USE_0_6_COMPAT) {
|
if (ACTIVE) {
|
||||||
FlwImpl.LOGGER.debug("Detected Sodium 0.6");
|
FlwImpl.LOGGER.debug("Detected Sodium");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +24,7 @@ public final class SodiumCompat {
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
public static <T extends BlockEntity> Object onSetBlockEntityVisualizer(BlockEntityType<T> type, @Nullable BlockEntityVisualizer<? super T> oldVisualizer, @Nullable BlockEntityVisualizer<? super T> newVisualizer, @Nullable Object predicate) {
|
public static <T extends BlockEntity> Object onSetBlockEntityVisualizer(BlockEntityType<T> type, @Nullable BlockEntityVisualizer<? super T> oldVisualizer, @Nullable BlockEntityVisualizer<? super T> newVisualizer, @Nullable Object predicate) {
|
||||||
if (!USE_0_6_COMPAT) {
|
if (!ACTIVE) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,7 +48,7 @@ public final class SodiumCompat {
|
||||||
|
|
||||||
private static final class Internals {
|
private static final class Internals {
|
||||||
static <T extends BlockEntity> Object addPredicate(BlockEntityType<T> type) {
|
static <T extends BlockEntity> Object addPredicate(BlockEntityType<T> type) {
|
||||||
BlockEntityRenderPredicate<T> predicate = (getter, pos, be) -> VisualizationHelper.tryAddBlockEntity(be);
|
BlockEntityRenderPredicate<T> predicate = (getter, pos, be) -> !VisualizationHelper.tryAddBlockEntity(be);
|
||||||
BlockEntityRenderHandler.instance().addRenderPredicate(type, predicate);
|
BlockEntityRenderHandler.instance().addRenderPredicate(type, predicate);
|
||||||
return predicate;
|
return predicate;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,22 +3,19 @@ package dev.engine_room.flywheel.impl.event;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
import org.joml.Matrix4fc;
|
import org.joml.Matrix4fc;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.RenderContext;
|
import dev.engine_room.flywheel.api.RenderContext;
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
import net.minecraft.client.renderer.RenderBuffers;
|
import net.minecraft.client.renderer.RenderBuffers;
|
||||||
|
|
||||||
public record RenderContextImpl(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack,
|
public record RenderContextImpl(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView,
|
||||||
Matrix4fc projection, Matrix4fc viewProjection, Camera camera,
|
Matrix4fc projection, Matrix4fc viewProjection, Camera camera,
|
||||||
float partialTick) implements RenderContext {
|
float partialTick) implements RenderContext {
|
||||||
public static RenderContextImpl create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, PoseStack stack, Matrix4f projection, Camera camera, float partialTick) {
|
public static RenderContextImpl create(LevelRenderer renderer, ClientLevel level, RenderBuffers buffers, Matrix4fc modelView, Matrix4f projection, Camera camera, float partialTick) {
|
||||||
Matrix4f viewProjection = new Matrix4f(projection);
|
Matrix4f viewProjection = new Matrix4f(projection);
|
||||||
viewProjection.mul(stack.last()
|
viewProjection.mul(modelView);
|
||||||
.pose());
|
|
||||||
|
|
||||||
return new RenderContextImpl(renderer, level, buffers, stack, projection, viewProjection, camera, partialTick);
|
return new RenderContextImpl(renderer, level, buffers, modelView, projection, viewProjection, camera, partialTick);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,7 +28,7 @@ abstract class BlockEntityTypeMixin<T extends BlockEntity> implements BlockEntit
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void flywheel$setVisualizer(@Nullable BlockEntityVisualizer<? super T> visualizer) {
|
public void flywheel$setVisualizer(@Nullable BlockEntityVisualizer<? super T> visualizer) {
|
||||||
if (SodiumCompat.USE_0_6_COMPAT) {
|
if (SodiumCompat.ACTIVE) {
|
||||||
flywheel$sodiumPredicate = SodiumCompat.onSetBlockEntityVisualizer((BlockEntityType<T>) (Object) this, flywheel$visualizer, visualizer, flywheel$sodiumPredicate);
|
flywheel$sodiumPredicate = SodiumCompat.onSetBlockEntityVisualizer((BlockEntityType<T>) (Object) this, flywheel$visualizer, visualizer, flywheel$sodiumPredicate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -22,6 +22,7 @@ import dev.engine_room.flywheel.impl.event.RenderContextImpl;
|
||||||
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
||||||
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
|
||||||
import net.minecraft.client.Camera;
|
import net.minecraft.client.Camera;
|
||||||
|
import net.minecraft.client.DeltaTracker;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraft.client.renderer.GameRenderer;
|
import net.minecraft.client.renderer.GameRenderer;
|
||||||
import net.minecraft.client.renderer.LevelRenderer;
|
import net.minecraft.client.renderer.LevelRenderer;
|
||||||
|
@ -51,8 +52,8 @@ abstract class LevelRendererMixin {
|
||||||
|
|
||||||
// @Inject(method = "renderLevel", at = @At("HEAD"))
|
// @Inject(method = "renderLevel", at = @At("HEAD"))
|
||||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I"))
|
@Inject(method = "renderLevel", at = @At(value = "INVOKE_ASSIGN", target = "Lnet/minecraft/world/level/lighting/LevelLightEngine;runLightUpdates()I"))
|
||||||
private void flywheel$beginRender(PoseStack poseStack, float partialTick, long finishNanoTime, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f projectionMatrix, CallbackInfo ci) {
|
private void flywheel$beginRender(DeltaTracker deltaTracker, boolean renderBlockOutline, Camera camera, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f modelMatrix, Matrix4f projectionMatrix, CallbackInfo ci) {
|
||||||
flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, poseStack, projectionMatrix, camera, partialTick);
|
flywheel$renderContext = RenderContextImpl.create((LevelRenderer) (Object) this, level, renderBuffers, modelMatrix, projectionMatrix, camera, deltaTracker.getGameTimeDeltaPartialTick(false));
|
||||||
|
|
||||||
VisualizationManager manager = VisualizationManager.get(level);
|
VisualizationManager manager = VisualizationManager.get(level);
|
||||||
if (manager != null) {
|
if (manager != null) {
|
||||||
|
@ -102,8 +103,8 @@ abstract class LevelRendererMixin {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Group(name = "afterParticles", min = 2, max = 2)
|
@Group(name = "afterParticles", min = 2, max = 3)
|
||||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;F)V", shift = Shift.AFTER))
|
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;F)V", shift = Shift.AFTER))
|
||||||
private void flywheel$afterParticles$fabric(CallbackInfo ci) {
|
private void flywheel$afterParticles$fabric(CallbackInfo ci) {
|
||||||
if (flywheel$renderContext != null) {
|
if (flywheel$renderContext != null) {
|
||||||
VisualizationManager manager = VisualizationManager.get(level);
|
VisualizationManager manager = VisualizationManager.get(level);
|
||||||
|
@ -114,8 +115,8 @@ abstract class LevelRendererMixin {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Group(name = "afterParticles")
|
@Group(name = "afterParticles")
|
||||||
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lcom/mojang/blaze3d/vertex/PoseStack;Lnet/minecraft/client/renderer/MultiBufferSource$BufferSource;Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;FLnet/minecraft/client/renderer/culling/Frustum;)V", shift = Shift.AFTER))
|
@Inject(method = "renderLevel", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/particle/ParticleEngine;render(Lnet/minecraft/client/renderer/LightTexture;Lnet/minecraft/client/Camera;FLnet/minecraft/client/renderer/culling/Frustum;Ljava/util/function/Predicate;)V", shift = Shift.AFTER))
|
||||||
private void flywheel$afterParticles$forge(CallbackInfo ci) {
|
private void flywheel$afterParticles$neoforge(CallbackInfo ci) {
|
||||||
if (flywheel$renderContext != null) {
|
if (flywheel$renderContext != null) {
|
||||||
VisualizationManager manager = VisualizationManager.get(level);
|
VisualizationManager manager = VisualizationManager.get(level);
|
||||||
if (manager != null) {
|
if (manager != null) {
|
||||||
|
|
|
@ -17,5 +17,5 @@ public interface ModelPartAccessor {
|
||||||
Map<String, ModelPart> flywheel$children();
|
Map<String, ModelPart> flywheel$children();
|
||||||
|
|
||||||
@Invoker("compile")
|
@Invoker("compile")
|
||||||
void flywheel$compile(PoseStack.Pose pose, VertexConsumer vertexConsumer, int packedLight, int packedOverlay, float red, float green, float blue, float alpha);
|
void flywheel$compile(PoseStack.Pose pose, VertexConsumer buffer, int packedLight, int packedOverlay, int color);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,36 +0,0 @@
|
||||||
package dev.engine_room.flywheel.impl.mixin.fix;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At.Shift;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
@Mixin(PoseStack.class)
|
|
||||||
abstract class FixNormalScalingMixin {
|
|
||||||
/**
|
|
||||||
* Minecraft negates the normal matrix if all scales are equal and negative, but
|
|
||||||
* does not return afterward. This allows the rest of the method's logic to be
|
|
||||||
* applied, which negates the matrix again, resulting in the matrix being the
|
|
||||||
* same as in the beginning.
|
|
||||||
*/
|
|
||||||
@Inject(method = "scale(FFF)V", at = @At(value = "INVOKE", target = "Lorg/joml/Matrix3f;scale(F)Lorg/joml/Matrix3f;", shift = Shift.AFTER, remap = false), cancellable = true)
|
|
||||||
private void flywheel$returnAfterNegate(float x, float y, float z, CallbackInfo ci) {
|
|
||||||
ci.cancel();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Minecraft takes the inverse cube root of the product of all scales to provide a
|
|
||||||
* rough estimate for normalization so that it does not need to be done later. It
|
|
||||||
* does not make sense for this "normalization factor" to be negative though, as
|
|
||||||
* that would invert all normals. Additionally, Minecraft's fastInvCubeRoot method
|
|
||||||
* does not work for negative numbers.
|
|
||||||
*/
|
|
||||||
@ModifyArg(method = "scale(FFF)V", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/Mth;fastInvCubeRoot(F)F"))
|
|
||||||
private float flywheel$absInvCbrtInput(float input) {
|
|
||||||
return Math.abs(input);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,11 +7,12 @@ import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
||||||
|
import net.minecraft.client.renderer.chunk.SectionCompiler;
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
import net.minecraft.world.level.block.entity.BlockEntity;
|
||||||
|
|
||||||
@Mixin(targets = "net.minecraft.client.renderer.chunk.ChunkRenderDispatcher$RenderChunk$RebuildTask")
|
@Mixin(SectionCompiler.class)
|
||||||
abstract class RebuildTaskMixin {
|
abstract class SectionCompilerMixin {
|
||||||
@Inject(method = "handleBlockEntity(Lnet/minecraft/client/renderer/chunk/ChunkRenderDispatcher$RenderChunk$RebuildTask$CompileResults;Lnet/minecraft/world/level/block/entity/BlockEntity;)V", at = @At("HEAD"), cancellable = true)
|
@Inject(method = "handleBlockEntity", at = @At("HEAD"), cancellable = true)
|
||||||
private void flywheel$tryAddBlockEntity(@Coerce Object compileResults, BlockEntity blockEntity, CallbackInfo ci) {
|
private void flywheel$tryAddBlockEntity(@Coerce Object compileResults, BlockEntity blockEntity, CallbackInfo ci) {
|
||||||
if (VisualizationHelper.tryAddBlockEntity(blockEntity)) {
|
if (VisualizationHelper.tryAddBlockEntity(blockEntity)) {
|
||||||
ci.cancel();
|
ci.cancel();
|
|
@ -2,7 +2,7 @@
|
||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "dev.engine_room.flywheel.impl.mixin",
|
"package": "dev.engine_room.flywheel.impl.mixin",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_21",
|
||||||
"refmap": "flywheel.refmap.json",
|
"refmap": "flywheel.refmap.json",
|
||||||
"client": [
|
"client": [
|
||||||
"BlockEntityTypeMixin",
|
"BlockEntityTypeMixin",
|
||||||
|
@ -15,11 +15,10 @@
|
||||||
"PoseStackAccessor",
|
"PoseStackAccessor",
|
||||||
"PoseStackMixin",
|
"PoseStackMixin",
|
||||||
"fix.FixFabulousDepthMixin",
|
"fix.FixFabulousDepthMixin",
|
||||||
"fix.FixNormalScalingMixin",
|
|
||||||
"visualmanage.BlockEntityMixin",
|
"visualmanage.BlockEntityMixin",
|
||||||
"visualmanage.LevelChunkMixin",
|
"visualmanage.LevelChunkMixin",
|
||||||
"visualmanage.LevelRendererMixin",
|
"visualmanage.LevelRendererMixin",
|
||||||
"visualmanage.RebuildTaskMixin"
|
"visualmanage.SectionCompilerMixin"
|
||||||
],
|
],
|
||||||
"injectors": {
|
"injectors": {
|
||||||
"defaultRequire": 1
|
"defaultRequire": 1
|
||||||
|
|
|
@ -1,38 +0,0 @@
|
||||||
// https://github.com/CaffeineMC/sodium-fabric/blob/e7643f4544f61180ed2f0ff4952d7daa2c1feaf4/common/src/api/java/net/caffeinemc/mods/sodium/api/blockentity/BlockEntityRenderHandler.java
|
|
||||||
// PolyForm Shield License 1.0.0
|
|
||||||
|
|
||||||
package net.caffeinemc.mods.sodium.api.blockentity;
|
|
||||||
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntityType;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
|
|
||||||
@ApiStatus.Experimental
|
|
||||||
@ApiStatus.AvailableSince("0.6.0")
|
|
||||||
public interface BlockEntityRenderHandler {
|
|
||||||
BlockEntityRenderHandler INSTANCE = null;
|
|
||||||
|
|
||||||
static BlockEntityRenderHandler instance() {
|
|
||||||
return INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Adds a predicate to determine if a block entity should be rendered.
|
|
||||||
*
|
|
||||||
* <p>Upon chunk bake, block entities of the given type will have {@code shouldRender} evaluated.
|
|
||||||
* <br>If <b>all predicates</b> returns {@code true} (and the block entity has a renderer), the block entity will be
|
|
||||||
* added to the chunk for future rendering.</p>
|
|
||||||
* @param type The block entity type to associate the given predicate with.
|
|
||||||
* @param shouldRender The predicate for the block entity to evaluate.
|
|
||||||
*/
|
|
||||||
<T extends BlockEntity> void addRenderPredicate(BlockEntityType<T> type, BlockEntityRenderPredicate<T> shouldRender);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes a predicate added by {@code addRenderPredicate}. <b>It must be the same object that was added.</b>
|
|
||||||
*
|
|
||||||
* @param type The block entity type to associate the given predicate with.
|
|
||||||
* @param shouldRender The predicate to remove.
|
|
||||||
* @return If the predicate existed and was removed.
|
|
||||||
*/
|
|
||||||
<T extends BlockEntity> boolean removeRenderPredicate(BlockEntityType<T> type, BlockEntityRenderPredicate<T> shouldRender);
|
|
||||||
}
|
|
|
@ -1,16 +0,0 @@
|
||||||
// https://github.com/CaffeineMC/sodium-fabric/blob/e7643f4544f61180ed2f0ff4952d7daa2c1feaf4/common/src/api/java/net/caffeinemc/mods/sodium/api/blockentity/BlockEntityRenderPredicate.java
|
|
||||||
// PolyForm Shield License 1.0.0
|
|
||||||
|
|
||||||
package net.caffeinemc.mods.sodium.api.blockentity;
|
|
||||||
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.world.level.BlockGetter;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
import org.jetbrains.annotations.ApiStatus;
|
|
||||||
|
|
||||||
@ApiStatus.Experimental
|
|
||||||
@ApiStatus.AvailableSince("0.6.0")
|
|
||||||
@FunctionalInterface
|
|
||||||
public interface BlockEntityRenderPredicate<T extends BlockEntity> {
|
|
||||||
boolean shouldRender(BlockGetter blockGetter, BlockPos blockPos, T entity);
|
|
||||||
}
|
|
|
@ -1,114 +0,0 @@
|
||||||
// https://github.com/IrisShaders/Iris/blob/20be7fc1ff8a48048cb4eb787e1299782bb1caa4/src/main/java/net/irisshaders/iris/api/v0/IrisApi.java
|
|
||||||
// GNU Lesser General Public License v3.0
|
|
||||||
|
|
||||||
package net.irisshaders.iris.api.v0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The entry point to the Iris API, major version 0. This is currently the latest
|
|
||||||
* version of the API.
|
|
||||||
*
|
|
||||||
* To access the API, use {@link #getInstance()}.
|
|
||||||
*/
|
|
||||||
public interface IrisApi {
|
|
||||||
/**
|
|
||||||
* @since API v0.0
|
|
||||||
*/
|
|
||||||
static IrisApi getInstance() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the minor revision of this API. This is incremented when
|
|
||||||
* new methods are added without breaking API. Mods can check this
|
|
||||||
* if they wish to check whether given API calls are available on
|
|
||||||
* the currently installed Iris version.
|
|
||||||
*
|
|
||||||
* @return The current minor revision. Currently, revision 2.
|
|
||||||
*/
|
|
||||||
int getMinorApiRevision();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether a shader pack is currently in use and being used
|
|
||||||
* for rendering. If there is no shader pack enabled or a shader
|
|
||||||
* pack failed to compile and is therefore not in use, this will
|
|
||||||
* return false.
|
|
||||||
*
|
|
||||||
* <p>Mods that need to enable custom workarounds for shaders
|
|
||||||
* should use this method.
|
|
||||||
*
|
|
||||||
* @return Whether shaders are being used for rendering.
|
|
||||||
* @since {@link #getMinorApiRevision() API v0.0}
|
|
||||||
*/
|
|
||||||
boolean isShaderPackInUse();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Checks whether the shadow pass is currently being rendered.
|
|
||||||
*
|
|
||||||
* <p>Generally, mods won't need to call this function for much.
|
|
||||||
* Mods should be fine with things being rendered multiple times
|
|
||||||
* each frame from different camera perspectives. Often, there's
|
|
||||||
* a better approach to fixing bugs than calling this function.
|
|
||||||
*
|
|
||||||
* <p>Pretty much the main legitimate use for this function that
|
|
||||||
* I've seen is in a mod like Immersive Portals, where it has
|
|
||||||
* very custom culling that doesn't work when the Iris shadow
|
|
||||||
* pass is active.
|
|
||||||
*
|
|
||||||
* <p>Naturally, this function can only return true if
|
|
||||||
* {@link #isShaderPackInUse()} returns true.
|
|
||||||
*
|
|
||||||
* @return Whether Iris is currently rendering the shadow pass.
|
|
||||||
* @since API v0.0
|
|
||||||
*/
|
|
||||||
boolean isRenderingShadowPass();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Opens the main Iris GUI screen. It's up to Iris to decide
|
|
||||||
* what this screen is, but generally this is the shader selection
|
|
||||||
* screen.
|
|
||||||
*
|
|
||||||
* This method takes and returns Objects instead of any concrete
|
|
||||||
* Minecraft screen class to avoid referencing Minecraft classes.
|
|
||||||
* Nevertheless, the passed parent must either be null, or an
|
|
||||||
* object that is a subclass of the appropriate {@code Screen}
|
|
||||||
* class for the given Minecraft version.
|
|
||||||
*
|
|
||||||
* @param parent The parent screen, an instance of the appropriate
|
|
||||||
* {@code Screen} class.
|
|
||||||
* @return A {@code Screen} class for the main Iris GUI screen.
|
|
||||||
* @since API v0.0
|
|
||||||
*/
|
|
||||||
Object openMainIrisScreenObj(Object parent);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the language key of the main screen. Currently, this
|
|
||||||
* is "options.iris.shaderPackSelection".
|
|
||||||
*
|
|
||||||
* @return the language key, for use with {@code TranslatableText}
|
|
||||||
* / {@code TranslatableComponent}
|
|
||||||
* @since API v0.0
|
|
||||||
*/
|
|
||||||
String getMainScreenLanguageKey();
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Gets a config object that can edit the Iris configuration.
|
|
||||||
// * @since API v0.0
|
|
||||||
// */
|
|
||||||
// IrisApiConfig getConfig();
|
|
||||||
|
|
||||||
// /**
|
|
||||||
// * Gets a text vertex sink to render into.
|
|
||||||
// * @param maxQuadCount Maximum amount of quads that will be rendered with this sink
|
|
||||||
// * @param bufferProvider An IntFunction that can provide a {@code ByteBuffer} with at minimum the bytes provided by the input parameter
|
|
||||||
// * @since API 0.1
|
|
||||||
// */
|
|
||||||
// IrisTextVertexSink createTextVertexSink(int maxQuadCount, IntFunction<ByteBuffer> bufferProvider);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the sun path rotation used by the current shader pack.
|
|
||||||
*
|
|
||||||
* @return The sun path rotation as specified by the shader pack, or 0 if no shader pack is in use.
|
|
||||||
* @since API v0.2
|
|
||||||
*/
|
|
||||||
float getSunPathRotation();
|
|
||||||
}
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
package dev.engine_room.vanillin;
|
||||||
|
|
||||||
|
public class Vanillin {
|
||||||
|
public static final String ID = "vanillin";
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.engine_room.flywheel.vanilla;
|
package dev.engine_room.vanillin.visuals;
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.engine_room.flywheel.vanilla;
|
package dev.engine_room.vanillin.visuals;
|
||||||
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.EnumMap;
|
import java.util.EnumMap;
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.engine_room.flywheel.vanilla;
|
package dev.engine_room.vanillin.visuals;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
@ -30,7 +30,7 @@ import net.minecraft.world.level.block.state.BlockState;
|
||||||
import net.minecraft.world.phys.Vec3;
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityVisual<T> implements SimpleTickableVisual, SimpleDynamicVisual {
|
public class MinecartVisual<T extends AbstractMinecart> extends ComponentEntityVisual<T> implements SimpleTickableVisual, SimpleDynamicVisual {
|
||||||
private static final ResourceLocation TEXTURE = new ResourceLocation("textures/entity/minecart.png");
|
private static final ResourceLocation TEXTURE = ResourceLocation.withDefaultNamespace("textures/entity/minecart.png");
|
||||||
private static final Material MATERIAL = SimpleMaterial.builder()
|
private static final Material MATERIAL = SimpleMaterial.builder()
|
||||||
.texture(TEXTURE)
|
.texture(TEXTURE)
|
||||||
.mipmap(false)
|
.mipmap(false)
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.engine_room.flywheel.vanilla;
|
package dev.engine_room.vanillin.visuals;
|
||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.engine_room.flywheel.vanilla;
|
package dev.engine_room.vanillin.visuals;
|
||||||
|
|
||||||
import org.joml.Matrix4f;
|
import org.joml.Matrix4f;
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package dev.engine_room.flywheel.vanilla;
|
package dev.engine_room.vanillin.visuals;
|
||||||
|
|
||||||
import static dev.engine_room.flywheel.lib.visualization.SimpleBlockEntityVisualizer.builder;
|
import static dev.engine_room.flywheel.lib.visualization.SimpleBlockEntityVisualizer.builder;
|
||||||
import static dev.engine_room.flywheel.lib.visualization.SimpleEntityVisualizer.builder;
|
import static dev.engine_room.flywheel.lib.visualization.SimpleEntityVisualizer.builder;
|
BIN
common/src/vanillin/resources/logo.png
Normal file
BIN
common/src/vanillin/resources/logo.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 14 KiB |
|
@ -7,6 +7,11 @@ plugins {
|
||||||
id("flywheel.platform")
|
id("flywheel.platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val common = ":common"
|
||||||
|
val commonProject = project(common)
|
||||||
|
|
||||||
|
subproject.init("flywheel-fabric", "flywheel_group", "flywheel_version")
|
||||||
|
|
||||||
val api = sourceSets.create("api")
|
val api = sourceSets.create("api")
|
||||||
val lib = sourceSets.create("lib")
|
val lib = sourceSets.create("lib")
|
||||||
val backend = sourceSets.create("backend")
|
val backend = sourceSets.create("backend")
|
||||||
|
@ -19,22 +24,34 @@ transitiveSourceSets {
|
||||||
|
|
||||||
sourceSet(api) {
|
sourceSet(api) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
|
|
||||||
|
from(commonProject)
|
||||||
}
|
}
|
||||||
sourceSet(lib) {
|
sourceSet(lib) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
compile(api)
|
compileClasspath(api)
|
||||||
|
|
||||||
|
from(commonProject)
|
||||||
}
|
}
|
||||||
sourceSet(backend) {
|
sourceSet(backend) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
compile(api, lib)
|
compileClasspath(api, lib)
|
||||||
|
|
||||||
|
from(commonProject)
|
||||||
}
|
}
|
||||||
sourceSet(stubs) {
|
sourceSet(stubs) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
|
|
||||||
|
from(commonProject)
|
||||||
}
|
}
|
||||||
sourceSet(main) {
|
sourceSet(main) {
|
||||||
// Don't want stubs at runtime
|
// Don't want stubs at runtime
|
||||||
compile(stubs)
|
compileClasspath(stubs)
|
||||||
implementation(api, lib, backend)
|
implementation(api, lib, backend)
|
||||||
|
|
||||||
|
bundleFrom(commonProject)
|
||||||
|
|
||||||
|
bundleOutput(api, lib, backend)
|
||||||
}
|
}
|
||||||
sourceSet(testMod) {
|
sourceSet(testMod) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
|
@ -44,19 +61,18 @@ transitiveSourceSets {
|
||||||
}
|
}
|
||||||
|
|
||||||
platform {
|
platform {
|
||||||
commonProject = project(":common")
|
|
||||||
compileWithCommonSourceSets(api, lib, backend, stubs, main)
|
|
||||||
setupLoomMod(api, lib, backend, main)
|
setupLoomMod(api, lib, backend, main)
|
||||||
setupLoomRuns()
|
setupLoomRuns()
|
||||||
setupFatJar(api, lib, backend, main)
|
|
||||||
setupTestMod(testMod)
|
setupTestMod(testMod)
|
||||||
}
|
}
|
||||||
|
|
||||||
jarSets {
|
jarSets {
|
||||||
mainSet.publish(platform.modArtifactId)
|
mainSet.publish("flywheel-fabric-${project.property("artifact_minecraft_version")}")
|
||||||
|
mainSet.outgoing("flywheel")
|
||||||
|
|
||||||
create("api", api, lib).apply {
|
create("api", api, lib).apply {
|
||||||
addToAssemble()
|
addToAssemble()
|
||||||
publish(platform.apiArtifactId)
|
publish("flywheel-fabric-api-${project.property("artifact_minecraft_version")}")
|
||||||
|
|
||||||
configureJar {
|
configureJar {
|
||||||
manifest {
|
manifest {
|
||||||
|
@ -82,11 +98,16 @@ dependencies {
|
||||||
modImplementation("net.fabricmc:fabric-loader:${property("fabric_loader_version")}")
|
modImplementation("net.fabricmc:fabric-loader:${property("fabric_loader_version")}")
|
||||||
modApi("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}")
|
modApi("net.fabricmc.fabric-api:fabric-api:${property("fabric_api_version")}")
|
||||||
|
|
||||||
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}")
|
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-fabric")
|
||||||
|
modCompileOnly("maven.modrinth:iris:${property("iris_version")}-fabric")
|
||||||
|
|
||||||
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
|
"forApi"(project(path = common, configuration = "apiClasses"))
|
||||||
"forLib"(project(path = ":common", configuration = "commonLib"))
|
"forLib"(project(path = common, configuration = "libClasses"))
|
||||||
"forBackend"(project(path = ":common", configuration = "commonBackend"))
|
"forBackend"(project(path = common, configuration = "backendClasses"))
|
||||||
"forStubs"(project(path = ":common", configuration = "commonStubs"))
|
"forStubs"(project(path = common, configuration = "stubsClasses"))
|
||||||
"forMain"(project(path = ":common", configuration = "commonImpl"))
|
"forMain"(project(path = common, configuration = "mainClasses"))
|
||||||
|
|
||||||
|
"forLib"(project(path = common, configuration = "libResources"))
|
||||||
|
"forBackend"(project(path = common, configuration = "backendResources"))
|
||||||
|
"forMain"(project(path = common, configuration = "mainResources"))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import java.util.Iterator;
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder.RenderedBuffer;
|
import com.mojang.blaze3d.vertex.MeshData;
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
import com.mojang.blaze3d.vertex.PoseStack;
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap;
|
import it.unimi.dsi.fastutil.objects.Reference2ReferenceMap;
|
||||||
|
@ -150,7 +150,7 @@ final class BakedModelBufferer {
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface ResultConsumer {
|
public interface ResultConsumer {
|
||||||
void accept(RenderType renderType, boolean shaded, RenderedBuffer data);
|
void accept(RenderType renderType, boolean shaded, MeshData data);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class ThreadLocalObjects {
|
private static class ThreadLocalObjects {
|
||||||
|
|
|
@ -1,64 +0,0 @@
|
||||||
package dev.engine_room.flywheel.lib.model.baked;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.Material;
|
|
||||||
import dev.engine_room.flywheel.api.model.Mesh;
|
|
||||||
import dev.engine_room.flywheel.api.model.Model;
|
|
||||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
public final class FabricBakedModelBuilder extends BakedModelBuilder {
|
|
||||||
public FabricBakedModelBuilder(BakedModel bakedModel) {
|
|
||||||
super(bakedModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricBakedModelBuilder level(BlockAndTintGetter level) {
|
|
||||||
super.level(level);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricBakedModelBuilder blockState(BlockState blockState) {
|
|
||||||
super.blockState(blockState);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricBakedModelBuilder poseStack(PoseStack poseStack) {
|
|
||||||
super.poseStack(poseStack);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricBakedModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
|
||||||
super.materialFunc(materialFunc);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SimpleModel build() {
|
|
||||||
if (materialFunc == null) {
|
|
||||||
materialFunc = ModelUtil::getMaterial;
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
|
||||||
|
|
||||||
BakedModelBufferer.bufferSingle(level, bakedModel, blockState, poseStack, (renderType, shaded, data) -> {
|
|
||||||
Material material = materialFunc.apply(renderType, shaded);
|
|
||||||
if (material != null) {
|
|
||||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BakedModelBuilder," + "bakedModel=" + bakedModel + ",renderType=" + renderType + ",shaded=" + shaded);
|
|
||||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return new SimpleModel(builder.build());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package dev.engine_room.flywheel.lib.model.baked;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.Material;
|
|
||||||
import dev.engine_room.flywheel.api.model.Mesh;
|
|
||||||
import dev.engine_room.flywheel.api.model.Model;
|
|
||||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
public final class FabricBlockModelBuilder extends BlockModelBuilder {
|
|
||||||
public FabricBlockModelBuilder(BlockState state) {
|
|
||||||
super(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricBlockModelBuilder level(BlockAndTintGetter level) {
|
|
||||||
super.level(level);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricBlockModelBuilder poseStack(PoseStack poseStack) {
|
|
||||||
super.poseStack(poseStack);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricBlockModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
|
||||||
super.materialFunc(materialFunc);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SimpleModel build() {
|
|
||||||
if (materialFunc == null) {
|
|
||||||
materialFunc = ModelUtil::getMaterial;
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
|
||||||
|
|
||||||
BakedModelBufferer.bufferBlock(level, state, poseStack, (renderType, shaded, data) -> {
|
|
||||||
Material material = materialFunc.apply(renderType, shaded);
|
|
||||||
if (material != null) {
|
|
||||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BlockModelBuilder," + "blockState=" + state + ",renderType=" + renderType + ",shaded=" + shaded);
|
|
||||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return new SimpleModel(builder.build());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,57 +0,0 @@
|
||||||
package dev.engine_room.flywheel.lib.model.baked;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.Material;
|
|
||||||
import dev.engine_room.flywheel.api.model.Mesh;
|
|
||||||
import dev.engine_room.flywheel.api.model.Model;
|
|
||||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
|
|
||||||
public final class FabricMultiBlockModelBuilder extends MultiBlockModelBuilder {
|
|
||||||
public FabricMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
|
||||||
super(level, positions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricMultiBlockModelBuilder poseStack(PoseStack poseStack) {
|
|
||||||
super.poseStack(poseStack);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricMultiBlockModelBuilder enableFluidRendering() {
|
|
||||||
super.enableFluidRendering();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FabricMultiBlockModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
|
||||||
super.materialFunc(materialFunc);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SimpleModel build() {
|
|
||||||
if (materialFunc == null) {
|
|
||||||
materialFunc = ModelUtil::getMaterial;
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
|
||||||
|
|
||||||
BakedModelBufferer.bufferMultiBlock(positions.iterator(), level, poseStack, renderFluids, (renderType, shaded, data) -> {
|
|
||||||
Material material = materialFunc.apply(renderType, shaded);
|
|
||||||
if (material != null) {
|
|
||||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=MultiBlockModelBuilder," + "renderType=" + renderType + ",shaded=" + shaded);
|
|
||||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return new SimpleModel(builder.build());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -3,6 +3,7 @@ package dev.engine_room.flywheel.lib.model.baked;
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
import org.jetbrains.annotations.UnknownNullability;
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.BufferBuilder;
|
import com.mojang.blaze3d.vertex.BufferBuilder;
|
||||||
|
import com.mojang.blaze3d.vertex.ByteBufferBuilder;
|
||||||
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
import com.mojang.blaze3d.vertex.DefaultVertexFormat;
|
||||||
import com.mojang.blaze3d.vertex.VertexFormat;
|
import com.mojang.blaze3d.vertex.VertexFormat;
|
||||||
|
|
||||||
|
@ -10,14 +11,16 @@ import net.minecraft.client.renderer.RenderType;
|
||||||
|
|
||||||
class MeshEmitter {
|
class MeshEmitter {
|
||||||
private final RenderType renderType;
|
private final RenderType renderType;
|
||||||
private final BufferBuilder bufferBuilder;
|
private final ByteBufferBuilder byteBufferBuilder;
|
||||||
|
@UnknownNullability
|
||||||
|
private BufferBuilder bufferBuilder;
|
||||||
|
|
||||||
private BakedModelBufferer.@UnknownNullability ResultConsumer resultConsumer;
|
private BakedModelBufferer.@UnknownNullability ResultConsumer resultConsumer;
|
||||||
private boolean currentShade;
|
private boolean currentShade;
|
||||||
|
|
||||||
MeshEmitter(RenderType renderType) {
|
MeshEmitter(RenderType renderType) {
|
||||||
this.renderType = renderType;
|
this.renderType = renderType;
|
||||||
this.bufferBuilder = new BufferBuilder(renderType.bufferSize());
|
this.byteBufferBuilder = new ByteBufferBuilder(renderType.bufferSize());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void prepare(BakedModelBufferer.ResultConsumer resultConsumer) {
|
public void prepare(BakedModelBufferer.ResultConsumer resultConsumer) {
|
||||||
|
@ -25,7 +28,7 @@ class MeshEmitter {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void end() {
|
public void end() {
|
||||||
if (bufferBuilder.building()) {
|
if (bufferBuilder != null) {
|
||||||
emit();
|
emit();
|
||||||
}
|
}
|
||||||
resultConsumer = null;
|
resultConsumer = null;
|
||||||
|
@ -36,23 +39,24 @@ class MeshEmitter {
|
||||||
return bufferBuilder;
|
return bufferBuilder;
|
||||||
}
|
}
|
||||||
|
|
||||||
void prepareForGeometry(boolean shade) {
|
private void prepareForGeometry(boolean shade) {
|
||||||
if (!bufferBuilder.building()) {
|
if (bufferBuilder == null) {
|
||||||
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||||
} else if (shade != currentShade) {
|
} else if (shade != currentShade) {
|
||||||
emit();
|
emit();
|
||||||
bufferBuilder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
bufferBuilder = new BufferBuilder(byteBufferBuilder, VertexFormat.Mode.QUADS, DefaultVertexFormat.BLOCK);
|
||||||
}
|
}
|
||||||
|
|
||||||
currentShade = shade;
|
currentShade = shade;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emit() {
|
private void emit() {
|
||||||
var renderedBuffer = bufferBuilder.endOrDiscardIfEmpty();
|
var data = bufferBuilder.build();
|
||||||
|
bufferBuilder = null;
|
||||||
|
|
||||||
if (renderedBuffer != null) {
|
if (data != null) {
|
||||||
resultConsumer.accept(renderType, currentShade, renderedBuffer);
|
resultConsumer.accept(renderType, currentShade, data);
|
||||||
renderedBuffer.release();
|
data.close();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
package dev.engine_room.flywheel.lib.model.baked;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.ApiStatus;
|
||||||
|
|
||||||
|
import dev.engine_room.flywheel.api.material.Material;
|
||||||
|
import dev.engine_room.flywheel.api.model.Mesh;
|
||||||
|
import dev.engine_room.flywheel.api.model.Model;
|
||||||
|
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||||
|
|
||||||
|
@ApiStatus.Internal
|
||||||
|
public final class ModelBuilderImpl {
|
||||||
|
private ModelBuilderImpl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) {
|
||||||
|
var builder1 = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||||
|
|
||||||
|
BakedModelBufferer.bufferSingle(builder.level, builder.bakedModel, builder.blockState, builder.poseStack, (renderType, shaded, data) -> {
|
||||||
|
Material material = builder.materialFunc.apply(renderType, shaded);
|
||||||
|
if (material != null) {
|
||||||
|
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BakedModelBuilder," + "bakedModel=" + builder.bakedModel + ",renderType=" + renderType + ",shaded=" + shaded);
|
||||||
|
builder1.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return new SimpleModel(builder1.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
|
||||||
|
var builder1 = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||||
|
|
||||||
|
BakedModelBufferer.bufferBlock(builder.level, builder.state, builder.poseStack, (renderType, shaded, data) -> {
|
||||||
|
Material material = builder.materialFunc.apply(renderType, shaded);
|
||||||
|
if (material != null) {
|
||||||
|
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BlockModelBuilder," + "blockState=" + builder.state + ",renderType=" + renderType + ",shaded=" + shaded);
|
||||||
|
builder1.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return new SimpleModel(builder1.build());
|
||||||
|
}
|
||||||
|
|
||||||
|
public static SimpleModel buildMultiBlockModelBuilder(MultiBlockModelBuilder builder) {
|
||||||
|
var builder1 = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
||||||
|
|
||||||
|
BakedModelBufferer.bufferMultiBlock(builder.positions.iterator(), builder.level, builder.poseStack, builder.renderFluids, (renderType, shaded, data) -> {
|
||||||
|
Material material = builder.materialFunc.apply(renderType, shaded);
|
||||||
|
if (material != null) {
|
||||||
|
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=MultiBlockModelBuilder," + "renderType=" + renderType + ",shaded=" + shaded);
|
||||||
|
builder1.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return new SimpleModel(builder1.build());
|
||||||
|
}
|
||||||
|
}
|
|
@ -56,69 +56,54 @@ class UniversalMeshEmitter implements VertexConsumer {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer vertex(double x, double y, double z) {
|
public VertexConsumer addVertex(float x, float y, float z) {
|
||||||
currentDelegate.vertex(x, y, z);
|
currentDelegate.addVertex(x, y, z);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer color(int red, int green, int blue, int alpha) {
|
public VertexConsumer setColor(int red, int green, int blue, int alpha) {
|
||||||
currentDelegate.color(red, green, blue, alpha);
|
currentDelegate.setColor(red, green, blue, alpha);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer uv(float u, float v) {
|
public VertexConsumer setUv(float u, float v) {
|
||||||
currentDelegate.uv(u, v);
|
currentDelegate.setUv(u, v);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer overlayCoords(int u, int v) {
|
public VertexConsumer setUv1(int u, int v) {
|
||||||
currentDelegate.overlayCoords(u, v);
|
currentDelegate.setUv1(u, v);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer uv2(int u, int v) {
|
public VertexConsumer setUv2(int u, int v) {
|
||||||
currentDelegate.uv2(u, v);
|
currentDelegate.setUv2(u, v);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public VertexConsumer normal(float x, float y, float z) {
|
public VertexConsumer setNormal(float x, float y, float z) {
|
||||||
currentDelegate.normal(x, y, z);
|
currentDelegate.setNormal(x, y, z);
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void endVertex() {
|
public void addVertex(float x, float y, float z, int color, float u, float v, int packedOverlay, int packedLight, float normalX, float normalY, float normalZ) {
|
||||||
currentDelegate.endVertex();
|
currentDelegate.addVertex(x, y, z, color, u, v, packedOverlay, packedLight, normalX, normalY, normalZ);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void defaultColor(int red, int green, int blue, int alpha) {
|
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, float alpha, int packedLight, int packedOverlay) {
|
||||||
currentDelegate.defaultColor(red, green, blue, alpha);
|
currentDelegate.putBulkData(pose, quad, red, green, blue, alpha, packedLight, packedOverlay);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void unsetDefaultColor() {
|
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightness, float red, float green, float blue, float alpha, int[] lightmap, int packedOverlay, boolean readAlpha) {
|
||||||
currentDelegate.unsetDefaultColor();
|
currentDelegate.putBulkData(pose, quad, brightness, red, green, blue, alpha, lightmap, packedOverlay, readAlpha);
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void vertex(float x, float y, float z, float red, float green, float blue, float alpha, float u, float v, int overlay, int light, float normalX, float normalY, float normalZ) {
|
|
||||||
currentDelegate.vertex(x, y, z, red, green, blue, alpha, u, v, overlay, light, normalX, normalY, normalZ);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float red, float green, float blue, int light, int overlay) {
|
|
||||||
currentDelegate.putBulkData(pose, quad, red, green, blue, light, overlay);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void putBulkData(PoseStack.Pose pose, BakedQuad quad, float[] brightnesses, float red, float green, float blue, int[] lights, int overlay, boolean readExistingColor) {
|
|
||||||
currentDelegate.putBulkData(pose, quad, brightnesses, red, green, blue, lights, overlay, readExistingColor);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class WrapperModel extends ForwardingBakedModel {
|
private class WrapperModel extends ForwardingBakedModel {
|
||||||
|
|
|
@ -110,7 +110,7 @@ public class FabricFlwConfig implements FlwConfig {
|
||||||
if (backendJson instanceof JsonPrimitive primitive && primitive.isString()) {
|
if (backendJson instanceof JsonPrimitive primitive && primitive.isString()) {
|
||||||
var value = primitive.getAsString();
|
var value = primitive.getAsString();
|
||||||
try {
|
try {
|
||||||
this.backend = Backend.REGISTRY.getOrThrow(new ResourceLocation(value));
|
this.backend = Backend.REGISTRY.getOrThrow(ResourceLocation.parse(value));
|
||||||
return;
|
return;
|
||||||
} catch (ResourceLocationException e) {
|
} catch (ResourceLocationException e) {
|
||||||
msg = "'backend' value '" + value + "' is not a valid resource location";
|
msg = "'backend' value '" + value + "' is not a valid resource location";
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package dev.engine_room.flywheel.impl;
|
package dev.engine_room.flywheel.impl;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.event.ReloadLevelRendererCallback;
|
import dev.engine_room.flywheel.api.event.ReloadLevelRendererCallback;
|
||||||
import dev.engine_room.flywheel.impl.compat.CompatMod;
|
|
||||||
import dev.engine_room.flywheel.impl.compat.FabricSodiumCompat;
|
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
import net.fabricmc.loader.api.FabricLoader;
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
|
|
||||||
|
@ -26,14 +24,4 @@ public class FlwImplXplatImpl implements FlwImplXplat {
|
||||||
public FlwConfig getConfig() {
|
public FlwConfig getConfig() {
|
||||||
return FabricFlwConfig.INSTANCE;
|
return FabricFlwConfig.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useSodium0_6Compat() {
|
|
||||||
return FabricSodiumCompat.USE_0_6_COMPAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useIrisCompat() {
|
|
||||||
return CompatMod.IRIS.isLoaded;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,18 +3,14 @@ package dev.engine_room.flywheel.impl;
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
import org.jetbrains.annotations.UnknownNullability;
|
||||||
|
|
||||||
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
import dev.engine_room.flywheel.lib.internal.FlwLibXplat;
|
||||||
|
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.BakedModelBuilder;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.BlockModelBuilder;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.FabricBakedModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.ModelBuilderImpl;
|
||||||
import dev.engine_room.flywheel.lib.model.baked.FabricBlockModelBuilder;
|
|
||||||
import dev.engine_room.flywheel.lib.model.baked.FabricMultiBlockModelBuilder;
|
|
||||||
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
|
import dev.engine_room.flywheel.lib.model.baked.MultiBlockModelBuilder;
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
import net.minecraft.client.resources.model.BakedModel;
|
||||||
import net.minecraft.client.resources.model.ModelManager;
|
import net.minecraft.client.resources.model.ModelManager;
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
import net.minecraft.resources.ResourceLocation;
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
|
|
||||||
public class FlwLibXplatImpl implements FlwLibXplat {
|
public class FlwLibXplatImpl implements FlwLibXplat {
|
||||||
@Override
|
@Override
|
||||||
|
@ -24,17 +20,17 @@ public class FlwLibXplatImpl implements FlwLibXplat {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BakedModelBuilder createBakedModelBuilder(BakedModel bakedModel) {
|
public SimpleModel buildBakedModelBuilder(BakedModelBuilder builder) {
|
||||||
return new FabricBakedModelBuilder(bakedModel);
|
return ModelBuilderImpl.buildBakedModelBuilder(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public BlockModelBuilder createBlockModelBuilder(BlockState state) {
|
public SimpleModel buildBlockModelBuilder(BlockModelBuilder builder) {
|
||||||
return new FabricBlockModelBuilder(state);
|
return ModelBuilderImpl.buildBlockModelBuilder(builder);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public MultiBlockModelBuilder createMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
public SimpleModel buildMultiBlockModelBuilder(MultiBlockModelBuilder builder) {
|
||||||
return new FabricMultiBlockModelBuilder(level, positions);
|
return ModelBuilderImpl.buildMultiBlockModelBuilder(builder);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,48 +0,0 @@
|
||||||
package dev.engine_room.flywheel.impl.compat;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.impl.FlwImpl;
|
|
||||||
import net.fabricmc.loader.api.FabricLoader;
|
|
||||||
import net.fabricmc.loader.api.ModContainer;
|
|
||||||
import net.fabricmc.loader.api.Version;
|
|
||||||
import net.fabricmc.loader.api.VersionParsingException;
|
|
||||||
import net.fabricmc.loader.api.metadata.version.VersionPredicate;
|
|
||||||
|
|
||||||
public final class FabricSodiumCompat {
|
|
||||||
public static final boolean USE_0_5_COMPAT;
|
|
||||||
public static final boolean USE_0_6_COMPAT;
|
|
||||||
|
|
||||||
static {
|
|
||||||
boolean use0_5Compat = false;
|
|
||||||
boolean use0_6Compat = false;
|
|
||||||
|
|
||||||
Optional<ModContainer> optionalModContainer = FabricLoader.getInstance().getModContainer(CompatMod.SODIUM.id);
|
|
||||||
|
|
||||||
if (optionalModContainer.isPresent()) {
|
|
||||||
ModContainer modContainer = optionalModContainer.get();
|
|
||||||
Version sodiumVersion = modContainer.getMetadata().getVersion();
|
|
||||||
|
|
||||||
try {
|
|
||||||
VersionPredicate predicate0_5 = VersionPredicate.parse("~0.5.0");
|
|
||||||
VersionPredicate predicate0_6 = VersionPredicate.parse(">=0.6.0-beta.2");
|
|
||||||
use0_5Compat = predicate0_5.test(sodiumVersion);
|
|
||||||
use0_6Compat = predicate0_6.test(sodiumVersion);
|
|
||||||
} catch (VersionParsingException e) {
|
|
||||||
FlwImpl.LOGGER.debug("Failed to parse Sodium version predicates", e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
USE_0_5_COMPAT = use0_5Compat;
|
|
||||||
USE_0_6_COMPAT = use0_6Compat;
|
|
||||||
}
|
|
||||||
|
|
||||||
static {
|
|
||||||
if (USE_0_5_COMPAT) {
|
|
||||||
FlwImpl.LOGGER.debug("Detected Sodium 0.5");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private FabricSodiumCompat() {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -7,6 +7,7 @@ import org.spongepowered.asm.mixin.Final;
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
import org.spongepowered.asm.mixin.Mixin;
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
import org.spongepowered.asm.mixin.Shadow;
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
import org.spongepowered.asm.mixin.injection.At;
|
||||||
|
import org.spongepowered.asm.mixin.injection.Coerce;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
|
@ -30,14 +31,14 @@ abstract class MinecraftMixin {
|
||||||
FabricFlwConfig.INSTANCE.load();
|
FabricFlwConfig.INSTANCE.load();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "method_24040", at = @At("HEAD"))
|
@Inject(method = "method_53522", at = @At("HEAD"))
|
||||||
private void flywheel$onEndInitialResourceReload(Optional<Throwable> error, CallbackInfo ci) {
|
private void flywheel$onEndInitialResourceReload(@Coerce Object gameLoadCookie, Optional<Throwable> error, CallbackInfo ci) {
|
||||||
EndClientResourceReloadCallback.EVENT.invoker()
|
EndClientResourceReloadCallback.EVENT.invoker()
|
||||||
.onEndClientResourceReload((Minecraft) (Object) this, resourceManager, true, error);
|
.onEndClientResourceReload((Minecraft) (Object) this, resourceManager, true, error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "method_24228", at = @At("HEAD"))
|
@Inject(method = "method_24228", at = @At("HEAD"))
|
||||||
private void flywheel$onEndManualResourceReload(boolean recovery, CompletableFuture<Void> future,
|
private void flywheel$onEndManualResourceReload(boolean recovery, @Coerce Object gameLoadCookie, CompletableFuture<Void> future,
|
||||||
Optional<Throwable> error, CallbackInfo ci) {
|
Optional<Throwable> error, CallbackInfo ci) {
|
||||||
EndClientResourceReloadCallback.EVENT.invoker()
|
EndClientResourceReloadCallback.EVENT.invoker()
|
||||||
.onEndClientResourceReload((Minecraft) (Object) this, resourceManager, false, error);
|
.onEndClientResourceReload((Minecraft) (Object) this, resourceManager, false, error);
|
||||||
|
|
|
@ -15,15 +15,15 @@ abstract class MinecraftMixin {
|
||||||
@Shadow
|
@Shadow
|
||||||
public ClientLevel level;
|
public ClientLevel level;
|
||||||
|
|
||||||
@Inject(method = "setLevel(Lnet/minecraft/client/multiplayer/ClientLevel;)V", at = @At("HEAD"))
|
@Inject(method = "setLevel(Lnet/minecraft/client/multiplayer/ClientLevel;Lnet/minecraft/client/gui/screens/ReceivingLevelScreen$Reason;)V", at = @At("HEAD"))
|
||||||
private void flywheel$onSetLevel(CallbackInfo ci) {
|
private void flywheel$onSetLevel(CallbackInfo ci) {
|
||||||
if (level != null) {
|
if (level != null) {
|
||||||
LevelAttached.invalidateLevel(level);
|
LevelAttached.invalidateLevel(level);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "clearLevel(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD"))
|
@Inject(method = "disconnect(Lnet/minecraft/client/gui/screens/Screen;)V", at = @At("HEAD"))
|
||||||
private void flywheel$onClearLevel(CallbackInfo ci) {
|
private void flywheel$onDisconnect(CallbackInfo ci) {
|
||||||
if (level != null) {
|
if (level != null) {
|
||||||
LevelAttached.invalidateLevel(level);
|
LevelAttached.invalidateLevel(level);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
package dev.engine_room.flywheel.impl.mixin.sodium;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.Operation;
|
|
||||||
import com.llamalad7.mixinextras.injector.wrapoperation.WrapOperation;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.lib.visualization.VisualizationHelper;
|
|
||||||
import me.jellysquid.mods.sodium.client.render.chunk.compile.tasks.ChunkBuilderMeshingTask;
|
|
||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderDispatcher;
|
|
||||||
import net.minecraft.client.renderer.blockentity.BlockEntityRenderer;
|
|
||||||
import net.minecraft.world.level.block.entity.BlockEntity;
|
|
||||||
|
|
||||||
@Mixin(value = ChunkBuilderMeshingTask.class, remap = false)
|
|
||||||
abstract class ChunkBuilderMeshingTaskMixin {
|
|
||||||
@WrapOperation(
|
|
||||||
method = "execute(Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildContext;Lme/jellysquid/mods/sodium/client/util/task/CancellationToken;)Lme/jellysquid/mods/sodium/client/render/chunk/compile/ChunkBuildOutput;",
|
|
||||||
at = @At(
|
|
||||||
value = "INVOKE",
|
|
||||||
target = "Lnet/minecraft/client/renderer/blockentity/BlockEntityRenderDispatcher;getRenderer(Lnet/minecraft/world/level/block/entity/BlockEntity;)Lnet/minecraft/client/renderer/blockentity/BlockEntityRenderer;",
|
|
||||||
remap = true
|
|
||||||
)
|
|
||||||
)
|
|
||||||
@Nullable
|
|
||||||
private BlockEntityRenderer<?> flywheel$wrapGetRenderer(BlockEntityRenderDispatcher instance, BlockEntity blockEntity, Operation<BlockEntityRenderer<BlockEntity>> original) {
|
|
||||||
if (VisualizationHelper.tryAddBlockEntity(blockEntity)) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
return original.call(instance, blockEntity);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,46 +0,0 @@
|
||||||
package dev.engine_room.flywheel.impl.mixin.sodium;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
import org.objectweb.asm.tree.ClassNode;
|
|
||||||
import org.spongepowered.asm.mixin.extensibility.IMixinConfigPlugin;
|
|
||||||
import org.spongepowered.asm.mixin.extensibility.IMixinInfo;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.impl.compat.FabricSodiumCompat;
|
|
||||||
|
|
||||||
public class SodiumMixinPlugin implements IMixinConfigPlugin {
|
|
||||||
@Override
|
|
||||||
public void onLoad(String mixinPackage) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public String getRefMapperConfig() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean shouldApplyMixin(String targetClassName, String mixinClassName) {
|
|
||||||
return FabricSodiumCompat.USE_0_5_COMPAT;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void acceptTargets(Set<String> myTargets, Set<String> otherTargets) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
@Nullable
|
|
||||||
public List<String> getMixins() {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void preApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void postApply(String targetClassName, ClassNode targetClass, String mixinClassName, IMixinInfo mixinInfo) {
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,9 +1,9 @@
|
||||||
{
|
{
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id": "${mod_id}",
|
"id" : "${flywheel_id}",
|
||||||
"version": "${mod_version}",
|
"version" : "${flywheel_version}",
|
||||||
"name": "${mod_name}",
|
"name" : "${flywheel_name}",
|
||||||
"description": "${mod_description}",
|
"description" : "${flywheel_description}",
|
||||||
"authors": [
|
"authors": [
|
||||||
"Jozufozu",
|
"Jozufozu",
|
||||||
"PepperCode1"
|
"PepperCode1"
|
||||||
|
@ -24,8 +24,7 @@
|
||||||
"mixins": [
|
"mixins": [
|
||||||
"flywheel.backend.mixins.json",
|
"flywheel.backend.mixins.json",
|
||||||
"flywheel.impl.mixins.json",
|
"flywheel.impl.mixins.json",
|
||||||
"flywheel.impl.fabric.mixins.json",
|
"flywheel.impl.fabric.mixins.json"
|
||||||
"flywheel.impl.sodium.mixins.json"
|
|
||||||
],
|
],
|
||||||
"depends": {
|
"depends": {
|
||||||
"minecraft": "${minecraft_semver_version_range}",
|
"minecraft": "${minecraft_semver_version_range}",
|
||||||
|
@ -33,7 +32,6 @@
|
||||||
"fabric-api": "${fabric_api_version_range}"
|
"fabric-api": "${fabric_api_version_range}"
|
||||||
},
|
},
|
||||||
"breaks": {
|
"breaks": {
|
||||||
"sodium": ["<0.5.0", "~0.6.0- <0.6.0-beta.2"],
|
"sodium": "<0.6.0-beta.2"
|
||||||
"embeddium": "*"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
"required": true,
|
"required": true,
|
||||||
"minVersion": "0.8",
|
"minVersion": "0.8",
|
||||||
"package": "dev.engine_room.flywheel.impl.mixin.fabric",
|
"package": "dev.engine_room.flywheel.impl.mixin.fabric",
|
||||||
"compatibilityLevel": "JAVA_17",
|
"compatibilityLevel": "JAVA_21",
|
||||||
"refmap": "flywheel.refmap.json",
|
"refmap": "flywheel.refmap.json",
|
||||||
"client": [
|
"client": [
|
||||||
"DebugScreenOverlayMixin",
|
"DebugScreenOverlayMixin",
|
||||||
|
|
|
@ -1,14 +0,0 @@
|
||||||
{
|
|
||||||
"required": true,
|
|
||||||
"minVersion": "0.8",
|
|
||||||
"package": "dev.engine_room.flywheel.impl.mixin.sodium",
|
|
||||||
"compatibilityLevel": "JAVA_17",
|
|
||||||
"refmap": "flywheel.refmap.json",
|
|
||||||
"plugin": "dev.engine_room.flywheel.impl.mixin.sodium.SodiumMixinPlugin",
|
|
||||||
"client": [
|
|
||||||
"ChunkBuilderMeshingTaskMixin"
|
|
||||||
],
|
|
||||||
"injectors": {
|
|
||||||
"defaultRequire": 1
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
{
|
{
|
||||||
"schemaVersion": 1,
|
"schemaVersion": 1,
|
||||||
"id" : "${mod_id}_testmod",
|
"id" : "${flywheel_id}_testmod",
|
||||||
"name": "${mod_name} Test Mod",
|
"name" : "${flywheel_name} Test Mod",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"environment": "*",
|
"environment": "*",
|
||||||
"license": "${mod_license}",
|
"license": "${mod_license}",
|
||||||
|
|
|
@ -1 +0,0 @@
|
||||||
loom.platform = forge
|
|
|
@ -1,78 +0,0 @@
|
||||||
package dev.engine_room.flywheel.lib.model.baked;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.Material;
|
|
||||||
import dev.engine_room.flywheel.api.model.Mesh;
|
|
||||||
import dev.engine_room.flywheel.api.model.Model;
|
|
||||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.client.resources.model.BakedModel;
|
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
|
||||||
|
|
||||||
public final class ForgeBakedModelBuilder extends BakedModelBuilder {
|
|
||||||
@Nullable
|
|
||||||
private ModelData modelData;
|
|
||||||
|
|
||||||
public ForgeBakedModelBuilder(BakedModel bakedModel) {
|
|
||||||
super(bakedModel);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeBakedModelBuilder level(BlockAndTintGetter level) {
|
|
||||||
super.level(level);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeBakedModelBuilder blockState(BlockState blockState) {
|
|
||||||
super.blockState(blockState);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeBakedModelBuilder poseStack(PoseStack poseStack) {
|
|
||||||
super.poseStack(poseStack);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeBakedModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
|
||||||
super.materialFunc(materialFunc);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ForgeBakedModelBuilder modelData(ModelData modelData) {
|
|
||||||
this.modelData = modelData;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SimpleModel build() {
|
|
||||||
if (materialFunc == null) {
|
|
||||||
materialFunc = ModelUtil::getMaterial;
|
|
||||||
}
|
|
||||||
if (modelData == null) {
|
|
||||||
modelData = ModelData.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
|
||||||
|
|
||||||
BakedModelBufferer.bufferSingle(level, bakedModel, blockState, poseStack, modelData, (renderType, shaded, data) -> {
|
|
||||||
Material material = materialFunc.apply(renderType, shaded);
|
|
||||||
if (material != null) {
|
|
||||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BakedModelBuilder," + "bakedModel=" + bakedModel + ",renderType=" + renderType + ",shaded=" + shaded);
|
|
||||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return new SimpleModel(builder.build());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,71 +0,0 @@
|
||||||
package dev.engine_room.flywheel.lib.model.baked;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.Material;
|
|
||||||
import dev.engine_room.flywheel.api.model.Mesh;
|
|
||||||
import dev.engine_room.flywheel.api.model.Model;
|
|
||||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
import net.minecraft.world.level.block.state.BlockState;
|
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
|
||||||
|
|
||||||
public final class ForgeBlockModelBuilder extends BlockModelBuilder {
|
|
||||||
@Nullable
|
|
||||||
private ModelData modelData;
|
|
||||||
|
|
||||||
public ForgeBlockModelBuilder(BlockState state) {
|
|
||||||
super(state);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeBlockModelBuilder level(BlockAndTintGetter level) {
|
|
||||||
super.level(level);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeBlockModelBuilder poseStack(PoseStack poseStack) {
|
|
||||||
super.poseStack(poseStack);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeBlockModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
|
||||||
super.materialFunc(materialFunc);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ForgeBlockModelBuilder modelData(ModelData modelData) {
|
|
||||||
this.modelData = modelData;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SimpleModel build() {
|
|
||||||
if (materialFunc == null) {
|
|
||||||
materialFunc = ModelUtil::getMaterial;
|
|
||||||
}
|
|
||||||
if (modelData == null) {
|
|
||||||
modelData = ModelData.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
|
||||||
|
|
||||||
BakedModelBufferer.bufferBlock(level, state, poseStack, modelData, (renderType, shaded, data) -> {
|
|
||||||
Material material = materialFunc.apply(renderType, shaded);
|
|
||||||
if (material != null) {
|
|
||||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=BlockModelBuilder," + "blockState=" + state + ",renderType=" + renderType + ",shaded=" + shaded);
|
|
||||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return new SimpleModel(builder.build());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,72 +0,0 @@
|
||||||
package dev.engine_room.flywheel.lib.model.baked;
|
|
||||||
|
|
||||||
import java.util.function.BiFunction;
|
|
||||||
import java.util.function.Function;
|
|
||||||
|
|
||||||
import org.jetbrains.annotations.Nullable;
|
|
||||||
|
|
||||||
import com.mojang.blaze3d.vertex.PoseStack;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.material.Material;
|
|
||||||
import dev.engine_room.flywheel.api.model.Mesh;
|
|
||||||
import dev.engine_room.flywheel.api.model.Model;
|
|
||||||
import dev.engine_room.flywheel.lib.model.ModelUtil;
|
|
||||||
import dev.engine_room.flywheel.lib.model.SimpleModel;
|
|
||||||
import net.minecraft.client.renderer.RenderType;
|
|
||||||
import net.minecraft.core.BlockPos;
|
|
||||||
import net.minecraft.world.level.BlockAndTintGetter;
|
|
||||||
import net.minecraftforge.client.model.data.ModelData;
|
|
||||||
|
|
||||||
public final class ForgeMultiBlockModelBuilder extends MultiBlockModelBuilder {
|
|
||||||
@Nullable
|
|
||||||
private Function<BlockPos, ModelData> modelDataLookup;
|
|
||||||
|
|
||||||
public ForgeMultiBlockModelBuilder(BlockAndTintGetter level, Iterable<BlockPos> positions) {
|
|
||||||
super(level, positions);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeMultiBlockModelBuilder poseStack(PoseStack poseStack) {
|
|
||||||
super.poseStack(poseStack);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeMultiBlockModelBuilder enableFluidRendering() {
|
|
||||||
super.enableFluidRendering();
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ForgeMultiBlockModelBuilder materialFunc(BiFunction<RenderType, Boolean, Material> materialFunc) {
|
|
||||||
super.materialFunc(materialFunc);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ForgeMultiBlockModelBuilder modelDataLookup(Function<BlockPos, ModelData> modelDataLookup) {
|
|
||||||
this.modelDataLookup = modelDataLookup;
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public SimpleModel build() {
|
|
||||||
if (materialFunc == null) {
|
|
||||||
materialFunc = ModelUtil::getMaterial;
|
|
||||||
}
|
|
||||||
if (modelDataLookup == null) {
|
|
||||||
modelDataLookup = pos -> ModelData.EMPTY;
|
|
||||||
}
|
|
||||||
|
|
||||||
var builder = ChunkLayerSortedListBuilder.<Model.ConfiguredMesh>getThreadLocal();
|
|
||||||
|
|
||||||
BakedModelBufferer.bufferMultiBlock(positions.iterator(), level, poseStack, modelDataLookup, renderFluids, (renderType, shaded, data) -> {
|
|
||||||
Material material = materialFunc.apply(renderType, shaded);
|
|
||||||
if (material != null) {
|
|
||||||
Mesh mesh = MeshHelper.blockVerticesToMesh(data, "source=MultiBlockModelBuilder," + "renderType=" + renderType + ",shaded=" + shaded);
|
|
||||||
builder.add(renderType, new Model.ConfiguredMesh(material, mesh));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
return new SimpleModel(builder.build());
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
package dev.engine_room.flywheel.impl;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent;
|
|
||||||
import dev.engine_room.flywheel.impl.compat.CompatMod;
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
|
||||||
import net.minecraftforge.fml.loading.LoadingModList;
|
|
||||||
|
|
||||||
public class FlwImplXplatImpl implements FlwImplXplat {
|
|
||||||
@Override
|
|
||||||
public boolean isModLoaded(String modId) {
|
|
||||||
return LoadingModList.get().getModFileById(modId) != null;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void dispatchReloadLevelRendererEvent(ClientLevel level) {
|
|
||||||
MinecraftForge.EVENT_BUS.post(new ReloadLevelRendererEvent(level));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String getVersionStr() {
|
|
||||||
return FlywheelForge.version().toString();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public FlwConfig getConfig() {
|
|
||||||
return ForgeFlwConfig.INSTANCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useSodium0_6Compat() {
|
|
||||||
return CompatMod.SODIUM.isLoaded && !CompatMod.EMBEDDIUM.isLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean useIrisCompat() {
|
|
||||||
return CompatMod.IRIS.isLoaded || CompatMod.OCULUS.isLoaded;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,132 +0,0 @@
|
||||||
package dev.engine_room.flywheel.impl;
|
|
||||||
|
|
||||||
import org.apache.maven.artifact.versioning.ArtifactVersion;
|
|
||||||
import org.jetbrains.annotations.UnknownNullability;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.Flywheel;
|
|
||||||
import dev.engine_room.flywheel.api.event.EndClientResourceReloadEvent;
|
|
||||||
import dev.engine_room.flywheel.api.event.ReloadLevelRendererEvent;
|
|
||||||
import dev.engine_room.flywheel.backend.compile.FlwProgramsReloader;
|
|
||||||
import dev.engine_room.flywheel.backend.engine.uniform.Uniforms;
|
|
||||||
import dev.engine_room.flywheel.impl.compat.EmbeddiumCompat;
|
|
||||||
import dev.engine_room.flywheel.impl.visualization.VisualizationEventHandler;
|
|
||||||
import dev.engine_room.flywheel.lib.model.baked.PartialModelEventHandler;
|
|
||||||
import dev.engine_room.flywheel.lib.util.LevelAttached;
|
|
||||||
import dev.engine_room.flywheel.lib.util.RendererReloadCache;
|
|
||||||
import dev.engine_room.flywheel.lib.util.ResourceReloadHolder;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.commands.synchronization.ArgumentTypeInfos;
|
|
||||||
import net.minecraftforge.api.distmarker.Dist;
|
|
||||||
import net.minecraftforge.client.event.CustomizeGuiOverlayEvent;
|
|
||||||
import net.minecraftforge.client.event.RegisterClientReloadListenersEvent;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
|
||||||
import net.minecraftforge.event.TickEvent;
|
|
||||||
import net.minecraftforge.event.entity.EntityJoinLevelEvent;
|
|
||||||
import net.minecraftforge.event.entity.EntityLeaveLevelEvent;
|
|
||||||
import net.minecraftforge.event.level.LevelEvent;
|
|
||||||
import net.minecraftforge.eventbus.api.IEventBus;
|
|
||||||
import net.minecraftforge.fml.CrashReportCallables;
|
|
||||||
import net.minecraftforge.fml.DistExecutor;
|
|
||||||
import net.minecraftforge.fml.LogicalSide;
|
|
||||||
import net.minecraftforge.fml.ModLoadingContext;
|
|
||||||
import net.minecraftforge.fml.common.Mod;
|
|
||||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
|
||||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
|
||||||
import net.minecraftforge.registries.ForgeRegistries;
|
|
||||||
import net.minecraftforge.registries.RegisterEvent;
|
|
||||||
|
|
||||||
@Mod(Flywheel.ID)
|
|
||||||
public final class FlywheelForge {
|
|
||||||
@UnknownNullability
|
|
||||||
private static ArtifactVersion version;
|
|
||||||
|
|
||||||
public FlywheelForge() {
|
|
||||||
ModLoadingContext modLoadingContext = ModLoadingContext.get();
|
|
||||||
|
|
||||||
version = modLoadingContext
|
|
||||||
.getActiveContainer()
|
|
||||||
.getModInfo()
|
|
||||||
.getVersion();
|
|
||||||
|
|
||||||
IEventBus forgeEventBus = MinecraftForge.EVENT_BUS;
|
|
||||||
IEventBus modEventBus = FMLJavaModLoadingContext.get()
|
|
||||||
.getModEventBus();
|
|
||||||
|
|
||||||
ForgeFlwConfig.INSTANCE.registerSpecs(modLoadingContext);
|
|
||||||
|
|
||||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> () -> FlywheelForge.clientInit(forgeEventBus, modEventBus));
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void clientInit(IEventBus forgeEventBus, IEventBus modEventBus) {
|
|
||||||
registerImplEventListeners(forgeEventBus, modEventBus);
|
|
||||||
registerLibEventListeners(forgeEventBus, modEventBus);
|
|
||||||
registerBackendEventListeners(forgeEventBus, modEventBus);
|
|
||||||
|
|
||||||
CrashReportCallables.registerCrashCallable("Flywheel Backend", BackendManagerImpl::getBackendString);
|
|
||||||
FlwImpl.init();
|
|
||||||
|
|
||||||
EmbeddiumCompat.init();
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void registerImplEventListeners(IEventBus forgeEventBus, IEventBus modEventBus) {
|
|
||||||
forgeEventBus.addListener((ReloadLevelRendererEvent e) -> BackendManagerImpl.onReloadLevelRenderer(e.level()));
|
|
||||||
|
|
||||||
forgeEventBus.addListener((TickEvent.LevelTickEvent e) -> {
|
|
||||||
// Make sure we don't tick on the server somehow.
|
|
||||||
if (e.phase == TickEvent.Phase.END && e.side == LogicalSide.CLIENT) {
|
|
||||||
VisualizationEventHandler.onClientTick(Minecraft.getInstance(), e.level);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
forgeEventBus.addListener((EntityJoinLevelEvent e) -> VisualizationEventHandler.onEntityJoinLevel(e.getLevel(), e.getEntity()));
|
|
||||||
forgeEventBus.addListener((EntityLeaveLevelEvent e) -> VisualizationEventHandler.onEntityLeaveLevel(e.getLevel(), e.getEntity()));
|
|
||||||
|
|
||||||
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
|
||||||
|
|
||||||
forgeEventBus.addListener((CustomizeGuiOverlayEvent.DebugText e) -> {
|
|
||||||
Minecraft minecraft = Minecraft.getInstance();
|
|
||||||
|
|
||||||
if (!minecraft.options.renderDebug) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
FlwDebugInfo.addDebugInfo(minecraft, e.getRight());
|
|
||||||
});
|
|
||||||
|
|
||||||
modEventBus.addListener((EndClientResourceReloadEvent e) -> BackendManagerImpl.onEndClientResourceReload(e.error().isPresent()));
|
|
||||||
|
|
||||||
modEventBus.addListener((FMLCommonSetupEvent e) -> {
|
|
||||||
ArgumentTypeInfos.registerByClass(BackendArgument.class, BackendArgument.INFO);
|
|
||||||
ArgumentTypeInfos.registerByClass(DebugModeArgument.class, DebugModeArgument.INFO);
|
|
||||||
ArgumentTypeInfos.registerByClass(LightSmoothnessArgument.class, LightSmoothnessArgument.INFO);
|
|
||||||
});
|
|
||||||
modEventBus.addListener((RegisterEvent e) -> {
|
|
||||||
if (e.getRegistryKey().equals(ForgeRegistries.Keys.COMMAND_ARGUMENT_TYPES)) {
|
|
||||||
e.register(ForgeRegistries.Keys.COMMAND_ARGUMENT_TYPES, Flywheel.rl("backend"), () -> BackendArgument.INFO);
|
|
||||||
e.register(ForgeRegistries.Keys.COMMAND_ARGUMENT_TYPES, Flywheel.rl("debug_mode"), () -> DebugModeArgument.INFO);
|
|
||||||
e.register(ForgeRegistries.Keys.COMMAND_ARGUMENT_TYPES, Flywheel.rl("light_smoothness"), () -> LightSmoothnessArgument.INFO);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void registerLibEventListeners(IEventBus forgeEventBus, IEventBus modEventBus) {
|
|
||||||
forgeEventBus.addListener((LevelEvent.Unload e) -> LevelAttached.invalidateLevel(e.getLevel()));
|
|
||||||
|
|
||||||
modEventBus.addListener((EndClientResourceReloadEvent e) -> RendererReloadCache.onReloadLevelRenderer());
|
|
||||||
modEventBus.addListener((EndClientResourceReloadEvent e) -> ResourceReloadHolder.onEndClientResourceReload());
|
|
||||||
|
|
||||||
modEventBus.addListener(PartialModelEventHandler::onRegisterAdditional);
|
|
||||||
modEventBus.addListener(PartialModelEventHandler::onBakingCompleted);
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void registerBackendEventListeners(IEventBus forgeEventBus, IEventBus modEventBus) {
|
|
||||||
forgeEventBus.addListener((ReloadLevelRendererEvent e) -> Uniforms.onReloadLevelRenderer());
|
|
||||||
|
|
||||||
modEventBus.addListener((RegisterClientReloadListenersEvent e) -> {
|
|
||||||
e.registerReloadListener(FlwProgramsReloader.INSTANCE);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public static ArtifactVersion version() {
|
|
||||||
return version;
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
package dev.engine_room.flywheel.impl.mixin;
|
|
||||||
|
|
||||||
import java.util.Optional;
|
|
||||||
import java.util.concurrent.CompletableFuture;
|
|
||||||
import java.util.concurrent.Executor;
|
|
||||||
|
|
||||||
import org.spongepowered.asm.mixin.Final;
|
|
||||||
import org.spongepowered.asm.mixin.Mixin;
|
|
||||||
import org.spongepowered.asm.mixin.Shadow;
|
|
||||||
import org.spongepowered.asm.mixin.injection.At;
|
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
|
||||||
import org.spongepowered.asm.mixin.injection.ModifyArg;
|
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
|
||||||
|
|
||||||
import com.mojang.realmsclient.client.RealmsClient;
|
|
||||||
|
|
||||||
import dev.engine_room.flywheel.api.event.EndClientResourceReloadEvent;
|
|
||||||
import dev.engine_room.flywheel.impl.FlwImpl;
|
|
||||||
import net.minecraft.client.Minecraft;
|
|
||||||
import net.minecraft.client.main.GameConfig;
|
|
||||||
import net.minecraft.server.packs.resources.ReloadInstance;
|
|
||||||
import net.minecraft.server.packs.resources.ReloadableResourceManager;
|
|
||||||
import net.minecraftforge.fml.ModLoader;
|
|
||||||
|
|
||||||
@Mixin(Minecraft.class)
|
|
||||||
abstract class MinecraftMixin {
|
|
||||||
@Shadow
|
|
||||||
@Final
|
|
||||||
private ReloadableResourceManager resourceManager;
|
|
||||||
|
|
||||||
// Inject at invoke cannot be used in constructors in vanilla Mixin, so use ModifyArg instead.
|
|
||||||
@ModifyArg(method = "<init>", at = @At(value = "INVOKE", target = "Lnet/minecraft/server/packs/resources/ReloadableResourceManager;createReload(Ljava/util/concurrent/Executor;Ljava/util/concurrent/Executor;Ljava/util/concurrent/CompletableFuture;Ljava/util/List;)Lnet/minecraft/server/packs/resources/ReloadInstance;"), index = 0)
|
|
||||||
private Executor flywheel$onBeginInitialResourceReload(Executor arg0) {
|
|
||||||
FlwImpl.freezeRegistries();
|
|
||||||
return arg0;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "lambda$new$5", at = @At("HEAD"))
|
|
||||||
private void flywheel$onEndInitialResourceReload(RealmsClient realmsClient, ReloadInstance reloadInstance, GameConfig gameConfig, Optional<Throwable> error, CallbackInfo ci) {
|
|
||||||
ModLoader.get().postEvent(new EndClientResourceReloadEvent((Minecraft) (Object) this, resourceManager, true, error));
|
|
||||||
}
|
|
||||||
|
|
||||||
@Inject(method = "lambda$reloadResourcePacks$28", at = @At("HEAD"))
|
|
||||||
private void flywheel$onEndManualResourceReload(boolean recovery, CompletableFuture<Void> future, Optional<Throwable> error, CallbackInfo ci) {
|
|
||||||
ModLoader.get().postEvent(new EndClientResourceReloadEvent((Minecraft) (Object) this, resourceManager, false, error));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +0,0 @@
|
||||||
modLoader = "javafml"
|
|
||||||
# The loader version doesn't matter. Modify the Forge and/or Minecraft version ranges instead.
|
|
||||||
loaderVersion = "[0,)"
|
|
||||||
license = "${mod_license}"
|
|
||||||
issueTrackerURL = "${mod_issues}"
|
|
||||||
|
|
||||||
[[mods]]
|
|
||||||
modId = "${mod_id}"
|
|
||||||
version = "${mod_version}"
|
|
||||||
displayName = "${mod_name}"
|
|
||||||
description = "${mod_description}"
|
|
||||||
logoFile = "logo.png"
|
|
||||||
authors = "Jozufozu, PepperCode1"
|
|
||||||
displayURL = "${mod_homepage}"
|
|
||||||
displayTest = "IGNORE_ALL_VERSION"
|
|
||||||
|
|
||||||
[[dependencies.${mod_id}]]
|
|
||||||
modId = "minecraft"
|
|
||||||
mandatory = true
|
|
||||||
versionRange = "${minecraft_maven_version_range}"
|
|
||||||
side = "CLIENT"
|
|
||||||
|
|
||||||
[[dependencies.${mod_id}]]
|
|
||||||
modId = "forge"
|
|
||||||
mandatory = true
|
|
||||||
versionRange = "${forge_version_range}"
|
|
||||||
side = "CLIENT"
|
|
||||||
|
|
||||||
[[dependencies.${mod_id}]]
|
|
||||||
modId = "embeddium"
|
|
||||||
mandatory = false
|
|
||||||
versionRange = "[0.3.25,)"
|
|
||||||
side = "CLIENT"
|
|
||||||
|
|
||||||
[[dependencies.${mod_id}]]
|
|
||||||
modId = "sodium"
|
|
||||||
mandatory = false
|
|
||||||
versionRange = "[0.6.0-beta.2,)"
|
|
||||||
side = "CLIENT"
|
|
|
@ -1,6 +0,0 @@
|
||||||
{
|
|
||||||
"pack": {
|
|
||||||
"description": "${mod_name} resources",
|
|
||||||
"pack_format": 15
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,39 +1,50 @@
|
||||||
org.gradle.jvmargs = -Xmx3G
|
org.gradle.jvmargs = -Xmx3G
|
||||||
org.gradle.daemon = false
|
org.gradle.daemon = false
|
||||||
|
# Common metadata
|
||||||
# Mod metadata
|
|
||||||
mod_id = flywheel
|
|
||||||
mod_name = Flywheel
|
|
||||||
mod_version = 1.0.0-beta
|
|
||||||
mod_description = An overhauled entity and block entity rendering API.
|
|
||||||
mod_license = MIT
|
mod_license = MIT
|
||||||
mod_sources = https://github.com/Engine-Room/Flywheel
|
mod_sources = https://github.com/Engine-Room/Flywheel
|
||||||
mod_issues = https://github.com/Engine-Room/Flywheel/issues
|
mod_issues = https://github.com/Engine-Room/Flywheel/issues
|
||||||
mod_homepage = https://github.com/Engine-Room/Flywheel
|
mod_homepage = https://github.com/Engine-Room/Flywheel
|
||||||
|
# Flywheel metadata
|
||||||
|
flywheel_id=flywheel
|
||||||
|
flywheel_name=Flywheel
|
||||||
|
flywheel_version=1.0.0-beta
|
||||||
|
flywheel_description=An overhauled entity and block entity rendering API.
|
||||||
|
# Vanillin metadata
|
||||||
|
vanillin_id=vanillin
|
||||||
|
vanillin_name=Vanillin
|
||||||
|
vanillin_version=1.0.0-beta
|
||||||
|
vanillin_description=Instanced rendering for entities and block entities via Flywheel.
|
||||||
|
# Vanillin dependencies
|
||||||
|
flywheel_maven_version_range=[1.0.0-beta,2.0)
|
||||||
|
flywheel_semver_version_range=>=1.0.0-beta <2.0.0
|
||||||
|
|
||||||
# Mod dependency declarations
|
# Mod dependency declarations
|
||||||
minecraft_semver_version_range = >=1.20.1 <1.20.2
|
minecraft_semver_version_range = >=1.21.1 <1.21.2
|
||||||
minecraft_maven_version_range = [1.20.1,1.20.2)
|
minecraft_maven_version_range = [1.21.1,1.21.2)
|
||||||
fabric_api_version_range = >=0.86.0
|
fabric_api_version_range = >=0.105.0
|
||||||
forge_version_range = [47.0.0,)
|
neoforge_version_range = [21.1.66,)
|
||||||
|
|
||||||
# General build dependency versions
|
# General build dependency versions
|
||||||
java_version = 17
|
java_version = 21
|
||||||
arch_loom_version = 1.7.412
|
arch_loom_version = 1.7.412
|
||||||
cursegradle_version = 1.4.0
|
cursegradle_version = 1.4.0
|
||||||
parchment_minecraft_version = 1.20.1
|
parchment_minecraft_version = 1.21
|
||||||
parchment_version = 2023.09.03
|
parchment_version = 2024.07.07
|
||||||
|
|
||||||
# Minecraft build dependency versions
|
# Minecraft build dependency versions
|
||||||
minecraft_version = 1.20.1
|
minecraft_version = 1.21.1
|
||||||
forge_version = 47.2.19
|
neoforge_version = 21.1.66
|
||||||
fabric_loader_version = 0.15.9
|
fabric_loader_version = 0.16.5
|
||||||
fabric_api_version = 0.92.1+1.20.1
|
fabric_api_version = 0.105.0+1.21.1
|
||||||
|
|
||||||
# Build dependency mod versions
|
# Build dependency mod versions
|
||||||
sodium_version = mc1.20.1-0.5.11
|
sodium_version = mc1.21.1-0.6.5
|
||||||
embeddium_version = 0.3.25+mc1.20.1
|
iris_version = 1.8.0-beta.8+1.21.1
|
||||||
|
# There is no oculus for 1.21.1 so we will only support iris
|
||||||
|
embeddium_version = 1.0.11+mc1.21.1
|
||||||
|
|
||||||
# Publication info
|
# Publication info
|
||||||
group = dev.engine_room.flywheel
|
flywheel_group=dev.engine_room.flywheel
|
||||||
artifact_minecraft_version = 1.20.1
|
vanillin_group=dev.engine_room.vanillin
|
||||||
|
artifact_minecraft_version = 1.21.1
|
||||||
|
|
|
@ -7,6 +7,11 @@ plugins {
|
||||||
id("flywheel.platform")
|
id("flywheel.platform")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val common = ":common"
|
||||||
|
val commonProject = project(common)
|
||||||
|
|
||||||
|
subproject.init("flywheel-neoforge", "flywheel_group", "flywheel_version")
|
||||||
|
|
||||||
val api = sourceSets.create("api")
|
val api = sourceSets.create("api")
|
||||||
val lib = sourceSets.create("lib")
|
val lib = sourceSets.create("lib")
|
||||||
val backend = sourceSets.create("backend")
|
val backend = sourceSets.create("backend")
|
||||||
|
@ -19,20 +24,32 @@ transitiveSourceSets {
|
||||||
|
|
||||||
sourceSet(api) {
|
sourceSet(api) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
|
|
||||||
|
from(commonProject)
|
||||||
}
|
}
|
||||||
sourceSet(lib) {
|
sourceSet(lib) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
compile(api)
|
compileClasspath(api)
|
||||||
|
|
||||||
|
from(commonProject)
|
||||||
}
|
}
|
||||||
sourceSet(backend) {
|
sourceSet(backend) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
compile(api, lib)
|
compileClasspath(api, lib)
|
||||||
|
|
||||||
|
from(commonProject)
|
||||||
}
|
}
|
||||||
sourceSet(stubs) {
|
sourceSet(stubs) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
|
|
||||||
|
from(commonProject)
|
||||||
}
|
}
|
||||||
sourceSet(main) {
|
sourceSet(main) {
|
||||||
compile(api, lib, backend, stubs)
|
compileClasspath(api, lib, backend)
|
||||||
|
|
||||||
|
bundleFrom(commonProject)
|
||||||
|
|
||||||
|
bundleOutput(api, lib, backend)
|
||||||
}
|
}
|
||||||
sourceSet(testMod) {
|
sourceSet(testMod) {
|
||||||
rootCompile()
|
rootCompile()
|
||||||
|
@ -42,19 +59,18 @@ transitiveSourceSets {
|
||||||
}
|
}
|
||||||
|
|
||||||
platform {
|
platform {
|
||||||
commonProject = project(":common")
|
|
||||||
compileWithCommonSourceSets(api, lib, backend, stubs, main)
|
|
||||||
setupLoomMod(api, lib, backend, main)
|
setupLoomMod(api, lib, backend, main)
|
||||||
setupLoomRuns()
|
setupLoomRuns()
|
||||||
setupFatJar(api, lib, backend, main)
|
|
||||||
setupTestMod(testMod)
|
setupTestMod(testMod)
|
||||||
}
|
}
|
||||||
|
|
||||||
jarSets {
|
jarSets {
|
||||||
mainSet.publish(platform.modArtifactId)
|
mainSet.publish("flywheel-neoforge-${project.property("artifact_minecraft_version")}")
|
||||||
|
mainSet.outgoing("flywheel")
|
||||||
|
|
||||||
create("api", api, lib).apply {
|
create("api", api, lib).apply {
|
||||||
addToAssemble()
|
addToAssemble()
|
||||||
publish(platform.apiArtifactId)
|
publish("flywheel-neoforge-api-${project.property("artifact_minecraft_version")}")
|
||||||
|
|
||||||
configureJar {
|
configureJar {
|
||||||
manifest {
|
manifest {
|
||||||
|
@ -75,11 +91,6 @@ loom {
|
||||||
add(backend, "backend-flywheel.refmap.json")
|
add(backend, "backend-flywheel.refmap.json")
|
||||||
}
|
}
|
||||||
|
|
||||||
forge {
|
|
||||||
mixinConfig("flywheel.backend.mixins.json")
|
|
||||||
mixinConfig("flywheel.impl.mixins.json")
|
|
||||||
}
|
|
||||||
|
|
||||||
runs {
|
runs {
|
||||||
configureEach {
|
configureEach {
|
||||||
property("forge.logging.markers", "")
|
property("forge.logging.markers", "")
|
||||||
|
@ -88,14 +99,25 @@ loom {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
repositories {
|
||||||
|
maven("https://maven.neoforged.net/releases/")
|
||||||
|
}
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
forge("net.minecraftforge:forge:${property("minecraft_version")}-${property("forge_version")}")
|
neoForge("net.neoforged:neoforge:${property("neoforge_version")}")
|
||||||
|
|
||||||
|
modCompileOnly("maven.modrinth:sodium:${property("sodium_version")}-neoforge")
|
||||||
|
modCompileOnly("maven.modrinth:iris:${property("iris_version")}-neoforge")
|
||||||
|
|
||||||
modCompileOnly("maven.modrinth:embeddium:${property("embeddium_version")}")
|
modCompileOnly("maven.modrinth:embeddium:${property("embeddium_version")}")
|
||||||
|
|
||||||
"forApi"(project(path = ":common", configuration = "commonApiOnly"))
|
"forApi"(project(path = common, configuration = "apiClasses"))
|
||||||
"forLib"(project(path = ":common", configuration = "commonLib"))
|
"forLib"(project(path = common, configuration = "libClasses"))
|
||||||
"forBackend"(project(path = ":common", configuration = "commonBackend"))
|
"forBackend"(project(path = common, configuration = "backendClasses"))
|
||||||
"forStubs"(project(path = ":common", configuration = "commonStubs"))
|
"forStubs"(project(path = common, configuration = "stubsClasses"))
|
||||||
"forMain"(project(path = ":common", configuration = "commonImpl"))
|
"forMain"(project(path = common, configuration = "mainClasses"))
|
||||||
|
|
||||||
|
"forLib"(project(path = common, configuration = "libResources"))
|
||||||
|
"forBackend"(project(path = common, configuration = "backendResources"))
|
||||||
|
"forMain"(project(path = common, configuration = "mainResources"))
|
||||||
}
|
}
|
1
neoforge/gradle.properties
Normal file
1
neoforge/gradle.properties
Normal file
|
@ -0,0 +1 @@
|
||||||
|
loom.platform = neoforge
|
|
@ -4,8 +4,8 @@ import java.util.Optional;
|
||||||
|
|
||||||
import net.minecraft.client.Minecraft;
|
import net.minecraft.client.Minecraft;
|
||||||
import net.minecraft.server.packs.resources.ResourceManager;
|
import net.minecraft.server.packs.resources.ResourceManager;
|
||||||
import net.minecraftforge.eventbus.api.Event;
|
import net.neoforged.bus.api.Event;
|
||||||
import net.minecraftforge.fml.event.IModBusEvent;
|
import net.neoforged.fml.event.IModBusEvent;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This event is posted to mod event buses.
|
* This event is posted to mod event buses.
|
|
@ -1,10 +1,10 @@
|
||||||
package dev.engine_room.flywheel.api.event;
|
package dev.engine_room.flywheel.api.event;
|
||||||
|
|
||||||
import net.minecraft.client.multiplayer.ClientLevel;
|
import net.minecraft.client.multiplayer.ClientLevel;
|
||||||
import net.minecraftforge.eventbus.api.Event;
|
import net.neoforged.bus.api.Event;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This event is posted to the Forge event bus.
|
* This event is posted to the NeoForge event bus.
|
||||||
*/
|
*/
|
||||||
public final class ReloadLevelRendererEvent extends Event {
|
public final class ReloadLevelRendererEvent extends Event {
|
||||||
private final ClientLevel level;
|
private final ClientLevel level;
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue