How to keep separate materials of merged Geometry - three.js

I managed to merge 2 pieces of geometry, namely plane and text. But the two materials must be separated at the end. How to do this ?
const globalMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const texture = THREE.ImageUtils.loadTexture(
"http://127.0.0.1:8080/pin_png/img_gps_dasloop_online.png"
);
texture.minFilter = THREE.LinearFilter;
const workerMaterial = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide,
});
const planeGeometry = new THREE.PlaneGeometry(1, 1);
const textGeometry = new THREE.TextGeometry(`Id : ${dbId}`, {
font: "monaco",
size: 1,
height: 0,
curveSegments: 3,
});
textGeometry.computeBoundingBox();
const workerIdMesh = new THREE.Mesh(textGeometry, globalMaterial);
const workerMesh = new THREE.Mesh(planeGeometry, workerMaterial);
// Merging
modelGeometry.merge(workerMesh.geometry, workerMesh.matrix);
modelGeometry.merge(workerIdMesh.geometry, workerIdMesh.matrix);
modelGeometry.computeVertexNormals();
const workerBufferGeometry = new THREE.BufferGeometry().fromGeometry(
modelGeometry
);
this.humanModel = new THREE.Mesh(workerBufferGeometry, workerMaterial);

Related

How to group Buffer Geometry Object in Autodesk Forge

I wondering is it posssible to add group of model group from scenebuilder. Initially I used a overlay.addMesh but I wanted to interact with a custom object that I created. Unfortunately the object must be a grouping. This is my code. Nothing appear on my Viewer.
this.sceneBuilder = await this.viewer.loadExtension(
"Autodesk.Viewing.SceneBuilder"
);
this.modelBuilder = await this.sceneBuilder.addNewModel({
modelNameOverride: "Beacon",
conserveMemory: false,
});
const sphereGeometry = new THREE.BufferGeometry().fromGeometry(
new THREE.SphereGeometry(5, 8, 8)
);
const sphereMaterial = new THREE.MeshPhongMaterial({
color: new THREE.Color(0.647, 0.165, 0.165),
});
this.meshBeacon = new THREE.Mesh(sphereGeometry, sphereMaterial);
this.meshBeacon2 = new THREE.Mesh(sphereGeometry, sphereMaterial);
this.meshBeacon.matrix = new THREE.Matrix4().compose(
position1,
quaternion,
scale
);
this.meshBeacon2.matrix = new THREE.Matrix4().compose(
position2,
quaternion,
scale
);
this.group = new THREE.Group();
this.group.add(this.meshBeacon);
this.group.add(this.meshBeacon2);
console.log(this.group);
this.group.dbId = 666666;
this.modelBuilder.addMesh(this.group);
We need to create single Geometry first. All done by this code.
let modelGeometry = new THREE.Geometry();
const globalMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const head = new THREE.SphereGeometry(0.5, 32, 16);
const body = new THREE.SphereGeometry(0.5, 32, 16);
const textGeometry = new THREE.TextGeometry("text ID", {
font: "monaco",
size: 1,
height: 0,
curveSegments: 3,
});
textGeometry.computeBoundingBox();
const textMaterial = new THREE.MeshBasicMaterial({ color: 0xff0000 });
const workerId = new THREE.Mesh(textGeometry, textMaterial);
const headMesh = new THREE.Mesh(head, globalMaterial);
const bodyMesh = new THREE.Mesh(body, globalMaterial);
headMesh.matrix.setPosition(new THREE.Vector3(0, 0, 3));
bodyMesh.matrix.scale(new THREE.Vector3(1, 1, 4));
// bodyMesh.matrix.scale(new THREE.Vector3(0.1, 0.1, 0.1));
modelGeometry.merge(headMesh.geometry, headMesh.matrix);
modelGeometry.merge(bodyMesh.geometry, bodyMesh.matrix);
modelGeometry.merge(workerId.geometry, workerId.matrix);

How to access camera three.js editor?

