-
Notifications
You must be signed in to change notification settings - Fork 85
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How best to access chunk/userData during block lifecycle hooks? #111
Comments
Hm, I see what you're asking and it wouldn't be hard, but I'm not sure it makes sense API-wise. But let's think it out. About that Now for your case, if I follow, you have the client asking the server for a chunk of data, and the server is replying with raw voxel data, and also using the The reason I say this is, Let me know if that makes sense, or if I'm misunderstanding the use case. |
I see what you’re saying — it probably doesn’t make sense for the Chunk to know about this Honestly, from an API perspective, it would be ideal if I could override a specific side of a block to insert a custom mesh on top as a Plane and as a one-off instead of registering a new block ID for it. This is a little like With the game, it could really be either slightly offset from (like a picture frame) or replacing a side (like wallpaper). I'm not sure which is best yet. Also I will have to make it potentially stretch across multiple voxels What do you think is the best approach for this?
I’m not sure how best to send the data from the server to the client either tbh. I don’t expect chunks to be filled with these objects (like block types), but I don’t think voxel-crunch supports strings (url). I currently have it as a map where the key is Unrelated, for my game I made it so there's no pointer lock, its third person with movement controls like World of Warcraft or Roblox – meaning you can comfortably move with just WSAD and no mouse, with the tradeoff that it loses precision expected for 1st person games To do this, picking is based on mouse coords instead of where the camera is looking. To support that, I slightly modified const _localPick = (pos, vec, dist, blockIdTestFunction) => {
if (_vec[0] === 0 && _vec[1] === 0 && _vec[2] === 0) {
return null;
}
// do a raycast in local coords - result obj will be in global coords
if (dist === 0) return null;
var testFn = blockIdTestFunction || noa.registry.getBlockSolidity;
var world = noa.world;
var testVoxel = function (x, y, z) {
var id = world.getBlockID(x + off[0], y + off[1], z + off[2]);
return testFn(id);
};
if (!pos) {
pos = noa.camera._localGetTargetPosition();
}
vec = _vec;
dist = dist || noa.blockTestDistance;
var rpos = _hitResult._localPosition;
var rnorm = _hitResult.normal;
var hit = raycast(testVoxel, pos, vec, dist, rpos, rnorm);
if (!hit) {
return null;
}
// position is right on a voxel border - adjust it so that flooring works reliably
// adjust along normal direction, i.e. away from the block struck
Vec3.scaleAndAdd(rpos, rpos, rnorm, 0.01);
// add global result
noa.localToGlobal(rpos, _hitResult.position);
noa.localToGlobal(this.pickPoint, comparePos);
if (Vec3.dist(comparePos, _hitResult.position) > 1) {
return null;
}
return _hitResult;
};
noa._localPick = _localPick; const updatePickPosition = (pointerInfo) => {
if (pointerInfo.pickInfo.hit) {
this.pickPoint = pointerInfo.pickInfo.pickedPoint.asArray();
Ray.CreateNewFromTo(
this.camera.parent.position,
pointerInfo.pickInfo.pickedPoint
).direction.toArray(_vec);
} else {
_vec[0] = 0;
_vec[1] = 0;
_vec[2] = 0;
}
};
scene.onPointerObservable.add((pointerInfo) => {
updatePickPosition(pointerInfo);
return true;
}); |
Okay, I have a vague idea where you're going here. My guess is that it'll be most robust to register a single block type for these blocks and create/destroy meshes in the voxel lifecycle events. And then to manage the strings for which URL goes where as a second variety of world data, keyed by absolute world positions, which would be exchanged with the server separately from voxel data. For how best to do this, broadly The easiest way to do this is usually to make an entity for the thing you want to add, with a position component and a mesh component to specify what goes where. There's a helper API for this: var pos = [5,5,5]
var wd = 1
var ht = 1
var mesh = // import...
var meshOffset = [0,0,0]
var doPhysics = false
var shadow = false
noa.entities.add(pos, wd, ht, mesh, meshOffset, doPhysics, shadow) If you do that, |
This makes sense – I'll use that approach. Do you suggest still using the registry for this, with custom block IDs? It would be helpful as a way of saying "place this here". Alternatively, I could have a callbacks for each and every block that could have another mesh associated with it, and then do the lookup in those callbacks |
If I follow your question, it's just a matter of convenience - if you know all the different kinds of media blocks at init time you could register an ID for each, but if you don't you could register them all as the same block and have one set of event handlers for all of them. Note though, if there are hundreds of different kinds then you'll want the latter approach, since voxel IDs are currently stored with 9 bits, so the maximum ID is 511. |
The
onLoad
function in my use case needs to be able to access additional data about the block. In my game, sometimes blocks will show a remote image for one of the sides and this will be user-generated content – so it likely doesn't make sense to usenoa.registry.registerBlock
hereInitially, I thought I could make this work by getting the chunk in the callback, but at the time of this function being called
noa.world._getChunkByCoords(x,y,z)
returnsnull
. Additionally,userData
is not set until after the chunk is initialized?I've worked around this locally in the meantime, but it'd be great if
userData
was optionally passed in to each of the block lifecycle hooks or if theChunk
object itself was accessible.For example:
Do you want a PR that does this?
The text was updated successfully, but these errors were encountered: