I'm having an issue with Raycasting with Three.js and WhitestormJS.
Maybe I didn't understood well some of the underlying principle of this particular element.
What I'm trying to do is syncing the direction of the raycaster with my camera.
So, once it intersect an element, this element will be added to the intersect array.
The problem is that my "intersect" array stay empty even if I move my camera in the direction of an element.
On codepen : https://codepen.io/paulbonneau/pen/zdVeJx?editors=1111
My code :
const app = new WHS.App([
new WHS.ElementModule({
container: document.getElementById('app')
}),
new WHS.SceneModule(),
new WHS.DefineModule('camera', new WHS.PerspectiveCamera({
position: new THREE.Vector3(0, 6, 18),
far: 10000
})),
new WHS.CameraModule({
position: {
y: 2,
z: 2,
x: 1,
},
}),
new WHS.RenderingModule({
bgColor: 0x162129,
renderer: {
antialias: true,
shadowmap: {
type: THREE.PCFSoftShadowMap
}
}
}, {shadow: true}),
new WHS.OrbitControlsModule(
),
new WHS.ResizeModule()
]);
app.modules[5].controls.enableZoom = false
var camera = app.get('camera');
crosshair = new THREE.Vector2(0,0);
// Rendu de la skybox càd l'environnement dans lequel se déroule le jeu
var path = "img/skybox/";
var format = '.jpg';
var urls = [
'./skybox/EH_0.front.jpg',
'./skybox/EH_0.back.jpg' ,
'./skybox/EH_0.top.jpg',
'./skybox/EH_0.bottom.jpg',
'./skybox/EH_0.left.jpg',
'./skybox/EH_0.right.jpg',
];
var reflectionCube = THREE.ImageUtils.loadTextureCube(urls, null);
reflectionCube.format = THREE.RGBFormat;
var shader = THREE.ShaderLib[ "cube" ];
shader.uniforms[ "tCube" ].value = reflectionCube;
var material = new THREE.ShaderMaterial( {
fragmentShader: shader.fragmentShader,
vertexShader: shader.vertexShader,
uniforms: shader.uniforms,
depthWrite: false,
side: THREE.BackSide
});
//End test
const world = new WHS.Box({ // Create box to contain the 3D space where the game happen
geometry: {
width: 100,
height: 100,
depth: 100
},
material: material
});
world.addTo(app);
var material = new THREE.MeshBasicMaterial( { color: 0xffffff, envMap: reflectionCube } );
var points = [];
for ( var deg = 0; deg <= 180; deg += 6 ) {
var rad = Math.PI * deg / 180;
var point = new THREE.Vector2( ( 0.72 + .08 * Math.cos( rad ) ) * Math.sin( rad ), - Math.cos( rad ) ); // the "egg equation"
//console.log( point ); // x-coord should be greater than zero to avoid degenerate triangles; it is not in this formula.
points.push( point );
}
const sphere = new WHS.Sphere({
geometry: {
radius: 100
},
material: new THREE.MeshBasicMaterial({
color: 0xffffff
}),
position: {
y: 1,
x: 1,
z: 0
}
});
for (var i = 0; i < 20; i++) {
egg_size = Math.random() * 10-2;
egg = new WHS.Lathe({
geometry: {
points: points
},
material: material,
position: {
y: Math.random() * 100 - 50,
x: Math.random() * 100 - 50 ,
z: Math.random() * 100 - 50
},
rotation: {
x: Math.random() * Math.PI/2,
y: Math.random() * Math.PI/2,
z: Math.random() * Math.PI/2
},
scale:{
x : egg_size,
z : egg_size,
y : egg_size
}
});
egg.addTo(sphere);
}
sphere.addTo(world);
raycaster = new THREE.Raycaster(camera, camera.position);
var intersects = raycaster.intersectObjects( app.children );
new WHS.Loop(() => {
raycaster.setFromCamera( camera.position , camera );
sphere.rotation.x += 0.01;
sphere.rotation.y += 0.01;
for (var i = 0; i < sphere.children.length-1; i++) {
sphere.children[i].rotation.x += 0.05;
sphere.children[i].rotation.y += 0.05;
sphere.children[i].rotation.z += 0.05;
}
}).start(app);
// Start the app
app.start();
You're constructing the raycaster in the wrong way (as of r87).
raycaster = new THREE.Raycaster(camera, camera.position);
As shown in the documentation, the raycaster is constructed like so:
var raycaster = new THREE.Raycaster();
The rest of the code looks correct, so I assume that is the problem.
Here's a working example
Related
In Three.js, we are now able to get the global position of a vertex of a non-skinned mesh thanks to this question, but how can I get the global position of a vertex of a skinned mesh with bones and morph targets?
For example, how can I print (2.5, 1.5, 0.5) in the following situation?
mesh.geometry.vertices[0] is originally at (0.5, 0.5, 0.5).
Then, bones[1] moves the vertex to (2.5, 0.5, 0.5).
Finally, morphing moves the vertex to (2.5, 1.5, 0.5).
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 200);
camera.position.z = 3;
camera.position.y = 2;
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry(1, 1, 1);
geometry.morphTargets.push({name: "morph", vertices: []});
for (const vertex of geometry.vertices) {
geometry.skinIndices.push(new THREE.Vector4(vertex.x < 0 ? 0 : 1, 0, 0, 0));
geometry.skinWeights.push(new THREE.Vector4(1, 0, 0, 0));
geometry.morphTargets[0].vertices.push(vertex.clone().add(new THREE.Vector3(0, 1, 0)));
}
const material = new THREE.MeshPhongMaterial({
skinning: true,
emissive: 0xffffff,
wireframe: true,
morphTargets: true
});
const mesh = new THREE.SkinnedMesh(geometry, material);
const bones = [new THREE.Bone(), new THREE.Bone()];
for (const bone of bones) {
mesh.add(bone);
}
const skeleton = new THREE.Skeleton(bones);
mesh.bind(skeleton);
bones[0].position.x = -2;
bones[1].position.x = 2;
mesh.morphTargetInfluences[0] = 1;
scene.add(mesh);
// This code assigns (0.5, 0.5, 0.5) to pos,
// but I want to know the code which assigns (2.5, 1.5, 0.5) to pos.
const pos = mesh.geometry.vertices[0].clone().applyMatrix4(mesh.matrixWorld);
console.log(`(${pos.x}, ${pos.y}, ${pos.z})`);
(function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
})();
body {
margin: 0;
overflow: hidden;
}
canvas {
width: 100%;
height: 100%;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script>
So this is what I did to try to figure this out. I'm too lazy to check if it works for all cases but ...
First I used the Shader Editor extension and then I ran a skinned example and using the shader editor I looked at the generated shader
Looking at the vertex shader the relevant part of the shader is
#ifdef USE_SKINNING
mat4 boneMatX = getBoneMatrix( skinIndex.x );
mat4 boneMatY = getBoneMatrix( skinIndex.y );
mat4 boneMatZ = getBoneMatrix( skinIndex.z );
mat4 boneMatW = getBoneMatrix( skinIndex.w );
#endif
#ifdef USE_SKINNING
mat4 skinMatrix = mat4( 0.0 );
skinMatrix += skinWeight.x * boneMatX;
skinMatrix += skinWeight.y * boneMatY;
skinMatrix += skinWeight.z * boneMatZ;
skinMatrix += skinWeight.w * boneMatW;
skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix;
objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz;
#endif
vec3 transformedNormal = normalMatrix * objectNormal;
#ifdef FLIP_SIDED
transformedNormal = - transformedNormal;
#endif
vec3 transformed = vec3( position );
#ifdef USE_MORPHTARGETS
transformed += ( morphTarget0 - position ) * morphTargetInfluences[ 0 ];
transformed += ( morphTarget1 - position ) * morphTargetInfluences[ 1 ];
transformed += ( morphTarget2 - position ) * morphTargetInfluences[ 2 ];
transformed += ( morphTarget3 - position ) * morphTargetInfluences[ 3 ];
#ifndef USE_MORPHNORMALS
transformed += ( morphTarget4 - position ) * morphTargetInfluences[ 4 ];
transformed += ( morphTarget5 - position ) * morphTargetInfluences[ 5 ];
transformed += ( morphTarget6 - position ) * morphTargetInfluences[ 6 ];
transformed += ( morphTarget7 - position ) * morphTargetInfluences[ 7 ];
#endif
#endif
#ifdef USE_SKINNING
vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 );
vec4 skinned = vec4( 0.0 );
skinned += boneMatX * skinVertex * skinWeight.x;
skinned += boneMatY * skinVertex * skinWeight.y;
skinned += boneMatZ * skinVertex * skinWeight.z;
skinned += boneMatW * skinVertex * skinWeight.w;
transformed = ( bindMatrixInverse * skinned ).xyz;
#endif
So translating that into JavaScript here's what I came up with
First off you need the scene to have all its world matrices
and the skeleton updated.
scene.updateMatrixWorld();
skeleton.update();
Then
// These are so we can avoid doing allocations
// in the inner loop.
const position = new THREE.Vector3();
const transformed = new THREE.Vector3();
const temp1 = new THREE.Vector3();
const tempBoneMatrix = new THREE.Matrix4();
const tempSkinnedVertex = new THREE.Vector3();
const tempSkinned = new THREE.Vector3();
const bindMatrix = mesh.bindMatrix;
const bindMatrixInverse = mesh.bindMatrixInverse;
for (let vndx = 0; vndx < mesh.geometry.vertices.length; ++vndx) {
position.copy(mesh.geometry.vertices[vndx]);
transformed.copy(position);
for (let i = 0; i < mesh.geometry.morphTargets.length; ++i) {
temp1.copy(mesh.geometry.morphTargets[i].vertices[vndx]);
transformed.add(temp1.sub(position).multiplyScalar(mesh.morphTargetInfluences[i]));
}
tempSkinnedVertex.copy(transformed).applyMatrix4(bindMatrix);
tempSkinned.set(0, 0, 0);
const skinIndices = geometry.skinIndices[vndx];
const skinWeights = geometry.skinWeights[vndx];
for (let i = 0; i < 4; ++i) {
const boneNdx = skinIndices.getComponent(i);
const weight = skinWeights.getComponent(i);
tempBoneMatrix.fromArray(skeleton.boneMatrices, boneNdx * 16);
temp1.copy(tempSkinnedVertex);
tempSkinned.add(temp1.applyMatrix4(tempBoneMatrix).multiplyScalar(weight));
}
transformed.copy(tempSkinned).applyMatrix4(bindMatrixInverse);
transformed.applyMatrix4(mesh.matrixWorld);
Example:
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(75, 2, 0.1, 200);
camera.position.z = 3;
camera.position.y = 2;
camera.lookAt(0, 0, 0);
const renderer = new THREE.WebGLRenderer({canvas:document.querySelector('canvas')});
renderer.setSize(512, 256, false);
document.body.appendChild(renderer.domElement);
const geometry = new THREE.BoxGeometry(1, 1, 1);
geometry.morphTargets.push({name: "morph", vertices: []});
for (const vertex of geometry.vertices) {
geometry.skinIndices.push(new THREE.Vector4(vertex.x < 0 ? 0 : 1, 0, 0, 0));
geometry.skinWeights.push(new THREE.Vector4(1, 0, 0, 0));
geometry.morphTargets[0].vertices.push(vertex.clone().add(new THREE.Vector3(0, 1, 0)));
}
const material = new THREE.MeshPhongMaterial({
skinning: true,
emissive: 0xffffff,
wireframe: true,
morphTargets: true
});
const mesh = new THREE.SkinnedMesh(geometry, material);
const bones = [new THREE.Bone(), new THREE.Bone()];
for (const bone of bones) {
mesh.add(bone);
}
const skeleton = new THREE.Skeleton(bones);
mesh.bind(skeleton);
bones[0].position.x = -2;
bones[1].position.x = 2;
mesh.morphTargetInfluences[0] = 1;
scene.add(mesh);
const putMeshesAtSkinnedVertices = (function() {
// These are so we can avoid doing allocations
// in the inner loop.
const position = new THREE.Vector3();
const transformed = new THREE.Vector3();
const temp1 = new THREE.Vector3();
const tempBoneMatrix = new THREE.Matrix4();
const tempSkinnedVertex = new THREE.Vector3();
const tempSkinned = new THREE.Vector3();
return function putMarkersAtSkinnedVertices(mesh, scene, marker, markerMaterial, markers) {
const bindMatrix = mesh.bindMatrix;
const bindMatrixInverse = mesh.bindMatrixInverse;
const geometry = mesh.geometry;
const vertices = geometry.vertices;
const morphTargets = geometry.morphTargets;
const skeleton = mesh.skeleton;
for (let vndx = 0; vndx < vertices.length; ++vndx) {
position.copy(vertices[vndx]);
transformed.copy(position);
for (let i = 0; i < morphTargets.length; ++i) {
temp1.copy(morphTargets[i].vertices[vndx]);
transformed.add(temp1.sub(position).multiplyScalar(mesh.morphTargetInfluences[i]));
}
tempSkinnedVertex.copy(transformed).applyMatrix4(bindMatrix);
tempSkinned.set(0, 0, 0);
const skinIndices = geometry.skinIndices[vndx];
const skinWeights = geometry.skinWeights[vndx];
for (let i = 0; i < 4; ++i) {
const boneNdx = skinIndices.getComponent(i);
const weight = skinWeights.getComponent(i);
tempBoneMatrix.fromArray(skeleton.boneMatrices, boneNdx * 16);
temp1.copy(tempSkinnedVertex);
tempSkinned.add(temp1.applyMatrix4(tempBoneMatrix).multiplyScalar(weight));
}
transformed.copy(tempSkinned).applyMatrix4(bindMatrixInverse);
transformed.applyMatrix4(mesh.matrixWorld);
// create them the first time this is called
let markerMesh = markers[vndx];
if (!markerMesh) {
markerMesh = new THREE.Mesh(marker, markerMaterial);
markers[vndx] = markerMesh;
scene.add(markerMesh);
}
markerMesh.position.copy(transformed);
}
}
}());
// Make sure all matrices are up to date
scene.updateMatrixWorld();
skeleton.update();
const marker = new THREE.BoxBufferGeometry(0.1, 0.1, 0.1);
const markerMaterial = new THREE.MeshBasicMaterial({color: 0xFF0000});
const markers = [];
putMeshesAtSkinnedVertices(mesh, scene, marker, markerMaterial, markers);
(function render() {
// requestAnimationFrame(render);
renderer.render(scene, camera);
})();
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/94/three.min.js"></script>
<canvas></canvas>
I did test it with this sample and it seemed to work.
So as the title states I'd like to know how to plot randomly generated meshes at the y-position that matches the terrain's corresponding y-position in three.js. I've looked through the docs and feel like using a raycaster might work, but I can only see examples that uses the detection as a mouse event, and not before render, so I'm not sure how to implement it.
Here is my code for the terrain, heightmap, and mesh plotting so far. It all works technically, but as you can see the plotAssets meshes y-positions are just sitting at zero right now. Any insights would be very much appreciated, I'm pretty new to three.js.
Terrain:
var heightmaploader = new THREE.ImageLoader();
heightmaploader.load(
"assets/noisemaps/cloud.png",
function(img) {
data = getHeightData(img);
var terrainG = new THREE.PlaneBufferGeometry(700, 700, worldWidth - 1, worldDepth - 1);
terrainG.rotateX(-Math.PI / 2);
var vertices = terrainG.attributes.position.array;
for (var i = 0, j = 0, l = vertices.length; i < l; i++, j += 3) {
vertices[j + 1] = data[i] * 5;
}
terrainG.computeFaceNormals();
terrainG.computeVertexNormals();
var material = new THREE.MeshLambertMaterial({
map: terrainT,
//side: THREE.DoubleSide,
color: 0xffffff,
transparent: false,
});
terrain = new THREE.Mesh(terrainG, material);
terrain.receiveShadow = true;
terrain.castShadow = true;
terrain.position.y = 0;
scene.add(terrain);
plotAsset('boulder-photo-01.png', 30, 18, data);
plotAsset('boulder-outline-01.png', 20, 20, data);
plotAsset('birch-outline-01.png', 10, 50, data);
plotAsset('tree-photo-01.png', 20, 50, data);
plotAsset('grass-outline-01.png', 10, 20, data);
plotAsset('grass-outline-02.png', 10, 20, data);
}
);
Plot Assets:
function plotAsset(texturefile, amount, size, array) {
console.log(array);
var loader = new THREE.TextureLoader();
loader.load(
"assets/textures/objects/" + texturefile,
function(texturefile) {
var geometry = new THREE.PlaneGeometry(size, size, 10, 1);
var material = new THREE.MeshBasicMaterial({
color: 0xFFFFFF,
map: texturefile,
side: THREE.DoubleSide,
transparent: true,
depthWrite: false,
depthTest: false,
alphaTest: 0.5,
});
var uniforms = { texture: { value: texturefile } };
var vertexShader = document.getElementById( 'vertexShaderDepth' ).textContent;
var fragmentShader = document.getElementById( 'fragmentShaderDepth' ).textContent;
// add bunch o' stuff
for (var i = 0; i < amount; i++) {
var scale = Math.random() * (1 - 0.8 + 1) + 0.8;
var object = new THREE.Mesh(geometry, material);
var x = Math.random() * 400 - 400 / 2;
var z = Math.random() * 400 - 400 / 2;
object.rotation.y = 180 * Math.PI / 180;
//object.position.y = size * scale / 2;
object.position.x = x;
object.position.z = z;
object.position.y = 0;
object.castShadow = true;
object.scale.x = scale; // random scale
object.scale.y = scale;
object.scale.z = scale;
scene.add(object);
object.customDepthMaterial = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader,
side: THREE.DoubleSide
} );
}
}
);
}
Height Data:
function getHeightData(img) {
var canvas = document.createElement('canvas');
canvas.width = 2048 / 8;
canvas.height = 2048 / 8;
var context = canvas.getContext('2d');
var size = 2048 / 8 * 2048 / 8,
data = new Float32Array(size);
context.drawImage(img, 0, 0);
for (var i = 0; i < size; i++) {
data[i] = 0
}
var imgd = context.getImageData(0, 0, 2048 / 8, 2048 / 8);
var pix = imgd.data;
var j = 0;
for (var i = 0, n = pix.length; i < n; i += (4)) {
var all = pix[i] + pix[i + 1] + pix[i + 2];
data[j++] = all / 40;
}
return data;
}
Yes, using of THREE.Raycaster() works well.
A raycaster has the .set(origin, direction) method. The only thing you have to do here is to set the point of origin higher than the highest point of the height map.
var n = new THREE.Mesh(...); // the object we want to aling along y-axis
var collider = new THREE.Raycaster();
var shiftY = new THREE.Vector3();
var colliderDir = new THREE.Vector3(0, -1, 0); // down along y-axis to the mesh of height map
shiftY.set(n.position.x, 100, n.position.z); // set the point of the origin
collider.set(shiftY, colliderDir); //set the ray of the raycaster
colliderIntersects = collider.intersectObject(plane); // plane is the mesh of height map
if (colliderIntersects.length > 0){
n.position.y = colliderIntersects[0].point.y; // set the position of the object
}
jsfiddle example
i'm not good at javascript... T_T
can i get position(x,y,z) where i clicked sprite (or object) ?????
below my code.. help me!!
//sprite
var spriteMap = new THREE.TextureLoader().load( 'tag.png' );
var spriteMaterial = new THREE.SpriteMaterial( { map: spriteMap, color: 0xffffff } );
var sprite = new THREE.Sprite( spriteMaterial );
sprite.scale.set(3, 3, 1)
sprite.position.set(25, 20, 20)
scene.add( sprite );
objects.push(sprite);
//sprite( text )
var spritey = makeTextSprite( " spritey ",
{ fontsize: 24, borderColor: {r:255, g:0, b:0, a:1.0}, backgroundColor: {r:255, g:100, b:100, a:1.0} } );
spritey.position.set(-85,105,55);
scene.add( spritey );
console.log(makeTextSprite);
objects.push(spritey);
///////////////////skip some codes//////////////////////////////////
function onDocumentMouseUp(event) {
event.preventDefault();
var vector = new THREE.Vector3((event.clientX / window.innerWidth) * 2-1, -(event.clientY / window.innerHeight) * 2 + 1, 0.5);
projector.unprojectVector(vector, camera);
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects(objects);
if (intersects.length > 0) {
window.open(intersects[0].object.userData.URL);
console.log(intersects.length)
}
}
if you want the position where you clicked:
var position = intersects[0].point
if you want the position of the object:
var position = intersects[0].object.position
I have a N number of random points (in this case 20), with a X,Y and Z constrains.
How can I create ANY (preferably closed) shape (using Three.js library) , given and starting only from N random points.
There are probably many variants, please share yours.
var program = new Program(reset,step)
program.add('g',false)
function reset() {
scene.clear()
scene.add(new THREE.GridHelper(100,1))
}
function step() {
}
program.startup()
var numpoints = 20;
var dots = []; //If you want to use for other task
for (var i = 0 ; i < numpoints ; i++){
var x = Math.random() * (80 - 1) + 1 //Math.random() * (max - min) + min
var y = Math.random() * (80 - 1) + 1
var z = Math.random() * (80 - 1) + 1
var dotGeometry = new THREE.Geometry();
dots.push(dotGeometry);
dotGeometry.vertices.push(new THREE.Vector3( x, y, z));
var dotMaterial = new THREE.PointsMaterial( { size: 3, sizeAttenuation: false, color: 0xFF0000 } );
var dot = new THREE.Points( dotGeometry, dotMaterial );
scene.add(dot);
}
Triangulation, Voronoi, I don't care, just show me ANY ideas you have, will help me learn a lot!
You can create a polyhedron which is the convex hull of a set of 3D points by using a pattern like so:
var points = [
new THREE.Vector3( 100, 0, 0 ),
new THREE.Vector3( 0, 100, 0 ),
...
new THREE.Vector3( 0, 0, 100 )
];
var geometry = new THREE.ConvexGeometry( points );
var material = new THREE.MeshPhongMaterial( {
color: 0xff0000,
shading: THREE.FlatShading
} );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
You must include the following in your project
<script src="/examples/js/geometries/ConvexGeometry.js"></script>
three.js r.78
I'm really confused, nothing works. I always get the error "THREE.CameraDolly is not a constructor". I'm using Three.js if someone haven't already noticed it.
My script:
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 45, WIDTH / HEIGHT, 1, 1000 );
var cameraDolly = new THREE.PerspectiveCamera( 45, WIDTH / HEIGHT, 1, 1000);
var renderer = new THREE.WebGLRenderer();
...
//LookAt & Camera Position Points
var points = {
"camera": [
{
"x": 100,
"y": 60,
"z": 40
},
{
"x": -20,
"y": 5,
"z": -10
},
{
"x": 30,
"y": 10,
"z": -5
}
],
"lookat": [
{
"x": 50,
"y": 30,
"z": 35
},
{
"x": 0,
"y": 2,
"z": 0
},
{
"x": 12,
"y": 8,
"z": -0.2
}
]
};
//Clock
var clock = new THREE.Clock( true );
//CameraDolly
***var dolly = new THREE.CameraDolly ( cameraDolly, scene, points );***//Here I got the error
scene.add(dolly, 'cameraPosition', 0, 1);
scene.add(dolly, 'lookatPosition', 0, 1);
function update() {
requestAnimationFrame(update);
render( cameraDolly, 0.75, 0, 0.25, 0.25 );
var delta = clock.getElapsedTime() * 0.2;
var position = THREE.Math.mapLinear(Math.sin(delta), -1, 1, 0, 1);
dolly.cameraPosition = position;
dolly.lookatPosition = position;
dolly.update();
};
function render() {
renderer.render(scene, cameraDolly);
};
render();
update();
And dolly.js:
/**
* #author DPR / http://ivxvixviii.io
*/
THREE.CameraDolly = function ( camera, scene, points ){
this.cameraPosition = 0;
this.lookatPosition = 0;
this.camera = camera;
this.scene = scene;
this.cameraPoints = points.camera;
this.lookatPoints = points.lookat;
this.bounds = 100;
}
// Lookat position Marker
this.lookatPositionMarker = this.createMarker(0xFF0000);
this.scene.add(this.lookatPositionMarker);
// Camera path markers
this.markers = [];
if(this.gui){
var cameraPointsFolder = this.gui.addFolder('cameraPointsFolder');
cameraPointsFolder.open();
}
var _this = this;
for( var i = 0; i < this.cameraPoints.length; ++i){
if(this.gui){
var point = this.cameraPoints[i];
var folder = cameraPointsFolder.addFolder('marker-' + i);
folder.add(point, 'x', -this.bounds, this.bounds).onChange(function(){
_this.createCurves();
});
folder.add(point, 'y', -this.bounds, this.bounds).onChange(function(){
_this.createCurves();
});
folder.add(point, 'z', -this.bounds, this.bounds).onChange(function(){
_this.createCurves();
});
// folder.open();
}
var marker = this.createMarker(0x00FF00);
this.scene.add( marker );
this.markers.push( marker );
};
// Camera lookat path markers
this.lookatMarkers = [];
if(this.gui){
var lookatPointsFolder = this.gui.addFolder('lookatPointsFolder');
lookatPointsFolder.open();
}
for( var i = 0; i < this.lookatPoints.length; ++i){
if(this.gui){
var point = this.lookatPoints[i];
var folder = lookatPointsFolder.addFolder('marker-' + i);
folder.add(point, 'x', -this.bounds, this.bounds).onChange(function(){
_this.createCurves();
});
folder.add(point, 'y', -this.bounds, this.bounds).onChange(function(){
_this.createCurves();
});
folder.add(point, 'z', -this.bounds, this.bounds).onChange(function(){
_this.createCurves();
});
// folder.open();
}
var marker = this.createMarker(0x0000FF);
this.scene.add( marker );
this.lookatMarkers.push( marker );
};
this.createCurves();
this.update();
};
THREE.CameraDolly.prototype.createCurves = function(){
// Camera curve
this.scene.remove(this.pathCurve);
var points = [];
for (var i = 0; i < this.cameraPoints.length ; ++i) {
var point = this.cameraPoints[i];
var vec = new THREE.Vector3( point.x, point.y, point.z );
this.markers[i].position.set( point.x, point.y, point.z );
points.push(vec);
};
var spline = this.createSpline( points );
var points = spline.getPoints( 50 );
this.cameraSpline = this.createSpline(points);
var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial( { 0xFFFFFF*Math.random() } /*{ transparent: true, opacity: 0 }*/ );
points.forEach(function(point){
geometry.vertices.push( point.clone() );
});
this.pathCurve = new THREE.Line( geometry, material );
this.scene.add( this.pathCurve );
// Lookat curve
this.scene.remove(this.pathLookatCurve);
var points = [];
for (var i = 0; i < this.lookatPoints.length ; ++i) {
var point = this.lookatPoints[i];
var vec = new THREE.Vector3( point.x, point.y, point.z );
this.lookatMarkers[i].position.set( point.x, point.y, point.z );
points.push(vec);
};
var spline = this.createSpline( points );
var points = spline.getPoints( 50 );
this.cameralookatSpline = this.createSpline(points);
var geometry = new THREE.Geometry();
var material = new THREE.LineBasicMaterial( { 0xFFFFFF*Math.random() } /*{ transparent: true, opacity: 0 }*/ );
points.forEach(function(point){
geometry.vertices.push( point.clone() );
});
this.pathLookatCurve = new THREE.Line( geometry, material );
this.scene.add( this.pathLookatCurve );
this.update();
};
THREE.CameraDolly.prototype.createSpline = function( points ) {
var tmp = [];
for( var i = 0; i < points.length; ++i){
tmp.push( points[i].clone() );
};
return new THREE.SplineCurve3( tmp );
}
THREE.CameraDolly.prototype.createMarker = function(color){
var geometry = new THREE.SphereGeometry( 1, 4, 4 );
var material = new THREE.MeshBasicMaterial({color: color /*transparent: true, opacity: 0*/ });
return new THREE.Mesh(geometry, material);
};
THREE.CameraDolly.prototype.update = function(){
var position = this.cameraSpline.getPointAt( this.cameraPosition );
this.camera.position.copy( position );
position = this.cameralookatSpline.getPointAt( this.lookatPosition );
this.lookatPositionMarker.position.copy( position );
this.camera.lookAt( this.lookatPositionMarker.position );
};
THREE.CameraDolly.prototype.exportPositions = function(){
var data = {
camera: [],
lookat: []
};
this.cameraPoints.forEach(function(point){
data.camera.push({
x: point.x,
y: point.y,
z: point.z
})
});
this.lookatPoints.forEach(function(point){
data.lookat.push({
x: point.x,
y: point.y,
z: point.z
})
});
var json = JSON.stringify( data, undefined, 4 );
window.prompt('Copy to clipboard: Ctrl+C, Enter', json );
};
I have already looked up on Google but I didn't find anything that could help me continous. I have everything included, I also tried it with a onload function and I renamed the variables, too!
Your dolly.js is altered and contains some errors. Debug it first if you are responsible for this, or just replace it with the original dolly.js file.
Doing so you will run you into this error:
THREE.Object3D.add:" Object { […] } "is not an instance of THREE.Object3D.
You cant add the dolly object to the THREE.Scene, the author of this script is adding it to his GUI. Please look at the example he provided and try to understand whats happening. Adapt your code from there.
The dolly helper is a third-party addon written for r68 and is not officialy supported by three.js, so you should report bugs at the projects github page.