Three.js import blender object - javascript

I'm trying to import blender scene to three.js with ObjectLoader() function. I want this to be as easy as possible, without animation just objects with right texture and colour in right place. Unfortunately three.js documentation is not a friendly place for newbies. So far I managed to draw every object from scene but every object is in different colour, plane lacks its texture and they are all in wrong places. What am I doing wrong? Here is my .js code:
var scene, camera, renderer;
var WIDTH = window.innerWidth;
var HEIGHT = window.innerHeight;
function init() {
scene = new THREE.Scene();
initCamera();
initLights();
initRenderer();
document.body.appendChild(renderer.domElement);
}
function initCamera() {
camera = new THREE.PerspectiveCamera(70, WIDTH / HEIGHT, 1, 10);
camera.position.set(0, 3.5, 5);
camera.lookAt(scene.position);
}
function initRenderer() {
renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setSize(WIDTH, HEIGHT);
}
function initLights() {
var light = new THREE.AmbientLight(0xffffff);
scene.add(light);
}
var loader = new THREE.ObjectLoader();
loader.load('./city.json', function(loadedObj) {
mesh = new THREE.Mesh(loadedObj);
var plane = loadedObj.getObjectByName("plane");
var building1 = loadedObj.getObjectByName("building1");
var building2 = loadedObj.getObjectByName("building2");
var building3 = loadedObj.getObjectByName("building3");
var building4 = loadedObj.getObjectByName("building4");
var building5 = loadedObj.getObjectByName("building5");
var building6 = loadedObj.getObjectByName("building6");
var building7 = loadedObj.getObjectByName("building7");
var building8 = loadedObj.getObjectByName("building8");
scene.add(loadedObj);
console.log(building1);
console.log(building2);
console.log(building3);
console.log(building4);
console.log(building5);
console.log(building6);
console.log(building7);
console.log(building8);
});
function render() {
requestAnimationFrame(render);
renderer.render(scene, camera);
}
init();
render();
Is it possible that there is problem with way of exporting from blender not with code?
EDIT: Sorry about that, here's my city.json file
city.json

Related

Three.Js positioning problem and coneGeometry error

I am trying to build a rocketship model by add different shapes to a large group and position them at specific axis.
When I try to use
rocketConeMesh.position.y = 15;
The shape does not move at all, I am trying to put the rocketCone (The nose of the rocket ship) on top of the rocketBody and then have them under the same group.
I get the followig error message
"THREE.Object3D.add: object not an instance of THREE.Object3D. "
for the coneGeometry object.
my code is as follows:
<script type="text/javascript">
// 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(75, window.innerWidth / window.innerHeight, 0.1, 1000);
// create a render and set the size
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
window.addEventListener('resize', function()
{
var width = window.innerWidth;
var height = window.innerHeight;
renderer.setSize(width, height);
camera.aspect = width / height;
camera.updateProjectionMatrix();
} );
controls = new THREE.OrbitControls(camera, renderer.domElement);
// create the object group that contains all the sub-shapes
var rocketGroup = new THREE.Object3D();
scene.add(rocketGroup);
//The object below is the top cone of the rocket
var rocketCone = new THREE.ConeGeometry(6, 10, 6);
var material = new THREE.MeshBasicMaterial({color: 0xcccccc, wireframe: true});
var cone = new THREE.Mesh(rocketCone, material);
rocketConeMesh = new THREE.Mesh(rocketCone,new THREE.MeshPhongMaterial())
scene.add(cone);
//Specify the position of the rocket cone
rocketConeMesh.position.y = 15;
//Add the rocketCone to the lowpolyRocket group
rocketGroup.add(rocketCone);
/******************************************************************************************************************/
//var rocketBody = new THREE.CylinderGeometry( 5, 5, 20, 32 );
//var material = new THREE.MeshBasicMaterial({color: 0xcccccc, wireframe:false});
//var cylinder = new THREE.Mesh(rocketBody, material);
//scene.add(cylinder);
// position and point the camera to the center of the scene
camera.position.x = -30;
camera.position.y = 20;
camera.position.z = 30;
camera.lookAt(scene.position);
// game logic
var update = function ( )
{
//cone.rotation.x += 0.01;
//cone.rotation.y += 0.005;
};
// draw scene
var render = function ( )
{
renderer.render(scene, camera);
};
// run game loop (update, render, repeat)
var GameLoop = function ( )
{
requestAnimationFrame(GameLoop);
update( );
render( );
};
GameLoop( );
</script>
rocketGroup.add(rocketCone);
This code is not valid since it's not possible to add an instance of ConeGeometry to an Object3D. Try to change your code to the following:
rocketGroup.add(rocketConeMesh);
Now you add the mesh (which is derived from THREE.Object3D) to rocketGroup. It's now part of the scene graph and changing its transformation should work.
BTW: I don't understand why you create two meshes with your rocketCone geometry. I guess you can remove the cone variable.

