How to travel multiple navmeshes in Patrol.JS? - three.js

I am using patrol.js. for navigation. On one navmesh I can navigate. Suppose I have to navMesh Can i navigate from one navMesh to other navmesh.
code for one navmesh
var objLoader = new THREE.OBJLoader();
objLoader.load( 'https://objpatroljs-zzcpndkpct.now.sh/navmesh.obj', function( object ) {
object.traverse(function (node) {
if (node.type === 'Mesh') navmesh = node;
});
var geometry = new THREE.Geometry();
geometry.fromBufferGeometry(navmesh.geometry);
var zoneNodes = patrol.buildNodes(geometry);
patrol.setZoneData('level', zoneNodes);
Object.assign(navmesh.material, {
color: 0x009688,
opacity: 0.5,
transparent: true
});
scene.add(navmesh);
// Set the player's navigation mesh group
playerNavMeshGroup = patrol.getGroup('level', player.position);
});
see image
Thank You..!

If you want to find a path between two navmeshes, you would need to merge them into one mesh.

Related

How to attach an image to loaded object in Three.js

I'm trying to attach a custom image to an object (.obj)
What I want is
But the result is
I want the image to be located in the center of the object for only one time. But the image is repeated to fill the entire material.
I googled a lot and read some articles about uv mapping but I could not figure out how to apply to a custom object.
Following is my code. Thanks in advance.
var mtlLoader = new MTLLoader();
mtlLoader.load("~~~.mtl", function (materials) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(materials);
objLoader.load(
"~~.obj",
function (geometry) {
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load("~~.jpg");
var material = new THREE.MeshLambertMaterial({
transparent: true,
map: texture, // <- ??
});
texture.minFilter = THREE.LinearFilter;
texture.wrapS = texture.wrapT = THREE.ClampToEdgeWrapping;
geometry.traverse(function (child) {
if (child instanceof THREE.Mesh) {
child.material = material;
}
});
scene.add(geometry);
}

Is there a way to add surface points/particles on the faces and not just vertices of a 3D .OBJ file on Three JS?

var loader = new THREE.OBJLoader();
// load a resource
loader.load(
// resource URL
'public/_resources/themes/webgl/images/Horse.obj',
// called when resource is loaded
function(object) {
object.traverse(function(child) {
if (child instanceof THREE.Mesh) {
var material = new THREE.PointsMaterial({
color: 0x000000
});
var points = new THREE.Points(child.geometry, material);
scene.add(points)
}
});
scene.add(object);
},
The above code adds to the vertices only, is there a way to add thousands of them on the Horse.obj SURFACE? It is using BufferGeometry. Kindly let me know thank you.

Update three.js Group after it was added to the scene on runtime

I have a THREE.Group(); in my scene and at runtime i want to add more to this group but it doesn't get updatet or better i cannot see the sprite that i added on runtime. The sprite is in the group but not rendered.
How can i update a THREE.Group();?
Example Code to clarify my problem. Not really running i know.
var systemGroup = new THREE.Group();
init();
animate();
function init() {
//add something to systemGroup like multiple meshes
systemGroup.add(mesh);
scene.add(systemGroup);
}
function render() {
scene.updateMatrixWorld();
renderer.render( scene, camera );
}
function animate() {
requestAnimationFrame( animate );
render();
}
function addMore(x,y,z){
var map = THREE.ImageUtils.loadTexture( "sprite.png" );
var material = new THREE.SpriteMaterial( { map: map, color: 0xffffff, fog: true } );
var sprite = new THREE.Sprite( material );
sprite.position.set(x,y,z);
systemGroup.add(sprite);
//Here how do i update the group so that the mesh is in the scene?
}
Thank you.
The code you are showing is adding the same mesh over and over again.
As the mesh is already in the group, it doesn't change anything.
What you seem to want is to clone() the mesh and add it at a different position.
Like this:
var group = new THREE.Group()
scene.add(group);
document.body.addEventListener('click', function(evt) {
var clone = mesh.clone()
clone.position.set(-100 + Math.random()*200, 0, 0)
group.add(mesh)
})
No need to update the group with anything else.

ThreeJS – way to show one object by intersecting another

I try to write a ThreeJS interaction where the user hovers a sphere and a connected text object will show up. The problem is to show the connected text object with the intersected sphere so every sphere shows its own text.
For now I only could show the same text object for each intersected sphere. I think there's some code in the raycast section missing that picks the right text object.
//create textObjects and add to scene
var selectTitles = [];
for (var i = 0; i < numSpheres; i++) {
var title = 'Title '+i;
var textGeom = new THREE.TextGeometry( title, {size: 0.5,height: 0});
var textMaterial = new THREE.MeshBasicMaterial({color:0x334455,transparent: true, opacity: 0});
var titles = new THREE.Mesh( textGeom, textMaterial );
group.add( titles );
titles = selectTitles[i];
}
//onMouseOver
if (intersects[0].object != INTERSECTED) {
INTERSECTED = intersects[0].object;
// here 'titles' doesn't pick different text objects because of the missing 'intersected' connection
new TWEEN.Tween(titles.material).to({opacity:1},350)
.easing(TWEEN.Easing.Bounce.EaseOut).start();
}
I advise you to stick to the same order, much like in the examples on the site threejs.org:
// global variables
var camera;
var scene;
...
window.onload = function() {
init();
render(); //final output
}
function init() {
...
}
function render() {
...
}
I took the liberty to alter your code. Here is the result. Code here.

three.js how to make double sided object

Blender export obj don't export double sided objects. How can I render objects in double sided mode. I tried this without succes:
var loader = new THREE.OBJMTLLoader();
loader.load('models/test.obj');
loader.addEventListener( 'load', function ( event ) {
objects = event.content;
objects.position.set(0,5,0);
objects.scale.set(1.5,1.5,1.5);
objects.mesh.doubleSided = true;
scene.add(objects);
});
In your case, you add the following to your callback function:
objects.traverse( function( node ) {
if( node.material ) {
node.material.side = THREE.DoubleSide;
}
});
The doubleSided property of Mesh is deprecated. It was replaced with the side property of Material
Also, it is best to learn from three.js examples that work with the current version of the library.
three.js r.57
2022
Future readers! Just add the side option to the material constructor:
const material = new THREE.MeshLambertMaterial({
color: 0xff0000,
side: THREE.DoubleSide
// ^ this line here
});

Resources