How do I access the standard camera in the three.js editor? I am trying to make a scene with a portal, in the scene I have two cameras (one inside the cube map) to project the image into the portal. In the case of a local project, everything works fine for me, but in the case of creating a similar scene in the editor, everything goes down a bad path. It seems to me that the reason is that when you click on PLAY, a new camera is created. I attach the script of the scene below. I hope that a solution will be found.
var mainMover, otherMover;
var otherCamera;
var portalA, portalB;
var portalRing;
function init() {
otherCamera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000);
//console.log(this.children[3].children[0]);
let ambientLight = new THREE.AmbientLight(0xcccccc, 1.00);
scene.add(ambientLight);
deltaTime = 0;
totalTime = 0;
let loader = new THREE.TextureLoader();
let defaultMaterial = new THREE.MeshBasicMaterial({
map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/sphere-colored.png"),
color: 0x444444,
side: THREE.DoubleSide,
transparent: true
});
// Portal A ================================
portalA = new THREE.Mesh(
new THREE.CircleGeometry(1, 64),
defaultMaterial.clone()
);
portalA.material.opacity = 0.5;
portalA.position.set(-22, 0.5, -3);
portalA.rotation.y = Math.PI / 4;
portalA.layers.set(1);
scene.add(portalA);
portalRing = new THREE.Mesh(
new THREE.RingGeometry(1, 1.1, 64),
new THREE.MeshBasicMaterial({ color: 0xffff00, side: THREE.DoubleSide, transparent: true })
);
portalRing.position.copy(portalA.position);
portalRing.rotation.copy(portalA.rotation);
portalRing.layers.set(0);
scene.add(portalRing);
mainMover = new THREE.Group();
mainMover.position.set(-21, 0.5, 0);
mainMover.add(camera);
mainMover.name = "mainMover";
scene.add(mainMover);
// Portal B - ================================
let skyMaterialArray2 = [
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/posx.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/negx.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/posy.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/negy.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/posz.jpg"), side: THREE.BackSide }),
new THREE.MeshBasicMaterial({ map: loader.load("https://raw.githubusercontent.com/stemkoski/AR-Examples/master/images/mountain/negz.jpg"), side: THREE.BackSide }),
];
let skyMesh2 = new THREE.Mesh(
new THREE.BoxGeometry(30, 30, 30),
skyMaterialArray2);
skyMesh2.position.x = 20;
scene.add(skyMesh2);
portalB = new THREE.Mesh(
new THREE.CircleGeometry(1, 64),
defaultMaterial.clone()
);
portalB.material.opacity = 0.5;
portalB.position.set(24, 0.5, -5);
portalB.rotation.y = -Math.PI / 4;
portalB.layers.set(2);
scene.add(portalB);
otherMover = new THREE.Group();
otherMover.add(otherCamera);
scene.add(otherMover);
}
function update() {
portalRing.material.color.setHSL(totalTime / 10 % 1, 1, 0.75);
let relativePosition = portalA.worldToLocal(mainMover.position.clone());
otherMover.position.copy(portalB.localToWorld(relativePosition));
let relativeRotation = mainMover.quaternion.clone().multiply(portalA.quaternion.clone().invert());
otherMover.quaternion.copy(relativeRotation.multiply(portalB.quaternion));
otherCamera.rotation.x = camera.rotation.x;
render()
}
function render() {
camera.layers.enable(0);
camera.layers.enable(1);
renderer.render(scene, camera);
let gl = renderer.getContext();
renderer.clear(true, true, true);
renderer.autoClear = false;
// FIRST PASS (enable stencil buffer)
gl.enable(gl.STENCIL_TEST);
camera.layers.set(1);
gl.stencilFunc(gl.ALWAYS, 1, 0xff);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.REPLACE);
gl.stencilMask(0xff);
gl.colorMask(false, false, false, false);
gl.depthMask(false);
renderer.render(scene, camera);
//SECOND PASS
let portalToCamera = new THREE.Vector3().subVectors(mainMover.position.clone(), portalA.position.clone()); // applyQuaternion( mainMover.quaternion );
let normalPortal = new THREE.Vector3(0, 0, 1).applyQuaternion(portalA.quaternion);
let clipSide = -Math.sign(portalToCamera.dot(normalPortal));
let clipNormal = new THREE.Vector3(0, 0, clipSide).applyQuaternion(portalB.quaternion);
let clipPoint = portalB.position;
let clipPlane = new THREE.Plane().setFromNormalAndCoplanarPoint(clipNormal, clipPoint);
renderer.clippingPlanes = [clipPlane];
gl.colorMask(true, true, true, true);
gl.depthMask(true);
gl.stencilFunc(gl.EQUAL, 1, 0xff);
gl.stencilOp(gl.KEEP, gl.KEEP, gl.KEEP);
otherCamera.layers.set(0);
renderer.render(scene, otherCamera);
renderer.clippingPlanes = [];
//THIRD PASS
gl.disable(gl.STENCIL_TEST);
gl.colorMask(false, false, false, false);
gl.depthMask(true);
renderer.clear(false, true, false);
renderer.render(scene, camera);
//FINAL PASS
gl.colorMask(true, true, true, true);
gl.depthMask(true);
camera.layers.set(0);
renderer.render(scene, camera);
renderer.autoClear = true;
}
UPDATE:
I added a helper for the camera, so the main camera should be in place of the cube. But, for some reason, when PLAYING, I find myself not in the place of this cube... (just create a mesh: let mainCameraMesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), new THREE.MeshBasicMaterial());
When you create a script in the three.js editor, you have access to certain global variables within the update() function. Next to the renderer and scene, you can also access the perspective camera. Just try this:
function update( event ) {
console.log( camera );
}

