I have a tool that allows players to place new entities (in this case blocks) around in the world via raycasting. I would like the blocks to place where the reticle is in world space. Here’s what’s happening visually:
Programmatically:
Tool.js - doRaycast() is called from left mouse button click to place item
Tool.prototype.doRaycast = function (screenX, screenY) {
var sceneGlobal = this.app.root.findByName('SceneGlobal');
var cameraEntity = this.entity.parent.parent.findByName('Camera Axis').findByName('Camera');
var cameraEntityPos = cameraEntity.getPosition();
var buildRayPos = this.entity.getPosition();
var reticle = sceneGlobal.findByName('UserInterface').findByName('Reticle').getPosition();
var reticleToWorldPOs = cameraEntity.camera.screenToWorld(reticle.x, reticle.y, cameraEntity.camera.nearClip);
// The pc.Vec3 to raycast from (the position of the camera)
var from = cameraEntity.getPosition();
var fromReticle = reticleToWorldPOs;
// The pc.Vec3 to raycast to (the click position projected onto the camera's far clip plane)
//var to = cameraEntity.camera.screenToWorld(screenX, screenY, cameraEntity.camera.nearClip);
var to = cameraEntity.camera.screenToWorld(screenX, screenY, cameraEntity.camera.farClip);
var toReticle = cameraEntity.camera.screenToWorld(screenX, screenY, cameraEntity.camera.nearClip);
// Raycast between the two points and return the closest hit result
var result = this.app.systems.rigidbody.raycastFirst(from, to);
// If there was a hit, store the entity
if (result && result.entity.name !== 'Terrain') {
var hitEntity = result.entity;
console.log('You selected ' + hitEntity.name);
} else {
var playerPos = this.entity.parent.parent.getPosition();
var toolbox = this.entity.parent.findByName('Toolbox');
var placeCube = toolbox.findByName('PlantCube').clone();
var distLimiter = 50;
var posX = to.x/distLimiter/4 + from.x;
//var posX = to.x/distLimiter + playerPos.x;
var posY = to.y/distLimiter/2 + from.y;
var posZ = to.z/distLimiter/2 + from.z;
var placementPos = new pc.Vec3(posX, posY, posZ);
placeCube.setLocalPosition(placementPos);
console.log('Place item:', placementPos);
placeCube.enabled = true;
sceneGlobal.addChild(placeCube);
this.fire('placeNewEntity', placeCube);
}
};
I’m sure there is a more effective way of placing the blocks but I couldn’t find any good article-based sources which excluded voxels.
I have a reticle to show where a new entity should be placed, I’m sure this has something to do with my way of calculating the placement position as I’m experimenting.
Thanks, any suggestions?