import {VRSPACEUI} from '../vrspace-ui.js';
import {World} from '../../world/world.js';
import {TextureSelector} from './texture-selector.js';
export class TerrainEditor {
/**
* @param {World} world
*/
constructor(world) {
this.world = world;
this.scene = world.scene;
this.terrain = world.terrain;
this.heightIncrement=1;
this.editing = false;
this.textureSelector = new TextureSelector(this.scene, (img) => this.publishTexture(img));
// add own selection predicate to the world
this.selectionPredicate = (mesh) => this.isSelectableMesh(mesh);
world.addSelectionPredicate(this.selectionPredicate);
this.observer = null;
this.groundPickable = null;
}
createSharedTerrain() {
if ( ! World.lastInstance.sharedTerrain ) {
var object = {
permanent: true,
active:true,
specularColor:this.terrain.terrainMaterial.specularColor,
diffuseColor:this.terrain.terrainMaterial.diffuseColor,
emissiveColor:this.terrain.terrainMaterial.emissiveColor
};
this.world.worldManager.VRSPACE.createSharedObject(object, "Terrain").then(obj=>{
console.log("Created new Terrain", obj);
World.lastInstance.sharedTerrain = obj;
});
}
}
edit() {
this.createSharedTerrain();
if ( ! this.observer ) {
this.observer = this.scene.onPointerObservable.add((pointerInfo) => {
switch (pointerInfo.type) {
case BABYLON.PointerEventTypes.POINTERDOWN:
if(pointerInfo.pickInfo.hit && pointerInfo.pickInfo.pickedMesh == this.terrain.mesh()) {
this.lastIndex = this.updatePicked(pointerInfo.pickInfo);
this.terrain.mesh().enablePointerMoveEvents = true;
}
break;
case BABYLON.PointerEventTypes.POINTERUP:
this.lastIndex = -1;
this.terrain.mesh().enablePointerMoveEvents = false;
break;
case BABYLON.PointerEventTypes.POINTERMOVE:
if ( this.lastIndex >= 0 && pointerInfo.pickInfo.pickedMesh == this.terrain.mesh() ) {
var newIndex = this.terrain.findIndex(pointerInfo.pickInfo.pickedPoint.x,pointerInfo.pickInfo.pickedPoint.z);
if ( newIndex != this.lastIndex ) {
this.lastIndex = newIndex;
this.updatePicked(pointerInfo.pickInfo);
}
}
break;
}
});
}
if ( World.lastInstance.ground ) {
this.groundPickable = World.lastInstance.ground.isPickable;
World.lastInstance.ground.isPickable = false;
}
this.raiseButton = VRSPACEUI.hud.addButton("Raise", VRSPACEUI.contentBase+"/content/icons/upload.png");
this.digButton = VRSPACEUI.hud.addButton("Dig", VRSPACEUI.contentBase+"/content/icons/download.png");
this.textureButton = VRSPACEUI.hud.addButton("Texture", VRSPACEUI.contentBase+"/content/icons/terrain-texture.png");
this.raiseSlider = VRSPACEUI.hud.addSlider("Height",0,2,this.heightIncrement)
this.raiseButton.onPointerDownObservable.add( () => {
this.direction = 1;
VRSPACEUI.hud.showButtons(this.editing,this.raiseButton,this.raiseSlider);
this.world.enableFloorSelection(this.editing);
this.editing = !this.editing;
this.terrain.terrainMaterial.wireframe = this.editing;
});
this.digButton.onPointerDownObservable.add( () => {
this.direction = -1;
VRSPACEUI.hud.showButtons(this.editing,this.digButton,this.raiseSlider);
this.world.enableFloorSelection(this.editing);
this.editing = !this.editing;
this.terrain.terrainMaterial.wireframe = this.editing;
});
this.textureButton.onPointerDownObservable.add( () => {
this.editing = !this.editing;
if ( this.editing ) {
this.textureSelector.show();
} else {
this.textureSelector.hide();
}
VRSPACEUI.hud.showButtons(!this.editing,this.textureButton);
});
this.raiseSlider.onValueChangedObservable.add(value=>{this.heightIncrement=value});
this.diffusePicker = VRSPACEUI.hud.addColorPicker("Diffuse", this.terrain.terrainMaterial.diffuseColor);
this.specularPicker = VRSPACEUI.hud.addColorPicker("Specular", this.terrain.terrainMaterial.specularColor);
this.emissivePicker = VRSPACEUI.hud.addColorPicker("Emissive", this.terrain.terrainMaterial.emissiveColor);
this.specularPicker.onValueChangedObservable.add( (val) => {
//this.terrain.terrainMaterial.specularColor.copyFrom(val);
this.world.worldManager.VRSPACE.sendEvent(World.lastInstance.sharedTerrain, {specularColor:val});
});
this.diffusePicker.onValueChangedObservable.add( (val) => {
//this.terrain.terrainMaterial.diffuseColor.copyFrom(val);
this.world.worldManager.VRSPACE.sendEvent(World.lastInstance.sharedTerrain, {diffuseColor:val});
});
this.emissivePicker.onValueChangedObservable.add( (val) => {
//this.terrain.terrainMaterial.emissiveColor.copyFrom(val);
this.world.worldManager.VRSPACE.sendEvent(World.lastInstance.sharedTerrain, {emissiveColor:val});
});
VRSPACEUI.hud.enableSpeech(true);
}
updatePicked( pickInfo ) {
var index = -1;
var x = pickInfo.pickedPoint.x;
var z = pickInfo.pickedPoint.z;
if ( this.editing ) {
var online = this.world.isOnline() && World.lastInstance.sharedTerrain;
if ( online ) {
// if online, terrain is not refreshed until the server responds with updated height
index = this.terrain.findIndex(x,z);
if ( index ) {
var point = this.terrain.point(index);
point.y += this.heightIncrement*this.direction;
// publish updates
var change = { change: {index: index, point: point} };
this.world.worldManager.VRSPACE.sendEvent(World.lastInstance.sharedTerrain, change);
} else {
console.log("ERROR: index "+index+" for "+x+","+z);
}
} else {
index = this.terrain.raise(x,z,this.heightIncrement*this.direction, online);
}
}
return index;
}
publishTexture(imgUrl) {
console.log("Publishing texture: "+imgUrl);
this.world.worldManager.VRSPACE.sendEvent(World.lastInstance.sharedTerrain, {diffuseTexture:imgUrl});
}
dispose() {
this.world.removeSelectionPredicate(this.selectionPredicate);
this.world.removeListener(this);
this.terrain.terrainMaterial.wireframe = false;
this.scene.onPointerObservable.remove(this.observer);
this.raiseButton.dispose();
this.digButton.dispose();
this.textureButton.dispose();
this.raiseSlider.dispose();
if ( World.lastInstance.ground ) {
World.lastInstance.ground.isPickable = this.groundPickable;
}
}
isSelectableMesh(mesh) {
// terrain is selectable only while editing
return this.editing && this.terrain && mesh == this.terrain.mesh();
}
}