I need to add an additional function to change the Z rotation value of the teapot from within the updateTeapot function. I saw this answer Three.js camera tilt up or down and keep horizon level, but how do I incorporate a z rotation function within this function?
function updateTeapot() {
if (teapot != null) {
teaPotHeight+=1;
teapot.position.y = teaPotHeight%200;
}
}
(function ( lab3 , $, undefined) {
lab3.init = function(hook) {
// Create a renderer
var WIDTH = 600,
HEIGHT = 500;
var renderer = new THREE.WebGLRenderer();
renderer.setSize(WIDTH, HEIGHT);
hook.append(renderer.domElement);
var scene = new THREE.Scene();
// Create lights
var pointLight =
new THREE.PointLight(0xFFFFFF);
pointLight.position = new THREE.Vector3(-10, 100, 100);
scene.add(pointLight);
// Add ambient light
var ambient = new THREE.AmbientLight( 0x555555 );
scene.add( ambient );
// Create a camera
var VIEW_ANGLE = 65, //65 FOV is most 'natural' FOV
ASPECT = WIDTH / HEIGHT,
NEAR = 0.1, //these elements are needed for cameras to
FAR = 10000; //partition space correctly
var camera = new THREE.PerspectiveCamera(
VIEW_ANGLE,
ASPECT,
NEAR,
FAR);
camera.position.z = 300;
scene.add(camera);
// Create and add controls
var controls = new THREE.TrackballControls( camera );
controls.target.set( 0, 0, 0 );
// Create a cube
var material =
new THREE.MeshLambertMaterial(
{
color: 0x00bbcc
});
var cube = new THREE.Mesh(
new THREE.CubeGeometry(
40, 55, 30),
material);
scene.add(cube);
// Animation
function renderLoop() {
renderer.render(scene, camera);
controls.update();
window.requestAnimationFrame(renderLoop);
updateTeapot();
}
window.requestAnimationFrame(renderLoop);
////////////////////////////////////////////////
var teapot = null;
var teaPotHeight=0;
loader = new THREE.JSONLoader();
loader.load( "models/utah-teapot.json", function( geometry ) {
teapot = new THREE.Mesh( geometry, new THREE.MeshLambertMaterial({
color: 0x00bb00,
side: THREE.DoubleSide
}));
teapot.scale.set( 20, 20, 20 );
teapot.position = new THREE.Vector3(-30, 100, 20);
function updateTeapot() {
if (teapot != null) {
teaPotHeight+=1;
teapot.position.y = teaPotHeight%200;
}
}
//add it to the scene
scene.add(teapot);
});
}
})(window.lab3 = window.lab3 || {} , jQuery)
Add
teapot.rotation.z = numInRadians;
Related
My project uses geometry where each face is its own mesh. I need to clip the geometry to cut away a portion of it and have a stenciled cap face cover the clipped edges. I examined and tinkered with the Three.js clipping stencil example and I understand how to use a stencil to cap trimmed solid geometry, but when I try it on collections of face geometries it doesn't work. Here is some code I have been tinkering with, based on the example:
body { margin: 0; }
canvas { display: block; }
<script type="module">
import * as THREE from 'https://unpkg.com/three#0.120.1/build/three.module.js';
import { OrbitControls } from 'https://unpkg.com/three#0.120.1/examples/jsm/controls/OrbitControls.js';
import { BufferGeometryUtils } from 'https://unpkg.com/three#0.120.1/examples/jsm/utils/BufferGeometryUtils.js';
var camera, scene, renderer;
var planes, planeObjects;
init();
animate();
function createPlaneStencilGroup( geometry, plane, renderOrder )
{
var group = new THREE.Group();
var baseMat = new THREE.MeshBasicMaterial();
baseMat.depthWrite = false;
baseMat.depthTest = false;
baseMat.colorWrite = false;
baseMat.stencilWrite = true;
baseMat.stencilFunc = THREE.AlwaysStencilFunc;
// back faces
var mat0 = baseMat.clone();
mat0.side = THREE.BackSide;
mat0.clippingPlanes = [ plane ];
mat0.stencilFail = THREE.IncrementWrapStencilOp;
mat0.stencilZFail = THREE.IncrementWrapStencilOp;
mat0.stencilZPass = THREE.IncrementWrapStencilOp;
var mesh0 = new THREE.Mesh( geometry, mat0 );
mesh0.renderOrder = renderOrder;
group.add( mesh0 );
// front faces
var mat1 = baseMat.clone();
mat1.side = THREE.FrontSide;
mat1.clippingPlanes = [ plane ];
mat1.stencilFail = THREE.DecrementWrapStencilOp;
mat1.stencilZFail = THREE.DecrementWrapStencilOp;
mat1.stencilZPass = THREE.DecrementWrapStencilOp;
var mesh1 = new THREE.Mesh( geometry, mat1 );
mesh1.renderOrder = renderOrder;
group.add( mesh1 );
return group;
}
function init()
{
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 36, window.innerWidth / window.innerHeight, 1, 100 );
camera.position.set( 2, 2, 2 );
initLights();
planes = [
new THREE.Plane( new THREE.Vector3( 0, - 1, 0 ), 0.42 ),
new THREE.Plane( new THREE.Vector3( 0, 0, - 1 ), 0.25 )
];
var material = new THREE.MeshStandardMaterial( {
color: 0x00ff00,
metalness: 0.1,
roughness: 0.75,
side: THREE.DoubleSide,
clippingPlanes: planes,
clipShadows: true,
shadowSide: THREE.DoubleSide,
} );
// Simple sphere geometry. Something I know works, for comparison.
var sphereGeom = new THREE.SphereBufferGeometry( 0.5, 32, 32 );
sphereGeom.translate( -1.1, 0, 0 );
// Make a cube out of 6 planes and merge them together
var planeGeoms = [];
for(var i = 0; i < 6; i++)
{
planeGeoms.push( new THREE.PlaneBufferGeometry( 1, 1 ) );
}
var mergedBufferGeom = BufferGeometryUtils.mergeBufferGeometries( planeGeoms );
// Set up clip plane rendering
planeObjects = [];
var planeGeom = new THREE.PlaneBufferGeometry( 4, 4 );
for ( var i = 0; i < 2; i ++ )
{
var poGroup = new THREE.Group();
var plane = planes[ i ];
var stencilGroup_sphere = createPlaneStencilGroup( sphereGeom, plane, i + 1 );
var stencilGroup_Box = createPlaneStencilGroup( mergedBufferGeom, plane, i + 1 )
// plane is clipped by the other clipping planes
var planeMat = new THREE.MeshStandardMaterial( {
color: 0x0000ff,
metalness: 0.1,
roughness: 0.75,
clippingPlanes: planes.filter( p => p !== plane ),
stencilWrite: true,
stencilRef: 0,
stencilFunc: THREE.NotEqualStencilFunc,
stencilFail: THREE.ReplaceStencilOp,
stencilZFail: THREE.ReplaceStencilOp,
stencilZPass: THREE.ReplaceStencilOp,
} );
var po = new THREE.Mesh( planeGeom, planeMat );
po.onAfterRender = function ( renderer ) {
renderer.clearStencil();
};
po.renderOrder = i + 1.1;
plane.coplanarPoint( po.position );
po.lookAt(
po.position.x - plane.normal.x,
po.position.y - plane.normal.y,
po.position.z - plane.normal.z,
);
scene.add( stencilGroup_sphere );
scene.add( stencilGroup_Box );
poGroup.add( po );
planeObjects.push( po );
scene.add( poGroup );
}
var sphereMesh = new THREE.Mesh( sphereGeom, material );
sphereMesh.renderOrder = 6;
scene.add( sphereMesh );
var planeMeshes = [];
for(var i = 0; i < 6; i++)
{
planeMeshes.push( new THREE.Mesh(planeGeoms[i], material) );
}
planeMeshes[0].position.copy(new THREE.Vector3(.5, 0, 0));
planeMeshes[1].position.copy(new THREE.Vector3(0, .5, 0));
planeMeshes[2].position.copy(new THREE.Vector3(0, 0, .5));
planeMeshes[3].position.copy(new THREE.Vector3(-.5, 0, 0));
planeMeshes[4].position.copy(new THREE.Vector3(0, -.5, 0));
planeMeshes[5].position.copy(new THREE.Vector3(0, 0, -.5));
planeMeshes[0].lookAt(new THREE.Vector3(2, 0, 0));
planeMeshes[1].lookAt(new THREE.Vector3(0, 2, 0));
planeMeshes[2].lookAt(new THREE.Vector3(0, 0, 2));
planeMeshes[3].lookAt(new THREE.Vector3(-2, 0, 0));
planeMeshes[4].lookAt(new THREE.Vector3(0, -2, 0));
planeMeshes[5].lookAt(new THREE.Vector3(0, 0, -2));
for(var i = 0; i < 6; i++)
scene.add( planeMeshes[i] );
// Renderer
renderer = new THREE.WebGLRenderer( { antialias: true } );
renderer.shadowMap.enabled = true;
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0x263238 );
renderer.localClippingEnabled = true;
window.addEventListener( 'resize', onWindowResize, false );
document.body.appendChild( renderer.domElement );
// Controls
var controls = new OrbitControls( camera, renderer.domElement );
controls.minDistance = 2;
controls.maxDistance = 20;
controls.update();
}
function initLights()
{
scene.add( new THREE.AmbientLight( 0xffffff, 0.5 ) );
var dirLight = new THREE.DirectionalLight( 0xffffff, 1 );
dirLight.position.set( 5, 10, 7.5 );
dirLight.castShadow = true;
dirLight.shadow.camera.right = 2;
dirLight.shadow.camera.left = - 2;
dirLight.shadow.camera.top = 2;
dirLight.shadow.camera.bottom = - 2;
dirLight.shadow.mapSize.width = 1024;
dirLight.shadow.mapSize.height = 1024;
scene.add( dirLight );
}
function onWindowResize()
{
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate()
{
requestAnimationFrame( animate );
renderer.render( scene, camera );
}
</script>
It contains 2 clipping planes, a cube made from 6 separate PlaneGeometries, and a solid sphere for comparison. I made the stencil for the cube using an additional BufferGeometry made from merging the planes together into a single geometry object. The stencil for the cube appears to be the right shape and size, but only one cap face is drawn and it is not at the location of either of the clipping planes. Is there anything else I'm supposed to do with the stencil or the clipping plane beyond what the example already does to make it work on geometry of this type?
Turns out the PlaneBufferGeometries that were getting merged for the stencil were not in the same positions as the plane meshes that used those geometries. That is why the cap face wasn't being drawn properly. I had not considered the fact that if you apply a transform to a Mesh, then get the Mesh's geometry to use elsewhere, that geometry won't reflect the transform applied to the Mesh. I got it to work by applying the transform matrices from the plane meshes to the PlaneBufferGeometries that needed to be merged.
I am rendering a cityscape using Three.js. When attempting to view the scene I can't seem to get the camera near/far settings correct to render the whole scene. When I increase the camera's far plane - I am able to see the model, but it appears blue (image below) until I zoom into it. Is there a way to see the entire model without having to zoom super close to the scene?
var scene = new THREE.Scene()
scene.background = new THREE.Color(33,33,33);
var ambient = new THREE.AmbientLight(0xe8ecff, 1.4)
ambient.name = 'ambientLight'
scene.add(ambient)
var directionalLight1 = new THREE.DirectionalLight(0xfff1f1, 0.7)
directionalLight1.name = 'directionalLight1'
directionalLight1.position.set(-1500, 900, 1500)
directionalLight1.castShadow = true
scene.add(directionalLight1)
directionalLight1.shadow.camera.right = 2500
directionalLight1.shadow.camera.left = -2500
directionalLight1.shadow.camera.top = 2500
directionalLight1.shadow.camera.bottom = -2500
directionalLight1.shadow.camera.near = 0
directionalLight1.shadow.camera.far = 5000
var shadowCameraHelper = new THREE.CameraHelper(directionalLight1.shadow.camera)
shadowCameraHelper.visible = false
shadowCameraHelper.name = 'directionalLight1Helper'
scene.add(shadowCameraHelper)
var directionalLight2 = new THREE.DirectionalLight(0x87c0ff, 0.2)
directionalLight2.name = 'directionalLight2'
directionalLight2.position.set(1, 1, -1)
scene.add(directionalLight2)
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 1, 10000);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
var canvas = document.getElementById("canvas");
canvas.appendChild( renderer.domElement );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
camera.position.set(-400, 700, 500)
function animate (){
requestAnimationFrame( animate );
controls.update();
stats.update()
renderer.render( scene, camera );
}
animate();
var loader = new THREE.ObjectLoader
loader.load("example_mesh.json",
function(obj){
var bb = new THREE.Box3()
bb.expandByObject(obj)
var center = new THREE.Vector3()
bb.getCenter(center)
let modelSettings = { x: -center.x, y: center.y, z: -center.z }
let cameraRadius = this.boundingBox.geometry.boundingSphere.radius/2 * (1 + Math.sqrt(5))
obj.position.set(modelSettings.x, modelSettings.y, modelSettings.z)
camera.position.set(cameraRadius, cameraRadius, cameraRadius);
controls.target.set(0,modelSettings.y, 0)
controls.update()
scene.add(obj)
}, onProgress, onError)
When an object is being clipped out of the camera's focal length, you can use Object3D.scale. AFter adjusting this scaler value the entire building is visible in the camera on load and does not get clipped. You adjust the objects scale during the loading callback.
var scene = new THREE.Scene()
scene.background = new THREE.Color(33,33,33);
var ambient = new THREE.AmbientLight(0xe8ecff, 1.4)
ambient.name = 'ambientLight'
scene.add(ambient)
var directionalLight1 = new THREE.DirectionalLight(0xfff1f1, 0.7)
directionalLight1.name = 'directionalLight1'
directionalLight1.position.set(-1500, 900, 1500)
directionalLight1.castShadow = true
scene.add(directionalLight1)
directionalLight1.shadow.camera.right = 2500
directionalLight1.shadow.camera.left = -2500
directionalLight1.shadow.camera.top = 2500
directionalLight1.shadow.camera.bottom = -2500
directionalLight1.shadow.camera.near = 0
directionalLight1.shadow.camera.far = 5000
var shadowCameraHelper = new THREE.CameraHelper(directionalLight1.shadow.camera)
shadowCameraHelper.visible = false
shadowCameraHelper.name = 'directionalLight1Helper'
scene.add(shadowCameraHelper)
var directionalLight2 = new THREE.DirectionalLight(0x87c0ff, 0.2)
directionalLight2.name = 'directionalLight2'
directionalLight2.position.set(1, 1, -1)
scene.add(directionalLight2)
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 1, 10000);
var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.shadowMap.enabled = true;
renderer.shadowMap.type = THREE.PCFSoftShadowMap;
var canvas = document.getElementById("canvas");
canvas.appendChild( renderer.domElement );
var controls = new THREE.OrbitControls( camera, renderer.domElement );
camera.position.set(-400, 700, 500)
function animate (){
requestAnimationFrame( animate );
controls.update();
stats.update()
renderer.render( scene, camera );
}
animate();
var loader = new THREE.ObjectLoader
loader.load("example_mesh.json",
function(obj){
// adjust the scale of the object in the scene.
// default scale is (1,1,1)
obj.scale.set( .1, .1, .1 );
var bb = new THREE.Box3()
bb.expandByObject(obj)
var center = new THREE.Vector3()
bb.getCenter(center)
let modelSettings = { x: -center.x, y: center.y, z: -center.z }
let cameraRadius = this.boundingBox.geometry.boundingSphere.radius/2 * (1 + Math.sqrt(5))
obj.position.set(modelSettings.x, modelSettings.y, modelSettings.z)
camera.position.set(cameraRadius, cameraRadius, cameraRadius);
controls.target.set(0,modelSettings.y, 0)
controls.update()
scene.add(obj)
}, onProgress, onError)
I have this code which should create a 3D form. The idea is that I have whatever coordinates stored into a vector in the same plan to which I should add a default height in order to make it 3D. As you can see I am a beginner in programming and this is the first time I use ThreeJS so can you tell me what am I doing wrong? Honestly I have no clue and I would like to know if there is another way of adding the default height to my 2D vector coordinates in order to make it 3D without using ThreeJS. Thank you!
$(document).ready(function(){
function storeCoordinate(x, y, array) {
array.push(x);
array.push(y);
}
var coords = [];
var z=500;
storeCoordinate(3, 5, coords);
storeCoordinate(10, 100, coords);
storeCoordinate(30, 120, coords);
storeCoordinate(3, 5, coords);
for (var i = 0; i < coords.length; i+=2) {
var x = coords[i];
var y = coords[i+1];
var canvas = document.getElementById('myCanvas');
var ctx = canvas.getContext('2d');
var shape = new THREE.Shape( coords );
ctx.moveTo(coords[i],coords[i+1]);
ctx.lineTo(coords[i+2],coords[i+3]);
ctx.stroke();
}
var render,mycanvas,scene,camera,renderer,light;
init();
animate();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 1, 1000 );
var extrudedGeometry = new THREE.ExtrudeGeometry(shape, {amount: 5, bevelEnabled: false});
var extrudedMesh = new THREE.Mesh(extrudedGeometry, new THREE.MeshPhongMaterial({color: 0xff0000}));
scene.add(extrudedMesh);
document.body.onmousemove = function(e){
extrudedMesh.rotation.z = e.pageX / 100;
extrudedMesh.rotation.x = e.pageY / 100;
}
//lights
dirLight = new THREE.DirectionalLight(0xffffff);
dirLight.intensity = .9;
dirLight.position.set(500, 140, 500);
dirLight.castShadow = true;
dirLight.shadowMapHeight = 2048
dirLight.shadowMapWidth = 2048
dirLight.shadowDarkness = .15
spotLight = new THREE.PointLight( 0xffffff );
spotLight.intensity = .5
spotLight.position.set( -500, 140, -500 );
camera.add( spotLight)
camera.add(dirLight);
lighthelper = new THREE.DirectionalLightHelper(dirLight, 20);
lighthelper.children[1].material.color.set(0,0,0)
lighthelper.visible = false;
scene.add(lighthelper);
ambientLight = new THREE.AmbientLight( 0x020202, 1 );
scene.add( ambientLight );
light = new THREE.PointLight(0xffffff);
light.position.set(-100,200,100);
scene.add(light);
renderer = new THREE.WebGLRenderer({canvas: mycanvas});
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.autoRotate = true;
controls.enableZoom = true;
controls.enablePan = true;
controls.rotateSpeed = 3.0;
controls.zoomSpeed = 1.0;
controls.panSpeed = 2.0;
controls.enableDamping = true;
controls.dampingFactor = 0.25;
controls.minDistance = 1.1;
controls.maxDistance = 1000;
controls.keys = [65, 83, 68]; // [ rotateKey, zoomKey, panKey ]
}
function animate() {
window.requestAnimationFrame( animate );
render();
}
function render() {
renderer.render( scene, camera );
}
var loader = new THREE.OBJLoader();
});
Just an option of how you can do it, using THREE.ExtrudeGeometry():
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(60, window.innerWidth / window.innerHeight, 1, 1000);
camera.position.set(0, 0, 3);
var renderer = new THREE.WebGLRenderer({
antialias: true
});
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var controls = new THREE.OrbitControls(camera, renderer.domElement);
var grid = new THREE.GridHelper(5, 10, "white", "gray");
grid.geometry.rotateX(Math.PI * 0.5);
scene.add(grid);
var points = [
new THREE.Vector2(0, 1),
new THREE.Vector2(1, 1),
new THREE.Vector2(1, 0)
]
var shape = new THREE.Shape(points);
var extrudeGeom = new THREE.ExtrudeGeometry(shape, {
amount: 0.5,
bevelEnabled: false
});
var mesh = new THREE.Mesh(extrudeGeom, new THREE.MeshBasicMaterial({
color: "aqua",
wireframe: true
}));
scene.add(mesh);
render();
function render() {
requestAnimationFrame(render)
renderer.render(scene, camera);
}
body {
overflow: hidden;
margin: 0;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/92/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
I have a basic scene in threejs that loads a .stl file, it loads normally, but it automatically changes color and I also want it to have its original color What do I have to do to fix it?
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 60, window.innerWidth/window.innerHeight, 1, 500 );
var renderer = new THREE.WebGLRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild(renderer.domElement);
controls = new THREE.OrbitControls(camera, renderer.domElement);
controls.center = new THREE.Vector3();
// var geometry = new THREE.BoxGeometry( 3, 1, 1 );
// var material = new THREE.MeshBasicMaterial( { color: 'skyblue' } );
// var cube = new THREE.Mesh( geometry, material );
// scene.add( cube );
var loader = new THREE.STLLoader();
loader.load( 'js/novo/undefined.stl', function ( geometry ) {
console.log(geometry);
var mesh = new THREE.Mesh(geometry);
mesh.scale.set( 0.1, 0.1, 0.1 );
// mesh.rotation.set( - Math.PI / 2, Math.PI / 2, 0 );
// mesh.scale.set( 0.3, 0.3, 0.3 );
// mesh.receiveShadow = true;
scene.add( mesh );
});
camera.position.z = 300;
var animate = function () {
requestAnimationFrame( animate );
renderer.render(scene, camera);
};
animate();
How should be:
How are you doing:
You are not applying a material to your Mesh.
var mesh = new THREE.Mesh(geometry);
When a mesh is created, if you do not specify a material, a random colored BasicMaterial is applied which can be seen if you look at the THREE.Mesh source.
function Mesh( geometry, material ) {
Object3D.call( this );
this.type = 'Mesh';
this.geometry = geometry !== undefined ? geometry : new BufferGeometry();
this.material = material !== undefined ? material : new MeshBasicMaterial( { color: Math.random() * 0xffffff } );
this.drawMode = TrianglesDrawMode;
this.updateMorphTargets();
}
So, to fix your problem, create some sort of material, and send it to the Mesh constructor as the second parameter.
eg.
// create a red material.
var myMaterial = new THREE.MeshBasicMaterial({color: 0xff0000})
// create mesh with red material applied
var mesh = new THREE.Mesh(geometry, myMaterial);
you can find here how to change color or texture for your loader
var loader = new THREE.STLLoader();
loader.load('./FA-FF/FA.STL', function (geometry) {
/* different texture */
var material = new THREE.MeshPhongMaterial({ map: THREE.ImageUtils.loadTexture('img/wood.jpg') });
/* for different color */
var material = new THREE.MeshPhongMaterial({ color: 0xAAAAAA, specular: 0x111111, shininess: 200 });
var mesh = new THREE.Mesh(geometry, material);
mesh.name = "first";
mesh.position.set(-1, 1, 0);
mesh.rotation.set(1.5707963267948963, -8.326672684688674, -1.570796326794894);
mesh.scale.set(0.005, 0.005, 0.005);
mesh.castShadow = true;
mesh.receiveShadow = true;
scene.add(mesh);
});
I have been trying to display a 3D json model using three.js. I am fairly new to three.js and have tried everything I can think of, but don't know anything else to try.
Currently when I try to load the model I get an error that says:
Uncaught TypeError: Cannot read property 'visible' of undefinedr # three.min.js:602r # three.min.js:602render # three.min.js:649render # test.html:106animate # test.html:100
I really am not sure where to go from here. Thanks for any help.
Here is my code:
<script type="text/javascript">
if (!Detector.webgl) Detector.addGetWebGLMessage();
var SCREEN_WIDTH = window.innerWidth;
var SCREEN_HEIGHT = window.innerHeight;
var FLOOR = 0;
var container;
var camera, scene;
var webglRenderer;
var zmesh, geometry;
var mouseX = 0, mouseY = 0;
var windowHalfX = window.innerWidth / 2;
var windowHalfY = window.innerHeight / 2;
document.addEventListener(
'mousemove',
onDocumentMouseMove,
false
);
init();
animate();
// Renderer
webglRenderer = new THREE.WebGLRenderer();
webglRenderer.setSize(SCREEN_WIDTH, SCREEN_HEIGHT);
webglRenderer.domElement.style.position = 'relative';
container.appendChild(webglRenderer.domElement);
// Loader
var loader = new THREE.JSONLoader(),
callbackModel = function(geometry) {
createScene(geometry, 90, FLOOR, -50, 105)
};
loader.load('can.js', callbackModel);
function init() {
container = document.createElement('div');
document.body.appendChild(container);
// Camera
camera = new THREE.PerspectiveCamera(
75,
SCREEN_WIDTH / SCREEN_HEIGHT,
1,
100000
);
camera.position.z = 75;
// Scene
scene = new THREE.Scene();
// Lights
var ambient = new THREE.AmbientLight(0xffffff);
scene.add(ambient);
// More lights
var directionalLight = new THREE.DirectionalLight(0xffeedd);
directionalLight.position.set(0, -70, 100).normalize();
scene.add(directionalLight);
}
function createScene( geometry, x, y, z, b ) {
zmesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial() );
zmesh.position.set( 0, 16, 0 );
zmesh.scale.set( 1, 1, 1 );
scene.add( zmesh );
}
function onDocumentMouseMove(event) {
mouseX = (event.clientX - windowHalfX);
mouseY = (event.clientY - windowHalfY);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
if(webglRenderer != undefined && zmesh != undefined) {
zmesh.rotation.set(-mouseY/500 + 1, -mouseX/200, 0);
webglRenderer.render(scene, camera);
}
}
</script>
If your JSON file contains material information, then a materials array will be passed to your callback function, and you need to do this:
callbackModel = function( geometry, materials ) {
// your code
};
...
zmesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
Otherwise, you need to define your own material. For example,
zmesh = new THREE.Mesh( geometry, new THREE.MeshPhongMaterial( { color: 0xff000 } ) );
three.js r.77