How to load objects with Three.js with high quality?

I'm trying to create an object loader with Three.js but I noticed that the quality is way too low and used too much CPU at the same time.
When I use my version, the scene looks like this:
But when I use this website to load it, looks so much better and uses less CPU:
My JavaScript to load this object is:
var camera;
var scene;
var renderer;
var controls;
var container = document.getElementById('webgl');
var WIDTH = container.clientWidth;
var HEIGHT = container.clientHeight;
var ASPECT = WIDTH / HEIGHT;
var ANGLE = 45;
var container = document.getElementById('webgl');
if (Detector.webgl) {
main();
} else {
var warning = Detector.getWebGLErrorMessage();
document.getElementById('webgl').appendChild(warning);
}
function main(){
//Scene
scene = new THREE.Scene();
//Camera
camera = new THREE.PerspectiveCamera(
ANGLE, // field of view
ASPECT, // aspect ratio
10, // near clipping plane
100000 // far clipping plane
);
camera.position.x = 500;
camera.position.y = 200;
camera.position.z = 500;
camera.lookAt(new THREE.Vector3(100, 100, 100));
//Renderer
renderer = new THREE.WebGLRenderer();
var ambientLight = getAmbientLigth(1);
scene.add(ambientLight);
scene.background = new THREE.Color( 0xc3c3c3 );
renderer.setSize(WIDTH, HEIGHT);
renderer.shadowMap.enabled = true;
document.getElementById('webgl').appendChild(renderer.domElement);
controls = new THREE.OrbitControls( camera, renderer.domElement );
controls.maxPolarAngle = Math.PI/2;
controls.enableKeys = true;
loadObject();
update(renderer, scene, camera, controls);
}
function getAmbientLigth(intensity, color) {
color = color === undefined ? 'rgb(255, 255, 255)' : color;
var light = new THREE.AmbientLight(color, intensity);
return light;
}
function loadObject() {
var mtlLoader = new THREE.MTLLoader();
var objLoader = new THREE.OBJLoader();
mtlLoader.setPath( 'objects/Blue_shed/' );
mtlLoader.load('blueShed.mtl', function( materials ) {
materials.isMultiMaterial = true;
materials.preload();
objLoader.setMaterials( materials );
objLoader.setPath( 'objects/Blue_shed/' );
objLoader.load( 'blueShed.obj', function ( object ) {
object.name = 'cute-house';
object.receiveShadow = true;
object.castShadow = true;
object.scale.set( 30, 30, 30);
scene.add( object );
} );
});
}
function update(renderer, scene, camera, controls) {
controls.update();
renderer.render(scene, camera);
requestAnimationFrame(function() {
update(renderer, scene, camera, controls);
});
}
I used renderer.setSize to increase the resolution of the renderer and that helped a little bit but still is not as good as in the second image, and still uses too much CPU.
Any ideas? Is there a setting or something that I'm not setting up correctly? I see that website uses a JSON loader, but I don't think that has something to do with this issue, but I mention it just in case.

Wrapping images around sphere

I've read many blogs/questions about this and didn't find the right answer. I'm creating an earth in three.js. But every time I'm mapping my texture and bump map it doesn't show. Also there aren't any console errors. It still shows my light on the sphere so the sphere is still there. But the textures won't show. :(
var scene,
camera,
light,
renderer,
earthObject;
var WIDTH = window.innerWidth,
HEIGHT = window.innerHeight;
var angle = 45,
aspect = WIDTH / HEIGHT,
near = 0.1,
far = 3000;
//Environment
var container = document.getElementById('container');
camera = new THREE.PerspectiveCamera(angle, aspect, near, far);
camera.position.set(0, 0, 0);
scene = new THREE.Scene();
//light
scene.add(new THREE.AmbientLight(0x333333));
var light = new THREE.DirectionalLight(0xffffff, 1);
light.position.set(5,3,5);
scene.add(light);
var earthGeo = new THREE.SphereGeometry (30, 40, 400),
earthMat = new THREE.MeshPhongMaterial();
// diffuse map
earthMat.map = THREE.ImageUtils.loadTexture('http://i317248.iris.fhict.nl/LSTE/globe/Images/globe.jpg');
// bump map
earthMat.bumpMap = THREE.ImageUtils.loadTexture('http://i317248.iris.fhict.nl/LSTE/globe/Images/bump.jpg');
earthMat.bumpScale = 8;
var earthMesh = new THREE.Mesh(earthGeo, earthMat);
earthMesh.position.set(-100, 0, 0);
earthMesh.rotation.y=5;
scene.add(earthMesh);
camera.lookAt( earthMesh.position );
//Renderer code.
var renderer = new THREE.WebGLRenderer({antialiasing : true});
renderer.setSize(WIDTH, HEIGHT);
renderer.domElement.style.position = 'relative';
container.appendChild(renderer.domElement);
renderer.autoClear = false;
renderer.shadowMapEnabled = true;
function render () {
renderer.render(scene, camera);
}
render();
Two problems in your code:
you're not waiting for the images to load before rendering the scene
you're having Cross-domain Policy problems (https://en.wikipedia.org/wiki/Same-origin_policy) so the images are actually never loaded

