Three.js Dom event ( linkify.js) - javascript

I can't make it work. on the console, it says that the click event work,
but i cant link the sphere with an url.
Iam using last version of three.js
here is my code : `
// once everything is loaded, we run our Three.js stuff.
$(function () {
var geometry, material, mesha;
var clock = new THREE.Clock();
var raycaster;
var stats = initStats();
// create a scene, that will hold all our elements such as objects, cameras and lights.
var scene = new THREE.Scene();
// create a camera, which defines where we're looking at.
var camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render and set the size
var webGLRenderer = new THREE.WebGLRenderer();
webGLRenderer.setClearColor(new THREE.Color(0x000, 1.0));
webGLRenderer.setSize(window.innerWidth, window.innerHeight);
webGLRenderer.shadowMapEnabled = true;
// position and point the camera to the center of the scene
camera.position.x = 100;
camera.position.y = 10;
camera.position.z = 1000;
camera.lookAt(new THREE.Vector3(0, 0, 0));
var camControls = new THREE.FirstPersonControls(camera);
camControls.lookSpeed = 0.4;
camControls.movementSpeed = 30;
camControls.noFly = true;
camControls.lookVertical = true;
camControls.constrainVertical = false;
camControls.verticalMin = 0.0;
camControls.verticalMax = 1.0;
camControls.lon = -150;
camControls.lat = 120;
var ambientLight = new THREE.AmbientLight(0x383838);
scene.add(ambientLight);
// add spotlight for the shadows
var spotLight = new THREE.SpotLight(0xffffff);
spotLight.position.set(100, 140, 130);
spotLight.intensity = 10;
scene.add(spotLight);
// add the output of the renderer to the html element
$("#WebGL-output").append(webGLRenderer.domElement);
// call the render function
var step = 0;
// setup the control gui
var controls = new function () {
// we need the first child, since it's a multimaterial
}
var domEvents = new THREEx.DomEvents(camera, webGLRenderer.domElement)
//////////////////////////////////////////////////////////////////////////////////
// add an object and make it move //
//////////////////////////////////////////////////////////////////////////////////
var geometry = new THREE.SphereGeometry( 100.5 )
var material = new THREE.MeshNormalMaterial()
var mesh = new THREE.Mesh( geometry, material )
scene.add( mesh )
//////////////////////////////////////////////////////////////////////////////////
// linkify our cube //
//////////////////////////////////////////////////////////////////////////////////
var url = 'http://jeromeetienne.github.io/threex/'
THREEx.Linkify(domEvents, mesh, url)
domEvents.addEventListener(mesh, 'click', function(event){
console.log('you clicked on mesh', mesh)
}, false)
var gui = new dat.GUI();
var mesh;
var onProgress = function ( xhr ) {
if ( xhr.lengthComputable ) {
var percentComplete = xhr.loaded / xhr.total * 100;
console.log( Math.round(percentComplete, 2) + '% downloaded' );
}
};
var onError = function ( xhr ) { };
var mtlLoader = new THREE.MTLLoader();
mtlLoader.setBaseUrl( '../assets/models/door/' );
mtlLoader.setPath( '../assets/models/door/' );
mtlLoader.load( 'door.mtl', function( materials ) {
materials.preload();
var objLoader = new THREE.OBJLoader();
objLoader.setMaterials( materials );
objLoader.setPath( '../assets/models/door/' );
objLoader.load( 'door.obj', function ( object ) {
object.position.y = -1;
object.scale.x = 2;
object.scale.y = 2;
object.scale.z = 2;
scene.add( object );
}, onProgress, onError );
});
// floor
geometry = new THREE.PlaneGeometry( 2000, 2000, 100, 100 );
geometry.rotateX( - Math.PI / 2 );
for ( var i = 0, l = geometry.vertices.length; i < l; i ++ ) {
var vertex = geometry.vertices[ i ];
vertex.x += Math.random() * 20 - 10;
vertex.y += Math.random() * 3;
vertex.z += Math.random() * 20 - 10;
}
for ( var i = 0, l = geometry.faces.length; i < l; i ++ ) {
var face = geometry.faces[ i ];
face.vertexColors[ 0 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 1 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 10.5, 0.75, Math.random() * 0.25 + 0.75 );
face.vertexColors[ 2 ] = new THREE.Color().setHSL( Math.random() * 0.3 + 0.5, 0.75, Math.random() * 0.25 + 0.75 );
}
material = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
function setCamControls() {
}
render();
function setRandomColors(object, scale) {
var children = object.children;
if (children && children.length > 0) {
children.forEach(function (e) {
setRandomColors(e, scale)
});
} else {
// no children assume contains a mesh
if (object instanceof THREE.Mesh) {
object.material.color = new THREE.Color(scale(Math.random()).hex());
if (object.material.name.indexOf("building") == 0) {
object.material.emissive = new THREE.Color(0x444444);
object.material.transparent = true;
object.material.opacity = 0.8;
}
}
}
}
function render() {
stats.update();
var delta = clock.getDelta();
if (mesh) {
// mesh.rotation.y+=0.006;
}
camControls.update(delta);
webGLRenderer.clear();
// render using requestAnimationFrame
requestAnimationFrame(render);
webGLRenderer.render(scene, camera)
}
function initStats() {
var stats = new Stats();
stats.setMode(0); // 0: fps, 1: ms
// Align top-left
stats.domElement.style.position = 'absolute';
stats.domElement.style.left = '0px';
stats.domElement.style.top = '0px';
$("#Stats-output").append(stats.domElement);
return stats;
}
});
can somebody help ? have you an idea?
Iam quite a newbie...

Solution:
Get the latest version of DomEvents (https://github.com/jeromeetienne/threex.domevents) which has been updated to r74 right now.
Explaination:
This one took me some time to figure out, lets see whats going on:
THREEx.DomEvents is internally using the THREE.Raycaster to detect when the mouse is pointing on meshes. ThreeJS changed lately the behavior of the raycaster to not intersect with invisible meshes anymore (source). Yeah well I dont care, my click event is fireing you say?
Lets have a look at Linkyfy:
THREEx.Linkify = function(domEvents, mesh, url, withBoundingBox){
withBoundingBox = withBoundingBox !== undefined ? withBoundingBox : true
// create the boundingBox if needed
if( withBoundingBox ){
var boundingBox = new THREE.Mesh(new THREE.CubeGeometry(1,1,1), new THREE.MeshBasicMaterial({
wireframe : true
}))
boundingBox.visible = false
boundingBox.scale.copy(size)
mesh.add(boundingBox)
}
// ...
The fourth parameter withBoundingBox is evaluating to true if you dont supply it. Linkify is then creating a "bounding box mesh" which is invisible and wrapping around your mesh you want to linkify. The raycaster does not trigger an intersection anymore and there you have it. To allow the raycaster to detect an intersection although the boundingBox-object is invisible, set only the meshs materials visibility to false and not the mesh:
boundingBox.material.visible = false

Related

How to add Threejs Object inside a vue code or add vue model inside threejs background

Dear Stackoverflow users :)
i need help to add trois model([https://codepen.io/soju22/pen/JjEqebK][1])
import { createApp } from 'https://unpkg.com/vue#3.0.11/dist/vue.esm-browser.prod.js'
import { lerp, BufferGeometry, Camera, EffectComposer, Points, Renderer, RenderPass, Scene, ShaderMaterial, Texture, UnrealBloomPass, ZoomBlurPass } from 'https://unpkg.com/troisjs#0.3.0-beta.4/build/trois.module.cdn.min.js'
import { Clock, Color, MathUtils, Vector3 } from 'https://unpkg.com/three#0.127.0/build/three.module.js'
const niceColors = [["#69d2e7","#a7dbd8","#e0e4cc","#f38630","#fa6900"],["#fe4365","#fc9d9a","#f9cdad","#c8c8a9","#83af9b"],["#ecd078","#d95b43","#c02942","#542437","#53777a"],["#556270","#4ecdc4","#c7f464","#ff6b6b","#c44d58"],["#774f38","#e08e79","#f1d4af","#ece5ce","#c5e0dc"],["#e8ddcb","#cdb380","#036564","#033649","#031634"],["#490a3d","#bd1550","#e97f02","#f8ca00","#8a9b0f"],["#594f4f","#547980","#45ada8","#9de0ad","#e5fcc2"],["#00a0b0","#6a4a3c","#cc333f","#eb6841","#edc951"],["#e94e77","#d68189","#c6a49a","#c6e5d9","#f4ead5"],["#3fb8af","#7fc7af","#dad8a7","#ff9e9d","#ff3d7f"],["#d9ceb2","#948c75","#d5ded9","#7a6a53","#99b2b7"],["#ffffff","#cbe86b","#f2e9e1","#1c140d","#cbe86b"],["#efffcd","#dce9be","#555152","#2e2633","#99173c"],["#343838","#005f6b","#008c9e","#00b4cc","#00dffc"],["#413e4a","#73626e","#b38184","#f0b49e","#f7e4be"],["#ff4e50","#fc913a","#f9d423","#ede574","#e1f5c4"],["#99b898","#fecea8","#ff847c","#e84a5f","#2a363b"],["#655643","#80bca3","#f6f7bd","#e6ac27","#bf4d28"],["#00a8c6","#40c0cb","#f9f2e7","#aee239","#8fbe00"],["#351330","#424254","#64908a","#e8caa4","#cc2a41"],["#554236","#f77825","#d3ce3d","#f1efa5","#60b99a"],["#5d4157","#838689","#a8caba","#cad7b2","#ebe3aa"],["#8c2318","#5e8c6a","#88a65e","#bfb35a","#f2c45a"],["#fad089","#ff9c5b","#f5634a","#ed303c","#3b8183"],["#ff4242","#f4fad2","#d4ee5e","#e1edb9","#f0f2eb"],["#f8b195","#f67280","#c06c84","#6c5b7b","#355c7d"],["#d1e751","#ffffff","#000000","#4dbce9","#26ade4"],["#1b676b","#519548","#88c425","#bef202","#eafde6"],["#5e412f","#fcebb6","#78c0a8","#f07818","#f0a830"],["#bcbdac","#cfbe27","#f27435","#f02475","#3b2d38"],["#452632","#91204d","#e4844a","#e8bf56","#e2f7ce"],["#eee6ab","#c5bc8e","#696758","#45484b","#36393b"],["#f0d8a8","#3d1c00","#86b8b1","#f2d694","#fa2a00"],["#2a044a","#0b2e59","#0d6759","#7ab317","#a0c55f"],["#f04155","#ff823a","#f2f26f","#fff7bd","#95cfb7"],["#b9d7d9","#668284","#2a2829","#493736","#7b3b3b"],["#bbbb88","#ccc68d","#eedd99","#eec290","#eeaa88"],["#b3cc57","#ecf081","#ffbe40","#ef746f","#ab3e5b"],["#a3a948","#edb92e","#f85931","#ce1836","#009989"],["#300030","#480048","#601848","#c04848","#f07241"],["#67917a","#170409","#b8af03","#ccbf82","#e33258"],["#aab3ab","#c4cbb7","#ebefc9","#eee0b7","#e8caaf"],["#e8d5b7","#0e2430","#fc3a51","#f5b349","#e8d5b9"],["#ab526b","#bca297","#c5ceae","#f0e2a4","#f4ebc3"],["#607848","#789048","#c0d860","#f0f0d8","#604848"],["#b6d8c0","#c8d9bf","#dadabd","#ecdbbc","#fedcba"],["#a8e6ce","#dcedc2","#ffd3b5","#ffaaa6","#ff8c94"],["#3e4147","#fffedf","#dfba69","#5a2e2e","#2a2c31"],["#fc354c","#29221f","#13747d","#0abfbc","#fcf7c5"],["#cc0c39","#e6781e","#c8cf02","#f8fcc1","#1693a7"],["#1c2130","#028f76","#b3e099","#ffeaad","#d14334"],["#a7c5bd","#e5ddcb","#eb7b59","#cf4647","#524656"],["#dad6ca","#1bb0ce","#4f8699","#6a5e72","#563444"],["#5c323e","#a82743","#e15e32","#c0d23e","#e5f04c"],["#edebe6","#d6e1c7","#94c7b6","#403b33","#d3643b"],["#fdf1cc","#c6d6b8","#987f69","#e3ad40","#fcd036"],["#230f2b","#f21d41","#ebebbc","#bce3c5","#82b3ae"],["#b9d3b0","#81bda4","#b28774","#f88f79","#f6aa93"],["#3a111c","#574951","#83988e","#bcdea5","#e6f9bc"],["#5e3929","#cd8c52","#b7d1a3","#dee8be","#fcf7d3"],["#1c0113","#6b0103","#a30006","#c21a01","#f03c02"],["#000000","#9f111b","#b11623","#292c37","#cccccc"],["#382f32","#ffeaf2","#fcd9e5","#fbc5d8","#f1396d"],["#e3dfba","#c8d6bf","#93ccc6","#6cbdb5","#1a1f1e"],["#f6f6f6","#e8e8e8","#333333","#990100","#b90504"],["#1b325f","#9cc4e4","#e9f2f9","#3a89c9","#f26c4f"],["#a1dbb2","#fee5ad","#faca66","#f7a541","#f45d4c"],["#c1b398","#605951","#fbeec2","#61a6ab","#accec0"],["#5e9fa3","#dcd1b4","#fab87f","#f87e7b","#b05574"],["#951f2b","#f5f4d7","#e0dfb1","#a5a36c","#535233"],["#8dccad","#988864","#fea6a2","#f9d6ac","#ffe9af"],["#2d2d29","#215a6d","#3ca2a2","#92c7a3","#dfece6"],["#413d3d","#040004","#c8ff00","#fa023c","#4b000f"],["#eff3cd","#b2d5ba","#61ada0","#248f8d","#605063"],["#ffefd3","#fffee4","#d0ecea","#9fd6d2","#8b7a5e"],["#cfffdd","#b4dec1","#5c5863","#a85163","#ff1f4c"],["#9dc9ac","#fffec7","#f56218","#ff9d2e","#919167"],["#4e395d","#827085","#8ebe94","#ccfc8e","#dc5b3e"],["#a8a7a7","#cc527a","#e8175d","#474747","#363636"],["#f8edd1","#d88a8a","#474843","#9d9d93","#c5cfc6"],["#046d8b","#309292","#2fb8ac","#93a42a","#ecbe13"],["#f38a8a","#55443d","#a0cab5","#cde9ca","#f1edd0"],["#a70267","#f10c49","#fb6b41","#f6d86b","#339194"],["#ff003c","#ff8a00","#fabe28","#88c100","#00c176"],["#ffedbf","#f7803c","#f54828","#2e0d23","#f8e4c1"],["#4e4d4a","#353432","#94ba65","#2790b0","#2b4e72"],["#0ca5b0","#4e3f30","#fefeeb","#f8f4e4","#a5b3aa"],["#4d3b3b","#de6262","#ffb88c","#ffd0b3","#f5e0d3"],["#fffbb7","#a6f6af","#66b6ab","#5b7c8d","#4f2958"],["#edf6ee","#d1c089","#b3204d","#412e28","#151101"],["#9d7e79","#ccac95","#9a947c","#748b83","#5b756c"],["#fcfef5","#e9ffe1","#cdcfb7","#d6e6c3","#fafbe3"],["#9cddc8","#bfd8ad","#ddd9ab","#f7af63","#633d2e"],["#30261c","#403831","#36544f","#1f5f61","#0b8185"],["#aaff00","#ffaa00","#ff00aa","#aa00ff","#00aaff"],["#d1313d","#e5625c","#f9bf76","#8eb2c5","#615375"],["#ffe181","#eee9e5","#fad3b2","#ffba7f","#ff9c97"],["#73c8a9","#dee1b6","#e1b866","#bd5532","#373b44"],["#805841","#dcf7f3","#fffcdd","#ffd8d8","#f5a2a2"]]
const { randFloat: rnd, randInt, randFloatSpread: rndFS } = MathUtils
const vertexShader = `
uniform float uTime;
attribute vec3 color;
attribute float size;
attribute float velocity;
varying vec4 vColor;
void main(){
vColor = vec4(color, 1.0);
vec3 p = vec3(position);
p.z = -150. + mod(position.z + uTime, 300.);
vec4 mvPosition = modelViewMatrix * vec4( p, 1.0 );
gl_PointSize = size * (-50.0 / mvPosition.z);
gl_Position = projectionMatrix * mvPosition;
}
`
const fragmentShader = `
uniform sampler2D uTexture;
varying vec4 vColor;
void main() {
gl_FragColor = vColor * texture2D(uTexture, gl_PointCoord);
}
`
createApp({
template: `
<Renderer ref="renderer" pointer resize="window">
<Camera :position="{ z: 0 }" :fov="35" />
<Scene>
<Points ref="points" :position="{ z: -100 }">
<BufferGeometry :attributes="attributes" />
<ShaderMaterial :blending="2" :depth-test="false" :uniforms="uniforms" :vertex-shader="vertexShader" :fragment-shader="fragmentShader">
<Texture src="https://assets.codepen.io/33787/sprite.png" uniform="uTexture" />
</ShaderMaterial>
</Points>
</Scene>
<EffectComposer>
<RenderPass />
<UnrealBloomPass :strength="2" :radius="0" :threshold="0" />
<ZoomBlurPass :strength="zoomStrength" />
</EffectComposer>
</Renderer>
Surprise!
`,
components: { BufferGeometry, Camera, EffectComposer, Points, Renderer, RenderPass, Scene, ShaderMaterial, Texture, UnrealBloomPass, ZoomBlurPass },
setup() {
const POINTS_COUNT = 50000
const palette = niceColors[23]
const positions = new Float32Array(POINTS_COUNT * 3)
const colors = new Float32Array(POINTS_COUNT * 3)
const sizes = new Float32Array(POINTS_COUNT)
const v3 = new Vector3(), color = new Color()
for (let i = 0; i < POINTS_COUNT; i++) {
v3.set(rndFS(200), rndFS(200), rndFS(300))
v3.toArray(positions, i * 3)
color.set(palette[Math.floor(rnd(0, palette.length))])
color.toArray(colors, i * 3)
sizes[i] = rnd(5, 20)
}
const attributes = [
{ name: 'position', array: positions, itemSize: 3 },
{ name: 'color', array: colors, itemSize: 3 },
{ name: 'size', array: sizes, itemSize: 1 },
]
const uniforms = { uTime: { value: 0 } }
const clock = new Clock()
const timeCoef = 1, targetTimeCoef = 1
return {
POINTS_COUNT,
attributes, uniforms, vertexShader, fragmentShader,
clock, timeCoef, targetTimeCoef,
}
},
data() {
return {
zoomStrength: 0,
}
},
mounted() {
const renderer = this.$refs.renderer
const positionN = renderer.three.pointer.positionN
const points = this.$refs.points.points
renderer.onBeforeRender(() => {
this.timeCoef = lerp(this.timeCoef, this.targetTimeCoef, 0.02)
this.uniforms.uTime.value += this.clock.getDelta() * this.timeCoef * 4
this.zoomStrength = this.timeCoef * 0.004
const da = 0.05
const tiltX = lerp(points.rotation.x, positionN.y * da, 0.02)
const tiltY = lerp(points.rotation.y, -positionN.x * da, 0.02)
points.rotation.set(tiltX, tiltY, 0)
})
},
methods: {
updateColors() {
const colorAttribute = this.$refs.points.geometry.attributes.color
const ip = randInt(0, 99); const palette = niceColors[ip];
const color = new Color()
for (let i = 0; i < this.POINTS_COUNT; i++) {
color.set(palette[randInt(0, palette.length)])
color.toArray(colorAttribute.array, i * 3)
}
colorAttribute.needsUpdate = true
},
},
}).mount('#app')
</script>
<script type="module">
/**
* #file
* The main scene.
*/
/**
* Define constants.
*/
const TEXTURE_PATH = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/';
/**
* Create the animation request.
*/
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (function() {
return window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
function (callback, element) {
// 60 FPS
window.setTimeout(callback, 1000 / 60);
};
})();
}
/**
* Set our global variables.
*/
var camera,
scene,
renderer,
effect,
controls,
element,
earthy,
sphere,
sphereCloud,
rotationPoint;
var degreeOffset = 90;
var earthRadius = 80;
var getEarthRotation = function() {
// Get the current time.
var d = new Date();
var h = d.getUTCHours();
var m = d.getUTCMinutes();
// Calculate total minutes.
var minutes = h * 60;
minutes += m;
// Turn minutes into degrees.
degrees = minutes/3.9907;
// Add an offset to match UTC time.
degrees += degreeOffset;
return degrees;
}
var degrees = getEarthRotation();
// Calculate Earth's rotation position.
setInterval(function() {
// Get the current time.
var d = new Date();
var h = d.getUTCHours();
var m = d.getUTCMinutes();
// Calculate total minutes.
var minutes = h * 60;
minutes += m;
// Turn minutes into degrees.
degrees = minutes/3.9907;
// Add an offset to match UTC time.
degrees += degreeOffset;
}, 60000);
init();
animate();
var string = '';
/**
* Initializer function.
*/
function init() {
// Build the
earthy = document.createElement( 'div' );
document.body.appendChild( earthy );
// Create the scene.
scene = new THREE.Scene();
// Create a rotation point.
baseRotationPoint = new THREE.Object3D();
baseRotationPoint.position.set( 0, 0, 0 );
scene.add( baseRotationPoint );
// Create world rotation point.
worldRotationPoint = new THREE.Object3D();
worldRotationPoint.position.set( 0, 0, 0 );
scene.add( worldRotationPoint );
rotationPoint = new THREE.Object3D();
rotationPoint.position.set( 0, 0, earthRadius * 4 );
baseRotationPoint.add( rotationPoint );
// Create the camera.
camera = new THREE.PerspectiveCamera(
45, // Angle
window.innerWidth / window.innerHeight, // Aspect Ratio.
0.1, // Near view.
1000 // Far view.
);
rotationPoint.add( camera );
// Build the renderer.
renderer = new THREE.WebGLRenderer({ alpha: true,transparent: true });
renderer.clear()
renderer.clearDepth();
element = renderer.domElement;
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.domElement.style.position = 'absolute';
renderer.domElement.style.top = '0px';
renderer.domElement.style.zIndex = '100';
renderer.domElement.style.margin = '0';
renderer.domElement.style.padding = '0';
/*renderer.domElement.style.clipPath = 'circle(25%)'; */
renderer.shadowMap.enabled;
earthy.appendChild( element );
window.addEventListener( 'resize', onWindowResize );
// Build the controls.
controls = new THREE.OrbitControls( camera, element );
controls.enablePan = true;
controls.enableZoom = false;
controls.maxDistance = earthRadius * 8;
controls.minDistance = earthRadius * 2;
controls.target.copy( new THREE.Vector3( 0, 0, -1 * earthRadius * 4 ));
function setOrientationControls(e) {
if (!e.alpha) {
return;
}
controls = new THREE.DeviceOrientationControls( camera );
controls.connect();
window.removeEventListener('deviceorientation', setOrientationControls, true);
}
window.addEventListener('deviceorientation', setOrientationControls, true);
// Ambient lights
var ambient = new THREE.AmbientLight( 0x222222 );
scene.add( ambient );
// The sun.
var light = new THREE.PointLight( 0xffeecc, 1, 5000 );
light.position.set( -400, 0, 100 );
scene.add( light );
// Since the sun is much bigger than a point of light, add four fillers.
var light2 = new THREE.PointLight( 0xffffff, 0.6, 4000 );
light2.position.set( -400, 0, 250 );
scene.add( light2 );
var light3 = new THREE.PointLight( 0xffffff, 0.6, 4000 );
light3.position.set( -400, 0, -150 );
scene.add( light3 );
var light4 = new THREE.PointLight( 0xffffff, 0.6, 4000 );
light4.position.set( -400, 150, 100 );
scene.add( light4 );
var light5 = new THREE.PointLight( 0xffffff, 0.6, 4000 );
light5.position.set( -400, -150, 100 );
scene.add( light5 );
// Add the Earth sphere model.
var geometry = new THREE.SphereGeometry( earthRadius, 128, 128 );
// Create the Earth materials.
loader = new THREE.TextureLoader();
loader.setCrossOrigin( 'https://s.codepen.io' );
var texture = loader.load( TEXTURE_PATH + 'ColorMap.jpg' );
var bump = null;
bump = loader.load( TEXTURE_PATH + 'Bump.jpg' );
var spec = null;
spec = loader.load( TEXTURE_PATH + 'SpecMask.jpg' );
var material = new THREE.MeshPhongMaterial({
color: "#ffffff",
shininess: 5,
map: texture,
specularMap: spec,
specular: "#666666",
bumpMap: bump,
});
sphere = new THREE.Mesh( geometry, material );
sphere.position.set( 0, 0, 0 );
sphere.rotation.y = Math.PI;
// Focus initially on the prime meridian.
sphere.rotation.y = -1 * (8.7 * Math.PI / 17);
// Add the Earth to the scene.https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/Bump.jpg
worldRotationPoint.add( sphere );
// Add the Earth sphere model.
var geometryCloud = new THREE.SphereGeometry( earthRadius + 0.2, 128, 128 );
loader = new THREE.TextureLoader();
loader.setCrossOrigin( 'https://s.codepen.io' );
var alpha = loader.load( TEXTURE_PATH + "alphaMap.jpg" );
var materialCloud = new THREE.MeshPhongMaterial({
alphaMap: alpha,
});
materialCloud.transparent = true;
sphereCloud = new THREE.Mesh( geometryCloud, materialCloud );
scene.add( sphereCloud );
// Add the skymap.
window.addEventListener('resize', onWindowResize, true);
}
/**
* Events to fire upon window resizing.
*/
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
/**
* Add the sun to the scene.
*/
function createSun() {
// Add the Sun sphere model.
var sunGeometry = new THREE.SphereGeometry( 100, 16, 16 );
// Create the Sun materials.
var sunMaterial = new THREE.MeshLambertMaterial({
color: '#ffff55',
emissive: '#ffff55',
});
}
/**
* Updates to apply to the scene while running.
*/
function update() {
camera.updateProjectionMatrix();
worldRotationPoint.rotation.y = degrees * Math.PI/180;
sphereCloud.rotation.y += 0.00025;
baseRotationPoint.rotation.y -= 0.00025;
}
/**
* Render the scene.
*/
function render() {
renderer.render(scene, camera);
}
/**
* Animate the scene.
*/
function animate() {
requestAnimationFrame(animate);
update();
render();
}
function addSkybox() {
var urlPrefix = TEXTURE_PATH;
var urls = [
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
];
var loader = new THREE.CubeTextureLoader();
loader.setCrossOrigin( 'https://s.codepen.io' );
var textureCube = loader.load( urls );
textureCube.format = THREE.RGBFormat;
var shader = THREE.ShaderLib[ "cube" ];
shader.uniforms[ "tCube" ].value = textureCube;
var material = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
}
in background inside Threejs object([https://codepen.io/bartuc/pen/yMMyav][2])
const TEXTURE_PATH = 'https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/';
/**
* Create the animation request.
*/
if (!window.requestAnimationFrame) {
window.requestAnimationFrame = (function() {
return window.mozRequestAnimationFrame ||
window.msRequestAnimationFrame ||
window.oRequestAnimationFrame ||
window.webkitRequestAnimationFrame ||
function (callback, element) {
// 60 FPS
window.setTimeout(callback, 1000 / 60);
};
})();
}
/**
* Set our global variables.
*/
var camera,
scene,
renderer,
effect,
controls,
element,
earthy,
sphere,
sphereCloud,
rotationPoint;
var degreeOffset = 90;
var earthRadius = 80;
var getEarthRotation = function() {
// Get the current time.
var d = new Date();
var h = d.getUTCHours();
var m = d.getUTCMinutes();
// Calculate total minutes.
var minutes = h * 60;
minutes += m;
// Turn minutes into degrees.
degrees = minutes/3.9907;
// Add an offset to match UTC time.
degrees += degreeOffset;
return degrees;
}
var degrees = getEarthRotation();
// Calculate Earth's rotation position.
setInterval(function() {
// Get the current time.
var d = new Date();
var h = d.getUTCHours();
var m = d.getUTCMinutes();
// Calculate total minutes.
var minutes = h * 60;
minutes += m;
// Turn minutes into degrees.
degrees = minutes/3.9907;
// Add an offset to match UTC time.
degrees += degreeOffset;
}, 60000);
init();
animate();
var string = '';
/**
* Initializer function.
*/
function init() {
// Build the
earthy = document.createElement( 'div' );
document.body.appendChild( earthy );
// Create the scene.
scene = new THREE.Scene();
// Create a rotation point.
baseRotationPoint = new THREE.Object3D();
baseRotationPoint.position.set( 0, 0, 0 );
scene.add( baseRotationPoint );
// Create world rotation point.
worldRotationPoint = new THREE.Object3D();
worldRotationPoint.position.set( 0, 0, 0 );
scene.add( worldRotationPoint );
rotationPoint = new THREE.Object3D();
rotationPoint.position.set( 0, 0, earthRadius * 4 );
baseRotationPoint.add( rotationPoint );
// Create the camera.
camera = new THREE.PerspectiveCamera(
45, // Angle
window.innerWidth / window.innerHeight, // Aspect Ratio.
0.1, // Near view.
1000 // Far view.
);
rotationPoint.add( camera );
// Build the renderer.
renderer = new THREE.WebGLRenderer({ alpha: true,transparent: true });
renderer.clear()
renderer.clearDepth();
element = renderer.domElement;
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.domElement.style.position = 'absolute';
renderer.domElement.style.top = '0px';
renderer.domElement.style.zIndex = '100';
renderer.domElement.style.margin = '0';
renderer.domElement.style.padding = '0';
/*renderer.domElement.style.clipPath = 'circle(25%)'; */
renderer.shadowMap.enabled;
earthy.appendChild( element );
window.addEventListener( 'resize', onWindowResize );
// Build the controls.
controls = new THREE.OrbitControls( camera, element );
controls.enablePan = true;
controls.enableZoom = false;
controls.maxDistance = earthRadius * 8;
controls.minDistance = earthRadius * 2;
controls.target.copy( new THREE.Vector3( 0, 0, -1 * earthRadius * 4 ));
function setOrientationControls(e) {
if (!e.alpha) {
return;
}
controls = new THREE.DeviceOrientationControls( camera );
controls.connect();
window.removeEventListener('deviceorientation', setOrientationControls, true);
}
window.addEventListener('deviceorientation', setOrientationControls, true);
// Ambient lights
var ambient = new THREE.AmbientLight( 0x222222 );
scene.add( ambient );
// The sun.
var light = new THREE.PointLight( 0xffeecc, 1, 5000 );
light.position.set( -400, 0, 100 );
scene.add( light );
// Since the sun is much bigger than a point of light, add four fillers.
var light2 = new THREE.PointLight( 0xffffff, 0.6, 4000 );
light2.position.set( -400, 0, 250 );
scene.add( light2 );
var light3 = new THREE.PointLight( 0xffffff, 0.6, 4000 );
light3.position.set( -400, 0, -150 );
scene.add( light3 );
var light4 = new THREE.PointLight( 0xffffff, 0.6, 4000 );
light4.position.set( -400, 150, 100 );
scene.add( light4 );
var light5 = new THREE.PointLight( 0xffffff, 0.6, 4000 );
light5.position.set( -400, -150, 100 );
scene.add( light5 );
// Add the Earth sphere model.
var geometry = new THREE.SphereGeometry( earthRadius, 128, 128 );
// Create the Earth materials.
loader = new THREE.TextureLoader();
loader.setCrossOrigin( 'https://s.codepen.io' );
var texture = loader.load( TEXTURE_PATH + 'ColorMap.jpg' );
var bump = null;
bump = loader.load( TEXTURE_PATH + 'Bump.jpg' );
var spec = null;
spec = loader.load( TEXTURE_PATH + 'SpecMask.jpg' );
var material = new THREE.MeshPhongMaterial({
color: "#ffffff",
shininess: 5,
map: texture,
specularMap: spec,
specular: "#666666",
bumpMap: bump,
});
sphere = new THREE.Mesh( geometry, material );
sphere.position.set( 0, 0, 0 );
sphere.rotation.y = Math.PI;
// Focus initially on the prime meridian.
sphere.rotation.y = -1 * (8.7 * Math.PI / 17);
// Add the Earth to the scene.https://s3-us-west-2.amazonaws.com/s.cdpn.io/123879/Bump.jpg
worldRotationPoint.add( sphere );
// Add the Earth sphere model.
var geometryCloud = new THREE.SphereGeometry( earthRadius + 0.2, 128, 128 );
loader = new THREE.TextureLoader();
loader.setCrossOrigin( 'https://s.codepen.io' );
var alpha = loader.load( TEXTURE_PATH + "alphaMap.jpg" );
var materialCloud = new THREE.MeshPhongMaterial({
alphaMap: alpha,
});
materialCloud.transparent = true;
sphereCloud = new THREE.Mesh( geometryCloud, materialCloud );
scene.add( sphereCloud );
// Add the skymap.
window.addEventListener('resize', onWindowResize, true);
}
/**
* Events to fire upon window resizing.
*/
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
}
/**
* Add the sun to the scene.
*/
function createSun() {
// Add the Sun sphere model.
var sunGeometry = new THREE.SphereGeometry( 100, 16, 16 );
// Create the Sun materials.
var sunMaterial = new THREE.MeshLambertMaterial({
color: '#ffff55',
emissive: '#ffff55',
});
}
/**
* Updates to apply to the scene while running.
*/
function update() {
camera.updateProjectionMatrix();
worldRotationPoint.rotation.y = degrees * Math.PI/180;
sphereCloud.rotation.y += 0.00025;
baseRotationPoint.rotation.y -= 0.00025;
}
/**
* Render the scene.
*/
function render() {
renderer.render(scene, camera);
}
/**
* Animate the scene.
*/
function animate() {
requestAnimationFrame(animate);
update();
render();
}
function addSkybox() {
var urlPrefix = TEXTURE_PATH;
var urls = [
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
urlPrefix + 'test.jpg',
];
var loader = new THREE.CubeTextureLoader();
loader.setCrossOrigin( 'https://s.codepen.io' );
var textureCube = loader.load( urls );
textureCube.format = THREE.RGBFormat;
var shader = THREE.ShaderLib[ "cube" ];
shader.uniforms[ "tCube" ].value = textureCube;
var material = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.BackSide
} );
}
like this: https://codepen.io/danacrypto/pen/yLKoLXY
I made it but it has some problems. I like use this inside my site made with WordPress and elementor.
I'm Not perfect # javascript
[1]: https://codepen.io/soju22/pen/JjEqebK
[2]: https://codepen.io/bartuc/pen/yMMyav

Three.js rotate a sphere that's followed by a camera

I'm working on a toy Three.js scene in which I want to follow a sphere with a camera [demo]. Right now, though, I can't figure out how to make the sphere "roll" without also rotating the camera.
Here's the code I use to update the sphere's position each frame:
function moveSphere() {
var delta = clock.getDelta(); // seconds
var moveDistance = 200 * delta; // 200 pixels per second
var rotateAngle = Math.PI / 2 * delta; // pi/2 radians (90 deg) per sec
// move forwards/backwards/left/right
if ( pressed['W'] ) {
sphere.translateZ( -moveDistance );
}
if ( pressed['S'] )
sphere.translateZ( moveDistance );
if ( pressed['Q'] )
sphere.translateX( -moveDistance );
if ( pressed['E'] )
sphere.translateX( moveDistance );
// rotate left/right/up/down
var rotation_matrix = new THREE.Matrix4().identity();
if ( pressed['A'] )
sphere.rotateOnAxis(new THREE.Vector3(0,1,0), rotateAngle);
if ( pressed['D'] )
sphere.rotateOnAxis(new THREE.Vector3(0,1,0), -rotateAngle);
if ( pressed['R'] )
sphere.rotateOnAxis(new THREE.Vector3(1,0,0), rotateAngle);
if ( pressed['F'] )
sphere.rotateOnAxis(new THREE.Vector3(1,0,0), -rotateAngle);
}
And the code to follow the sphere each tick of time:
function moveCamera() {
var relativeCameraOffset = new THREE.Vector3(0,50,200);
var cameraOffset = relativeCameraOffset.applyMatrix4(sphere.matrixWorld);
camera.position.x = cameraOffset.x;
camera.position.y = cameraOffset.y;
camera.position.z = cameraOffset.z;
camera.lookAt(sphere.position);
}
Is there an easy way to make the ball roll without making the camera spiral all over the place? Inside of the if (pressed['W']) block, I tried various permutations of sphere.rotateOnAxis(new THREE.Vector3(0,0,1), rotateAngle); but haven't found a natural way to make the ball roll. I would be very grateful for any advice others can offer on this!
Your issue is this line:
var cameraOffset = relativeCameraOffset.applyMatrix4(sphere.matrixWorld);
This takes the offset you specify and applies not only the sphere position, but it's rotation as well. For example, if your sphere is rotated 180 degrees on the Y-axis, the resulting vector is (0, 50, -200) + (sphere position).
You need to extract the translation component from the sphere matrix, and apply it to the offset. The code below uses an intermediate matrix to store the position of the sphere.
/**
* Follow the sphere
**/
var sphereTranslation = new THREE.Matrix4(); // only make it once to reduce overhead
function moveCamera() {
var relativeCameraOffset = new THREE.Vector3(0,50,200);
sphereTranslation.copyPosition(sphere.matrixWorld); // get sphere position only
var cameraOffset = relativeCameraOffset.applyMatrix4(sphereTranslation);
camera.position.x = cameraOffset.x;
camera.position.y = cameraOffset.y;
camera.position.z = cameraOffset.z;
camera.lookAt(sphere.position);
}
The key here was to create a sphere, then add that sphere to a group, so that I could translate and rotate the group (which controls the ball's position) while also rotating the sphere inside the group (which allows the ball to "roll"). Separating these entities out allows the camera to follow the sphere group just as before while allowing the ball to rotate independently of the sphere group's movement [updated demo]:
/**
* Generate a scene object with a background color
**/
function getScene() {
var scene = new THREE.Scene();
scene.background = new THREE.Color(0x111111);
return scene;
}
/**
* Generate the camera to be used in the scene. Camera args:
* [0] field of view: identifies the portion of the scene
* visible at any time (in degrees)
* [1] aspect ratio: identifies the aspect ratio of the
* scene in width/height
* [2] near clipping plane: objects closer than the near
* clipping plane are culled from the scene
* [3] far clipping plane: objects farther than the far
* clipping plane are culled from the scene
**/
function getCamera() {
var aspectRatio = window.innerWidth / window.innerHeight;
var camera = new THREE.PerspectiveCamera(75, aspectRatio, 0.1, 10000);
camera.position.set(0,150,400);
camera.lookAt(scene.position);
return camera;
}
/**
* Generate the light to be used in the scene. Light args:
* [0]: Hexadecimal color of the light
* [1]: Numeric value of the light's strength/intensity
* [2]: The distance from the light where the intensity is 0
* #param {obj} scene: the current scene object
**/
function getLight(scene) {
var lights = [];
lights[0] = new THREE.PointLight( 0xffffff, 0.6, 0 );
lights[0].position.set( 100, 200, 100 );
scene.add( lights[0] );
var ambientLight = new THREE.AmbientLight(0x111111);
scene.add(ambientLight);
return light;
}
/**
* Generate the renderer to be used in the scene
**/
function getRenderer() {
// Create the canvas with a renderer
var renderer = new THREE.WebGLRenderer({antialias: true});
// Add support for retina displays
renderer.setPixelRatio(window.devicePixelRatio);
// Specify the size of the canvas
renderer.setSize(window.innerWidth, window.innerHeight);
// Add the canvas to the DOM
document.body.appendChild(renderer.domElement);
return renderer;
}
/**
* Generate the controls to be used in the scene
* #param {obj} camera: the three.js camera for the scene
* #param {obj} renderer: the three.js renderer for the scene
**/
function getControls(camera, renderer) {
var controls = new THREE.TrackballControls(camera, renderer.domElement);
controls.zoomSpeed = 0.4;
controls.panSpeed = 0.4;
return controls;
}
/**
* Get grass
**/
function getPlane(scene, loader) {
var texture = loader.load('grass.jpg');
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(1000, 1000, 10, 10);
var plane = new THREE.Mesh(geometry, material);
plane.position.y = -0.5;
plane.rotation.x = Math.PI / 2;
scene.add(plane);
return plane;
}
/**
* Add background
**/
function getBackground(scene, loader) {
var imagePrefix = 'sky-parts/';
var directions = ['right', 'left', 'top', 'bottom', 'front', 'back'];
var imageSuffix = '.bmp';
var geometry = new THREE.BoxGeometry( 1000, 1000, 1000 );
var materialArray = [];
for (var i = 0; i < 6; i++)
materialArray.push( new THREE.MeshBasicMaterial({
map: loader.load(imagePrefix + directions[i] + imageSuffix),
side: THREE.BackSide
}));
var sky = new THREE.Mesh( geometry, materialArray );
scene.add(sky);
}
/**
* Add a character
**/
function getSphere(scene) {
var geometry = new THREE.SphereGeometry( 30, 12, 9 );
var material = new THREE.MeshPhongMaterial({
color: 0xd0901d,
emissive: 0xaf752a,
side: THREE.DoubleSide,
flatShading: true
});
var sphere = new THREE.Mesh( geometry, material );
// create a group for translations and rotations
var sphereGroup = new THREE.Group();
sphereGroup.add(sphere)
sphereGroup.position.set(0, 24, 100);
scene.add(sphereGroup);
return [sphere, sphereGroup];
}
/**
* Store all currently pressed keys
**/
function addListeners() {
window.addEventListener('keydown', function(e) {
pressed[e.key.toUpperCase()] = true;
})
window.addEventListener('keyup', function(e) {
pressed[e.key.toUpperCase()] = false;
})
}
/**
* Update the sphere's position
**/
function moveSphere() {
var delta = clock.getDelta(); // seconds
var moveDistance = 200 * delta; // 200 pixels per second
var rotateAngle = Math.PI / 2 * delta; // pi/2 radians (90 deg) per sec
// move forwards/backwards/left/right
if ( pressed['W'] ) {
sphere.rotateOnAxis(new THREE.Vector3(1,0,0), -rotateAngle)
sphereGroup.translateZ( -moveDistance );
}
if ( pressed['S'] )
sphereGroup.translateZ( moveDistance );
if ( pressed['Q'] )
sphereGroup.translateX( -moveDistance );
if ( pressed['E'] )
sphereGroup.translateX( moveDistance );
// rotate left/right/up/down
var rotation_matrix = new THREE.Matrix4().identity();
if ( pressed['A'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(0,1,0), rotateAngle);
if ( pressed['D'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(0,1,0), -rotateAngle);
if ( pressed['R'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(1,0,0), rotateAngle);
if ( pressed['F'] )
sphereGroup.rotateOnAxis(new THREE.Vector3(1,0,0), -rotateAngle);
}
/**
* Follow the sphere
**/
function moveCamera() {
var relativeCameraOffset = new THREE.Vector3(0,50,200);
var cameraOffset = relativeCameraOffset.applyMatrix4(sphereGroup.matrixWorld);
camera.position.x = cameraOffset.x;
camera.position.y = cameraOffset.y;
camera.position.z = cameraOffset.z;
camera.lookAt(sphereGroup.position);
}
// Render loop
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
moveSphere();
moveCamera();
};
// state
var pressed = {};
var clock = new THREE.Clock();
// globals
var scene = getScene();
var camera = getCamera();
var light = getLight(scene);
var renderer = getRenderer();
// add meshes
var loader = new THREE.TextureLoader();
var floor = getPlane(scene, loader);
var background = getBackground(scene, loader);
var sphereData = getSphere(scene);
var sphere = sphereData[0];
var sphereGroup = sphereData[1];
addListeners();
render();
body { margin: 0; overflow: hidden; }
canvas { width: 100%; height: 100%; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/88/three.min.js"></script>

Rotate the mergeometry object at its center in Three.js

I am struggling to find the way to rotate the object at its center. At the moment i am able to rotate the scene, but when i do the rotation, the object goes away from the user. I look into the some the already asked questions in the same line on the forum, but couldn't able to get it work. Below is the part of the html/three.js file i am using /attached you will find the complete working example.Any help is greatly appreciated
<script src="../build/three.min.js"></script>
<script src="js/controls/TrackballControls.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var container, stats;
var camera, controls, scene, renderer;
var pickingData = [], pickingTexture, pickingScene;
var objects = [];
var highlightBox;
var splitCoord;
var avStdProp;
var mouse = new THREE.Vector2();
var offset = new THREE.Vector3( 10, 10, 10 );
var geom = new THREE.BoxGeometry(0.005, 0.005, 0.005 );
geom.colorsNeedUpdate = true;
init();
animate();
function init() {
container = document.getElementById( "container" );
camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.x=250;
camera.position.y=300;
camera.position.z=400;
renderer = new THREE.WebGLRenderer( { antialias: true } );
controls = new THREE.TrackballControls(camera);
controls.rotateSpeed = 1.0;
controls.zoomSpeed = 4;
controls.panSpeed = 0.8;
controls.noZoom = false;
controls.noPan = false;
controls.staticMoving = true;
controls.dynamicDampingFactor = 0.3;
scene = new THREE.Scene();
pickingScene = new THREE.Scene();
pickingTexture = new THREE.WebGLRenderTarget(800, 800);
pickingTexture.minFilter = THREE.LinearFilter;
pickingTexture.generateMipmaps = false;
scene.add( new THREE.AmbientLight( 0x555555 ) );
var light = new THREE.SpotLight( 0xffffff, 1.5 );
light.position.set( 0, 500, 2000 );
scene.add( light );
var geometry = new THREE.Geometry(),
pickingGeometry = new THREE.Geometry(),
pickingMaterial = new THREE.MeshBasicMaterial( { vertexColors: THREE.VertexColors } ),
defaultMaterial = new THREE.MeshLambertMaterial({ color: 0xffffff, shading: THREE.FlatShading, vertexColors: THREE.VertexColors } );
function applyVertexColors( g, c ) {
g.faces.forEach( function( f ) {
var n = ( f instanceof THREE.Face3 ) ? 3 : 4;
for( var j = 0; j < n; j ++ ) {
f.vertexColors[ j ] = c;
}
} );
}
var color = new THREE.Color();
var matrix = new THREE.Matrix4();
var quaternion = new THREE.Quaternion();
var coord="219_163_189;130_173_179;161_113_231;92_103_176;169_193_180;161_165_187;262_163_166;198_143_155;161_189_155;125_121_107";
splitCoord=coord.split(";");
var coordColr="0_255_255;255_255_0;0_0_255;0_255_0;255_255_0;0_255_0;0_0_255;0_255_255;255_255_0;210_210_45";
var splitCoordColor=coordColr.split(";");
var avgStd="1_0;3_0;0_0;2_0;3_0;2_0;0_0;1_0;3_0;3_0.35";
avStdProp=avgStd.split(";");
for ( var i = 0; i < splitCoord.length; i++ ) {
var position = new THREE.Vector3();
var xyz=splitCoord[i].split("_");
var col=splitCoordColor[i].split("_");
position.x = xyz[0];
position.y = xyz[1];
position.z = xyz[2];
var rotation = new THREE.Euler();
rotation.x = 0
rotation.y = 0;
rotation.z = 0;
var scale = new THREE.Vector3();
scale.x = 200 + 100;
scale.y = 200 + 100;
scale.z = 200 + 100;
quaternion.setFromEuler( rotation, false );
matrix.compose( position, quaternion, scale );
// give the geom's vertices a random color, to be displayed
col[0]=col[0]/255;
col[1]=col[1]/255;
col[2]=col[2]/255;
applyVertexColors(geom, color.setRGB(col[0], col[1], col[2]));
geometry.merge( geom, matrix );
// give the geom's vertices a color corresponding to the "id"
applyVertexColors( geom, color.setHex( i ) );
pickingGeometry.merge( geom, matrix );
pickingData[ i ] = {
position: position,
rotation: rotation,
scale: scale
};
}
var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
scene.add( drawnObject );
pickingScene.add( new THREE.Mesh( pickingGeometry, pickingMaterial ) );
highlightBox = new THREE.Mesh(
new THREE.BoxGeometry( 0.009, 0.009, 0.009 ),
new THREE.MeshLambertMaterial( { color: 0xffffff }
) );
scene.add( highlightBox );
//renderer.setClearColor( 0xffffff );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize(800,800);
renderer.sortObjects = false;
container.appendChild( renderer.domElement );
renderer.domElement.addEventListener( 'mousemove', onMouseMove );
}
//
function onMouseMove( e ) {
mouse.x = e.clientX;
mouse.y = e.clientY;
}
function pick() {
//render the picking scene off-screen
renderer.render( pickingScene, camera, pickingTexture );
//create buffer for reading single pixel
var pixelBuffer = new Uint8Array( 4 );
//read the pixel under the mouse from the texture
renderer.readRenderTargetPixels(pickingTexture, mouse.x+window.pageXOffset, pickingTexture.height - (mouse.y+window.pageYOffset), 1, 1, pixelBuffer);
//interpret the pixel as an ID
var id = ( pixelBuffer[0] << 16 ) | ( pixelBuffer[1] << 8 ) | ( pixelBuffer[2]);
var data = pickingData[ id ];
if (data) {
//move our highlightBox so that it surrounds the picked object
if (data.position && data.rotation && data.scale && controls.enabled){
highlightBox.position.copy( data.position );
highlightBox.rotation.copy( data.rotation );
highlightBox.scale.copy( data.scale ).add( offset );
highlightBox.visible = true;
}
}
else {
highlightBox.visible = false;
}
}
function animate() {
requestAnimationFrame( animate );
render();
//stats.update();
}
function render() {
controls.update();
pick();
renderer.render(scene, camera);
}
any help?
You can set your objects geometry to center, so the center of the mesh will then be at position (0,0,0) and it wont "move away" while rotating.
Do it like this:
geometry.center();
var drawnObject = new THREE.Mesh( geometry, defaultMaterial );
scene.add( drawnObject );
Update
Because you want to use picking in an unusual way by saving your geometrys coordinates into an array, centering the geometry doesnt help you. Your question was "Rotate the mergeometry object at its center", but it seems like you want to rotate the camera around your geometrys center.
Calculate the bounding sphere of your geometry and set the controls target to its position:
drawnObject.geometry.computeBoundingSphere();
controls.target = drawnObject.geometry.boundingSphere.center;

Raycasting and container in Three.js

I have been struggling with issues concerning raycasting on small circlegeometries on a sphere.
I know raycasting can't be done with sprites and this is why I use circlegeometries, but it doesn't work all the time, and moreover the raycasting doesn't always work on circles but sometimes around them as well.
Does anybody have an idea ? Here is a JSBin to show you basically
Edit :
I updated my previous version of JSBin, you can click any circleGeometries it will work here, run it with output tab only open for better results
This is related to the renderer width and height properties, my sphere isn't in fullscreen and this is why it fails.
Does anybody have an idea on how to set up it right in order to get this to work perfectly ?
The formula used to compute intersections wasn't the good one, here is the one that works :
mouse.x = ( ( event.clientX - renderer.domElement.offsetLeft ) / renderer.domElement.width ) * 2 - 1;
mouse.y = - ( ( event.clientY - renderer.domElement.offsetTop ) / renderer.domElement.height ) * 2 + 1;
mouse x and y have slightly changed from the examples you can get, and are now fine.
var vector = new THREE.Vector3(mouse.x, mouse.y, 0.5);
projector.unprojectVector(vector, camera);
var ray = new THREE.Raycaster(camera.position, vector.sub(
camera.position).normalize());
var intersects = ray.intersectObjects(objects);
if ( intersects.length > 0 ) {
//do something
}
if you looking for some thing like this....Your code might need little changes... check this link http://jsfiddle.net/ebeit303/rjJ6q/
// standard global variables
var container, scene, camera, renderer, controls, stats;
var clock = new THREE.Clock();
// custom global variables
var targetList = [];
var projector, mouse = { x: 0, y: 0 };
init();
animate();
// FUNCTIONS
function init()
{
// SCENE
scene = new THREE.Scene();
// CAMERA
var SCREEN_WIDTH = window.innerWidth, SCREEN_HEIGHT = window.innerHeight;
var VIEW_ANGLE = 45, ASPECT = SCREEN_WIDTH / SCREEN_HEIGHT, NEAR = 0.1, FAR = 100000;
camera = new THREE.PerspectiveCamera( VIEW_ANGLE, ASPECT, NEAR, FAR);
scene.add(camera);
camera.position.set(600,0,-1200);
camera.lookAt(scene.position);
// RENDERER
renderer = new THREE.CanvasRenderer();
renderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
container = document.getElementById( 'ThreeJS' );
container.appendChild( renderer.domElement );
// EVENTS
// CONTROLS
// this material causes a mesh to use colors assigned to faces
var faceColorMaterial = new THREE.MeshBasicMaterial(
{ color: 0xffffff, vertexColors: THREE.FaceColors } );
var sphereGeometry = new THREE.SphereGeometry( 500, 64, 64 );
for ( var i = 0; i < sphereGeometry.faces.length; i++ )
{
face = sphereGeometry.faces[ i ];
face.color.setRGB( 0, 0, 0.8 * Math.random() + 0.2 );
}
var sphere = new THREE.Mesh( sphereGeometry, faceColorMaterial );
sphere.rotation.set(0, 14.5, 0);
scene.add(sphere);
//targetList.push(sphere);
var j=0;
for (var i =0; i<100;i+=5){
//var circle = new THREE.CubeGeometry(5,5,5);
var circle = new THREE.CircleGeometry(5, 8, 0, Math.PI * 2);
//THREE.GeometryUtils.triangulateQuads(circle);
var circleMaterial = new THREE.MeshBasicMaterial({color: 0xDEF2EF});
circleMaterial.side = THREE.DoubleSide;
var mesh = new THREE.Mesh(circle, circleMaterial);
var Alon = i - 90;
var Alat = j;
var Aphi = Math.PI/2 - Alat * Math.PI / 180;
var Atheta = 2 * Math.PI - Alon * Math.PI / 180;
mesh.position.x = Math.sin(Aphi) * Math.cos(Atheta) * (501);
mesh.position.y = Math.cos(Aphi) * (501);
mesh.position.z = Math.sin(Aphi) * Math.sin(Atheta) * (501);
mesh.verticesNeedUpdate = true;
mesh.lookAt( sphere.position );
sphere.add(mesh);
targetList.push(mesh);
j++;
}
// initialize object to perform world/screen calculations
projector = new THREE.Projector();
// when the mouse moves, call the given function
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event )
{
// update the mouse variable
mouse.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
var vector = new THREE.Vector3( mouse.x, mouse.y, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Raycaster( camera.position, vector.sub( camera.position ).normalize() );
var intersects = ray.intersectObjects( targetList );
if ( intersects.length > 0 )
{
intersects[ 0 ].object.material.color.setRGB( 0.8 * Math.random() + 0.2,
0.8 * Math.random() + 0.2,
0.8 * Math.random() + 0.2 );
}
}
function animate()
{
requestAnimationFrame( animate );
render();
}
function render()
{
renderer.render( scene, camera );
}

How can I Import my object with it's inherent textures from Blender to ThreeJS?

I have used the STL Loader for threejs to import my object from Blender into threejs but for some reason, the textures don't appear. I assume it has to do with the object's MeshBasicMaterial. I tried changing it to Phong but the object turns black instead.
Then I realized, instead of changing the material from basic to phong, why can't I kept the inherent features/textures from Blender when I load the object from STL loader to threejs? Is there a way to keep the texture? Is there a tutorial I can follow?
THanks!
EDIT:
Here's a snippet of my code where I exported my Blender object with textures to a threejs .js file. The object loads in my viewer but it's black with no textures. I'm not sure how to fix this. I followed another example that used an inn for texture (hence the name. Didn't change the name yet).
var Viewport = function ( signals ) {
var container = new UI.Panel( 'absolute' );
container.setBackgroundColor( '#aaa' );
var clock = new THREE.Clock();
// settings
var enableHelpersFog = true;
// helpers
var objects = [];
var INTERSECTED;
var sceneHelpers = new THREE.Scene();
//the grid that appears at the beginning.
var size = 500, step = 25;
var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial( { vertexColors: THREE.VertexColors } );
var color1 = new THREE.Color( 0x444444 ), color2 = new THREE.Color( 0x888888 );
for ( var i = - size; i <= size; i += step ) {
geometry.vertices.push( new THREE.Vector3( -size, 0, i ) );
geometry.vertices.push( new THREE.Vector3( size, 0, i ) );
geometry.vertices.push( new THREE.Vector3( i, 0, -size ) );
geometry.vertices.push( new THREE.Vector3( i, 0, size ) );
var color = i === 0 ? color1 : color2;
geometry.colors.push( color, color, color, color );
}
var grid = new THREE.Line( geometry, material, THREE.LinePieces );
sceneHelpers.add( grid );
///Objects stuff
var objectshapes = [];
//stl files
group = new THREE.Object3D();
var loader_slotted_disk = new THREE.STLLoader();
loader_slotted_disk.addEventListener( 'load', function ( event ) {
var geometry = event.content;
console.log(geometry);
var material = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 });
var mesh1 = new THREE.Mesh( geometry, material );
mesh1.name='slotted disk';
mesh1.castShadow = true;
mesh1.receiveShadow = true;
sceneHelpers.add( mesh1 );
objectshapes.push( mesh1 );
} );
loader_slotted_disk.load( 'js/ui/assests/slotted_disk.stl' );
var loader_left_bronchus = new THREE.STLLoader();
loader_left_bronchus.addEventListener( 'load', function ( event ) {
var geometry = event.content;
console.log(geometry);
var material = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 });
var mesh1 = new THREE.Mesh( geometry, material );
mesh1.name='left bronchus';
mesh1.castShadow = true;
mesh1.receiveShadow = true;
mesh1.position.x = Math.random() * 200 - 50;
mesh1.position.y = Math.random() * 200 - 50;
mesh1.position.z = Math.random() * 200 - 50;
sceneHelpers.add( mesh1 );
objectshapes.push( mesh1 );
} );
loader_left_bronchus.load( 'js/ui/assests/left_bronchus.stl' );
var loader_parenchyma = new THREE.STLLoader();
loader_parenchyma.addEventListener( 'load', function ( event ) {
var geometry = event.content;
console.log(geometry);
var material = new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 });
var mesh2 = new THREE.Mesh( geometry, material );
mesh2.name='parenchyma';
mesh2.castShadow = true;
mesh2.receiveShadow = true;
sceneHelpers.add( mesh2 );
objectshapes.push( mesh2 );
} );
//loader_parenchyma.load( 'js/ui/assests/parenchyma.stl' );
//group.rotation.x = Math.PI* 3/2
////////////
// CUSTOM //
////////////
var inn_loader = new THREE.JSONLoader(); inn_loader.load("js/reducedandcoloredmodel[Conflict].js", function(geo, material) { var materials = new THREE.MeshFaceMaterial(material); inn = new THREE.Mesh(geo, materials); scene.add(inn); }); //
///stl files added
var geometry = new THREE.CubeGeometry( 50, 50, 50 );
var geometry2 = new THREE.SphereGeometry( 50, 10, 10);
var object = new THREE.Mesh( geometry, new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) );
object.name = "cube";
object.position.x = Math.random() * 200 - 50;
object.position.y = Math.random() * 200 - 50;
object.position.z = Math.random() * 200 - 50;
object.rotation.x = Math.random() * 2 * Math.PI;
object.rotation.y = Math.random() * 2 * Math.PI;
object.rotation.z = Math.random() * 2 * Math.PI;
sceneHelpers.add( object );
objectshapes.push( object );
var object2 = new THREE.Mesh( geometry2, new THREE.MeshBasicMaterial( { color: Math.random() * 0xffffff, opacity: 0.5 } ) );
object2.name = "sphere";
object2.position.x = Math.random() * 200 - 50;
object2.position.y = Math.random() * 200 - 50;
object2.position.z = Math.random() * 200 - 50;
object2.rotation.x = Math.random() * 2 * Math.PI;
object2.rotation.y = Math.random() * 2 * Math.PI;
object2.rotation.z = Math.random() * 2 * Math.PI;
sceneHelpers.add( object2 );
objectshapes.push( object2 );
console.log(objectshapes);
///box around object
var selectionBox = new THREE.Mesh( new THREE.CubeGeometry( 1, 1, 1 ), new THREE.MeshBasicMaterial( { color: 0xffff00, wireframe: true, fog: false } ) );
selectionBox.matrixAutoUpdate = false;
selectionBox.visible = false;
sceneHelpers.add( selectionBox );
///axis
var selectionAxis = new THREE.AxisHelper( 100 );
selectionAxis.material.depthTest = false;
selectionAxis.material.transparent = true;
selectionAxis.matrixAutoUpdate = false;
selectionAxis.visible = false;
sceneHelpers.add( selectionAxis );
// default dummy scene and camera
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 50, 1, 1, 5000 );;
// fog
var oldFogType = "None";
var oldFogColor = 0xaaaaaa;
var oldFogNear = 1;
var oldFogFar = 5000;
var oldFogDensity = 0.00025;
// object picking
var intersectionPlane = new THREE.Mesh( new THREE.PlaneGeometry( 10000, 10000, 8, 8 ) );
intersectionPlane.visible = false;
sceneHelpers.add( intersectionPlane );
var ray = new THREE.Raycaster();
var projector = new THREE.Projector();
var offset = new THREE.Vector3();
var cameraChanged = false;
var helpersVisible = true;
//by default the selected scene object is the camera.
var picked = null;
var selected = camera;
mr doob already points out that stl doesn't specify color or texture, it is pure geometry. I suggest exporting something trivial from blender (like a cube with textures) with the three.js exporter, to get an understanding of what's going on. I have example code at threejs-and-blender. View the source of those threejs demos and look at which files are being pulled in, you should find references to images too.
Once you have that working, figuring out the more complex model becomes easier. Plus if you don't want to share you original model you should have no trouble sharing a simple cube for debugging.
While I didn't use the JSON Loader, I tried to use the Collada Loader (as my model retained textures offline when imported in the Webgl loader collada example) and inside this current 3-D viewer, my model was still black. However, after adding a light, the textures were shown.
Essentially, I'm assuming just as well with the JSON Loader, I need to add a light inside my 3-D viewer for the model's exterior to show.
I had the same issue using Blender v 2.68a. The problem was solved with Blender 2.71.
I imported, using Blender 2.71, the .stl file which was previously shown black on WebGl, then exported it without changing any setting parameter from the default .stl exporter menu.
I reloaded the file with WebGl and there it was, full colour!

Categories

Resources