mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2025-01-27 05:17:56 +01:00
Pre-port tasks I
- Rename Client to FlywheelClient - Remove Shadow plugin - Remove generated source set - Remove unused properties in gradle.properties - Organize all imports - Thanks for the list pepper!
This commit is contained in:
parent
f89673a79e
commit
f615825846
85 changed files with 555 additions and 651 deletions
|
@ -19,4 +19,4 @@ indent_style = tab
|
|||
ij_continuation_indent_size = 8
|
||||
ij_java_class_count_to_use_import_on_demand = 99
|
||||
ij_java_names_count_to_use_import_on_demand = 99
|
||||
ij_java_imports_layout = $*,|,java.**,|,javax.**,|,org.**,|,com.**,|,*
|
||||
ij_java_imports_layout = $*, |, java.**, |, javax.**, |, org.**, |, com.**, |, *
|
||||
|
|
169
LICENCE.md
169
LICENCE.md
|
@ -2,99 +2,75 @@
|
|||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed.
|
||||
|
||||
|
||||
This version of the GNU Lesser General Public License incorporates
|
||||
the terms and conditions of version 3 of the GNU General Public
|
||||
License, supplemented by the additional permissions listed below.
|
||||
This version of the GNU Lesser General Public License incorporates the terms and conditions of version 3 of the GNU
|
||||
General Public License, supplemented by the additional permissions listed below.
|
||||
|
||||
0. Additional Definitions.
|
||||
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser
|
||||
General Public License, and the "GNU GPL" refers to version 3 of the GNU
|
||||
General Public License.
|
||||
As used herein, "this License" refers to version 3 of the GNU Lesser General Public License, and the "GNU GPL" refers to
|
||||
version 3 of the GNU General Public License.
|
||||
|
||||
"The Library" refers to a covered work governed by this License,
|
||||
other than an Application or a Combined Work as defined below.
|
||||
"The Library" refers to a covered work governed by this License, other than an Application or a Combined Work as defined
|
||||
below.
|
||||
|
||||
An "Application" is any work that makes use of an interface provided
|
||||
by the Library, but which is not otherwise based on the Library.
|
||||
Defining a subclass of a class defined by the Library is deemed a mode
|
||||
of using an interface provided by the Library.
|
||||
An "Application" is any work that makes use of an interface provided by the Library, but which is not otherwise based on
|
||||
the Library. Defining a subclass of a class defined by the Library is deemed a mode of using an interface provided by
|
||||
the Library.
|
||||
|
||||
A "Combined Work" is a work produced by combining or linking an
|
||||
Application with the Library. The particular version of the Library
|
||||
with which the Combined Work was made is also called the "Linked
|
||||
Version".
|
||||
A "Combined Work" is a work produced by combining or linking an Application with the Library. The particular version of
|
||||
the Library with which the Combined Work was made is also called the "Linked Version".
|
||||
|
||||
The "Minimal Corresponding Source" for a Combined Work means the
|
||||
Corresponding Source for the Combined Work, excluding any source code
|
||||
for portions of the Combined Work that, considered in isolation, are
|
||||
based on the Application, and not on the Linked Version.
|
||||
The "Minimal Corresponding Source" for a Combined Work means the Corresponding Source for the Combined Work, excluding
|
||||
any source code for portions of the Combined Work that, considered in isolation, are based on the Application, and not
|
||||
on the Linked Version.
|
||||
|
||||
The "Corresponding Application Code" for a Combined Work means the
|
||||
object code and/or source code for the Application, including any data
|
||||
and utility programs needed for reproducing the Combined Work from the
|
||||
Application, but excluding the System Libraries of the Combined Work.
|
||||
The "Corresponding Application Code" for a Combined Work means the object code and/or source code for the Application,
|
||||
including any data and utility programs needed for reproducing the Combined Work from the Application, but excluding the
|
||||
System Libraries of the Combined Work.
|
||||
|
||||
1. Exception to Section 3 of the GNU GPL.
|
||||
|
||||
You may convey a covered work under sections 3 and 4 of this License
|
||||
without being bound by section 3 of the GNU GPL.
|
||||
You may convey a covered work under sections 3 and 4 of this License without being bound by section 3 of the GNU GPL.
|
||||
|
||||
2. Conveying Modified Versions.
|
||||
|
||||
If you modify a copy of the Library, and, in your modifications, a
|
||||
facility refers to a function or data to be supplied by an Application
|
||||
that uses the facility (other than as an argument passed when the
|
||||
facility is invoked), then you may convey a copy of the modified
|
||||
version:
|
||||
If you modify a copy of the Library, and, in your modifications, a facility refers to a function or data to be supplied
|
||||
by an Application that uses the facility (other than as an argument passed when the facility is invoked), then you may
|
||||
convey a copy of the modified version:
|
||||
|
||||
a) under this License, provided that you make a good faith effort to
|
||||
ensure that, in the event an Application does not supply the
|
||||
function or data, the facility still operates, and performs
|
||||
whatever part of its purpose remains meaningful, or
|
||||
a) under this License, provided that you make a good faith effort to ensure that, in the event an Application does not
|
||||
supply the function or data, the facility still operates, and performs whatever part of its purpose remains meaningful,
|
||||
or
|
||||
|
||||
b) under the GNU GPL, with none of the additional permissions of
|
||||
this License applicable to that copy.
|
||||
b) under the GNU GPL, with none of the additional permissions of this License applicable to that copy.
|
||||
|
||||
3. Object Code Incorporating Material from Library Header Files.
|
||||
|
||||
The object code form of an Application may incorporate material from
|
||||
a header file that is part of the Library. You may convey such object
|
||||
code under terms of your choice, provided that, if the incorporated
|
||||
material is not limited to numerical parameters, data structure
|
||||
layouts and accessors, or small macros, inline functions and templates
|
||||
The object code form of an Application may incorporate material from a header file that is part of the Library. You may
|
||||
convey such object code under terms of your choice, provided that, if the incorporated material is not limited to
|
||||
numerical parameters, data structure layouts and accessors, or small macros, inline functions and templates
|
||||
(ten or fewer lines in length), you do both of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the object code that the
|
||||
Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
a) Give prominent notice with each copy of the object code that the Library is used in it and that the Library and its
|
||||
use are covered by this License.
|
||||
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license
|
||||
document.
|
||||
b) Accompany the object code with a copy of the GNU GPL and this license document.
|
||||
|
||||
4. Combined Works.
|
||||
|
||||
You may convey a Combined Work under terms of your choice that,
|
||||
taken together, effectively do not restrict modification of the
|
||||
portions of the Library contained in the Combined Work and reverse
|
||||
engineering for debugging such modifications, if you also do each of
|
||||
the following:
|
||||
You may convey a Combined Work under terms of your choice that, taken together, effectively do not restrict modification
|
||||
of the portions of the Library contained in the Combined Work and reverse engineering for debugging such modifications,
|
||||
if you also do each of the following:
|
||||
|
||||
a) Give prominent notice with each copy of the Combined Work that
|
||||
the Library is used in it and that the Library and its use are
|
||||
covered by this License.
|
||||
a) Give prominent notice with each copy of the Combined Work that the Library is used in it and that the Library and its
|
||||
use are covered by this License.
|
||||
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license
|
||||
document.
|
||||
b) Accompany the Combined Work with a copy of the GNU GPL and this license document.
|
||||
|
||||
c) For a Combined Work that displays copyright notices during
|
||||
execution, include the copyright notice for the Library among
|
||||
these notices, as well as a reference directing the user to the
|
||||
copies of the GNU GPL and this license document.
|
||||
c) For a Combined Work that displays copyright notices during execution, include the copyright notice for the Library
|
||||
among these notices, as well as a reference directing the user to the copies of the GNU GPL and this license document.
|
||||
|
||||
d) Do one of the following:
|
||||
|
||||
|
@ -113,53 +89,38 @@ d) Do one of the following:
|
|||
of the Library that is interface-compatible with the Linked
|
||||
Version.
|
||||
|
||||
e) Provide Installation Information, but only if you would otherwise
|
||||
be required to provide such information under section 6 of the
|
||||
GNU GPL, and only to the extent that such information is
|
||||
necessary to install and execute a modified version of the
|
||||
Combined Work produced by recombining or relinking the
|
||||
Application with a modified version of the Linked Version. (If
|
||||
you use option 4d0, the Installation Information must accompany
|
||||
the Minimal Corresponding Source and Corresponding Application
|
||||
Code. If you use option 4d1, you must provide the Installation
|
||||
Information in the manner specified by section 6 of the GNU GPL
|
||||
for conveying Corresponding Source.)
|
||||
e) Provide Installation Information, but only if you would otherwise be required to provide such information under
|
||||
section 6 of the GNU GPL, and only to the extent that such information is necessary to install and execute a modified
|
||||
version of the Combined Work produced by recombining or relinking the Application with a modified version of the Linked
|
||||
Version. (If you use option 4d0, the Installation Information must accompany the Minimal Corresponding Source and
|
||||
Corresponding Application Code. If you use option 4d1, you must provide the Installation Information in the manner
|
||||
specified by section 6 of the GNU GPL for conveying Corresponding Source.)
|
||||
|
||||
5. Combined Libraries.
|
||||
|
||||
You may place library facilities that are a work based on the
|
||||
Library side by side in a single library together with other library
|
||||
facilities that are not Applications and are not covered by this
|
||||
License, and convey such a combined library under terms of your
|
||||
choice, if you do both of the following:
|
||||
You may place library facilities that are a work based on the Library side by side in a single library together with
|
||||
other library facilities that are not Applications and are not covered by this License, and convey such a combined
|
||||
library under terms of your choice, if you do both of the following:
|
||||
|
||||
a) Accompany the combined library with a copy of the same work based
|
||||
on the Library, uncombined with any other library facilities,
|
||||
conveyed under the terms of this License.
|
||||
a) Accompany the combined library with a copy of the same work based on the Library, uncombined with any other library
|
||||
facilities, conveyed under the terms of this License.
|
||||
|
||||
b) Give prominent notice with the combined library that part of it
|
||||
is a work based on the Library, and explaining where to find the
|
||||
accompanying uncombined form of the same work.
|
||||
b) Give prominent notice with the combined library that part of it is a work based on the Library, and explaining where
|
||||
to find the accompanying uncombined form of the same work.
|
||||
|
||||
6. Revised Versions of the GNU Lesser General Public License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions
|
||||
of the GNU Lesser General Public License from time to time. Such new
|
||||
versions will be similar in spirit to the present version, but may
|
||||
differ in detail to address new problems or concerns.
|
||||
The Free Software Foundation may publish revised and/or new versions of the GNU Lesser General Public License from time
|
||||
to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new
|
||||
problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Library as you received it specifies that a certain numbered version
|
||||
of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and
|
||||
conditions either of that published version or of any later version
|
||||
published by the Free Software Foundation. If the Library as you
|
||||
received it does not specify a version number of the GNU Lesser
|
||||
General Public License, you may choose any version of the GNU Lesser
|
||||
General Public License ever published by the Free Software Foundation.
|
||||
Each version is given a distinguishing version number. If the Library as you received it specifies that a certain
|
||||
numbered version of the GNU Lesser General Public License "or any later version"
|
||||
applies to it, you have the option of following the terms and conditions either of that published version or of any
|
||||
later version published by the Free Software Foundation. If the Library as you received it does not specify a version
|
||||
number of the GNU Lesser General Public License, you may choose any version of the GNU Lesser General Public License
|
||||
ever published by the Free Software Foundation.
|
||||
|
||||
If the Library as you received it specifies that a proxy can decide
|
||||
whether future versions of the GNU Lesser General Public License shall
|
||||
apply, that proxy's public statement of acceptance of any version is
|
||||
permanent authorization for you to choose that version for the
|
||||
Library.
|
||||
If the Library as you received it specifies that a proxy can decide whether future versions of the GNU Lesser General
|
||||
Public License shall apply, that proxy's public statement of acceptance of any version is permanent authorization for
|
||||
you to choose that version for the Library.
|
||||
|
|
23
README.md
23
README.md
|
@ -9,28 +9,34 @@
|
|||
</div>
|
||||
|
||||
### About
|
||||
The goal of this project is to provide tools for mod developers so they no longer have to worry about performance, or limitations of Minecraft's archaic rendering engine.
|
||||
That said, this is primarily an outlet for me to have fun with graphics programming.
|
||||
|
||||
The goal of this project is to provide tools for mod developers so they no longer have to worry about performance, or
|
||||
limitations of Minecraft's archaic rendering engine. That said, this is primarily an outlet for me to have fun with
|
||||
graphics programming.
|
||||
|
||||
### Instancing
|
||||
Flywheel provides an alternate, unified path for entity and tile entity rendering that takes advantage of GPU instancing. In doing so, Flywheel gives the developer the flexibility to define their own vertex and instance formats, and write custom shaders to ingest that data.
|
||||
|
||||
Flywheel provides an alternate, unified path for entity and tile entity rendering that takes advantage of GPU
|
||||
instancing. In doing so, Flywheel gives the developer the flexibility to define their own vertex and instance formats,
|
||||
and write custom shaders to ingest that data.
|
||||
|
||||
### Shaders
|
||||
To accomodate the developer and leave more in the hands of the engine, Flywheel provides a custom shader loading and templating system to hide the details of the CPU/GPU interface. This system is a work in progress. There will be breaking changes, and I make no guarantees of backwards compatibility.
|
||||
|
||||
To accomodate the developer and leave more in the hands of the engine, Flywheel provides a custom shader loading and
|
||||
templating system to hide the details of the CPU/GPU interface. This system is a work in progress. There will be
|
||||
breaking changes, and I make no guarantees of backwards compatibility.
|
||||
|
||||
### Plans
|
||||
- Vanilla performance improvements
|
||||
- Compute shader particles
|
||||
- Deferred rendering
|
||||
- Different renderers for differently aged hardware
|
||||
|
||||
- Vanilla performance improvements
|
||||
- Compute shader particles
|
||||
- Deferred rendering
|
||||
- Different renderers for differently aged hardware
|
||||
|
||||
### Getting Started (For Developers)
|
||||
|
||||
Add the following repo to your `build.gradle`:
|
||||
|
||||
```groovy
|
||||
repositories {
|
||||
maven {
|
||||
|
@ -41,6 +47,7 @@ repositories {
|
|||
```
|
||||
|
||||
Then add Flywheel as a dependency:
|
||||
|
||||
```groovy
|
||||
dependencies {
|
||||
implementation fg.deobf("com.jozufozu.flywheel:Flywheel:1.16-0.0.2.9")
|
||||
|
|
|
@ -3,7 +3,7 @@ buildscript {
|
|||
maven { url = 'https://files.minecraftforge.net/maven' }
|
||||
jcenter()
|
||||
mavenCentral()
|
||||
maven { url='https://repo.spongepowered.org/repository/maven-public/' }
|
||||
maven { url = 'https://repo.spongepowered.org/repository/maven-public/' }
|
||||
}
|
||||
dependencies {
|
||||
classpath group: 'net.minecraftforge.gradle', name: 'ForgeGradle', version: '3.+', changing: true
|
||||
|
@ -11,7 +11,6 @@ buildscript {
|
|||
}
|
||||
}
|
||||
plugins {
|
||||
id 'com.github.johnrengelman.shadow' version '5.2.0'
|
||||
id 'com.matthewprenger.cursegradle' version '1.4.0'
|
||||
}
|
||||
|
||||
|
@ -89,9 +88,6 @@ mixin {
|
|||
add sourceSets.main, "flywheel.refmap.json"
|
||||
}
|
||||
|
||||
// Include resources generated by data generators.
|
||||
sourceSets.main.resources { srcDir 'src/generated/resources' }
|
||||
|
||||
repositories {
|
||||
maven {
|
||||
name "tterrag maven"
|
||||
|
|
|
@ -5,18 +5,10 @@ org.gradle.daemon=false
|
|||
mod_version=0.0.3
|
||||
mc_update_version=1.16
|
||||
minecraft_version=1.16.5
|
||||
|
||||
forge_version=36.0.42
|
||||
mcp_mappings=20200920-mixed-1.16.3
|
||||
|
||||
# dependency versions
|
||||
registrate_version=1.0.4
|
||||
jei_version=7.6.1.71
|
||||
|
||||
# curseforge information
|
||||
# projectId=486392
|
||||
# curse_type=beta
|
||||
|
||||
# github information
|
||||
projectId=486392
|
||||
curse_type=beta
|
||||
github_project=Jozufozu/Flywheel
|
||||
|
|
|
@ -1,34 +1,35 @@
|
|||
package com.jozufozu.flywheel;
|
||||
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
import com.jozufozu.flywheel.config.FlwCommands;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.config.FlwPackets;
|
||||
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.common.MinecraftForge;
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.DistExecutor;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
import net.minecraftforge.fml.event.lifecycle.FMLCommonSetupEvent;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
||||
@Mod("flywheel")
|
||||
public class Flywheel {
|
||||
|
||||
public static final String ID = "flywheel";
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
public static final String ID = "flywheel";
|
||||
private static final Logger LOGGER = LogManager.getLogger();
|
||||
|
||||
public Flywheel() {
|
||||
FMLJavaModLoadingContext.get().getModEventBus().addListener(this::setup);
|
||||
public Flywheel() {
|
||||
FMLJavaModLoadingContext.get()
|
||||
.getModEventBus()
|
||||
.addListener(this::setup);
|
||||
|
||||
MinecraftForge.EVENT_BUS.addListener(FlwCommands::onServerStarting);
|
||||
|
||||
FlwConfig.init();
|
||||
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> Client::clientInit);
|
||||
DistExecutor.unsafeRunWhenOn(Dist.CLIENT, () -> FlywheelClient::clientInit);
|
||||
}
|
||||
|
||||
private void setup(final FMLCommonSetupEvent event) {
|
||||
|
|
|
@ -2,20 +2,19 @@ package com.jozufozu.flywheel;
|
|||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.core.AtlasStitcher;
|
||||
|
||||
import com.jozufozu.flywheel.core.Contexts;
|
||||
|
||||
import com.jozufozu.flywheel.core.Materials;
|
||||
|
||||
import net.minecraftforge.eventbus.api.IEventBus;
|
||||
import net.minecraftforge.fml.javafmlmod.FMLJavaModLoadingContext;
|
||||
|
||||
public class Client {
|
||||
public class FlywheelClient {
|
||||
|
||||
public static void clientInit() {
|
||||
|
||||
Backend.init();
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get().getModEventBus();
|
||||
IEventBus modEventBus = FMLJavaModLoadingContext.get()
|
||||
.getModEventBus();
|
||||
|
||||
modEventBus.addListener(AtlasStitcher.getInstance()::onTextureStitch);
|
||||
|
|
@ -6,7 +6,7 @@ import java.util.HashMap;
|
|||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
import org.apache.logging.log4j.Logger;
|
||||
|
@ -16,6 +16,7 @@ import org.lwjgl.opengl.GLCapabilities;
|
|||
import com.jozufozu.flywheel.backend.gl.versioned.GlCompat;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstanceData;
|
||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
||||
import com.jozufozu.flywheel.config.FlwConfig;
|
||||
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
@ -24,8 +25,6 @@ import net.minecraft.util.math.vector.Matrix4f;
|
|||
import net.minecraft.world.IWorld;
|
||||
import net.minecraft.world.World;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
public class Backend {
|
||||
public static final Logger log = LogManager.getLogger(Backend.class);
|
||||
|
||||
|
@ -111,7 +110,9 @@ public class Backend {
|
|||
}
|
||||
materialRegistry.put(name, spec);
|
||||
|
||||
log.debug("registered material '" + name + "' with vertex size " + spec.getModelFormat().getStride() + " and instance size " + spec.getInstanceFormat().getStride());
|
||||
log.debug("registered material '" + name + "' with vertex size " + spec.getModelFormat()
|
||||
.getStride() + " and instance size " + spec.getInstanceFormat()
|
||||
.getStride());
|
||||
|
||||
return spec;
|
||||
}
|
||||
|
@ -146,11 +147,10 @@ public class Backend {
|
|||
|
||||
compat = new GlCompat(capabilities);
|
||||
|
||||
instancedArrays = compat.vertexArrayObjectsSupported() &&
|
||||
compat.drawInstancedSupported() &&
|
||||
compat.instancedArraysSupported();
|
||||
instancedArrays = compat.vertexArrayObjectsSupported() && compat.drawInstancedSupported() && compat.instancedArraysSupported();
|
||||
|
||||
enabled = FlwConfig.get().enabled() && !OptifineHandler.usingShaders();
|
||||
enabled = FlwConfig.get()
|
||||
.enabled() && !OptifineHandler.usingShaders();
|
||||
}
|
||||
|
||||
public boolean canUseInstancing(World world) {
|
||||
|
@ -181,11 +181,9 @@ public class Backend {
|
|||
* Used to avoid calling Flywheel functions on (fake) worlds that don't specifically support it.
|
||||
*/
|
||||
public static boolean isFlywheelWorld(@Nullable IWorld world) {
|
||||
if (world == null)
|
||||
return false;
|
||||
if (world == null) return false;
|
||||
|
||||
if (world instanceof IFlywheelWorld && ((IFlywheelWorld) world).supportsFlywheel())
|
||||
return true;
|
||||
if (world instanceof IFlywheelWorld && ((IFlywheelWorld) world).supportsFlywheel()) return true;
|
||||
|
||||
return world == Minecraft.getInstance().world;
|
||||
}
|
||||
|
@ -198,5 +196,6 @@ public class Backend {
|
|||
RenderWork.enqueue(Minecraft.getInstance().worldRenderer::loadRenderers);
|
||||
}
|
||||
|
||||
public static void init() { }
|
||||
public static void init() {
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,8 @@ import net.minecraft.util.ResourceLocation;
|
|||
public interface IShaderContext<P extends GlProgram> {
|
||||
|
||||
default P getProgram(ResourceLocation loc) {
|
||||
return this.getProgramSupplier(loc).get();
|
||||
return this.getProgramSupplier(loc)
|
||||
.get();
|
||||
}
|
||||
|
||||
Supplier<P> getProgramSupplier(ResourceLocation loc);
|
||||
|
|
|
@ -45,7 +45,8 @@ public class OptifineHandler {
|
|||
|
||||
if (optifine == null) {
|
||||
Backend.log.info("Optifine not detected.");
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
Backend.log.info("Optifine detected.");
|
||||
|
||||
refresh();
|
||||
|
|
|
@ -17,7 +17,8 @@ public class RenderWork {
|
|||
@SubscribeEvent(priority = EventPriority.LOWEST)
|
||||
public static void onRenderWorldLast(RenderWorldLastEvent event) {
|
||||
while (!runs.isEmpty()) {
|
||||
runs.remove().run();
|
||||
runs.remove()
|
||||
.run();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,7 +9,8 @@ public class ResourceUtil {
|
|||
}
|
||||
|
||||
public static ResourceLocation removePrefixUnchecked(ResourceLocation full, String root) {
|
||||
return new ResourceLocation(full.getNamespace(), full.getPath().substring(root.length()));
|
||||
return new ResourceLocation(full.getNamespace(), full.getPath()
|
||||
.substring(root.length()));
|
||||
}
|
||||
|
||||
public static ResourceLocation trim(ResourceLocation loc, String prefix, String suffix) {
|
||||
|
|
|
@ -57,7 +57,8 @@ public abstract class ShaderContext<P extends GlProgram> implements IShaderConte
|
|||
|
||||
@Override
|
||||
public void delete() {
|
||||
programs.values().forEach(IMultiProgram::delete);
|
||||
programs.values()
|
||||
.forEach(IMultiProgram::delete);
|
||||
programs.clear();
|
||||
}
|
||||
|
||||
|
|
|
@ -19,15 +19,6 @@ import java.util.stream.Stream;
|
|||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.event.ForgeEvents;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
|
||||
import net.minecraftforge.event.world.WorldEvent;
|
||||
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
import com.google.common.collect.Lists;
|
||||
|
@ -35,6 +26,7 @@ import com.google.gson.Gson;
|
|||
import com.google.gson.GsonBuilder;
|
||||
import com.google.gson.JsonElement;
|
||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||
import com.jozufozu.flywheel.backend.instancing.InstancedRenderDispatcher;
|
||||
import com.jozufozu.flywheel.backend.loading.Shader;
|
||||
import com.jozufozu.flywheel.backend.loading.ShaderLoadingException;
|
||||
import com.jozufozu.flywheel.core.shader.spec.ProgramSpec;
|
||||
|
@ -44,6 +36,8 @@ import com.mojang.datafixers.util.Pair;
|
|||
import com.mojang.serialization.DataResult;
|
||||
import com.mojang.serialization.JsonOps;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.world.ClientWorld;
|
||||
import net.minecraft.resources.IReloadableResourceManager;
|
||||
import net.minecraft.resources.IResource;
|
||||
import net.minecraft.resources.IResourceManager;
|
||||
|
@ -84,7 +78,8 @@ public class ShaderSources implements ISelectiveResourceReloadListener {
|
|||
shouldCrash = false;
|
||||
|
||||
backend.clearContexts();
|
||||
ModLoader.get().postEvent(new GatherContextEvent(backend));
|
||||
ModLoader.get()
|
||||
.postEvent(new GatherContextEvent(backend));
|
||||
|
||||
loadProgramSpecs(manager);
|
||||
loadShaderSources(manager);
|
||||
|
@ -123,7 +118,9 @@ public class ShaderSources implements ISelectiveResourceReloadListener {
|
|||
|
||||
DataResult<Pair<ProgramSpec, JsonElement>> result = ProgramSpec.CODEC.decode(JsonOps.INSTANCE, GSON.fromJson(s, JsonElement.class));
|
||||
|
||||
ProgramSpec spec = result.get().orThrow().getFirst();
|
||||
ProgramSpec spec = result.get()
|
||||
.orThrow()
|
||||
.getFirst();
|
||||
|
||||
spec.setName(specName);
|
||||
|
||||
|
@ -210,7 +207,8 @@ public class ShaderSources implements ISelectiveResourceReloadListener {
|
|||
|
||||
while (filechannel.read(bytebuffer) != -1) {
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
bytebuffer = MemoryUtil.memAlloc(8192);
|
||||
ReadableByteChannel readablebytechannel = Channels.newChannel(is);
|
||||
|
||||
|
|
|
@ -53,9 +53,11 @@ public enum GlNumericType {
|
|||
public void castAndBuffer(ByteBuffer buf, int val) {
|
||||
if (this == UBYTE || this == BYTE) {
|
||||
buf.put((byte) val);
|
||||
} else if (this == USHORT || this == SHORT) {
|
||||
}
|
||||
else if (this == USHORT || this == SHORT) {
|
||||
buf.putShort((short) val);
|
||||
} else if (this == UINT || this == INT) {
|
||||
}
|
||||
else if (this == UINT || this == INT) {
|
||||
buf.putInt(val);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -56,7 +56,8 @@ public class GlBuffer extends GlObject {
|
|||
public MappedBuffer getBuffer(int offset, int length) {
|
||||
if (Backend.getInstance().compat.mapBufferRange != MapBufferRange.UNSUPPORTED) {
|
||||
return new MappedBufferRange(this, offset, length, GL30.GL_MAP_WRITE_BIT);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
MappedFullBuffer fullBuffer = new MappedFullBuffer(this, MappedBufferUsage.WRITE_ONLY);
|
||||
fullBuffer.position(offset);
|
||||
return fullBuffer;
|
||||
|
|
|
@ -39,8 +39,8 @@ public class VecBuffer {
|
|||
for (float f : floats) {
|
||||
internal.putFloat(f);
|
||||
}
|
||||
// internal.asFloatBuffer().put(floats);
|
||||
// internal.position(internal.position() + floats.length * 4);
|
||||
// internal.asFloatBuffer().put(floats);
|
||||
// internal.position(internal.position() + floats.length * 4);
|
||||
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,10 @@ public class GlCompat {
|
|||
throw new IllegalStateException("");
|
||||
}
|
||||
|
||||
return Arrays.stream(constants).filter(it -> it.supported(caps)).findFirst().get();
|
||||
return Arrays.stream(constants)
|
||||
.filter(it -> it.supported(caps))
|
||||
.findFirst()
|
||||
.get();
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -61,8 +61,7 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
|||
int dY = pos.getY() - cY;
|
||||
int dZ = pos.getZ() - cZ;
|
||||
|
||||
if ((tick % getUpdateDivisor(dX, dY, dZ)) == 0)
|
||||
instance.tick();
|
||||
if ((tick % getUpdateDivisor(dX, dY, dZ)) == 0) instance.tick();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,16 +87,18 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
|||
int cZ = (int) info.getProjectedView().z;
|
||||
|
||||
if (dynamicInstances.size() > 0) {
|
||||
dynamicInstances.object2ObjectEntrySet().fastForEach(e -> {
|
||||
IDynamicInstance dyn = e.getValue();
|
||||
if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
|
||||
dyn.beginFrame();
|
||||
});
|
||||
dynamicInstances.object2ObjectEntrySet()
|
||||
.fastForEach(e -> {
|
||||
IDynamicInstance dyn = e.getValue();
|
||||
if (!dyn.decreaseFramerateWithDistance() || shouldFrameUpdate(dyn.getWorldPosition(), lookX, lookY, lookZ, cX, cY, cZ))
|
||||
dyn.beginFrame();
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void add(T obj) {
|
||||
if (!Backend.getInstance().canUseInstancing()) return;
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing()) return;
|
||||
|
||||
if (obj instanceof IInstanceRendered) {
|
||||
addInternal(obj);
|
||||
|
@ -105,13 +106,15 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
|||
}
|
||||
|
||||
public synchronized void queueAdd(T obj) {
|
||||
if (!Backend.getInstance().canUseInstancing()) return;
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing()) return;
|
||||
|
||||
queuedAdditions.add(obj);
|
||||
}
|
||||
|
||||
public void update(T obj) {
|
||||
if (!Backend.getInstance().canUseInstancing()) return;
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing()) return;
|
||||
|
||||
if (obj instanceof IInstanceRendered) {
|
||||
IInstance instance = getInstance(obj, false);
|
||||
|
@ -122,7 +125,8 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
|||
removeInternal(obj, instance);
|
||||
|
||||
createInternal(obj);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
instance.update();
|
||||
}
|
||||
}
|
||||
|
@ -130,29 +134,30 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
|||
}
|
||||
|
||||
public synchronized void queueUpdate(T obj) {
|
||||
if (!Backend.getInstance().canUseInstancing()) return;
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing()) return;
|
||||
|
||||
queuedUpdates.add(obj);
|
||||
}
|
||||
|
||||
public void onLightUpdate(T obj) {
|
||||
if (!Backend.getInstance().canUseInstancing()) return;
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing()) return;
|
||||
|
||||
if (obj instanceof IInstanceRendered) {
|
||||
IInstance instance = getInstance(obj, false);
|
||||
|
||||
if (instance != null)
|
||||
instance.updateLight();
|
||||
if (instance != null) instance.updateLight();
|
||||
}
|
||||
}
|
||||
|
||||
public void remove(T obj) {
|
||||
if (!Backend.getInstance().canUseInstancing()) return;
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing()) return;
|
||||
|
||||
if (obj instanceof IInstanceRendered) {
|
||||
IInstance instance = getInstance(obj, false);
|
||||
if (instance != null)
|
||||
removeInternal(obj, instance);
|
||||
if (instance != null) removeInternal(obj, instance);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -165,15 +170,18 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
|||
@SuppressWarnings("unchecked")
|
||||
@Nullable
|
||||
protected <I extends T> IInstance getInstance(I obj, boolean create) {
|
||||
if (!Backend.getInstance().canUseInstancing()) return null;
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing()) return null;
|
||||
|
||||
IInstance instance = instances.get(obj);
|
||||
|
||||
if (instance != null) {
|
||||
return instance;
|
||||
} else if (create && canCreateInstance(obj)) {
|
||||
}
|
||||
else if (create && canCreateInstance(obj)) {
|
||||
return createInternal(obj);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -222,11 +230,9 @@ public abstract class InstanceManager<T> implements MaterialManager.OriginShiftL
|
|||
renderer.updateLight();
|
||||
instances.put(obj, renderer);
|
||||
|
||||
if (renderer instanceof IDynamicInstance)
|
||||
dynamicInstances.put(obj, (IDynamicInstance) renderer);
|
||||
if (renderer instanceof IDynamicInstance) dynamicInstances.put(obj, (IDynamicInstance) renderer);
|
||||
|
||||
if (renderer instanceof ITickableInstance)
|
||||
tickableInstances.put(obj, ((ITickableInstance) renderer));
|
||||
if (renderer instanceof ITickableInstance) tickableInstances.put(obj, ((ITickableInstance) renderer));
|
||||
}
|
||||
|
||||
return renderer;
|
||||
|
|
|
@ -55,7 +55,10 @@ public class InstanceMaterial<D extends InstanceData> {
|
|||
}
|
||||
|
||||
public boolean nothingToRender() {
|
||||
return models.size() > 0 && models.asMap().values().stream().allMatch(Instancer::empty);
|
||||
return models.size() > 0 && models.asMap()
|
||||
.values()
|
||||
.stream()
|
||||
.allMatch(Instancer::empty);
|
||||
}
|
||||
|
||||
public void delete() {
|
||||
|
@ -66,11 +69,14 @@ public class InstanceMaterial<D extends InstanceData> {
|
|||
* Clear all instance data without freeing resources.
|
||||
*/
|
||||
public void clear() {
|
||||
models.asMap().values().forEach(Instancer::clear);
|
||||
models.asMap()
|
||||
.values()
|
||||
.forEach(Instancer::clear);
|
||||
}
|
||||
|
||||
public void forEachInstancer(Consumer<Instancer<D>> f) {
|
||||
for (Instancer<D> model : models.asMap().values()) {
|
||||
for (Instancer<D> model : models.asMap()
|
||||
.values()) {
|
||||
f.accept(model);
|
||||
}
|
||||
}
|
||||
|
@ -84,8 +90,7 @@ public class InstanceMaterial<D extends InstanceData> {
|
|||
}
|
||||
|
||||
public Instancer<D> getModel(PartialModel partial, BlockState referenceState, Direction dir, Supplier<MatrixStack> modelTransform) {
|
||||
return get(Pair.of(dir, partial),
|
||||
() -> buildModel(partial.get(), referenceState, modelTransform.get()));
|
||||
return get(Pair.of(dir, partial), () -> buildModel(partial.get(), referenceState, modelTransform.get()));
|
||||
}
|
||||
|
||||
public Instancer<D> getModel(BlockState toRender) {
|
||||
|
@ -102,7 +107,8 @@ public class InstanceMaterial<D extends InstanceData> {
|
|||
}
|
||||
|
||||
private BufferedModel buildModel(BlockState renderedState) {
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance().getBlockRendererDispatcher();
|
||||
BlockRendererDispatcher dispatcher = Minecraft.getInstance()
|
||||
.getBlockRendererDispatcher();
|
||||
return buildModel(dispatcher.getModelForState(renderedState), renderedState);
|
||||
}
|
||||
|
||||
|
@ -153,16 +159,15 @@ public class InstanceMaterial<D extends InstanceData> {
|
|||
BlockModelRenderer blockRenderer = dispatcher.getBlockModelRenderer();
|
||||
BufferBuilder builder = new BufferBuilder(512);
|
||||
|
||||
// BakedQuadWrapper quadReader = new BakedQuadWrapper();
|
||||
//
|
||||
// IModelData modelData = model.getModelData(mc.world, BlockPos.ZERO.up(255), referenceState, VirtualEmptyModelData.INSTANCE);
|
||||
// List<BakedQuad> quads = Arrays.stream(dirs)
|
||||
// .flatMap(dir -> model.getQuads(referenceState, dir, mc.world.rand, modelData).stream())
|
||||
// .collect(Collectors.toList());
|
||||
// BakedQuadWrapper quadReader = new BakedQuadWrapper();
|
||||
//
|
||||
// IModelData modelData = model.getModelData(mc.world, BlockPos.ZERO.up(255), referenceState, VirtualEmptyModelData.INSTANCE);
|
||||
// List<BakedQuad> quads = Arrays.stream(dirs)
|
||||
// .flatMap(dir -> model.getQuads(referenceState, dir, mc.world.rand, modelData).stream())
|
||||
// .collect(Collectors.toList());
|
||||
|
||||
builder.begin(GL11.GL_QUADS, DefaultVertexFormats.BLOCK);
|
||||
blockRenderer.renderModel(mc.world, model, referenceState, BlockPos.ZERO.up(255), ms, builder, true,
|
||||
mc.world.rand, 42, OverlayTexture.DEFAULT_UV, VirtualEmptyModelData.INSTANCE);
|
||||
blockRenderer.renderModel(mc.world, model, referenceState, BlockPos.ZERO.up(255), ms, builder, true, mc.world.rand, 42, OverlayTexture.DEFAULT_UV, VirtualEmptyModelData.INSTANCE);
|
||||
builder.finishDrawing();
|
||||
return builder;
|
||||
}
|
||||
|
|
|
@ -109,7 +109,8 @@ public class InstancedRenderDispatcher {
|
|||
@SubscribeEvent
|
||||
public static void renderLayer(RenderLayerEvent event) {
|
||||
ClientWorld world = event.getWorld();
|
||||
if (!Backend.getInstance().canUseInstancing(world)) return;
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing(world)) return;
|
||||
|
||||
event.type.startDrawing();
|
||||
|
||||
|
@ -122,7 +123,8 @@ public class InstancedRenderDispatcher {
|
|||
@SubscribeEvent
|
||||
public static void onReloadRenderers(ReloadRenderersEvent event) {
|
||||
ClientWorld world = event.getWorld();
|
||||
if (Backend.getInstance().canUseInstancing() && world != null) {
|
||||
if (Backend.getInstance()
|
||||
.canUseInstancing() && world != null) {
|
||||
loadAllInWorld(world);
|
||||
}
|
||||
}
|
||||
|
@ -130,7 +132,8 @@ public class InstancedRenderDispatcher {
|
|||
private static final RenderType crumblingLayer = ModelBakery.BLOCK_DESTRUCTION_RENDER_LAYERS.get(0);
|
||||
|
||||
public static void renderBreaking(ClientWorld world, Matrix4f viewProjection, double cameraX, double cameraY, double cameraZ) {
|
||||
if (!Backend.getInstance().canUseInstancing(world)) return;
|
||||
if (!Backend.getInstance()
|
||||
.canUseInstancing(world)) return;
|
||||
|
||||
WorldRenderer worldRenderer = Minecraft.getInstance().worldRenderer;
|
||||
Long2ObjectMap<SortedSet<DestroyBlockProgress>> breakingProgressions = worldRenderer.blockBreakingProgressions;
|
||||
|
@ -145,9 +148,11 @@ public class InstancedRenderDispatcher {
|
|||
|
||||
SortedSet<DestroyBlockProgress> progresses = entry.getValue();
|
||||
if (progresses != null && !progresses.isEmpty()) {
|
||||
int blockDamage = progresses.last().getPartialBlockDamage();
|
||||
int blockDamage = progresses.last()
|
||||
.getPartialBlockDamage();
|
||||
bitSet.set(blockDamage);
|
||||
renderers.get(blockDamage).add(world.getTileEntity(breakingPos));
|
||||
renderers.get(blockDamage)
|
||||
.add(world.getTileEntity(breakingPos));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -155,38 +160,41 @@ public class InstancedRenderDispatcher {
|
|||
ActiveRenderInfo info = Minecraft.getInstance().gameRenderer.getActiveRenderInfo();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE).getGlTextureId());
|
||||
glBindTexture(GL_TEXTURE_2D, textureManager.getTexture(PlayerContainer.BLOCK_ATLAS_TEXTURE)
|
||||
.getGlTextureId());
|
||||
|
||||
glActiveTexture(GL_TEXTURE4);
|
||||
|
||||
crumblingLayer.startDrawing();
|
||||
bitSet.stream().forEach(i -> {
|
||||
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(i));
|
||||
CrumblingInstanceManager renderer = renderers.get(i);
|
||||
renderer.beginFrame(info);
|
||||
bitSet.stream()
|
||||
.forEach(i -> {
|
||||
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(i));
|
||||
CrumblingInstanceManager renderer = renderers.get(i);
|
||||
renderer.beginFrame(info);
|
||||
|
||||
if (breaking != null) {
|
||||
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||
renderer.materialManager.render(RenderType.getCutoutMipped(), viewProjection, cameraX, cameraY, cameraZ);
|
||||
}
|
||||
if (breaking != null) {
|
||||
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||
renderer.materialManager.render(RenderType.getCutoutMipped(), viewProjection, cameraX, cameraY, cameraZ);
|
||||
}
|
||||
|
||||
renderer.invalidate();
|
||||
});
|
||||
renderer.invalidate();
|
||||
});
|
||||
crumblingLayer.endDrawing();
|
||||
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
Texture breaking = textureManager.getTexture(ModelBakery.BLOCK_DESTRUCTION_STAGE_TEXTURES.get(0));
|
||||
if (breaking != null)
|
||||
glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||
if (breaking != null) glBindTexture(GL_TEXTURE_2D, breaking.getGlTextureId());
|
||||
}
|
||||
|
||||
public static void loadAllInWorld(ClientWorld world) {
|
||||
Contexts.WORLD.getMaterialManager(world).delete();
|
||||
Contexts.WORLD.getMaterialManager(world)
|
||||
.delete();
|
||||
|
||||
TileInstanceManager tiles = tileInstanceManager.replace(world);
|
||||
world.loadedTileEntityList.forEach(tiles::add);
|
||||
|
||||
EntityInstanceManager entities = entityInstanceManager.replace(world);
|
||||
world.getAllEntities().forEach(entities::add);
|
||||
world.getAllEntities()
|
||||
.forEach(entities::add);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,8 +65,7 @@ public class Instancer<D extends InstanceData> {
|
|||
vao.bind();
|
||||
renderSetup();
|
||||
|
||||
if (glInstanceCount > 0)
|
||||
model.drawInstances(glInstanceCount);
|
||||
if (glInstanceCount > 0) model.drawInstances(glInstanceCount);
|
||||
|
||||
vao.unbind();
|
||||
}
|
||||
|
@ -160,12 +159,13 @@ public class Instancer<D extends InstanceData> {
|
|||
if (length > 0) {
|
||||
MappedBuffer mapped = instanceVBO.getBuffer(offset, length);
|
||||
|
||||
dirtySet.stream().forEach(i -> {
|
||||
final D d = data.get(i);
|
||||
dirtySet.stream()
|
||||
.forEach(i -> {
|
||||
final D d = data.get(i);
|
||||
|
||||
mapped.position(i * stride);
|
||||
d.write(mapped);
|
||||
});
|
||||
mapped.position(i * stride);
|
||||
d.write(mapped);
|
||||
});
|
||||
mapped.flush();
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +236,8 @@ public class Instancer<D extends InstanceData> {
|
|||
|
||||
anyToUpdate = true;
|
||||
|
||||
data.subList(newSize, oldSize).clear();
|
||||
data.subList(newSize, oldSize)
|
||||
.clear();
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -42,7 +42,9 @@ public class MaterialManager<P extends WorldProgram> {
|
|||
this.context = context;
|
||||
|
||||
this.atlasMaterials = new HashMap<>();
|
||||
this.atlasRenderers = new ArrayList<>(Backend.getInstance().allMaterials().size());
|
||||
this.atlasRenderers = new ArrayList<>(Backend.getInstance()
|
||||
.allMaterials()
|
||||
.size());
|
||||
|
||||
this.materials = new HashMap<>();
|
||||
this.renderers = new HashMap<>();
|
||||
|
@ -90,8 +92,13 @@ public class MaterialManager<P extends WorldProgram> {
|
|||
}
|
||||
|
||||
public void delete() {
|
||||
atlasMaterials.values().forEach(InstanceMaterial::delete);
|
||||
materials.values().stream().flatMap(m -> m.values().stream()).forEach(InstanceMaterial::delete);
|
||||
atlasMaterials.values()
|
||||
.forEach(InstanceMaterial::delete);
|
||||
materials.values()
|
||||
.stream()
|
||||
.flatMap(m -> m.values()
|
||||
.stream())
|
||||
.forEach(InstanceMaterial::delete);
|
||||
|
||||
atlasMaterials.clear();
|
||||
atlasRenderers.clear();
|
||||
|
@ -151,8 +158,13 @@ public class MaterialManager<P extends WorldProgram> {
|
|||
|
||||
originCoordinate = new BlockPos(cX, cY, cZ);
|
||||
|
||||
materials.values().stream().flatMap(m -> m.values().stream()).forEach(InstanceMaterial::clear);
|
||||
atlasMaterials.values().forEach(InstanceMaterial::clear);
|
||||
materials.values()
|
||||
.stream()
|
||||
.flatMap(m -> m.values()
|
||||
.stream())
|
||||
.forEach(InstanceMaterial::clear);
|
||||
atlasMaterials.values()
|
||||
.forEach(InstanceMaterial::clear);
|
||||
listeners.forEach(OriginShiftListener::onOriginShift);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,7 +24,7 @@ import net.minecraft.world.World;
|
|||
|
||||
/**
|
||||
* The layer between a {@link TileEntity} and the Flywheel backend.
|
||||
**
|
||||
* *
|
||||
* <br><br> There are a few additional features that overriding classes can opt in to:
|
||||
* <ul>
|
||||
* <li>{@link IDynamicInstance}</li>
|
||||
|
@ -94,11 +94,7 @@ public abstract class EntityInstance<E extends Entity> implements IInstance {
|
|||
public Vector3f getInstancePosition() {
|
||||
Vector3d pos = entity.getPositionVec();
|
||||
Vector3i origin = materialManager.getOriginCoordinate();
|
||||
return new Vector3f(
|
||||
(float) (pos.x - origin.getX()),
|
||||
(float) (pos.y - origin.getY()),
|
||||
(float) (pos.z - origin.getZ())
|
||||
);
|
||||
return new Vector3f((float) (pos.x - origin.getX()), (float) (pos.y - origin.getY()), (float) (pos.z - origin.getZ()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -119,7 +115,8 @@ public abstract class EntityInstance<E extends Entity> implements IInstance {
|
|||
}
|
||||
|
||||
protected <L extends IFlatLight<?>> void relight(int block, int sky, Stream<L> models) {
|
||||
models.forEach(model -> model.setBlockLight(block).setSkyLight(sky));
|
||||
models.forEach(model -> model.setBlockLight(block)
|
||||
.setSkyLight(sky));
|
||||
}
|
||||
|
||||
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
||||
|
|
|
@ -19,7 +19,8 @@ public class EntityInstanceManager extends InstanceManager<Entity> {
|
|||
|
||||
@Override
|
||||
protected IInstance createRaw(Entity obj) {
|
||||
return InstancedRenderRegistry.getInstance().create(materialManager, obj);
|
||||
return InstancedRenderRegistry.getInstance()
|
||||
.create(materialManager, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -117,7 +117,8 @@ public abstract class TileEntityInstance<T extends TileEntity> implements IInsta
|
|||
}
|
||||
|
||||
protected <L extends IFlatLight<?>> void relight(int block, int sky, Stream<L> models) {
|
||||
models.forEach(model -> model.setBlockLight(block).setSkyLight(sky));
|
||||
models.forEach(model -> model.setBlockLight(block)
|
||||
.setSkyLight(sky));
|
||||
}
|
||||
|
||||
protected InstanceMaterial<ModelData> getTransformMaterial() {
|
||||
|
|
|
@ -19,7 +19,8 @@ public class TileInstanceManager extends InstanceManager<TileEntity> {
|
|||
|
||||
@Override
|
||||
protected IInstance createRaw(TileEntity obj) {
|
||||
return InstancedRenderRegistry.getInstance().create(materialManager, obj);
|
||||
return InstancedRenderRegistry.getInstance()
|
||||
.create(materialManager, obj);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -33,7 +33,9 @@ public class InstancedArraysTemplate extends ProgramTemplate {
|
|||
public void attachAttributes(Program builder) {
|
||||
Shader shader = builder.attached.get(ShaderType.VERTEX);
|
||||
|
||||
shader.getTag(vertexData).addPrefixedAttributes(builder, vertexPrefix);
|
||||
shader.getTag(instanceData).addPrefixedAttributes(builder, instancePrefix);
|
||||
shader.getTag(vertexData)
|
||||
.addPrefixedAttributes(builder, vertexPrefix);
|
||||
shader.getTag(instanceData)
|
||||
.addPrefixedAttributes(builder, instancePrefix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,6 +30,7 @@ public class ModelTemplate extends ProgramTemplate {
|
|||
public void attachAttributes(Program builder) {
|
||||
Shader shader = builder.attached.get(ShaderType.VERTEX);
|
||||
|
||||
shader.getTag(vertexData).addPrefixedAttributes(builder, vertexPrefix);
|
||||
shader.getTag(vertexData)
|
||||
.addPrefixedAttributes(builder, vertexPrefix);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,7 +72,9 @@ public class Shader {
|
|||
|
||||
if (matcher.find()) {
|
||||
StringBuffer sourceWithDefines = new StringBuffer();
|
||||
String lines = defines.stream().map(it -> "#define " + it).collect(Collectors.joining("\n"));
|
||||
String lines = defines.stream()
|
||||
.map(it -> "#define " + it)
|
||||
.collect(Collectors.joining("\n"));
|
||||
|
||||
matcher.appendReplacement(sourceWithDefines, matcher.group() + '\n' + lines);
|
||||
|
||||
|
@ -92,7 +94,8 @@ public class Shader {
|
|||
|
||||
structs.add(struct);
|
||||
|
||||
String replacement = decorator.matcher(struct.source).replaceFirst("");
|
||||
String replacement = decorator.matcher(struct.source)
|
||||
.replaceFirst("");
|
||||
structMatcher.appendReplacement(strippedSrc, replacement);
|
||||
|
||||
tag2Struct.put(struct.tag, struct);
|
||||
|
@ -138,12 +141,14 @@ public class Shader {
|
|||
public String printSource() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.append("Source for shader '").append(name).append("':\n");
|
||||
builder.append("Source for shader '")
|
||||
.append(name)
|
||||
.append("':\n");
|
||||
int i = 1;
|
||||
for (String s : source.split("\n")) {
|
||||
builder.append(String.format("%1$4s: ", i++))
|
||||
.append(s)
|
||||
.append('\n');
|
||||
.append(s)
|
||||
.append('\n');
|
||||
}
|
||||
|
||||
return builder.toString();
|
||||
|
|
|
@ -47,7 +47,8 @@ public class ShaderTemplate {
|
|||
|
||||
if (struct != null) {
|
||||
s = s.replace(name, struct.name);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
missing.add(name);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -40,9 +40,6 @@ public class TaggedField {
|
|||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "TaggedField{" +
|
||||
"name='" + name + '\'' +
|
||||
", type='" + type + '\'' +
|
||||
'}';
|
||||
return "TaggedField{" + "name='" + name + '\'' + ", type='" + type + '\'' + '}';
|
||||
}
|
||||
}
|
||||
|
|
|
@ -25,7 +25,8 @@ public class IndexedModel extends BufferedModel {
|
|||
}
|
||||
|
||||
public static IndexedModel fromSequentialQuads(VertexFormat modelFormat, ByteBuffer quads, int vertices) {
|
||||
return new IndexedModel(modelFormat, quads, vertices, QuadConverter.getInstance().quads2Tris(vertices / 4));
|
||||
return new IndexedModel(modelFormat, quads, vertices, QuadConverter.getInstance()
|
||||
.quads2Tris(vertices / 4));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
@ParametersAreNonnullByDefault
|
||||
@MethodsReturnNonnullByDefault
|
||||
@ParametersAreNonnullByDefault @MethodsReturnNonnullByDefault
|
||||
package com.jozufozu.flywheel.backend;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
||||
import javax.annotation.ParametersAreNonnullByDefault;
|
||||
|
||||
import mcp.MethodsReturnNonnullByDefault;
|
||||
|
|
|
@ -1,5 +1,8 @@
|
|||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
||||
|
||||
|
@ -12,9 +15,6 @@ import net.minecraft.util.text.TextFormatting;
|
|||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public enum BooleanConfig {
|
||||
ENGINE(() -> BooleanConfig::enabled),
|
||||
NORMAL_OVERLAY(() -> BooleanConfig::normalOverlay),
|
||||
|
|
|
@ -22,28 +22,24 @@ public class BooleanConfigCommand {
|
|||
public ArgumentBuilder<CommandSource, ?> register() {
|
||||
return Commands.literal(name)
|
||||
.executes(context -> {
|
||||
ServerPlayerEntity player = context.getSource().asPlayer();
|
||||
FlwPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureBooleanPacket(value, BooleanDirective.DISPLAY)
|
||||
);
|
||||
ServerPlayerEntity player = context.getSource()
|
||||
.asPlayer();
|
||||
FlwPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), new SConfigureBooleanPacket(value, BooleanDirective.DISPLAY));
|
||||
return Command.SINGLE_SUCCESS;
|
||||
})
|
||||
.then(Commands.literal("on").executes(context -> {
|
||||
ServerPlayerEntity player = context.getSource().asPlayer();
|
||||
FlwPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureBooleanPacket(value, BooleanDirective.TRUE)
|
||||
);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}))
|
||||
.then(Commands.literal("off").executes(context -> {
|
||||
ServerPlayerEntity player = context.getSource().asPlayer();
|
||||
FlwPackets.channel.send(
|
||||
PacketDistributor.PLAYER.with(() -> player),
|
||||
new SConfigureBooleanPacket(value, BooleanDirective.FALSE)
|
||||
);
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}));
|
||||
.then(Commands.literal("on")
|
||||
.executes(context -> {
|
||||
ServerPlayerEntity player = context.getSource()
|
||||
.asPlayer();
|
||||
FlwPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), new SConfigureBooleanPacket(value, BooleanDirective.TRUE));
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}))
|
||||
.then(Commands.literal("off")
|
||||
.executes(context -> {
|
||||
ServerPlayerEntity player = context.getSource()
|
||||
.asPlayer();
|
||||
FlwPackets.channel.send(PacketDistributor.PLAYER.with(() -> player), new SConfigureBooleanPacket(value, BooleanDirective.FALSE));
|
||||
return Command.SINGLE_SUCCESS;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,19 +1,18 @@
|
|||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import com.mojang.brigadier.Command;
|
||||
import com.mojang.brigadier.CommandDispatcher;
|
||||
|
||||
import net.minecraft.command.CommandSource;
|
||||
import net.minecraft.command.Commands;
|
||||
import net.minecraft.entity.player.ServerPlayerEntity;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.event.server.FMLServerStartingEvent;
|
||||
import net.minecraftforge.fml.network.PacketDistributor;
|
||||
|
||||
public class FlwCommands {
|
||||
@SubscribeEvent
|
||||
public static void onServerStarting(FMLServerStartingEvent event) {
|
||||
CommandDispatcher<CommandSource> dispatcher = event.getServer().getCommandManager().getDispatcher();
|
||||
CommandDispatcher<CommandSource> dispatcher = event.getServer()
|
||||
.getCommandManager()
|
||||
.getDispatcher();
|
||||
|
||||
dispatcher.register(Commands.literal("flywheel")
|
||||
.then(new BooleanConfigCommand("backend", BooleanConfig.ENGINE).register())
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
import net.minecraftforge.common.ForgeConfigSpec;
|
||||
import net.minecraftforge.common.ForgeConfigSpec.BooleanValue;
|
||||
import net.minecraftforge.fml.ModLoadingContext;
|
||||
|
||||
import net.minecraftforge.fml.config.ModConfig;
|
||||
|
||||
import org.apache.commons.lang3.tuple.Pair;
|
||||
|
||||
public class FlwConfig {
|
||||
|
||||
private static final FlwConfig INSTANCE = new FlwConfig();
|
||||
|
@ -19,7 +18,8 @@ public class FlwConfig {
|
|||
|
||||
this.client = client.getLeft();
|
||||
|
||||
ModLoadingContext.get().registerConfig(ModConfig.Type.CLIENT, client.getRight());
|
||||
ModLoadingContext.get()
|
||||
.registerConfig(ModConfig.Type.CLIENT, client.getRight());
|
||||
}
|
||||
|
||||
public static FlwConfig get() {
|
||||
|
@ -34,7 +34,8 @@ public class FlwConfig {
|
|||
return client.normalDebug.get();
|
||||
}
|
||||
|
||||
public static void init() { }
|
||||
public static void init() {
|
||||
}
|
||||
|
||||
public static class ClientConfig {
|
||||
public final BooleanValue enabled;
|
||||
|
@ -43,10 +44,10 @@ public class FlwConfig {
|
|||
public ClientConfig(ForgeConfigSpec.Builder builder) {
|
||||
|
||||
enabled = builder.comment("Enable or disable the entire engine")
|
||||
.define("enabled", true);
|
||||
.define("enabled", true);
|
||||
|
||||
normalDebug = builder.comment("Enable or disable a debug overlay that colors pixels by their normal")
|
||||
.define("normalDebug", false);
|
||||
.define("normalDebug", false);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,15 +14,15 @@ public class FlwPackets {
|
|||
|
||||
public static void registerPackets() {
|
||||
channel = NetworkRegistry.ChannelBuilder.named(CHANNEL_NAME)
|
||||
.serverAcceptedVersions(NETWORK_VERSION::equals)
|
||||
.clientAcceptedVersions(NETWORK_VERSION::equals)
|
||||
.networkProtocolVersion(() -> NETWORK_VERSION)
|
||||
.simpleChannel();
|
||||
.serverAcceptedVersions(NETWORK_VERSION::equals)
|
||||
.clientAcceptedVersions(NETWORK_VERSION::equals)
|
||||
.networkProtocolVersion(() -> NETWORK_VERSION)
|
||||
.simpleChannel();
|
||||
|
||||
channel.messageBuilder(SConfigureBooleanPacket.class, 0, NetworkDirection.PLAY_TO_CLIENT)
|
||||
.decoder(SConfigureBooleanPacket::new)
|
||||
.encoder(SConfigureBooleanPacket::encode)
|
||||
.consumer(SConfigureBooleanPacket::execute)
|
||||
.add();
|
||||
.decoder(SConfigureBooleanPacket::new)
|
||||
.encoder(SConfigureBooleanPacket::encode)
|
||||
.consumer(SConfigureBooleanPacket::execute)
|
||||
.add();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
package com.jozufozu.flywheel.config;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import net.minecraft.network.PacketBuffer;
|
||||
import net.minecraftforge.fml.network.NetworkEvent;
|
||||
|
||||
import java.util.function.Supplier;
|
||||
|
||||
/**
|
||||
* Thanks, @zelophed
|
||||
*/
|
||||
|
@ -29,8 +29,10 @@ public class SConfigureBooleanPacket {
|
|||
}
|
||||
|
||||
public void execute(Supplier<NetworkEvent.Context> ctx) {
|
||||
target.receiver.get().accept(directive);
|
||||
ctx.get().setPacketHandled(true);
|
||||
target.receiver.get()
|
||||
.accept(directive);
|
||||
ctx.get()
|
||||
.setPacketHandled(true);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -30,8 +30,7 @@ public class AtlasStitcher {
|
|||
public void onTextureStitch(TextureStitchEvent.Pre event) {
|
||||
if (!event.getMap()
|
||||
.getId()
|
||||
.equals(PlayerContainer.BLOCK_ATLAS_TEXTURE))
|
||||
return;
|
||||
.equals(PlayerContainer.BLOCK_ATLAS_TEXTURE)) return;
|
||||
|
||||
sprites.forEach(StitchedSprite::reset);
|
||||
sprites.stream()
|
||||
|
|
|
@ -13,8 +13,6 @@ import com.jozufozu.flywheel.event.GatherContextEvent;
|
|||
import net.minecraft.util.ResourceLocation;
|
||||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
import net.minecraftforge.eventbus.api.SubscribeEvent;
|
||||
import net.minecraftforge.fml.common.Mod;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
public class Contexts {
|
||||
|
@ -31,15 +29,13 @@ public class Contexts {
|
|||
SpecMetaRegistry.register(WorldFog.LINEAR);
|
||||
SpecMetaRegistry.register(WorldFog.EXP2);
|
||||
|
||||
CRUMBLING = backend.register(new WorldContext<>(backend, CrumblingProgram::new)
|
||||
.withName(Names.CRUMBLING)
|
||||
.withBuiltin(ShaderType.FRAGMENT, Names.CRUMBLING, "/builtin.frag")
|
||||
.withBuiltin(ShaderType.VERTEX, Names.CRUMBLING, "/builtin.vert"));
|
||||
CRUMBLING = backend.register(new WorldContext<>(backend, CrumblingProgram::new).withName(Names.CRUMBLING)
|
||||
.withBuiltin(ShaderType.FRAGMENT, Names.CRUMBLING, "/builtin.frag")
|
||||
.withBuiltin(ShaderType.VERTEX, Names.CRUMBLING, "/builtin.vert"));
|
||||
|
||||
WORLD = backend.register(new WorldContext<>(backend, WorldProgram::new)
|
||||
.withName(Names.WORLD)
|
||||
.withBuiltin(ShaderType.FRAGMENT, Names.WORLD, "/builtin.frag")
|
||||
.withBuiltin(ShaderType.VERTEX, Names.WORLD, "/builtin.vert"));
|
||||
WORLD = backend.register(new WorldContext<>(backend, WorldProgram::new).withName(Names.WORLD)
|
||||
.withBuiltin(ShaderType.FRAGMENT, Names.WORLD, "/builtin.frag")
|
||||
.withBuiltin(ShaderType.VERTEX, Names.WORLD, "/builtin.vert"));
|
||||
}
|
||||
|
||||
public static class Names {
|
||||
|
|
|
@ -9,12 +9,9 @@ public class Formats {
|
|||
.addAttributes(CommonAttributes.VEC3, CommonAttributes.NORMAL, CommonAttributes.UV)
|
||||
.build();
|
||||
|
||||
public static final VertexFormat TRANSFORMED = litInstance()
|
||||
.addAttributes(MatrixAttributes.MAT4,
|
||||
MatrixAttributes.MAT3)
|
||||
public static final VertexFormat TRANSFORMED = litInstance().addAttributes(MatrixAttributes.MAT4, MatrixAttributes.MAT3)
|
||||
.build();
|
||||
public static final VertexFormat ORIENTED = litInstance()
|
||||
.addAttributes(CommonAttributes.VEC3, CommonAttributes.VEC3, CommonAttributes.QUATERNION)
|
||||
public static final VertexFormat ORIENTED = litInstance().addAttributes(CommonAttributes.VEC3, CommonAttributes.VEC3, CommonAttributes.QUATERNION)
|
||||
.build();
|
||||
|
||||
public static VertexFormat.Builder litInstance() {
|
||||
|
|
|
@ -15,14 +15,9 @@ public class FullscreenQuad {
|
|||
|
||||
private static final float[] vertices = {
|
||||
// pos // tex
|
||||
-1.0f, -1.0f, 0.0f, 0.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f,
|
||||
-1.0f, 1.0f, 0.0f, 1.0f,
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f,
|
||||
|
||||
-1.0f, -1.0f, 0.0f, 0.0f,
|
||||
1.0f, -1.0f, 1.0f, 0.0f,
|
||||
1.0f, 1.0f, 1.0f, 1.0f
|
||||
};
|
||||
-1.0f, -1.0f, 0.0f, 0.0f, 1.0f, -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f, 1.0f};
|
||||
|
||||
private static final int bufferSize = vertices.length * 4;
|
||||
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
package com.jozufozu.flywheel.core;
|
||||
|
||||
import com.jozufozu.flywheel.backend.Backend;
|
||||
import com.jozufozu.flywheel.backend.instancing.MaterialSpec;
|
||||
import com.jozufozu.flywheel.core.materials.ModelData;
|
||||
import com.jozufozu.flywheel.core.materials.OrientedData;
|
||||
|
@ -16,8 +15,10 @@ public class Materials {
|
|||
public static final MaterialSpec<ModelData> TRANSFORMED = new MaterialSpec<>(Locations.MODEL, Programs.TRANSFORMED, Formats.UNLIT_MODEL, Formats.TRANSFORMED, ModelData::new);
|
||||
|
||||
public static void flwInit(GatherContextEvent event) {
|
||||
event.getBackend().register(ORIENTED);
|
||||
event.getBackend().register(TRANSFORMED);
|
||||
event.getBackend()
|
||||
.register(ORIENTED);
|
||||
event.getBackend()
|
||||
.register(TRANSFORMED);
|
||||
}
|
||||
|
||||
public static class Locations {
|
||||
|
|
|
@ -82,7 +82,8 @@ public class QuadConverter {
|
|||
}
|
||||
|
||||
public void free() {
|
||||
ebos.values().forEach(GlBuffer::delete);
|
||||
ebos.values()
|
||||
.forEach(GlBuffer::delete);
|
||||
ebos.clear();
|
||||
initCapacities();
|
||||
}
|
||||
|
@ -100,7 +101,8 @@ public class QuadConverter {
|
|||
ByteBuffer indices;
|
||||
if (bytes > stack.getSize()) {
|
||||
indices = MemoryUtil.memAlloc(bytes); // not enough space on the preallocated stack
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
stack.push();
|
||||
indices = stack.malloc(bytes);
|
||||
}
|
||||
|
@ -117,7 +119,8 @@ public class QuadConverter {
|
|||
|
||||
if (bytes > stack.getSize()) {
|
||||
MemoryUtil.memFree(indices);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
stack.pop();
|
||||
}
|
||||
|
||||
|
|
|
@ -102,8 +102,7 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
|||
}
|
||||
|
||||
template = templateFactory.create(backend.sources);
|
||||
transformer = new ShaderTransformer()
|
||||
.pushStage(this::injectBuiltins)
|
||||
transformer = new ShaderTransformer().pushStage(this::injectBuiltins)
|
||||
.pushStage(Shader::processIncludes)
|
||||
.pushStage(template)
|
||||
.pushStage(Shader::processIncludes);
|
||||
|
@ -150,8 +149,7 @@ public class WorldContext<P extends WorldProgram> extends ShaderContext<P> {
|
|||
public void injectBuiltins(Shader shader) {
|
||||
Matcher matcher = builtinPattern.matcher(shader.getSource());
|
||||
|
||||
if (matcher.find())
|
||||
shader.setSource(matcher.replaceFirst(builtinSources.get(shader.type)));
|
||||
if (matcher.find()) shader.setSource(matcher.replaceFirst(builtinSources.get(shader.type)));
|
||||
else
|
||||
throw new ShaderLoadingException(String.format("%s is missing %s, cannot use in World Context", shader.type.name, declaration));
|
||||
}
|
||||
|
|
|
@ -38,7 +38,8 @@ public class ConditionalInstance<D extends InstanceData> {
|
|||
if (shouldShow && instance == null) {
|
||||
instance = model.createInstance();
|
||||
if (setupFunc != null) setupFunc.accept(instance);
|
||||
} else if (!shouldShow && instance != null) {
|
||||
}
|
||||
else if (!shouldShow && instance != null) {
|
||||
instance.delete();
|
||||
instance = null;
|
||||
}
|
||||
|
|
|
@ -46,7 +46,8 @@ public class GroupInstance<D extends InstanceData> extends AbstractCollection<D>
|
|||
for (int i = size; i < count; i++) {
|
||||
addInstance();
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
List<D> unnecessary = backing.subList(count, size);
|
||||
unnecessary.forEach(InstanceData::delete);
|
||||
unnecessary.clear();
|
||||
|
|
|
@ -37,10 +37,12 @@ public class SelectInstance<D extends InstanceData> {
|
|||
current.delete();
|
||||
current = null;
|
||||
}
|
||||
} else if (i != last) {
|
||||
}
|
||||
else if (i != last) {
|
||||
if (current != null) current.delete();
|
||||
|
||||
current = models.get(i).createInstance();
|
||||
current = models.get(i)
|
||||
.createInstance();
|
||||
}
|
||||
|
||||
last = i;
|
||||
|
|
|
@ -44,7 +44,8 @@ public abstract class BasicData extends InstanceData implements IFlatLight<Basic
|
|||
if (alpha) {
|
||||
byte a = (byte) ((color >> 24) & 0xFF);
|
||||
return setColor(r, g, b, a);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
return setColor(r, g, b);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -82,18 +82,7 @@ public class OrientedData extends BasicData {
|
|||
public void write(MappedBuffer buf) {
|
||||
super.write(buf);
|
||||
|
||||
buf.putFloatArray(new float[]{
|
||||
posX,
|
||||
posY,
|
||||
posZ,
|
||||
pivotX,
|
||||
pivotY,
|
||||
pivotZ,
|
||||
qX,
|
||||
qY,
|
||||
qZ,
|
||||
qW
|
||||
});
|
||||
buf.putFloatArray(new float[]{posX, posY, posZ, pivotX, pivotY, pivotZ, qX, qY, qZ, qW});
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -35,7 +35,8 @@ public class ExtensibleGlProgram extends GlProgram {
|
|||
list.add(extension);
|
||||
}
|
||||
this.extensions = list;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
this.extensions = Collections.emptyList();
|
||||
}
|
||||
}
|
||||
|
@ -51,12 +52,12 @@ public class ExtensibleGlProgram extends GlProgram {
|
|||
public String toString() {
|
||||
StringBuilder builder = new StringBuilder();
|
||||
builder.append("program ")
|
||||
.append(name)
|
||||
.append('[');
|
||||
.append(name)
|
||||
.append('[');
|
||||
|
||||
for (IExtensionInstance extension : extensions) {
|
||||
builder.append(extension)
|
||||
.append('+');
|
||||
.append('+');
|
||||
}
|
||||
|
||||
builder.append(']');
|
||||
|
|
|
@ -35,13 +35,13 @@ public class GlFog {
|
|||
int mode = getFogModeGlEnum();
|
||||
|
||||
switch (mode) {
|
||||
case GL11.GL_EXP2:
|
||||
case GL11.GL_EXP:
|
||||
return WorldFog.EXP2;
|
||||
case GL11.GL_LINEAR:
|
||||
return WorldFog.LINEAR;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown fog mode: " + mode);
|
||||
case GL11.GL_EXP2:
|
||||
case GL11.GL_EXP:
|
||||
return WorldFog.EXP2;
|
||||
case GL11.GL_LINEAR:
|
||||
return WorldFog.LINEAR;
|
||||
default:
|
||||
throw new UnsupportedOperationException("Unknown fog mode: " + mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,8 +34,8 @@ public class StateSensitiveMultiProgram<P extends GlProgram> implements IMultiPr
|
|||
@Override
|
||||
public P get() {
|
||||
for (Pair<IContextCondition, P> variant : variants) {
|
||||
if (variant.getFirst().get())
|
||||
return variant.getSecond();
|
||||
if (variant.getFirst()
|
||||
.get()) return variant.getSecond();
|
||||
}
|
||||
|
||||
return fallback;
|
||||
|
@ -44,7 +44,8 @@ public class StateSensitiveMultiProgram<P extends GlProgram> implements IMultiPr
|
|||
@Override
|
||||
public void delete() {
|
||||
for (Pair<IContextCondition, P> variant : variants) {
|
||||
variant.getSecond().delete();
|
||||
variant.getSecond()
|
||||
.delete();
|
||||
}
|
||||
|
||||
fallback.delete();
|
||||
|
|
|
@ -7,8 +7,8 @@ import java.util.List;
|
|||
|
||||
import com.jozufozu.flywheel.backend.loading.Program;
|
||||
import com.jozufozu.flywheel.core.shader.extension.IProgramExtension;
|
||||
|
||||
import com.jozufozu.flywheel.util.AnimationTickHolder;
|
||||
|
||||
import net.minecraft.util.math.vector.Matrix4f;
|
||||
|
||||
public class WorldProgram extends ExtensibleGlProgram {
|
||||
|
|
|
@ -9,7 +9,8 @@ public class UnitExtensionInstance implements IExtensionInstance {
|
|||
|
||||
public static final ResourceLocation NAME = new ResourceLocation(Flywheel.ID, "unit");
|
||||
|
||||
public UnitExtensionInstance(GlProgram program) { }
|
||||
public UnitExtensionInstance(GlProgram program) {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void bind() {
|
||||
|
|
|
@ -17,7 +17,8 @@ public class NormalDebugStateProvider implements IBooleanStateProvider {
|
|||
|
||||
@Override
|
||||
public boolean isTrue() {
|
||||
return FlwConfig.get().normalOverlayEnabled();
|
||||
return FlwConfig.get()
|
||||
.normalOverlayEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -12,16 +12,12 @@ import net.minecraft.util.ResourceLocation;
|
|||
public class ProgramSpec {
|
||||
|
||||
// TODO: Block model style inheritance?
|
||||
public static final Codec<ProgramSpec> CODEC = RecordCodecBuilder.create(instance ->
|
||||
instance.group(
|
||||
ResourceLocation.CODEC.fieldOf("vert")
|
||||
.forGetter(ProgramSpec::getVert),
|
||||
ResourceLocation.CODEC.fieldOf("frag")
|
||||
.forGetter(ProgramSpec::getFrag),
|
||||
ProgramState.CODEC.listOf()
|
||||
.optionalFieldOf("states", Collections.emptyList())
|
||||
.forGetter(ProgramSpec::getStates)
|
||||
).apply(instance, ProgramSpec::new));
|
||||
public static final Codec<ProgramSpec> CODEC = RecordCodecBuilder.create(instance -> instance.group(ResourceLocation.CODEC.fieldOf("vert")
|
||||
.forGetter(ProgramSpec::getVert), ResourceLocation.CODEC.fieldOf("frag")
|
||||
.forGetter(ProgramSpec::getFrag), ProgramState.CODEC.listOf()
|
||||
.optionalFieldOf("states", Collections.emptyList())
|
||||
.forGetter(ProgramSpec::getStates))
|
||||
.apply(instance, ProgramSpec::new));
|
||||
|
||||
public ResourceLocation name;
|
||||
public final ResourceLocation vert;
|
||||
|
|
|
@ -13,35 +13,26 @@ import com.mojang.serialization.codecs.RecordCodecBuilder;
|
|||
public class ProgramState {
|
||||
|
||||
// TODO: Use Codec.dispatch
|
||||
private static final Codec<IContextCondition> WHEN = Codec.either(
|
||||
BooleanContextCondition.BOOLEAN_SUGAR,
|
||||
SpecificValueCondition.CODEC
|
||||
).flatXmap(
|
||||
either -> either.map(DataResult::success, DataResult::success),
|
||||
any -> {
|
||||
if (any instanceof BooleanContextCondition) {
|
||||
return DataResult.success(Either.left((BooleanContextCondition) any));
|
||||
}
|
||||
private static final Codec<IContextCondition> WHEN = Codec.either(BooleanContextCondition.BOOLEAN_SUGAR, SpecificValueCondition.CODEC)
|
||||
.flatXmap(either -> either.map(DataResult::success, DataResult::success), any -> {
|
||||
if (any instanceof BooleanContextCondition) {
|
||||
return DataResult.success(Either.left((BooleanContextCondition) any));
|
||||
}
|
||||
|
||||
if (any instanceof SpecificValueCondition) {
|
||||
return DataResult.success(Either.right((SpecificValueCondition) any));
|
||||
}
|
||||
if (any instanceof SpecificValueCondition) {
|
||||
return DataResult.success(Either.right((SpecificValueCondition) any));
|
||||
}
|
||||
|
||||
return DataResult.error("unknown context condition");
|
||||
}
|
||||
);
|
||||
return DataResult.error("unknown context condition");
|
||||
});
|
||||
|
||||
public static final Codec<ProgramState> CODEC = RecordCodecBuilder.create(state ->
|
||||
state.group(
|
||||
WHEN.fieldOf("when")
|
||||
.forGetter(ProgramState::getContext),
|
||||
CodecUtil.oneOrMore(Codec.STRING)
|
||||
.optionalFieldOf("define", Collections.emptyList())
|
||||
.forGetter(ProgramState::getDefines),
|
||||
CodecUtil.oneOrMore(IProgramExtension.CODEC)
|
||||
.optionalFieldOf("extend", Collections.emptyList())
|
||||
.forGetter(ProgramState::getExtensions)
|
||||
).apply(state, ProgramState::new));
|
||||
public static final Codec<ProgramState> CODEC = RecordCodecBuilder.create(state -> state.group(WHEN.fieldOf("when")
|
||||
.forGetter(ProgramState::getContext), CodecUtil.oneOrMore(Codec.STRING)
|
||||
.optionalFieldOf("define", Collections.emptyList())
|
||||
.forGetter(ProgramState::getDefines), CodecUtil.oneOrMore(IProgramExtension.CODEC)
|
||||
.optionalFieldOf("extend", Collections.emptyList())
|
||||
.forGetter(ProgramState::getExtensions))
|
||||
.apply(state, ProgramState::new));
|
||||
|
||||
private final IContextCondition context;
|
||||
private final List<String> defines;
|
||||
|
|
|
@ -8,10 +8,10 @@ import net.minecraft.util.ResourceLocation;
|
|||
|
||||
public class SpecificValueCondition implements IContextCondition {
|
||||
|
||||
public static final Codec<SpecificValueCondition> CODEC = RecordCodecBuilder.create(condition -> condition.group(
|
||||
IGameStateProvider.CODEC.fieldOf("provider").forGetter(SpecificValueCondition::contextProvider),
|
||||
Codec.STRING.fieldOf("value").forGetter(SpecificValueCondition::getValue)
|
||||
).apply(condition, SpecificValueCondition::new));
|
||||
public static final Codec<SpecificValueCondition> CODEC = RecordCodecBuilder.create(condition -> condition.group(IGameStateProvider.CODEC.fieldOf("provider")
|
||||
.forGetter(SpecificValueCondition::contextProvider), Codec.STRING.fieldOf("value")
|
||||
.forGetter(SpecificValueCondition::getValue))
|
||||
.apply(condition, SpecificValueCondition::new));
|
||||
|
||||
private final String required;
|
||||
private final IGameStateProvider context;
|
||||
|
@ -37,6 +37,7 @@ public class SpecificValueCondition implements IContextCondition {
|
|||
|
||||
@Override
|
||||
public boolean get() {
|
||||
return required.equals(context.getValue().toString());
|
||||
return required.equals(context.getValue()
|
||||
.toString());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,15 +13,13 @@ public class EntityWorldHandler {
|
|||
|
||||
@SubscribeEvent
|
||||
public static void onEntityJoinWorld(EntityJoinWorldEvent event) {
|
||||
if (event.getWorld().isRemote)
|
||||
InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||
.queueAdd(event.getEntity());
|
||||
if (event.getWorld().isRemote) InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||
.queueAdd(event.getEntity());
|
||||
}
|
||||
|
||||
@SubscribeEvent
|
||||
public static void onEntityLeaveWorld(EntityLeaveWorldEvent event) {
|
||||
if (event.getWorld().isRemote)
|
||||
InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||
.remove(event.getEntity());
|
||||
if (event.getWorld().isRemote) InstancedRenderDispatcher.getEntities(event.getWorld())
|
||||
.remove(event.getEntity());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,11 +24,13 @@ public class ForgeEvents {
|
|||
|
||||
ArrayList<String> right = event.getRight();
|
||||
|
||||
String text = "Flywheel: " + Backend.getInstance().getBackendDescriptor();
|
||||
String text = "Flywheel: " + Backend.getInstance()
|
||||
.getBackendDescriptor();
|
||||
if (right.size() < 10) {
|
||||
right.add("");
|
||||
right.add(text);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
right.add(9, "");
|
||||
right.add(10, text);
|
||||
}
|
||||
|
|
|
@ -46,32 +46,17 @@ public class GridAlignedBB {
|
|||
}
|
||||
|
||||
public static GridAlignedBB from(SectionPos pos) {
|
||||
return new GridAlignedBB(pos.getWorldStartX(),
|
||||
pos.getWorldStartY(),
|
||||
pos.getWorldStartZ(),
|
||||
pos.getWorldEndX() + 1,
|
||||
pos.getWorldEndY() + 1,
|
||||
pos.getWorldEndZ() + 1);
|
||||
return new GridAlignedBB(pos.getWorldStartX(), pos.getWorldStartY(), pos.getWorldStartZ(), pos.getWorldEndX() + 1, pos.getWorldEndY() + 1, pos.getWorldEndZ() + 1);
|
||||
}
|
||||
|
||||
public static GridAlignedBB from(BlockPos start, BlockPos end) {
|
||||
return new GridAlignedBB(start.getX(),
|
||||
start.getY(),
|
||||
start.getZ(),
|
||||
end.getX() + 1,
|
||||
end.getY() + 1,
|
||||
end.getZ() + 1);
|
||||
return new GridAlignedBB(start.getX(), start.getY(), start.getZ(), end.getX() + 1, end.getY() + 1, end.getZ() + 1);
|
||||
}
|
||||
|
||||
public static GridAlignedBB from(int sectionX, int sectionZ) {
|
||||
int startX = sectionX << 4;
|
||||
int startZ = sectionZ << 4;
|
||||
return new GridAlignedBB(startX,
|
||||
0,
|
||||
startZ,
|
||||
startX + 16,
|
||||
256,
|
||||
startZ + 16);
|
||||
return new GridAlignedBB(startX, 0, startZ, startX + 16, 256, startZ + 16);
|
||||
}
|
||||
|
||||
public static AxisAlignedBB toAABB(GridAlignedBB bb) {
|
||||
|
@ -83,12 +68,7 @@ public class GridAlignedBB {
|
|||
}
|
||||
|
||||
public boolean sameAs(GridAlignedBB other) {
|
||||
return minX == other.minX &&
|
||||
minY == other.minY &&
|
||||
minZ == other.minZ &&
|
||||
maxX == other.maxX &&
|
||||
maxY == other.maxY &&
|
||||
maxZ == other.maxZ;
|
||||
return minX == other.minX && minY == other.minY && minZ == other.minZ && maxX == other.maxX && maxY == other.maxY && maxZ == other.maxZ;
|
||||
}
|
||||
|
||||
public void fixMinMax() {
|
||||
|
@ -125,9 +105,7 @@ public class GridAlignedBB {
|
|||
|
||||
public boolean empty() {
|
||||
// if any dimension has side length 0 this box contains no volume
|
||||
return minX == maxX ||
|
||||
minY == maxY ||
|
||||
minZ == maxZ;
|
||||
return minX == maxX || minY == maxY || minZ == maxZ;
|
||||
}
|
||||
|
||||
public void translate(Vector3i by) {
|
||||
|
@ -144,7 +122,8 @@ public class GridAlignedBB {
|
|||
}
|
||||
|
||||
public void mirrorAbout(Direction.Axis axis) {
|
||||
Vector3i axisVec = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis).getDirectionVec();
|
||||
Vector3i axisVec = Direction.getFacingFromAxis(Direction.AxisDirection.POSITIVE, axis)
|
||||
.getDirectionVec();
|
||||
int flipX = axisVec.getX() - 1;
|
||||
int flipY = axisVec.getY() - 1;
|
||||
int flipZ = axisVec.getZ() - 1;
|
||||
|
@ -267,12 +246,7 @@ public class GridAlignedBB {
|
|||
}
|
||||
|
||||
public boolean contains(GridAlignedBB other) {
|
||||
return other.minX >= this.minX &&
|
||||
other.maxX <= this.maxX &&
|
||||
other.minY >= this.minY &&
|
||||
other.maxY <= this.maxY &&
|
||||
other.minZ >= this.minZ &&
|
||||
other.maxZ <= this.maxZ;
|
||||
return other.minX >= this.minX && other.maxX <= this.maxX && other.minY >= this.minY && other.maxY <= this.maxY && other.minZ >= this.minZ && other.maxZ <= this.maxZ;
|
||||
}
|
||||
|
||||
public boolean isContainedBy(GridAlignedBB other) {
|
||||
|
|
|
@ -24,8 +24,7 @@ public interface ILightUpdateListener {
|
|||
default boolean onLightPacket(IBlockDisplayReader world, int chunkX, int chunkZ) {
|
||||
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
|
||||
|
||||
if (onLightUpdate(world, LightType.BLOCK, changedVolume))
|
||||
return true;
|
||||
if (onLightUpdate(world, LightType.BLOCK, changedVolume)) return true;
|
||||
|
||||
return onLightUpdate(world, LightType.SKY, changedVolume);
|
||||
}
|
||||
|
|
|
@ -27,8 +27,7 @@ public class LightUpdater {
|
|||
private static LightUpdater instance;
|
||||
|
||||
public static LightUpdater getInstance() {
|
||||
if (instance == null)
|
||||
instance = new LightUpdater();
|
||||
if (instance == null) instance = new LightUpdater();
|
||||
|
||||
return instance;
|
||||
}
|
||||
|
@ -151,7 +150,8 @@ public class LightUpdater {
|
|||
if (set == null) {
|
||||
set = new LongRBTreeSet();
|
||||
listeners.put(listener, set);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
set.forEach((LongConsumer) l -> {
|
||||
WeakHashSet<ILightUpdateListener> listeningSections = lookup.get(l);
|
||||
|
||||
|
|
|
@ -126,11 +126,13 @@ public class LightVolume {
|
|||
sampleVolume = newSampleVolume;
|
||||
|
||||
copyLight(world, newArea);
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
sampleVolume = newSampleVolume;
|
||||
initialize(world);
|
||||
}
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
setSampleVolume(newSampleVolume);
|
||||
int volume = textureVolume.volume();
|
||||
if (volume * 2 > lightData.capacity()) {
|
||||
|
@ -141,11 +143,9 @@ public class LightVolume {
|
|||
}
|
||||
|
||||
public void notifyLightUpdate(IBlockDisplayReader world, LightType type, GridAlignedBB changedVolume) {
|
||||
if (removed)
|
||||
return;
|
||||
if (removed) return;
|
||||
|
||||
if (!changedVolume.intersects(sampleVolume))
|
||||
return;
|
||||
if (!changedVolume.intersects(sampleVolume)) return;
|
||||
changedVolume = changedVolume.intersect(sampleVolume); // compute the region contained by us that has dirty lighting data.
|
||||
|
||||
if (type == LightType.BLOCK) copyBlock(world, changedVolume);
|
||||
|
@ -156,8 +156,7 @@ public class LightVolume {
|
|||
if (removed) return;
|
||||
|
||||
GridAlignedBB changedVolume = GridAlignedBB.from(chunkX, chunkZ);
|
||||
if (!changedVolume.intersects(sampleVolume))
|
||||
return;
|
||||
if (!changedVolume.intersects(sampleVolume)) return;
|
||||
changedVolume.intersectAssign(sampleVolume); // compute the region contained by us that has dirty lighting data.
|
||||
|
||||
copyLight(world, changedVolume);
|
||||
|
|
|
@ -24,7 +24,8 @@ public class CancelEntityRenderMixin {
|
|||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/world/ClientWorld;getAllEntities()Ljava/lang/Iterable;"))
|
||||
private Iterable<Entity> filterEntities(ClientWorld world) {
|
||||
Iterable<Entity> entities = world.getAllEntities();
|
||||
if (Backend.getInstance().canUseInstancing()) {
|
||||
if (Backend.getInstance()
|
||||
.canUseInstancing()) {
|
||||
|
||||
ArrayList<Entity> filtered = Lists.newArrayList(entities);
|
||||
filtered.removeIf(entity -> entity instanceof IInstanceRendered && !((IInstanceRendered) entity).shouldRenderNormally());
|
||||
|
@ -37,7 +38,8 @@ public class CancelEntityRenderMixin {
|
|||
@Group(name = "entityFilter")
|
||||
@Redirect(method = "render", at = @At(value = "INVOKE", target = "Lnet/minecraft/util/ClassInheritanceMultiMap;iterator()Ljava/util/Iterator;"))
|
||||
private Iterator<Entity> filterEntitiesOF(ClassInheritanceMultiMap<Entity> classInheritanceMultiMap) {
|
||||
if (Backend.getInstance().canUseInstancing()) {
|
||||
if (Backend.getInstance()
|
||||
.canUseInstancing()) {
|
||||
|
||||
ArrayList<Entity> filtered = Lists.newArrayList(classInheritanceMultiMap);
|
||||
filtered.removeIf(entity -> entity instanceof IInstanceRendered && !((IInstanceRendered) entity).shouldRenderNormally());
|
||||
|
|
|
@ -27,7 +27,8 @@ public class CancelTileEntityRenderMixin {
|
|||
*/
|
||||
@Inject(at = @At("RETURN"), method = "getTileEntities", cancellable = true)
|
||||
private void noRenderInstancedTiles(CallbackInfoReturnable<List<TileEntity>> cir) {
|
||||
if (Backend.getInstance().canUseInstancing()) {
|
||||
if (Backend.getInstance()
|
||||
.canUseInstancing()) {
|
||||
List<TileEntity> tiles = cir.getReturnValue();
|
||||
|
||||
tiles.removeIf(tile -> tile instanceof IInstanceRendered && !((IInstanceRendered) tile).shouldRenderNormally());
|
||||
|
|
|
@ -1,5 +1,10 @@
|
|||
package com.jozufozu.flywheel.mixin;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
import com.mojang.blaze3d.matrix.MatrixStack;
|
||||
import com.mojang.blaze3d.platform.GlStateManager;
|
||||
|
||||
|
@ -11,11 +16,6 @@ import net.minecraft.util.math.vector.Matrix4f;
|
|||
import net.minecraftforge.api.distmarker.Dist;
|
||||
import net.minecraftforge.api.distmarker.OnlyIn;
|
||||
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.injection.At;
|
||||
import org.spongepowered.asm.mixin.injection.Inject;
|
||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||
|
||||
@OnlyIn(Dist.CLIENT)
|
||||
@Mixin(WorldRenderer.class)
|
||||
public class FixFabulousDepthMixin {
|
||||
|
|
|
@ -1,5 +1,7 @@
|
|||
package com.jozufozu.flywheel.mixin;
|
||||
|
||||
import com.jozufozu.flywheel.backend.OptifineHandler;
|
||||
|
||||
import org.lwjgl.opengl.GL20;
|
||||
import org.spongepowered.asm.mixin.Mixin;
|
||||
import org.spongepowered.asm.mixin.Shadow;
|
||||
|
@ -36,9 +38,7 @@ public class RenderHooksMixin {
|
|||
private ClientWorld world;
|
||||
|
||||
@Inject(at = @At(value = "INVOKE", target = "net.minecraft.client.renderer.WorldRenderer.updateChunks(J)V"), method = "render")
|
||||
private void setupFrame(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_,
|
||||
ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_,
|
||||
CallbackInfo ci) {
|
||||
private void setupFrame(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_, CallbackInfo ci) {
|
||||
MinecraftForge.EVENT_BUS.post(new BeginFrameEvent(world, stack, info, gameRenderer, lightTexture));
|
||||
}
|
||||
|
||||
|
@ -48,12 +48,12 @@ public class RenderHooksMixin {
|
|||
* This should probably be a forge event.
|
||||
*/
|
||||
@Inject(at = @At("TAIL"), method = "renderLayer")
|
||||
private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ,
|
||||
CallbackInfo ci) {
|
||||
private void renderLayer(RenderType type, MatrixStack stack, double camX, double camY, double camZ, CallbackInfo ci) {
|
||||
Matrix4f view = stack.peek()
|
||||
.getModel();
|
||||
Matrix4f viewProjection = view.copy();
|
||||
viewProjection.multiplyBackward(Backend.getInstance().getProjectionMatrix());
|
||||
viewProjection.multiplyBackward(Backend.getInstance()
|
||||
.getProjectionMatrix());
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new RenderLayerEvent(world, type, viewProjection, camX, camY, camZ));
|
||||
GL20.glUseProgram(0);
|
||||
|
@ -61,33 +61,30 @@ public class RenderHooksMixin {
|
|||
|
||||
@Inject(at = @At("TAIL"), method = "loadRenderers")
|
||||
private void refresh(CallbackInfo ci) {
|
||||
Backend.getInstance().refresh();
|
||||
Backend.getInstance()
|
||||
.refresh();
|
||||
|
||||
MinecraftForge.EVENT_BUS.post(new ReloadRenderersEvent(world));
|
||||
}
|
||||
|
||||
|
||||
@Inject(at =
|
||||
@At(
|
||||
value = "INVOKE",
|
||||
target = "Lnet/minecraft/client/renderer/WorldRenderer;checkEmpty(Lcom/mojang/blaze3d/matrix/MatrixStack;)V",
|
||||
ordinal = 2 // after the game renders the breaking overlay normally
|
||||
),
|
||||
method = "render")
|
||||
private void renderBlockBreaking(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_,
|
||||
ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_,
|
||||
CallbackInfo ci) {
|
||||
if (!Backend.getInstance().available())
|
||||
return;
|
||||
@Inject(at = @At(value = "INVOKE", target = "Lnet/minecraft/client/renderer/WorldRenderer;checkEmpty(Lcom/mojang/blaze3d/matrix/MatrixStack;)V", ordinal = 2 // after the game renders the breaking overlay normally
|
||||
), method = "render")
|
||||
private void renderBlockBreaking(MatrixStack stack, float p_228426_2_, long p_228426_3_, boolean p_228426_5_, ActiveRenderInfo info, GameRenderer gameRenderer, LightTexture lightTexture, Matrix4f p_228426_9_, CallbackInfo ci) {
|
||||
if (!Backend.getInstance()
|
||||
.available()) return;
|
||||
|
||||
Matrix4f view = stack.peek()
|
||||
.getModel();
|
||||
Matrix4f viewProjection = view.copy();
|
||||
viewProjection.multiplyBackward(Backend.getInstance().getProjectionMatrix());
|
||||
viewProjection.multiplyBackward(Backend.getInstance()
|
||||
.getProjectionMatrix());
|
||||
|
||||
Vector3d cameraPos = info.getProjectedView();
|
||||
InstancedRenderDispatcher.renderBreaking(world, viewProjection, cameraPos.x, cameraPos.y, cameraPos.z);
|
||||
GL20.glUseProgram(0);
|
||||
|
||||
if (!OptifineHandler.usingShaders())
|
||||
GL20.glUseProgram(0);
|
||||
}
|
||||
|
||||
// Instancing
|
||||
|
|
|
@ -26,8 +26,8 @@ public class ShaderCloseMixin {
|
|||
if (OptifineHandler.optifineInstalled() && screen instanceof VideoSettingsScreen) {
|
||||
Screen old = this.currentScreen;
|
||||
if (old != null && old.getClass()
|
||||
.getName()
|
||||
.startsWith(OptifineHandler.SHADER_PACKAGE)) {
|
||||
.getName()
|
||||
.startsWith(OptifineHandler.SHADER_PACKAGE)) {
|
||||
OptifineHandler.refresh();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,8 @@ public abstract class StoreProjectionMatrixMixin {
|
|||
@Inject(method = "loadProjectionMatrix", at = @At("TAIL"))
|
||||
private void onProjectionMatrixLoad(Matrix4f projection, CallbackInfo ci) {
|
||||
if (shouldCopy) {
|
||||
Backend.getInstance().setProjectionMatrix(projection.copy());
|
||||
Backend.getInstance()
|
||||
.setProjectionMatrix(projection.copy());
|
||||
shouldCopy = false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,8 +23,7 @@ public class TileRemoveMixin {
|
|||
|
||||
@Inject(at = @At("TAIL"), method = "remove")
|
||||
private void onRemove(CallbackInfo ci) {
|
||||
if (world instanceof ClientWorld)
|
||||
InstancedRenderDispatcher.getTiles(this.world)
|
||||
.remove((TileEntity) (Object) this);
|
||||
if (world instanceof ClientWorld) InstancedRenderDispatcher.getTiles(this.world)
|
||||
.remove((TileEntity) (Object) this);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -43,16 +43,15 @@ public abstract class LightUpdateMixin extends AbstractChunkProvider {
|
|||
.entrySet()
|
||||
.stream()
|
||||
.filter(entry -> SectionPos.toChunk(entry.getKey()
|
||||
.getY()) == sectionY)
|
||||
.getY()) == sectionY)
|
||||
.map(Map.Entry::getValue)
|
||||
.forEach(InstancedRenderDispatcher.getTiles(world)::onLightUpdate);
|
||||
|
||||
if (sectionY >= 0) // TODO: 1.17
|
||||
chunk.getEntityLists()[sectionY]
|
||||
.forEach(InstancedRenderDispatcher.getEntities(world)::onLightUpdate);
|
||||
chunk.getEntityLists()[sectionY].forEach(InstancedRenderDispatcher.getEntities(world)::onLightUpdate);
|
||||
}
|
||||
|
||||
LightUpdater.getInstance()
|
||||
.onLightUpdate(world, type, pos.asLong());
|
||||
.onLightUpdate(world, type, pos.asLong());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,14 +26,13 @@ public class NetworkLightUpdateMixin {
|
|||
RenderWork.enqueue(() -> {
|
||||
ClientWorld world = Minecraft.getInstance().world;
|
||||
|
||||
if (world == null)
|
||||
return;
|
||||
if (world == null) return;
|
||||
|
||||
int chunkX = packet.getChunkX();
|
||||
int chunkZ = packet.getChunkZ();
|
||||
|
||||
Chunk chunk = world.getChunkProvider()
|
||||
.getChunk(chunkX, chunkZ, false);
|
||||
.getChunk(chunkX, chunkZ, false);
|
||||
|
||||
if (chunk != null) {
|
||||
chunk.getTileEntityMap()
|
||||
|
@ -46,7 +45,7 @@ public class NetworkLightUpdateMixin {
|
|||
}
|
||||
|
||||
LightUpdater.getInstance()
|
||||
.onLightPacket(world, chunkX, chunkZ);
|
||||
.onLightPacket(world, chunkX, chunkZ);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,8 +10,7 @@ public class AngleHelper {
|
|||
*/
|
||||
public static float horizontalAngle(Direction facing) {
|
||||
float angle = facing.getHorizontalAngle();
|
||||
if (facing.getAxis() == Axis.X)
|
||||
angle = -angle;
|
||||
if (facing.getAxis() == Axis.X) angle = -angle;
|
||||
return angle;
|
||||
}
|
||||
|
||||
|
@ -19,12 +18,12 @@ public class AngleHelper {
|
|||
* Same as {@link #horizontalAngle(Direction)}, but returns 0 instead of -90 for vertical directions.
|
||||
*/
|
||||
public static float horizontalAngleNew(Direction facing) {
|
||||
if (facing.getAxis().isVertical()) {
|
||||
if (facing.getAxis()
|
||||
.isVertical()) {
|
||||
return 0;
|
||||
}
|
||||
float angle = facing.getHorizontalAngle();
|
||||
if (facing.getAxis() == Axis.X)
|
||||
angle = -angle;
|
||||
if (facing.getAxis() == Axis.X) angle = -angle;
|
||||
return angle;
|
||||
}
|
||||
|
||||
|
@ -33,14 +32,12 @@ public class AngleHelper {
|
|||
}
|
||||
|
||||
public static float rad(double angle) {
|
||||
if (angle == 0)
|
||||
return 0;
|
||||
if (angle == 0) return 0;
|
||||
return (float) (angle / 180 * Math.PI);
|
||||
}
|
||||
|
||||
public static float deg(double angle) {
|
||||
if (angle == 0)
|
||||
return 0;
|
||||
if (angle == 0) return 0;
|
||||
return (float) (angle * 180 / Math.PI);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,41 +1,41 @@
|
|||
package com.jozufozu.flywheel.util;
|
||||
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.world.IWorld;
|
||||
|
||||
public class AnimationTickHolder {
|
||||
|
||||
private static int ticks;
|
||||
private static int paused_ticks;
|
||||
private static int ticks;
|
||||
private static int paused_ticks;
|
||||
|
||||
public static void reset() {
|
||||
ticks = 0;
|
||||
paused_ticks = 0;
|
||||
}
|
||||
public static void reset() {
|
||||
ticks = 0;
|
||||
paused_ticks = 0;
|
||||
}
|
||||
|
||||
public static void tick() {
|
||||
if (!Minecraft.getInstance()
|
||||
.isGamePaused()) {
|
||||
ticks = (ticks + 1) % 1_728_000; // wrap around every 24 hours so we maintain enough floating point precision
|
||||
} else {
|
||||
paused_ticks = (paused_ticks + 1) % 1_728_000;
|
||||
}
|
||||
}
|
||||
public static void tick() {
|
||||
if (!Minecraft.getInstance()
|
||||
.isGamePaused()) {
|
||||
ticks = (ticks + 1) % 1_728_000; // wrap around every 24 hours so we maintain enough floating point precision
|
||||
}
|
||||
else {
|
||||
paused_ticks = (paused_ticks + 1) % 1_728_000;
|
||||
}
|
||||
}
|
||||
|
||||
public static int getTicks() {
|
||||
return getTicks(false);
|
||||
}
|
||||
public static int getTicks() {
|
||||
return getTicks(false);
|
||||
}
|
||||
|
||||
public static int getTicks(boolean includePaused) {
|
||||
return includePaused ? ticks + paused_ticks : ticks;
|
||||
}
|
||||
public static int getTicks(boolean includePaused) {
|
||||
return includePaused ? ticks + paused_ticks : ticks;
|
||||
}
|
||||
|
||||
public static float getRenderTime() {
|
||||
return getTicks() + getPartialTicks();
|
||||
}
|
||||
public static float getRenderTime() {
|
||||
return getTicks() + getPartialTicks();
|
||||
}
|
||||
|
||||
public static float getPartialTicks() {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
return (mc.isGamePaused() ? mc.renderPartialTicksPaused : mc.getRenderPartialTicks());
|
||||
}
|
||||
public static float getPartialTicks() {
|
||||
Minecraft mc = Minecraft.getInstance();
|
||||
return (mc.isGamePaused() ? mc.renderPartialTicksPaused : mc.getRenderPartialTicks());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -194,20 +194,26 @@ public class BakedQuadWrapper {
|
|||
|
||||
public void refresh() {
|
||||
vertexSize = FORMAT.getIntegerSize();
|
||||
for (int elementId = 0; elementId < FORMAT.getElements().size(); elementId++) {
|
||||
VertexFormatElement element = FORMAT.getElements().get(elementId);
|
||||
for (int elementId = 0; elementId < FORMAT.getElements()
|
||||
.size(); elementId++) {
|
||||
VertexFormatElement element = FORMAT.getElements()
|
||||
.get(elementId);
|
||||
int intOffset = FORMAT.getOffset(elementId) / Integer.BYTES;
|
||||
if (element.getUsage() == VertexFormatElement.Usage.POSITION) {
|
||||
position = intOffset;
|
||||
} else if (element.getUsage() == VertexFormatElement.Usage.COLOR) {
|
||||
}
|
||||
else if (element.getUsage() == VertexFormatElement.Usage.COLOR) {
|
||||
color = intOffset;
|
||||
} else if (element.getUsage() == VertexFormatElement.Usage.UV) {
|
||||
}
|
||||
else if (element.getUsage() == VertexFormatElement.Usage.UV) {
|
||||
if (element.getIndex() == 0) {
|
||||
texture = intOffset;
|
||||
} else if (element.getIndex() == 2) {
|
||||
}
|
||||
else if (element.getIndex() == 2) {
|
||||
light = intOffset;
|
||||
}
|
||||
} else if (element.getUsage() == VertexFormatElement.Usage.NORMAL) {
|
||||
}
|
||||
else if (element.getUsage() == VertexFormatElement.Usage.NORMAL) {
|
||||
normal = intOffset;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,13 +27,13 @@ public class BufferBuilderReader {
|
|||
size = vertexCount * formatSize;
|
||||
|
||||
// TODO: adjust the getters based on the input format
|
||||
// ImmutableList<VertexFormatElement> elements = vertexFormat.getElements();
|
||||
// for (int i = 0, size = elements.size(); i < size; i++) {
|
||||
// VertexFormatElement element = elements.get(i);
|
||||
// int offset = vertexFormat.getOffset(i);
|
||||
//
|
||||
// element.getUsage()
|
||||
// }
|
||||
// ImmutableList<VertexFormatElement> elements = vertexFormat.getElements();
|
||||
// for (int i = 0, size = elements.size(); i < size; i++) {
|
||||
// VertexFormatElement element = elements.get(i);
|
||||
// int offset = vertexFormat.getOffset(i);
|
||||
//
|
||||
// element.getUsage()
|
||||
// }
|
||||
}
|
||||
|
||||
public boolean isEmpty() {
|
||||
|
|
|
@ -13,14 +13,13 @@ public class CodecUtil {
|
|||
*/
|
||||
public static <T> Codec<List<T>> oneOrMore(Codec<T> codec) {
|
||||
return Codec.either(codec.listOf(), codec)
|
||||
.xmap(
|
||||
either -> either.map(l -> l, Collections::singletonList),
|
||||
list -> {
|
||||
if (list.size() == 1) {
|
||||
return Either.right(list.get(0));
|
||||
} else {
|
||||
return Either.left(list);
|
||||
}
|
||||
});
|
||||
.xmap(either -> either.map(l -> l, Collections::singletonList), list -> {
|
||||
if (list.size() == 1) {
|
||||
return Either.right(list.get(0));
|
||||
}
|
||||
else {
|
||||
return Either.left(list);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
@ -38,8 +38,7 @@ public class Pair<F, S> {
|
|||
|
||||
@Override
|
||||
public boolean equals(final Object obj) {
|
||||
if (obj == this)
|
||||
return true;
|
||||
if (obj == this) return true;
|
||||
if (obj instanceof Pair) {
|
||||
final Pair<?, ?> other = (Pair<?, ?>) obj;
|
||||
return Objects.equals(first, other.first) && Objects.equals(second, other.second);
|
||||
|
|
|
@ -29,70 +29,31 @@ public class RenderUtil {
|
|||
}
|
||||
|
||||
public static float[] writeMatrixStack(MatrixStack stack) {
|
||||
return writeMatrixStack(stack.peek().getModel(), stack.peek().getNormal());
|
||||
return writeMatrixStack(stack.peek()
|
||||
.getModel(), stack.peek()
|
||||
.getNormal());
|
||||
}
|
||||
|
||||
// GPUs want matrices in column major order.
|
||||
public static float[] writeMatrixStack(Matrix4f model, Matrix3f normal) {
|
||||
return new float[]{
|
||||
model.a00,
|
||||
model.a10,
|
||||
model.a20,
|
||||
model.a30,
|
||||
model.a01,
|
||||
model.a11,
|
||||
model.a21,
|
||||
model.a31,
|
||||
model.a02,
|
||||
model.a12,
|
||||
model.a22,
|
||||
model.a32,
|
||||
model.a03,
|
||||
model.a13,
|
||||
model.a23,
|
||||
model.a33,
|
||||
normal.a00,
|
||||
normal.a10,
|
||||
normal.a20,
|
||||
normal.a01,
|
||||
normal.a11,
|
||||
normal.a21,
|
||||
normal.a02,
|
||||
normal.a12,
|
||||
normal.a22,
|
||||
};
|
||||
return new float[]{model.a00, model.a10, model.a20, model.a30, model.a01, model.a11, model.a21, model.a31, model.a02, model.a12, model.a22, model.a32, model.a03, model.a13, model.a23, model.a33, normal.a00, normal.a10, normal.a20, normal.a01, normal.a11, normal.a21, normal.a02, normal.a12, normal.a22,};
|
||||
}
|
||||
|
||||
public static float[] writeMatrix(Matrix4f model) {
|
||||
return new float[]{
|
||||
model.a00,
|
||||
model.a10,
|
||||
model.a20,
|
||||
model.a30,
|
||||
model.a01,
|
||||
model.a11,
|
||||
model.a21,
|
||||
model.a31,
|
||||
model.a02,
|
||||
model.a12,
|
||||
model.a22,
|
||||
model.a32,
|
||||
model.a03,
|
||||
model.a13,
|
||||
model.a23,
|
||||
model.a33,
|
||||
};
|
||||
return new float[]{model.a00, model.a10, model.a20, model.a30, model.a01, model.a11, model.a21, model.a31, model.a02, model.a12, model.a22, model.a32, model.a03, model.a13, model.a23, model.a33,};
|
||||
}
|
||||
|
||||
public static Supplier<MatrixStack> rotateToFace(Direction facing) {
|
||||
return () -> {
|
||||
MatrixStack stack = new MatrixStack();
|
||||
// MatrixStacker.of(stack)
|
||||
// .centre()
|
||||
// .rotateY(AngleHelper.horizontalAngle(facing))
|
||||
// .rotateX(AngleHelper.verticalAngle(facing))
|
||||
// .unCentre();
|
||||
stack.peek().getModel().setTranslation(0.5f, 0.5f, 0.5f);
|
||||
// MatrixStacker.of(stack)
|
||||
// .centre()
|
||||
// .rotateY(AngleHelper.horizontalAngle(facing))
|
||||
// .rotateX(AngleHelper.verticalAngle(facing))
|
||||
// .unCentre();
|
||||
stack.peek()
|
||||
.getModel()
|
||||
.setTranslation(0.5f, 0.5f, 0.5f);
|
||||
stack.multiply(Vector3f.POSITIVE_Y.getDegreesQuaternion(AngleHelper.horizontalAngle(facing)));
|
||||
stack.multiply(Vector3f.POSITIVE_X.getDegreesQuaternion(AngleHelper.verticalAngle(facing)));
|
||||
stack.translate(-0.5f, -0.5f, -0.5f);
|
||||
|
|
|
@ -57,7 +57,7 @@ public class WeakHashSet<T> extends AbstractSet<T> {
|
|||
@Override
|
||||
public Iterator<T> iterator() {
|
||||
return map.keySet()
|
||||
.iterator();
|
||||
.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
|
@ -88,13 +88,12 @@ public class WeakHashSet<T> extends AbstractSet<T> {
|
|||
@Override
|
||||
public Object[] toArray() {
|
||||
return map.keySet()
|
||||
.toArray();
|
||||
.toArray();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean containsAll(Collection<?> c) {
|
||||
return stream()
|
||||
.allMatch(map::containsKey);
|
||||
return stream().allMatch(map::containsKey);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
|
|
@ -7,7 +7,6 @@ import java.util.function.Consumer;
|
|||
import java.util.function.Function;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
import net.minecraft.world.IWorld;
|
||||
|
||||
|
@ -24,8 +23,7 @@ public class WorldAttached<T> {
|
|||
@Nonnull
|
||||
public T get(IWorld world) {
|
||||
T t = attached.get(world);
|
||||
if (t != null)
|
||||
return t;
|
||||
if (t != null) return t;
|
||||
T entry = factory.apply(world);
|
||||
put(world, entry);
|
||||
return entry;
|
||||
|
|
Loading…
Reference in a new issue