Wip on many things
Added partial inner node child update support
This commit is contained in:
@@ -88,6 +88,11 @@ public class Shader extends TrackedObject {
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> define(String name, String value) {
|
||||
this.defines.put(name, value);
|
||||
return this;
|
||||
}
|
||||
|
||||
public Builder<T> add(ShaderType type, String id) {
|
||||
this.addSource(type, ShaderLoader.parse(id));
|
||||
return this;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package me.cortex.voxy.client.core.rendering;
|
||||
|
||||
import com.mojang.datafixers.util.Either;
|
||||
import me.cortex.voxy.client.core.model.ModelBakerySubsystem;
|
||||
import me.cortex.voxy.client.core.model.ModelStore;
|
||||
import me.cortex.voxy.client.core.rendering.building.BuiltSection;
|
||||
@@ -15,11 +16,13 @@ import me.cortex.voxy.client.core.rendering.section.MDICSectionRenderer;
|
||||
import me.cortex.voxy.client.core.rendering.util.DownloadStream;
|
||||
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||
import me.cortex.voxy.common.util.MessageQueue;
|
||||
import me.cortex.voxy.common.util.Pair;
|
||||
import me.cortex.voxy.common.world.WorldEngine;
|
||||
import me.cortex.voxy.common.thread.ServiceThreadPool;
|
||||
import me.cortex.voxy.common.world.WorldSection;
|
||||
import net.minecraft.client.render.Camera;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@@ -49,7 +52,7 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
|
||||
|
||||
//Max sections: ~500k
|
||||
//Max geometry: 1 gb
|
||||
this.sectionRenderer = (T) createSectionRenderer(this.modelService.getStore(),1<<20, (1L<<31)-1024);
|
||||
this.sectionRenderer = (T) createSectionRenderer(this.modelService.getStore(),1<<20, (1L<<32)-1024);
|
||||
|
||||
//Do something incredibly hacky, we dont need to keep the reference to this around, so just connect and discard
|
||||
var router = new SectionUpdateRouter();
|
||||
@@ -93,16 +96,51 @@ public class RenderService<T extends AbstractSectionRenderer<J, ?>, J extends Vi
|
||||
}
|
||||
}
|
||||
}*/
|
||||
|
||||
|
||||
final int H_WIDTH = 20;
|
||||
if (true) {
|
||||
if (true) {
|
||||
final int H_WIDTH = 10;
|
||||
for (int x = -H_WIDTH; x <= H_WIDTH; x++) {
|
||||
for (int y = -1; y <= 0; y++) {
|
||||
for (int z = -H_WIDTH; z <= H_WIDTH; z++) {
|
||||
for (int y = -1; y <= 0; y++) {
|
||||
this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (int x = -5; x <= 20; x++) {
|
||||
for (int z = -5; z <= 20; z++) {
|
||||
for (int y = 0; y <= 1; y++) {
|
||||
this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
/*
|
||||
for (int x = -5; x <= 5; x++) {
|
||||
for (int z = -5; z <= 5; z++) {
|
||||
for (int y = -5; y <= 5; y++) {
|
||||
this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int x = -5; x <= 5; x++) {
|
||||
for (int z = -5; z <= 5; z++) {
|
||||
for (int y = -5; y <= 5; y++) {
|
||||
this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, x+16, y, z));
|
||||
}
|
||||
}
|
||||
}*/
|
||||
for (int x = -3; x <= 3; x++) {
|
||||
for (int z = -3; z <= 3; z++) {
|
||||
for (int y = -8; y <= 7; y++) {
|
||||
this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, x, y, z));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//this.nodeManager.insertTopLevelNode(WorldEngine.getWorldSectionId(4, 0,0,0));
|
||||
}
|
||||
|
||||
@@ -100,11 +100,12 @@ public class RenderGenerationService {
|
||||
try {
|
||||
mesh = factory.generateMesh(section);
|
||||
} catch (IdNotYetComputedException e) {
|
||||
//TODO: maybe move this to _after_ task as been readded to queue??
|
||||
|
||||
if (!this.modelBakery.factory.hasModelForBlockId(e.id)) {
|
||||
this.modelBakery.requestBlockBake(e.id);
|
||||
}
|
||||
if (task.hasDoneModelRequest) {
|
||||
|
||||
try {
|
||||
Thread.sleep(1);
|
||||
} catch (InterruptedException ex) {
|
||||
@@ -114,6 +115,8 @@ public class RenderGenerationService {
|
||||
//The reason for the extra id parameter is that we explicitly add/check against the exception id due to e.g. requesting accross a chunk boarder wont be captured in the request
|
||||
this.computeAndRequestRequiredModels(section, e.id);
|
||||
}
|
||||
|
||||
|
||||
{//Keep the lock on the section, and attach it to the task, this prevents needing to re-aquire it later
|
||||
task.section = section;
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ public class HierarchicalOcclusionTraverser {
|
||||
private final GlBuffer renderList = new GlBuffer(100_000 * 4 + 4).zero();//100k sections max to render, TODO: Maybe move to render service or somewhere else
|
||||
|
||||
private final GlBuffer queueMetaBuffer = new GlBuffer(4*4*5).zero();
|
||||
private final GlBuffer scratchQueueA = new GlBuffer(50_000*4).zero();
|
||||
private final GlBuffer scratchQueueB = new GlBuffer(50_000*4).zero();
|
||||
private final GlBuffer scratchQueueA = new GlBuffer(100_000*4).zero();
|
||||
private final GlBuffer scratchQueueB = new GlBuffer(100_000*4).zero();
|
||||
|
||||
private static final int LOCAL_WORK_SIZE_BITS = 5;
|
||||
private static final int MAX_ITERATIONS = 5;
|
||||
|
||||
@@ -6,6 +6,7 @@ import me.cortex.voxy.client.core.gl.GlBuffer;
|
||||
import me.cortex.voxy.client.core.gl.shader.AutoBindingShader;
|
||||
import me.cortex.voxy.client.core.gl.shader.Shader;
|
||||
import me.cortex.voxy.client.core.gl.shader.ShaderType;
|
||||
import me.cortex.voxy.client.core.rendering.util.DownloadStream;
|
||||
import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||
import org.lwjgl.system.MemoryUtil;
|
||||
|
||||
@@ -63,6 +64,19 @@ public class NodeCleaner {
|
||||
public void tick() {
|
||||
this.clearIds();
|
||||
|
||||
if (false) {
|
||||
this.outputBuffer.zero();//TODO: maybe dont set to zero??
|
||||
|
||||
this.sorter.bind();
|
||||
//TODO: choose whether this is in nodeSpace or section/geometryId space
|
||||
//glDispatchCompute(, 1, 1);
|
||||
|
||||
//DownloadStream.INSTANCE.download(this.outputBuffer, this::onDownload);
|
||||
}
|
||||
}
|
||||
|
||||
private void onDownload(long ptr, long size) {
|
||||
|
||||
}
|
||||
|
||||
private void clearIds() {
|
||||
|
||||
@@ -11,6 +11,7 @@ import me.cortex.voxy.client.core.rendering.util.UploadStream;
|
||||
import me.cortex.voxy.client.core.util.ExpandingObjectAllocationList;
|
||||
import me.cortex.voxy.common.Logger;
|
||||
import me.cortex.voxy.common.world.WorldEngine;
|
||||
import me.cortex.voxy.commonImpl.VoxyCommon;
|
||||
import net.caffeinemc.mods.sodium.client.util.MathUtil;
|
||||
|
||||
import java.util.List;
|
||||
@@ -24,6 +25,7 @@ import java.util.List;
|
||||
|
||||
|
||||
public class NodeManager2 {
|
||||
private static final boolean VERIFY_NODE_MANAGER_OPERATIONS = VoxyCommon.isVerificationFlagOn("nodeManager");
|
||||
//Assumptions:
|
||||
// all nodes have children (i.e. all nodes have at least one child existence bit set at all times)
|
||||
// leaf nodes always contain geometry (empty geometry counts as geometry (it just doesnt take any memory to store))
|
||||
@@ -243,8 +245,7 @@ public class NodeManager2 {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
} else if ((nodeId&NODE_TYPE_MSK)==NODE_TYPE_INNER) {
|
||||
//Very complex and painful operation
|
||||
Logger.error("UNFINISHED OPERATION TODO: FIXME");
|
||||
this.updateChildSectionsInner(pos, nodeId&NODE_ID_MSK, childExistence);
|
||||
} else if ((nodeId&NODE_TYPE_MSK)==NODE_TYPE_LEAF) {
|
||||
|
||||
//We might be leaf but we still might be inflight
|
||||
@@ -252,7 +253,7 @@ public class NodeManager2 {
|
||||
// Logger.error("UNFINISHED OPERATION TODO: FIXME: painful operation, needs to account for both adding and removing, need to do the same with inner node, but also create requests, or cleanup children");
|
||||
int requestId = this.nodeData.getNodeRequest(nodeId);
|
||||
var request = this.childRequests.get(requestId);// TODO: do not assume request is childRequest (it will probably always be)
|
||||
if (request.getPosition() != pos) throw new IllegalStateException("Request not in pos");
|
||||
if (request.getPosition() != pos) throw new IllegalStateException("Request is not at pos");
|
||||
{//Update the request
|
||||
byte oldMsk = request.getMsk();
|
||||
byte change = (byte) (oldMsk ^ childExistence);
|
||||
@@ -293,16 +294,131 @@ public class NodeManager2 {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//If the request is now satisfied we need to finish it
|
||||
if (request.isSatisfied()) {
|
||||
this.finishRequest(requestId, request);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Just need to update the child node data, nothing else
|
||||
this.nodeData.setNodeChildExistence(nodeId&NODE_ID_MSK, childExistence);
|
||||
//Need to resubmit to gpu
|
||||
this.invalidateNode(nodeId&NODE_ID_MSK);
|
||||
this.invalidateNode(nodeId&NODE_ID_MSK);//TODO:FIXME: Do we???
|
||||
}
|
||||
}
|
||||
|
||||
private void updateChildSectionsInner(long pos, int nodeId, byte childExistence) {
|
||||
|
||||
//Very complex and painful operation
|
||||
|
||||
/**
|
||||
if (this.nodeData.isNodeRequestInFlight(nodeId&NODE_ID_MSK)) {
|
||||
int requestId = this.nodeData.getNodeRequest(nodeId);
|
||||
var request = this.childRequests.get(requestId);// TODO: do not assume request is childRequest (it will probably always be)
|
||||
if (request.getPosition() != pos) throw new IllegalStateException("Request is not at pos");
|
||||
byte oldMsk = request.getMsk();
|
||||
byte change = (byte) (oldMsk ^ childExistence);
|
||||
|
||||
|
||||
// {//Remove children that no longer exist, TODO: FIXME: THEY MIGHT NOT BE IN THE REQUEST
|
||||
// byte rem = (byte) (change&childExistence);
|
||||
// for (int i = 0; i < 8; i++) {
|
||||
// if ((rem & (1 << i)) == 0) continue;
|
||||
// int meshId = request.removeAndUnRequire(i);
|
||||
// if (meshId != NULL_GEOMETRY_ID && meshId != EMPTY_GEOMETRY_ID) {
|
||||
// this.geometryManager.removeSection(meshId);
|
||||
// }
|
||||
//
|
||||
// //Remove child from being watched and activeSections
|
||||
// long cPos = makeChildPos(pos, i);
|
||||
// if (this.activeSectionMap.remove(cPos) == -1) {//TODO: verify the removed section is a request type of child and the request id matches this
|
||||
// throw new IllegalStateException("Child pos was in a request but not in active section map");
|
||||
// }
|
||||
// if (!this.updateRouter.unwatch(cPos, WorldEngine.UPDATE_FLAGS)) {
|
||||
// throw new IllegalStateException("Child pos was not being watched");
|
||||
// }
|
||||
//
|
||||
//
|
||||
// throw new IllegalStateException("UNFINISHED!: need to recursivly remove children");
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
{//Add new children
|
||||
byte add = (byte) (change&childExistence);
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if ((add&(1<<i))==0) continue;
|
||||
//Add child to request
|
||||
request.addChildRequirement(i);
|
||||
|
||||
//Add child to active tracker and put in updateRouter
|
||||
long cPos = makeChildPos(pos, i);
|
||||
if (this.activeSectionMap.put(cPos, requestId|NODE_TYPE_REQUEST|REQUEST_TYPE_CHILD) != -1) {
|
||||
throw new IllegalStateException("Child pos was already in active section tracker but was part of a request");
|
||||
}
|
||||
if (!this.updateRouter.watch(cPos, WorldEngine.UPDATE_FLAGS)) {
|
||||
throw new IllegalStateException("Child pos update router issue");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
//TODO: operation of needing to create a request node to add new sections
|
||||
// (or modify the node to remove a child node (recursively probably ;-;))
|
||||
|
||||
|
||||
|
||||
//This works in 2 parts, adding and removing, adding is (surprisingly) much easier than removing
|
||||
// adding, either adds to a request, or creates a new request
|
||||
byte existence = this.nodeData.getNodeChildExistence(nodeId);
|
||||
byte add = (byte) ((existence^childExistence)&childExistence);
|
||||
if (add != 0) {//We have nodes to add
|
||||
if (!this.nodeData.isNodeRequestInFlight(nodeId)) {//If there is not an existing request, create it
|
||||
var request = new NodeChildRequest(pos);
|
||||
int requestId = this.childRequests.put(request);
|
||||
|
||||
this.nodeData.markRequestInFlight(nodeId);
|
||||
this.nodeData.setNodeRequest(nodeId, requestId);
|
||||
this.activeNodeRequestCount++;
|
||||
}
|
||||
//It is guaranteed that at this point the node has a request
|
||||
// so add the new nodes to it
|
||||
int requestId = this.nodeData.getNodeRequest(nodeId);
|
||||
var request = this.childRequests.get(requestId);// TODO: do not assume request is childRequest (it will probably always be)
|
||||
if (request.getPosition() != pos) throw new IllegalStateException("Request is not at pos");
|
||||
|
||||
//Add all new children to the request
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if ((add&(1<<i))==0) continue;
|
||||
//Add child to request
|
||||
request.addChildRequirement(i);
|
||||
//Add child to active tracker and put in updateRouter
|
||||
long cPos = makeChildPos(pos, i);
|
||||
if (this.activeSectionMap.put(cPos, requestId|NODE_TYPE_REQUEST|REQUEST_TYPE_CHILD) != -1) {
|
||||
throw new IllegalStateException("Child pos was already in active section tracker but was part of a request");
|
||||
}
|
||||
if (!this.updateRouter.watch(cPos, WorldEngine.UPDATE_FLAGS)) {
|
||||
throw new IllegalStateException("Child pos update router issue");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Do removals
|
||||
byte rem = (byte) ((existence^childExistence)&existence);;
|
||||
if (rem != 0) {
|
||||
Logger.error("UNFINISHED OPERATION TODO: FIXME");
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Update the nodes existence msk to the new one
|
||||
this.nodeData.setNodeChildExistence(nodeId&NODE_ID_MSK, childExistence);
|
||||
}
|
||||
|
||||
//==================================================================================================================
|
||||
|
||||
private void finishRequest(SingleNodeRequest request) {
|
||||
@@ -378,7 +494,108 @@ public class NodeManager2 {
|
||||
|
||||
this.invalidateNode(parentNodeId);
|
||||
} else if (parentNodeType==NODE_TYPE_INNER) {
|
||||
Logger.error("TODO: FIXME FINISH: finishRequest NODE_TYPE_INNER");
|
||||
//Logger.error("TODO: FIXME FINISH: finishRequest NODE_TYPE_INNER");
|
||||
//For this, only need to add the nodes to the existing child set thing (shuffle around whatever) dont ever have to remove nodes
|
||||
|
||||
int childPtr = this.nodeData.getChildPtr(parentNodeId);
|
||||
int childCnt = this.nodeData.getChildPtrCount(parentNodeId);
|
||||
if (childPtr == -1) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
//Ok so technically, it _is ok_ to just add to the end of the childPtr, however, imo that is stupid
|
||||
// and it should follow the logical allocation with respect to the 8 child indices
|
||||
// this means, need to extract the child indices already in the ptr (or technically could use the child existance? but having both and doing verification would be good)
|
||||
|
||||
int existingChildMsk = 0;
|
||||
for (int i = 0; i < childCnt; i++) {
|
||||
if (!this.nodeData.nodeExists(i+childPtr)) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
existingChildMsk |= 1<<getChildIdx(this.nodeData.nodePosition(i+childPtr));
|
||||
}
|
||||
int reqMsk = Byte.toUnsignedInt(request.getMsk());
|
||||
if ((byte) (existingChildMsk|reqMsk) != this.nodeData.getNodeChildExistence(parentNodeId)) {
|
||||
//System.out.println(Integer.toBinaryString(Byte.toUnsignedInt(this.nodeData.getNodeChildExistence(parentNodeId))));System.out.println(Integer.toBinaryString(existingChildMsk));System.out.println(Integer.toBinaryString(reqMsk));
|
||||
throw new IllegalStateException("node data existence state does not match pointer mask");
|
||||
}
|
||||
|
||||
|
||||
if ((reqMsk&existingChildMsk)!=0) {
|
||||
throw new IllegalStateException("Overlapping child data!!! BAD");
|
||||
}
|
||||
|
||||
//Create the new allocation
|
||||
int newMsk = reqMsk | existingChildMsk;
|
||||
int newChildPtr = this.nodeData.allocate(Integer.bitCount(newMsk));
|
||||
|
||||
//Need to interlace the old and new data into the new allocation
|
||||
// FOR OLD ALLOCATIONS, NEED TO UPDATE POINTERS
|
||||
int childId = newChildPtr-1;
|
||||
int prevChildId = childPtr-1;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if ((newMsk&(1<<i))==0) continue;
|
||||
childId++;
|
||||
|
||||
if ((reqMsk&(1<<i))!=0) {
|
||||
//Its an entry from the request
|
||||
long childPos = makeChildPos(request.getPosition(), i);
|
||||
|
||||
this.nodeData.setNodePosition(childId, childPos);
|
||||
byte childExistence = request.getChildChildExistence(i);
|
||||
if (childExistence == 0) {
|
||||
throw new IllegalStateException("Request result with child existence of 0");
|
||||
}
|
||||
this.nodeData.setNodeChildExistence(childId, childExistence);
|
||||
this.nodeData.setNodeGeometry(childId, request.getChildMesh(i));
|
||||
|
||||
//Mark for update
|
||||
this.invalidateNode(childId);
|
||||
|
||||
//Put in map
|
||||
int pid = this.activeSectionMap.put(childPos, childId|NODE_TYPE_LEAF);
|
||||
if ((pid&NODE_TYPE_MSK) != NODE_TYPE_REQUEST) {
|
||||
throw new IllegalStateException("Put node in map from request but type was not request: " + pid + " " + WorldEngine.pprintPos(childPos));
|
||||
}
|
||||
} else {
|
||||
prevChildId++;
|
||||
|
||||
long pos = this.nodeData.nodePosition(prevChildId);
|
||||
|
||||
//Its a previous entry, copy it to its new location
|
||||
this.nodeData.copyNode(prevChildId, childId);
|
||||
|
||||
int prevNodeId = this.activeSectionMap.get(pos);
|
||||
if ((prevNodeId&NODE_TYPE_MSK) == NODE_TYPE_REQUEST) {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
if ((prevNodeId&NODE_ID_MSK) != prevChildId) {
|
||||
throw new IllegalStateException("State inconsistency");
|
||||
}
|
||||
this.activeSectionMap.put(pos, (prevNodeId&NODE_TYPE_MSK)|childId);
|
||||
//Need to invalidate the old and the new
|
||||
this.invalidateNode(prevChildId);
|
||||
this.invalidateNode(childId);
|
||||
}
|
||||
}
|
||||
|
||||
//Do final steps
|
||||
|
||||
//Free the old child data
|
||||
this.nodeData.free(childPtr, childCnt);
|
||||
|
||||
//Free request
|
||||
this.childRequests.release(requestId);
|
||||
|
||||
//Update the parent
|
||||
this.nodeData.setChildPtr(parentNodeId, newChildPtr);
|
||||
this.nodeData.setChildPtrCount(parentNodeId, Integer.bitCount(newMsk));
|
||||
this.nodeData.setNodeRequest(parentNodeId, 0);//TODO: create a better null request
|
||||
this.activeNodeRequestCount--;
|
||||
this.nodeData.unmarkRequestInFlight(parentNodeId);
|
||||
|
||||
//Invalidate parent
|
||||
this.invalidateNode(parentNodeId);
|
||||
} else {
|
||||
throw new IllegalStateException();
|
||||
}
|
||||
|
||||
@@ -70,12 +70,13 @@ public final class NodeStore {
|
||||
this.free(nodeId, 1);
|
||||
}
|
||||
|
||||
private void free(int baseNodeId, int count) {
|
||||
public void free(int baseNodeId, int count) {
|
||||
for (int i = 0; i < count; i++) {
|
||||
int nodeId = baseNodeId + i;
|
||||
if (!this.allocationSet.free(nodeId)) {
|
||||
if (!this.allocationSet.free(nodeId)) {//TODO: add batch free
|
||||
throw new IllegalStateException("Node " + nodeId + " was not allocated!");
|
||||
}
|
||||
this.clear(nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,6 +90,20 @@ public final class NodeStore {
|
||||
this.localNodeData[idx+3] = 0;
|
||||
}
|
||||
|
||||
|
||||
//Copy from allocated index A to allocated index B
|
||||
public void copyNode(int fromId, int toId) {
|
||||
if (!(this.allocationSet.isSet(fromId)&&this.allocationSet.isSet(toId))) {
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
int f = id2idx(fromId);
|
||||
int t = id2idx(toId);
|
||||
this.localNodeData[t ] = this.localNodeData[f ];
|
||||
this.localNodeData[t+1] = this.localNodeData[f+1];
|
||||
this.localNodeData[t+2] = this.localNodeData[f+2];
|
||||
this.localNodeData[t+3] = this.localNodeData[f+3];
|
||||
}
|
||||
|
||||
public void setNodePosition(int node, long position) {
|
||||
this.localNodeData[id2idx(node)] = position;
|
||||
}
|
||||
@@ -213,7 +228,7 @@ public final class NodeStore {
|
||||
|
||||
public int getChildPtrCount(int nodeId) {
|
||||
long data = this.localNodeData[id2idx(nodeId)+1];
|
||||
return (int) ((data>>56)&0x7);
|
||||
return ((int)((data>>56)&0x7))+1;
|
||||
}
|
||||
|
||||
public void setChildPtrCount(int nodeId, int count) {
|
||||
@@ -236,7 +251,7 @@ public final class NodeStore {
|
||||
|
||||
short flags = 0;
|
||||
flags |= (short) (this.isNodeRequestInFlight(nodeId)?1:0);
|
||||
flags |= (short) (this.getChildPtrCount(nodeId)<<2);
|
||||
flags |= (short) ((this.getChildPtrCount(nodeId)-1)<<2);
|
||||
|
||||
{
|
||||
int geometry = this.getNodeGeometry(nodeId);
|
||||
@@ -246,8 +261,9 @@ public final class NodeStore {
|
||||
z |= geometry&0xFFFFFF;//TODO: check and ensure bounds
|
||||
}
|
||||
}
|
||||
|
||||
w |= this.getChildPtr(nodeId)&0xFFFFFF;//TODO: check and ensure bounds
|
||||
int childPtr = this.getChildPtr(nodeId);
|
||||
//TODO: check and ensure bounds
|
||||
w |= childPtr&0xFFFFFF;
|
||||
|
||||
z |= (flags&0xFF)<<24;
|
||||
w |= ((flags>>8)&0xFF)<<24;
|
||||
|
||||
@@ -22,14 +22,18 @@ public class ServiceThreadPool {
|
||||
private final ThreadGroup threadGroup;
|
||||
|
||||
public ServiceThreadPool(int threadCount) {
|
||||
this.threadGroup = new ThreadGroup("Service job workers");
|
||||
this(threadCount, 4);//Maybe change to 3
|
||||
}
|
||||
|
||||
public ServiceThreadPool(int threadCount, int priority) {
|
||||
this.threadGroup = new ThreadGroup("Service job workers");
|
||||
this.workers = new Thread[threadCount];
|
||||
for (int i = 0; i < threadCount; i++) {
|
||||
int threadId = i;
|
||||
var worker = new Thread(this.threadGroup, ()->this.worker(threadId));
|
||||
worker.setDaemon(false);
|
||||
worker.setName("Service worker #" + i);
|
||||
worker.setPriority(priority);
|
||||
worker.start();
|
||||
worker.setUncaughtExceptionHandler(this::handleUncaughtException);
|
||||
this.workers[i] = worker;
|
||||
|
||||
@@ -75,7 +75,6 @@ vec3 swizzelDataAxis(uint axis, vec3 data) {
|
||||
void main() {
|
||||
int cornerIdx = gl_VertexID&3;
|
||||
Quad quad = quadData[uint(gl_VertexID)>>2];
|
||||
vec3 innerPos = extractPos(quad);
|
||||
uint face = extractFace(quad);
|
||||
uint modelId = extractStateId(quad);
|
||||
BlockModel model = modelData[modelId];
|
||||
|
||||
@@ -87,8 +87,8 @@ bool isCulledByHiz() {
|
||||
|
||||
|
||||
vec2 ssize = size * vec2(screenW, screenH);
|
||||
float miplevel = ceil(log2(max(max(ssize.x, ssize.y),1)))-1;
|
||||
miplevel = clamp(miplevel, 1, 10);
|
||||
float miplevel = ceil(log2(max(max(ssize.x, ssize.y),1)));
|
||||
miplevel = clamp(miplevel, 1, 20);
|
||||
vec2 midpoint = (maxBB.xy + minBB.xy)*0.5f;
|
||||
//TODO: maybe get rid of clamp
|
||||
//Todo: replace with some rasterization, e.g. especially for request back to cpu
|
||||
|
||||
Reference in New Issue
Block a user