three js - How a sphere can shine inside it emitting light to all directions

How to make the sun as a sphere shine inside it and radiate light in all directions?
thanks in advance
I have only this rendering at screen the SUN in the center and a box to see how light reflects to it.
// create a geometry
const radius = 2;
const widthSegments = 100;
const heightSegments = 96;
const geometry = new THREE.SphereBufferGeometry(
radius,
widthSegments,
heightSegments
);
const geometry1 = new THREE.BoxBufferGeometry(3, 13, 3);
//create texture loader
const textureLoader = new THREE.TextureLoader();
const texture = textureLoader.load("https://i.ibb.co/3srcxqp/Sol.jpg");
texture.encoding = THREE.sRGBEncoding;
texture.anisotropy = 16;
const material = new THREE.MeshStandardMaterial({
map: texture,
color: "#ffffff",
specular: "#ffffff",
transparent: true,
side: THREE.DoubleSide,
alphaTest: 0.5,
opacity: 1,
roughness: 1,
});
material.alphaMap = texture;
material.alphaMap.magFilter = THREE.NearestFilter;
material.alphaMap.wrapT = THREE.RepeatWrapping;
material.alphaMap.repeat.y = 1;
var material1 = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
mesh = new THREE.Mesh(geometry, material);
const mesh1 = new THREE.Mesh(geometry1, material1);
scene.add(mesh);
scene.add(mesh1);
mesh1.position.set(-10, -10, -10);
mesh1.updateMatrix();

STL file read using three.js issue

I am able to read successfully stl file by three.js but problem is that is not showing exact color which is defined in the stl file. My code looks like:
var loader = new THREE.STLLoader();
loader.addEventListener( 'load', function ( event ) {
var geometry = event.content;
var material = new THREE.MeshPhongMaterial( { ambient: 0x555555, color: 0xAAAAAA, specular: 0x111111, shininess: 200 } );
if (geometry.hasColors) {
material = new THREE.MeshPhongMaterial({ color: 0xFFFFFF, specular: 0x111111, ambient: 0x555555, opacity: geometry.alpha, vertexColors: THREE.VertexColors });
}
var mesh = new THREE.Mesh( geometry, material );
mesh.position.x = x - w/2;
mesh.position.y = y;
mesh.position.z = - h + h/2 + z/2;
//mesh.rotation.set( 0.5, 0, 0 );
mesh.castShadow = true;
mesh.receiveShadow = true;
board.add(mesh);
} );
loader.load( fileName );
But its showing only black color after applying vertex color.
Any suggestion?

how to use imgVar inTHREE3.ImageUtils.loadTexture( imgVar )?

taken from AlteredQualia demo:
map = THREE3.ImageUtils.loadTexture( "textures/terrain/grasslight-big.jpg" );
map.wrapS = map.wrapT = THREE3.RepeatWrapping;
map.repeat.set( 16, 16 );
var planeGeo = new THREE3.PlaneGeometry( 200, 200 );
ground = new THREE3.Mesh( planeGeo, new THREE3.MeshPhongMaterial( { color: 0xffffff, ambient: 0xffffff, specular: 0x111111, shininess: 50, map: map, perPixel: true, metal: true } ) );
I have extracted png data from an HTML canvas with ExtJS Ext.getDom('cnvs_img').src; into a var and the var string starts " data:image/png;base64, ..." so think it is valid. I want to use this data instead of loading from disk with loadTexture. Would appreciate some pointers, thanks.
THREE3.ImageUtils.loadTexture( imgVar ) does not work of course :-)
To load a texture from a dataURL, you can follow this pattern:
var image = document.createElement( 'img' );
image.src = dataURL;
image.onload = function() {
var texture = new THREE.Texture( image );
texture.needsUpdate = true; // important!
var material = new THREE.MeshLambertMaterial( {
color: 0xffffff,
map: texture
} );
var mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
};
three.js r.67

Resources