I'm back for question two on .points. This time wondering how to change the opacity from 0, to 1 and then back within certain pixel distances from the emitter.
var particleCount = 14,
particles = new THREE.Geometry(),
pMaterial = new THREE.PointsMaterial({
map: new THREE.TextureLoader().load("x.png"),
blending: THREE.multiplyBlending,
flatShading: true,
size: 40,
transparent: true,
depthTest: true,
sizeAttenuation: true,
opacity: 1
});
var particleSystem;
My main confusion is that even though I've given it transparency I can't change the value within the update comp I've made for my emitter.
function update() {
//particleSystem.rotation.y += 0.01;
pCount = particleCount;
while (pCount--) {
particle = particles.vertices[pCount];
(This is where a bunch of validation is for where the points are)
particleSystem.geometry.verticesNeedUpdate = true;
particleSystem.rotation.y += (Math.random()*0.001)
}
Render loop:
renderer.setAnimationLoop(() => {
update();
composer.render(scene, camera);
});
I want to make it fade out and not appear in the scene for 20 or so pixels and then fade in. But I'm not entirely sure on how to change the opacity as particle.opacity += 0.1 won't work.
Edit: I'm also uncertain about Size as I want to do a similar thing with it but from 20 to 40, I could probably base it depending on it's Y cordinate. Anyway; I'm also uncertain how to gradually change that too.
Sorry if this is a obvious answer, duplicate question and any help I get. Any alternate methods of what I've seen is in an alternate structure that I don't understand or in array in which I don't know how to put into what I want.
(Thanks in advance)
The issue is that the opacity and the size is a property of the THREE.PointsMaterial. If the pints should have different sizes it is not sufficient to have a list of different vertices in one THREE.Points. There has to be a list of different THREE.Points with different HREE.PointsMaterials.
Create a list of THREE.Points with different materials:
var texture = new THREE.TextureLoader().load( "..." );
var particleSystemCount = 14;
var particleSystems = [];
for (var i = 0; i < particleSystemCount; ++ i) {
var geometry = new THREE.Geometry();
var pMaterial = new THREE.PointsMaterial({
size: 20,
map: texture,
blending: THREE.AdditiveBlending,
transparent: true,
depthTest: false,
sizeAttenuation: true,
opacity: 0
});
// ...
var points = new THREE.Points(geometry, pMaterial);
scene.add(points);
particleSystems.push(points);
}
So in update the opacity and size can be changed individually:
function update() {
for (var i = 0; i < particleSystems.length; ++ i) {
var points = particleSystems[i];
var material = points.material;
var particle = points.geometry.vertices[0];
// ....
if ( material.size < 40 )
material.size += 0.5;
if ( material.opacity < 1 )
material.opacity += 0.01;
// ....
}
}
var canvas_w = window.innerWidth, canvas_h = window.innerHeight;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, canvas_w/canvas_h, 1, 1000);
camera.position.set(0, 0, 400);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(canvas_w, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.onresize = function() {
canvas_w = window.innerWidth, canvas_h = window.innerHeight;
renderer.setSize(canvas_w, canvas_h);
camera.aspect = canvas_w/canvas_h;
camera.updateProjectionMatrix();
}
var texture = new THREE.TextureLoader().load("https://threejs.org/examples/textures/sprites/circle.png");
var particleSystemCount = 14;
var particleSystems = [];
for (var i = 0; i < particleSystemCount; ++ i) {
var geometry = new THREE.Geometry();
var pMaterial = new THREE.PointsMaterial({
size: 20,
map: texture,
blending: THREE.AdditiveBlending,
transparent: true,
depthTest: false,
sizeAttenuation: true,
opacity: 0
});
var px = (Math.random() - 0.5) * 100;
var py = (Math.random() - 0.5) * 100 + 200;
var pz = (Math.random() - 0.5) * 100;
var particle = new THREE.Vector3(px, py, pz);
particle.velocity = new THREE.Vector3(0, 0, 0);
geometry.vertices.push(particle);
var points = new THREE.Points(geometry, pMaterial);
scene.add(points);
particleSystems.push(points);
}
function update() {
for (var i = 0; i < particleSystems.length; ++ i) {
var points = particleSystems[i];
var material = points.material;
var particle = points.geometry.vertices[0];
if (particle.y < -200) {
particle.x = (Math.random() - 0.5) * 100;
particle.y = (Math.random() - 0.5) * 100 + 200;
particle.z = (Math.random() - 0.5) * 100;
particle.velocity.y = 0;
material.size = 20;
material.opacity = 0;
}
particle.velocity.y -= Math.random() * .1;
particle.add(particle.velocity);
if ( material.size < 40 )
material.size += 0.25;
if ( material.opacity < 1 )
material.opacity += 0.01;
points.geometry.verticesNeedUpdate = true;
points.rotation.y += (Math.random()*0.001)
}
}
renderer.setAnimationLoop(() => {
update();
renderer.render(scene, camera);
});
body { overflow: hidden; margin: 0; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/99/three.min.js"></script>
Related
I'm working on a little three.js scene in which I want to drive a car down a road. The trouble is my car is flipping end to end each frame, instead of rolling on its tires:
Does anyone know how I can make my car roll with cannon.js? Any pointers would be hugely helpful. For the sake of preservation, here's my raw scene:
var carBody,
floorBody,
pressed = {},
rotation = 0,
clock = new THREE.Clock(),
loader = new THREE.TextureLoader(),
container = document.querySelector('body'),
w = container.clientWidth,
h = container.clientHeight,
scene = new THREE.Scene(),
camera = new THREE.PerspectiveCamera(75, w/h, 0.1, 100000),
controls = new THREE.TrackballControls(camera, container),
renderConfig = {antialias: true, alpha: true},
renderer = new THREE.WebGLRenderer(renderConfig);
controls.target = new THREE.Vector3(0, 0, 0.75);
controls.panSpeed = 0.4;
camera.position.set(0,80,-4900);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(w, h);
container.appendChild(renderer.domElement);
window.addEventListener('resize', function() {
w = container.clientWidth;
h = container.clientHeight;
camera.aspect = w/h;
camera.updateProjectionMatrix();
renderer.setSize(w, h);
})
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
if (car && carBody && carBody.position) {
moveCar();
updatePhysics();
moveCamera();
//controls.update();
}
}
function getPlane(img, w, h, wrap) {
var texture = loader.load(img);
if (wrap) {
texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
texture.repeat.set(10, 10);
}
var material = new THREE.MeshBasicMaterial({
map: texture,
side: THREE.DoubleSide,
});
var geometry = new THREE.PlaneGeometry(w, h, 10, 10);
return new THREE.Mesh(geometry, material);
}
function getSides() {
var d = 300;
var group = new THREE.Group();
for (var i=0; i<2; i++) {
var plane = getPlane('asphalt.jpg', 10000, 200, true);
plane.position.y = 100;
plane.rotation.set(Math.PI/2, -Math.PI/2, Math.PI/2);
plane.position.x = i == 0 ? -d : d;
group.add(plane);
}
return group;
}
function getSky() {
var directions = ['right', 'left', 'top', 'bottom', 'front', 'back'];
var geometry = new THREE.BoxGeometry(50000, 50000, 50000);
var materialArray = [];
for (var i=0; i<6; i++)
materialArray.push( new THREE.MeshBasicMaterial({
map: loader.load(directions[i] + '.bmp'),
side: THREE.BackSide
}));
return new THREE.Mesh( geometry, materialArray );
}
function getCar() {
var mtlLoader = new THREE.MTLLoader();
mtlLoader.load('car.mtl', function(mat) {
mat.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials(mat);
objLoader.load('car.obj', function(obj) {
window.car = obj;
car.scale.set(0.1, 0.1, 0.1);
obj.position.set(0, 0, -4800);
scene.add(obj);
})
})
}
function getPhysics() {
world = new CANNON.World();
world.gravity.set(0, -100, 0); // earth = -9.82 m/s
world.broadphase = new CANNON.NaiveBroadphase();
world.broadphase.useBoundingBoxes = true;
var solver = new CANNON.GSSolver();
solver.iterations = 7;
solver.tolerance = 0.1;
world.solver = solver;
world.quatNormalizeSkip = 0;
world.quatNormalizeFast = false;
world.defaultContactMaterial.contactEquationStiffness = 1e9;
world.defaultContactMaterial.contactEquationRelaxation = 4;
return world;
}
function addPhysics() {
var m = getPhysicsMaterial();
carBody = new CANNON.Body({
mass: 10,
material: m,
shape: new CANNON.Sphere(30),
linearDamping: 0.6,
angularDamping: 0.8,
position: new CANNON.Vec3(0, 30, -4900)
});
world.addBody(carBody);
// floor
var q = floor.quaternion;
var floorBody = new CANNON.Body({
mass: 0, // mass = 0 makes the body static
material: m,
shape: new CANNON.Plane(),
quaternion: new CANNON.Quaternion(-q._x, q._y, q._z, q._w)
});
world.addBody(floorBody);
}
function getPhysicsMaterial() {
var m = new CANNON.Material('slipperyMaterial');
var c = new CANNON.ContactMaterial(m, m, {
friction: 0.3,
restitution: 0.3,
})
world.addContactMaterial(c);
return m;
}
function moveCar() {
var delta = clock.getDelta(); // seconds
var moveDistance = 2000 * delta; // n pixels per second
// set roll sensitivity
var sensitivity = 1.5;
var rotateAngle = Math.PI / 2 * delta * sensitivity;
// determine the direction to travel
var p = carBody.position;
var dir = new THREE.Vector3(p.x, p.y, p.z);
dir.sub(camera.position).normalize(); // vector b/w camera and car
if (pressed['W'] || pressed['ARROWUP']) {
carBody.velocity.x += moveDistance * dir.x;
carBody.velocity.z += moveDistance * dir.z;
}
if (pressed['S'] || pressed['ARROWDOWN']) {
carBody.velocity.x -= moveDistance * dir.x;
carBody.velocity.z -= moveDistance * dir.z;
}
if (pressed['A'] || pressed['ARROWLEFT']) {
rotation += rotateAngle;
}
if (pressed['D'] || pressed['ARROWRIGHT']) {
rotation -= rotateAngle;
}
if (pressed[' ']) {
carBody.velocity.y = 10;
}
}
function updatePhysics() {
world.step(1/60);
car.position.copy(carBody.position);
car.quaternion.copy(carBody.quaternion);
}
function moveCamera() {
var rotZ = Math.cos(rotation);
var rotX = Math.sin(rotation);
var distance = 100;
camera.position.x = carBody.position.x - (distance * rotX);
camera.position.y = carBody.position.y + 20;
camera.position.z = carBody.position.z - (distance * rotZ);
camera.lookAt(car.position);
}
window.addEventListener('keydown', function(e) {
pressed[e.key.toUpperCase()] = true;
})
window.addEventListener('keyup', function(e) {
pressed[e.key.toUpperCase()] = false;
})
/**
* Add elems
**/
var light = new THREE.HemisphereLight(0xffffbb, 0x080820, 1);
scene.add(light);
var geometry = new THREE.PlaneGeometry(10000, 10000);
var material = new THREE.MeshBasicMaterial();
var floor = new THREE.Mesh(geometry, material);
floor.rotation.x = Math.PI / 2;
scene.add(floor);
var street = getPlane('asphalt.jpg', 10000, 1000, true);
street.rotation.x = Math.PI/2;
street.rotation.z = Math.PI/2;
scene.add(street);
var sides = getSides();
scene.add(sides);
var sky = getSky();
scene.add(sky);
var car = getCar();
var world = getPhysics();
addPhysics();
render();
html,
body {
width: 100%;
height: 100%;
background: #aaa;
}
body {
margin: 0;
overflow: hidden;
}
canvas {
width: 100%;
height: 100%;
}
<script src="https://threejs.org/build/three.min.js"></script>
<script src='https://cdnjs.cloudflare.com/ajax/libs/cannon.js/0.6.2/cannon.js'></script>
<script src='https://raw.githack.com/mrdoob/three.js/master/examples/js/loaders/ObjLoader.js'></script>
<script src='https://raw.githack.com/mrdoob/three.js/master/examples/js/loaders/MTLLoader.js'></script>
<script src='https://raw.githack.com/mrdoob/three.js/master/examples/js/controls/TrackballControls.js'></script>
I'm trying to rotate each particle along its own axis of rotation rather than rotate them all along one point. I've looked at many similar questions on setting the pivot points, but I'm lost and confused to be honest.
My goal is to animate the particles as if they're falling from top to bottom, similar to this animation.
var camera,
scene,
renderer,
materials = [],
parameters;
var windowHalfX = window.innerWidth / 2,
windowHalfY = window.innerHeight / 2;
var particles = [];
var confetti = {
maxCount: 2000, //set max confetti count
speed: 1, //set the particle animation speed
frameInterval: 30, //the confetti animation frame interval in milliseconds
waveThreshold: 3, //
start: null, //call to start confetti animation (with optional timeout in milliseconds, and optional min and max random confetti count)
stop: null, //call to stop adding confetti
toggle: null, //call to start or stop the confetti animation depending on whether it's already running
pause: null, //call to freeze confetti animation
resume: null, //call to unfreeze confetti animation
togglePause: null, //call to toggle whether the confetti animation is paused
remove: null, //call to stop the confetti animation and remove all confetti immediately
isPaused: null, //call and returns true or false depending on whether the confetti animation is paused
isRunning: null //call and returns true or false depending on whether the animation is running
};
init();
animate();
window.addEventListener('resize', onWindowResize);
function init() {
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 20, 900);
camera.position.z = 100;
var geometry = new THREE.BufferGeometry();
var vertices = [];
var textureLoader = new THREE.TextureLoader();
var sprite1 = textureLoader.load('https://i.postimg.cc/Rhx8t6CM/confetti1.png');
var sprite2 = textureLoader.load('https://i.postimg.cc/Rhx8t6CM/confetti1.png');
var sprite3 = textureLoader.load('https://i.postimg.cc/Rhx8t6CM/confetti1.png');
var sprite4 = textureLoader.load('https://i.postimg.cc/Rhx8t6CM/confetti1.png');
var sprite5 = textureLoader.load('https://i.postimg.cc/Rhx8t6CM/confetti1.png');
for (var i = 0; i < confetti.maxCount; i++) {
var x = Math.random() * 2000 - 1000;
var y = Math.random() * 2000 - 1000;
var z = Math.random() * 1000 - 900;
vertices.push(x, y, z);
//particles[i].tilt = Math.random() * 10 - 10;
//particle.tiltAngleIncrement = Math.random() * 0.07 + 0.05;
//particles[i].tiltAngle = Math.random() * Math.PI;
particles.push({
'tilt': Math.random() * 1 - 1,
'tiltAngle': Math.random() * Math.PI
})
}
geometry.setAttribute('position', new THREE.Float32BufferAttribute(vertices, 3));
parameters = [
[sprite2, 10],
[sprite3, 9],
[sprite1, 10],
[sprite5, 8],
[sprite4, 10]
];
for (var i = 0; i < parameters.length; i++) {
var sprite = parameters[i][0];
var size = parameters[i][1];
materials[i] = new THREE.PointsMaterial({
size: size,
map: sprite,
blending: THREE.AdditiveBlending,
depthTest: false,
transparent: true
});
var particle = new THREE.Points(geometry, materials[i]);
particle.rotation.x = Math.random() * 5;
particle.rotation.y = Math.random() * 5;
particle.rotation.z = Math.random() * 5;
scene.add(particle);
}
renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setClearColor('#121212')
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function onWindowResize() {
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
var time = Date.now() * 0.00005;
for (var i = 0; i < scene.children.length; i++) {
var object = scene.children[i];
if (object instanceof THREE.Points) {
//object.rotation.x = time * ( i < 4 ? i + 1 : ( i + 1 ) );
//object.position.x -= time * ( i < 4 ? i + 1 : -( i + 1 ) );
object.position.y -= 1;
object.position.x += particles[i]['tilt'] / 3;
object.rotation.y += .001;
//object.rotation.x += time * particles[i]['tiltAngle'];
}
}
renderer.render(scene, camera);
}
body {
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/109/three.js" type="text/javascript"></script>
I just started exploring three.js and have been trying to adapt a project I found.
I would like to know if it would be possible to have the globe object rotate around it's y-axis with minor additions to the code or whether it has to be rewritten from the ground up.
var canvas = document.querySelector('canvas');
var width = canvas.offsetWidth,
height = canvas.offsetHeight;
var colors = [
new THREE.Color(0xac1122),
new THREE.Color(0x96789f),
new THREE.Color(0x535353)];
var renderer = new THREE.WebGLRenderer({
canvas: canvas,
antialias: true
});
renderer.setPixelRatio(window.devicePixelRatio > 1 ? 2 : 1);
renderer.setSize(width, height);
renderer.setClearColor(0xffffff);
var scene = new THREE.Scene();
var raycaster = new THREE.Raycaster();
raycaster.params.Points.threshold = 6;
var camera = new THREE.PerspectiveCamera(50, width / height, 0.1, 2000);
camera.position.set(0, 0, 350);
var galaxy = new THREE.Group();
scene.add(galaxy);
// Create dots
var loader = new THREE.TextureLoader();
loader.crossOrigin = "";
var dotTexture = loader.load("img/dotTexture.png");
var dotsAmount = 3000;
var dotsGeometry = new THREE.Geometry();
var positions = new Float32Array(dotsAmount * 3);
var sizes = new Float32Array(dotsAmount);
var colorsAttribute = new Float32Array(dotsAmount * 3);
for (var i = 0; i < dotsAmount; i++) {
var vector = new THREE.Vector3();
vector.color = Math.floor(Math.random() * colors.length);
vector.theta = Math.random() * Math.PI * 2;
vector.phi =
(1 - Math.sqrt(Math.random())) *
Math.PI /
2 *
(Math.random() > 0.5 ? 1 : -1);
vector.x = Math.cos(vector.theta) * Math.cos(vector.phi);
vector.y = Math.sin(vector.phi);
vector.z = Math.sin(vector.theta) * Math.cos(vector.phi);
vector.multiplyScalar(120 + (Math.random() - 0.5) * 5);
vector.scaleX = 5;
if (Math.random() > 0.5) {
moveDot(vector, i);
}
dotsGeometry.vertices.push(vector);
vector.toArray(positions, i * 3);
colors[vector.color].toArray(colorsAttribute, i*3);
sizes[i] = 5;
}
function moveDot(vector, index) {
var tempVector = vector.clone();
tempVector.multiplyScalar((Math.random() - 0.5) * 0.2 + 1);
TweenMax.to(vector, Math.random() * 3 + 3, {
x: tempVector.x,
y: tempVector.y,
z: tempVector.z,
yoyo: true,
repeat: -1,
delay: -Math.random() * 3,
ease: Power0.easeNone,
onUpdate: function () {
attributePositions.array[index*3] = vector.x;
attributePositions.array[index*3+1] = vector.y;
attributePositions.array[index*3+2] = vector.z;
}
});
}
var bufferWrapGeom = new THREE.BufferGeometry();
var attributePositions = new THREE.BufferAttribute(positions, 3);
bufferWrapGeom.addAttribute('position', attributePositions);
var attributeSizes = new THREE.BufferAttribute(sizes, 1);
bufferWrapGeom.addAttribute('size', attributeSizes);
var attributeColors = new THREE.BufferAttribute(colorsAttribute, 3);
bufferWrapGeom.addAttribute('color', attributeColors);
var shaderMaterial = new THREE.ShaderMaterial({
uniforms: {
texture: {
value: dotTexture
}
},
vertexShader: document.getElementById("wrapVertexShader").textContent,
fragmentShader: document.getElementById("wrapFragmentShader").textContent,
transparent:true
});
var wrap = new THREE.Points(bufferWrapGeom, shaderMaterial);
scene.add(wrap);
// Create white segments
var segmentsGeom = new THREE.Geometry();
var segmentsMat = new THREE.LineBasicMaterial({
color: 0xffffff,
transparent: true,
opacity: 0.3,
vertexColors: THREE.VertexColors
});
for (i = dotsGeometry.vertices.length - 1; i >= 0; i--) {
vector = dotsGeometry.vertices[i];
for (var j = dotsGeometry.vertices.length - 1; j >= 0; j--) {
if (i !== j && vector.distanceTo(dotsGeometry.vertices[j]) < 12) {
segmentsGeom.vertices.push(vector);
segmentsGeom.vertices.push(dotsGeometry.vertices[j]);
segmentsGeom.colors.push(colors[vector.color]);
segmentsGeom.colors.push(colors[vector.color]);
}
}
}
var segments = new THREE.LineSegments(segmentsGeom, segmentsMat);
galaxy.add(segments);
var hovered = [];
var prevHovered = [];
function render(a) {
var i;
dotsGeometry.verticesNeedUpdate = true;
segmentsGeom.verticesNeedUpdate = true;
raycaster.setFromCamera( mouse, camera );
var intersections = raycaster.intersectObjects([wrap]);
hovered = [];
if (intersections.length) {
for(i = 0; i < intersections.length; i++) {
var index = intersections[i].index;
hovered.push(index);
if (prevHovered.indexOf(index) === -1) {
onDotHover(index);
}
}
}
for(i = 0; i < prevHovered.length; i++){
if(hovered.indexOf(prevHovered[i]) === -1){
mouseOut(prevHovered[i]);
}
}
prevHovered = hovered.slice(0);
attributeSizes.needsUpdate = true;
attributePositions.needsUpdate = true;
renderer.render(scene, camera);
}
function onDotHover(index) {
dotsGeometry.vertices[index].tl = new TimelineMax();
dotsGeometry.vertices[index].tl.to(dotsGeometry.vertices[index], 1, {
scaleX: 10,
ease: Elastic.easeOut.config(2, 0.2),
onUpdate: function() {
attributeSizes.array[index] = dotsGeometry.vertices[index].scaleX;
}
});
}
function mouseOut(index) {
dotsGeometry.vertices[index].tl.to(dotsGeometry.vertices[index], 0.4, {
scaleX: 5,
ease: Power2.easeOut,
onUpdate: function() {
attributeSizes.array[index] = dotsGeometry.vertices[index].scaleX;
}
});
}
function onResize() {
canvas.style.width = '';
canvas.style.height = '';
width = canvas.offsetWidth;
height = canvas.offsetHeight;
camera.aspect = width / height;
camera.updateProjectionMatrix();
renderer.setSize(width, height);
}
var mouse = new THREE.Vector2(-100,-100);
function onMouseMove(e) {
var canvasBounding = canvas.getBoundingClientRect();
mouse.x = ((e.clientX - canvasBounding.left) / width) * 2 - 1;
mouse.y = -((e.clientY - canvasBounding.top) / height) * 2 + 1;
}
TweenMax.ticker.addEventListener("tick", render);
window.addEventListener("mousemove", onMouseMove);
var resizeTm;
window.addEventListener("resize", function(){
resizeTm = clearTimeout(resizeTm);
resizeTm = setTimeout(onResize, 200);
});
Codepen here - https://codepen.io/quickwaste/pen/PaGPdw
Thanks.
(A stretch goal would be to have the camera move in response to mouse movement)
Simply add galaxy.rotateY(0.005 * Math.PI); to render(), right before renderer.render(scene, camera) call, like this:
// pulled from the CodePen
function render(a) {
// ... omitted for brevity
prevHovered = hovered.slice(0);
attributeSizes.needsUpdate = true;
attributePositions.needsUpdate = true;
galaxy.rotateY(0.005 * Math.PI);
renderer.render(scene, camera);
}
I used a multiplier of 0.005 to give the globe a nice, lazy spin.
The 'galaxy' object is a THREE.Group, a wrapper of sorts for collections of THREE.Object3D objects. The Object3D has all sorts of nifty functions to help rotate, translate, and transform 3D objects. The rotateY() will spin the model around its local y-axis.
Right now, I am trying to make a navigational menu, but to do this, I need to detect what side is clicked by the user. Is there any way to do this with raycasting, or if not, any other way?
Here is my code if you need it:
CodePen Link
The short version is here
var geometry = new THREE.BoxGeometry(200, 200, 200);
var material = new THREE.MeshLambertMaterial(
{
color: 65535,
morphTargets: true
});
for (var i = 0; i < 8; i++)
{
var vertices = [];
for (var v = 0; v < geometry.vertices.length; v++)
{
vertices.push(geometry.vertices[v].clone());
if (v === i)
{
vertices[vertices.length - 1].x *= 2;
vertices[vertices.length - 1].y *= 2;
vertices[vertices.length - 1].z *= 2
}
}
geometry.morphTargets.push(
{
name: "target" + i,
vertices: vertices
})
}
mesh = new THREE.Mesh(geometry, material);
mesh.position.y = 0;
scene.add(mesh);
scene.background = new THREE.Color(15790320);
var params = {
influence1: 1,
influence2: 1,
influence3: 1,
influence4: 1,
influence5: 1,
influence6: 1,
influence7: 1,
influence8: 1
};
var geometry = new THREE.PlaneBufferGeometry(5e3, 5e3);
geometry.rotateX(-Math.PI / 2);
var material = new THREE.MeshBasicMaterial(
{
color: 975132,
overdraw: .5
});
onMouseDown(event) {
this.mouse.x = (event.pageX / window.innerWidth) * 2 - 1;
this.mouse.y = -(event.pageY / window.innerHeight) * 2 + 1;
this.raycaster.setFromCamera(this.mouse, this.camera);
let intersectCube = this.raycaster.intersectObjects( Cube , true );
}
Make a raycaster on your mouse and check for intersections with the Cube or its faces
I am very new to threejs, and I have created a for loop to draw 400 cylinders. Everything is fine and they are called into the scene and rendered properly. When I go to animate the objects, only one of the 400 appears to rotate. How can I rotate all of the cylinders?
Code:
for( var j = 0; j < 400; j++){
abgeometry2 = new THREE.CylinderGeometry (1, 5, 8, 4);
abmesh2 = new THREE.MeshPhongMaterial({color: 0x3B170B,
wireframe: false });
mesh2 = new THREE.Mesh(abgeometry2, abmesh2);
mesh2.position.x = Math.random() * 400 - 200;
mesh2.position.y = Math.random() * 400 - 200;
mesh2.position.z = Math.random() * 400 - 200;
scene.add( mesh2 );
}
And in the animate I put : mesh2.rotation.z += 0.06;
I know I may be doing something stupid but I'm not quite familiar with threejs.
You're only applying the rotation to the last cylinder since they're all assigned to mesh2 during the loop.
Try something like this:
var numCylinders = 400;
var cylinders = [];
var geo = new THREE.CylinderGeometry (1, 5, 8, 4);
var mesh = new THREE.MeshPhongMaterial({color: 0x3B170B, wireframe: false });
for (var i = 0; i < numCylinders; i++){
var curCylinder = new THREE.Mesh(geo, mesh);
curCylinder.position.x = Math.random() * 400 - 200;
curCylinder.position.y = Math.random() * 400 - 200;
curCylinder.position.z = Math.random() * 400 - 200;
scene.add(curCylinder);
cylinders.push(curCylinder);
}
var render = function () {
requestAnimationFrame( render );
for (var i = 0; i <numCylinders; i++){
cylinders[i].rotation.z += 0.06;
}
renderer.render(scene, camera);
};
render();