THREE.JS Object Oriented Structure Problems

I am making a THREE.JS game for one of my classes. I am very keen to learn and understand THREE.JS so I followed some of their tutorials and learnt Javascript. I am more of a C# and C++ guy, so the following question may just the result of the lack of my understanding of Javascript.
I wrote the following Object oriented structure for the game.
ObjectEnum = {
Cube: 0,
Sphere: 1,
Cylinder: 2
}
Transform = function () {
var position, rotation, scale;
}
function TransformInit(position, rotation, scale) {
var t = new Transform();
t.position = position;
t.rotation = rotation;
t.scale = scale;
return t;
}
GameObject = function () {
var mesh, geometry, material, transform;
var GameObject = this;
this.init = function (ObjectEnumType, materialShader, transformVector3) {
if (ObjectEnumType == 0) {
geometry = new THREE.BoxGeometry(transformVector3.scale);
}
transform = transformVector3;
material = materialShader;
mesh = new THREE.Mesh(geometry, material);
}
this.getMesh = function () {
return mesh;
}
}
var go = new GameObject();
this.onload = function () {
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
var renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
var t = TransformInit(new THREE.Vector3(10, 0, 0), new THREE.Vector3(10, 0, 0), new THREE.Vector3(1, 1, 1));
go.init(ObjectEnum.Cube, new THREE.MeshPhongMaterial({
specular: '#a9fcff',
color: '#00abb1',
emissive: '#006063',
shininess: 100
}), t);
var w = go.getMesh();
scene.add(w);
camera.position.z = 5;
console.log(t);
var render = function () {
requestAnimationFrame(render);
renderer.render(scene, camera);
};
render();
}
Apparently, it doesn't render anything on the screen. I used a Debugger, found out that everything has non zero values, no console errors, all THREE.JS scripts are loaded before this one, things are fine in the editor, but nothing on the screen. When, I change it to an simple procedural structure, it works. Is there a problem in my code or is there a JS concept I am missing in the implementation ?
Followed tutorials from here
http://threejs.org/docs/#Manual/Introduction/Creating_a_scene
http://blog.teamtreehouse.com/the-beginners-guide-to-three-js
Doesn't work on IE11, Chrome, Firefox!
you have passed incorrect argument to BoxGeometry. transformVector3 is Vector3 so you should write:
geometry = new THREE.BoxGeometry(transformVector3.scale.x,
transformVector3.scale.y,
transformVector3.scale.z );
position is not assigned to your mesh:
transform = transformVector3;
material = materialShader;
mesh = new THREE.Mesh(geometry, material);
//here
mesh.position.copy(transform.position);

Three.js wont render on canvas

I loaded the script in index.html but when I open the page it shows the rendered but nothing inside, nothing renderer, I can't find the problem
Here is the code of external .js:
var wdt = $('.design').width();
var hgh = $('.design').height();
var scene = new THREE.Scene();
var camera = new THREE.Camera(75, wdt/hgh, 0.1, 1000);
var renderer = new THREE.WebGLRenderer({ alpha: true });
renderer.setSize(wdt, hgh);
document.getElementById('designer').appendChild(renderer.domElement);
var geometry = new THREE.CubeGeometry(1,1,1);
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
scene.add(cube);
camera.position.z = 5;
var render = function () {
requestAnimationFrame(render);
cube.rotation.x += 0.1;
cube.rotation.y += 0.1;
renderer.render(scene, camera);
};
render();
Can anybody help please?
Camera issues
Here's a jsfiddle of a working version.
Camera in Three.js is abstract, so I picked the common one to construct:
var camera = new THREE.PerspectiveCamera (75, wdt / hgh, 0.1, 1000);
The camera's viewpoint doesn't line up by default, so explicit calls eliminate confusion:
camera.lookAt(cube.position);
And adding the camera to the scene:
scene.add(camera);

Categories