Edgeshelper not updating position of mesh - javascript

I would like to draw a coloured box, including the edges (in a different colour)
This is the code I am using to create the box and edges. I have added them both to a object3D since I will have a number of differnt objects in the scene and would like to enforce encapsulation.
var mesh = new THREE.Mesh( geo, material );
var edge = new THREE.EdgesHelper( mesh, 0xffffff );
var container = new THREE.Object3D();
container.add(mesh);
container.add(edge);
scene.add(container);
The above posted code works and produces this:
But when I change the position of the parent object like so:
container.position.set(0,30,0);
Only the edges are moved. Why?
Adding .updateMatrix() to the container, mesh, or edges objects doesnt seem to produce different results.
How can the parent object be moved, included all of its children?

You need to add the helpers as children of the scene directly.
This is due to the following lines that appear in many of the helpers:
this.matrix = object.matrixWorld;
this.matrixAutoUpdate = false;
three.js r.70

Related

Drawing custom shapes with THREE BufferGeometry - shape is see through depending on angle

I am working with THREE.js and BufferGeometry to create a view of a set of points based on an image. Currently, I have the following:
As can be seen, the "object" that I have constructed has faces that can only be viewed from the opposite side as intended.
I have constructed my BufferGeometry with the a set of points with a corresponding array of normals, implemented like so (assuming that verts and norms are valid):
vertices = Float32Array.from(verts)
normals = Float32Array.from(norms)
// Make new geometry
geometry = new THREE.BufferGeometry();
geometry.setAttribute('position', new THREE.BufferAttribute(vertices, 3))
geometry.setAttribute('normal', new THREE.BufferAttribute(normals, 3))
material = new THREE.MeshPhongMaterial({color: 0xffffff})
mesh = new THREE.Mesh(geometry, material)
geometry.computeVertexNormals()
scene.add(mesh)
As you can see from trying to add the array of normals, I have tried adding normals in which all are (0,1,0). Without geometry.computeVertexNormals(), this still results in none of the faces being solid/behaving correctly. With such, the result in the image is generated.
What could be causing the solid to behave as such?

Three.js - update Mesh Colour of Object3D

I have a Three.js Object3D that I would like to update the colour of.
I originally construct the Mesh using a MeshStandardMaterial and add it into the scene. Later, I look up this object by ID and retrieve an Object3D from the scene. How can I update the colour of the Mesh at this point - is it possible?
If I have to delete the 3D object and add an entirely new one - is there a way to retrieve the geometry that was originally used to construct it from the Object3D itself? I would rather not store a mapping of the original geometry to an object's ID, as this would make the code messy. One option I can think of is to store the geometry on Object3D.UserData, but this is again suboptimal as currently the Meshes are constructed elsewhere - and then added to the scene (user data is available only once it has been added to the scene).
I find a way to add texture into a Object3D.
You can map children property to update material of meshes.
function onLoad(object) {
// `children` is an array of `Mesh` than contain 1 or more Meshes
object.children.forEach((mesh) => {
if (!mesh) return;
const material = mesh.material;
material.map = ghostColorTexture;
material.normalMap = ghostNormalTexture;
});
}
const objLoader = new OBJLoader();
objLoader.load(
'/models/ghost/model/ghost.obj',
onLoad,
undefined,
function (error) {
console.error('error', error);
}
);
An Object3D can be a Mesh that's composed of a Geometry and a Material. If you want to update the color, simply select that material, and assign a new color to it:
object.material.color.setHex(0xff9900); // Sets to orange
In the docs, you can see that .color is a property of MeshStandardMaterial and .material is a property of Mesh

Three.js - how to create custom shapes

I´m using Three.js and trying to create some custom shapes, similar to one that appears in a project from one of agencies using threejs:
three.js featured project esample
How did they generated these boxes with holes inside? (on that examples
boxes basically have only borders around and are empty inside).
As I saw in the code (I was trying to figure out myself) they use BoxGeometry but I have no idea how to accomplish that. Does anyone know or can give me any directions? It would be really helpfull as i´m stuck with this and have no idea on how to create them.
So in THREE.js Meshes represent any kind of 3D object. They combine Geometries and Shaders. Generally to create a mesh you call
var mesh = new THREE.Mesh( geometry, shader );
If you use any of the builtin shaders (also known as Materials [ MeshBasicMaterial, MeshLambertMaterial, etc]) they have a wireFrame boolean attribute that allows this functionality.
var geometry = new THREE.BoxGeometry( x, y, z ),
material = new THREE.MeshBasicMaterial( {
wireFrame: true, // This makes the object appear wireframe
color: 0xffffff // You can alter other properties
});
var box = new THREE.Mesh( geometry, material );
// You can also change it later
box.material.wireFrame = false;

Overlaying texture onto STL loaded mesh

I'm looking for an efficient method of overlaying a texture to cover a mesh. I'm not an expert, more a novice, when it comes to 3 dimensional mapping/objects. Below shows how I would like the end product to look.
When attempting to apply texture with the following code, the end result looks similar to below. I have not done any UV mapping, I believe my answer may be lay here. As you can see from the below image it roughly takes the general shade of the picture but I get the impression that the texture is being drawn between each vertice of the model rather than across the entirity.
var textureLoader = new THREE.TextureLoader();
var texture = textureLoader.load('resource/images/materials/Mahogany.jpg');
var STLLoader = new THREE.STLLoader();
STLLoader.load( 'test.stl', function ( geometry1 ) {
var meshMaterial = new THREE.MeshBasicMaterial({map:texture});
var mesh = new THREE.Mesh( geometry1, meshMaterial );
mesh.scale.set(1, 1, 1);
mesh.position.set(5, 20, 80);
scene.add(mesh);
});
The cube has the correct texturing, whereas my STL loaded mesh does not.
Please ignore the rotation of the object in the above picture, I will move to unioning my objects together once I have fixed my texturing issues.
Fairly new at asking questions on here so please do comment to help me expand my question if it's too general or not percise enough. Thank you.
You may use
THREE.MeshPhongMaterial()
instead of
THREE.MeshBasicMaterial()
THREE.MeshPhongMaterial() will wrap the material outside the object and we can get curved material as per the object.

How to Change a Box's dimensions/size after creation?

One can easily create a THREE.BoxGeometry where you have to pass arguments when creating as three separated arguments for width, height, and depth.
I would like to create any and all THREE[types]() with no parameters and set the values after that.
Is there a way to set the dimensions/size of the box geometry after creation (possibly buried in a Mesh already too)? other then scaling etc.
I couldn't find this in the documentation if so, otherwise maybe a major feature request if not a bug there. Any thoughts on how to classify this? maybe just a documentation change.
If you want to scale a mesh, you have two choices: scale the mesh
mesh.scale.set( x, y, z );
or scale the mesh's geometry
mesh.geometry.scale( x, y, z );
The first method modifies the mesh's matrix transform.
The second method modifies the vertices of the geometry.
Look at the source code so you understand what each scale method is doing.
three.js r.73
When you instantiate a BoxGeometry object, or any other geometry for that matter, the vertices and such buffers are created on the spot using the parameters provided. As such, it is not possible to simply change a property of the geometry and have the vertices update; the entire object must be re-instantiated.
You will need to create your geometries as you have the parameters for them available. You can however create meshes without geometries, add them to a scene, and update the mesh's geometry property once you have enough information to instantiate the object. If not that, you could also set a default value at first and then scale to reach your target.
Technically, scaling only creates the illusion of an updated geometry and the question did say (other then scaling). So, I would say a better approach would be to reassign the geometry property of your mesh to a new geometry.
mesh.geometry = new THREE.BoxGeometry(newSize, newSize, newSize)
With this approach you can update any aspect of the geometry including width segments for example. This is especially useful when working with non box geometries like cylinders or spheres.
Here is a full working example using this approach:
let size = 10
let newSize = 20
// Create a blank geometry and make a mesh from it.
let geometry = new THREE.BoxGeometry()
let material = new THREE.MeshNormalMaterial()
let mesh = new THREE.Mesh(geometry, material)
// Adding this mesh to the scene won't display anything because ...
// the geometry has no parameters yet.
scene.add(mesh)
// Unless you intend to reuse your old geometry dispose of it...
// this will significantly reduce memory footprint.
mesh.geometry.dispose()
// Update the mesh geometry to a new geometry with whatever parameters you desire.
// You will now see these changes reflected in the scene.
mesh.geometry = new THREE.BoxGeometry(size, size, size)
// You can update the geometry as many times as you like.
// This can be done before or after adding the mesh to the scene.
mesh.geometry = new THREE.BoxGeometry(newSize, newSize, newSize)

Categories

Resources