I published a ready-textured model using the editor and then tried to load it with the JSONLoader. whatever i´m trying to resolve that issue (tried the ObjectLoader) - it seems I´m missing an important thing: the model just won´t show up.
<body ontouchstart="">
<script src="js/three.js"></script>
<script src="js/app.js"></script>
<script src="js/TrackballControls.js"></script>
<script src="js/JSONLoader.js"></script>
<script src="js/PerspectiveCamera.js"></script>
<script>
width=window.innerWidth;
height=window.innerHeight;
start();
animate();
function start(){
camera=new THREE.PerspectiveCamera(45,width/height,1,10000);
camera.position.set(0,0,-80);
control=new THREE.TrackballControls(camera);
control.addEventListener("change",render);
scene=new THREE.Scene();
var loader = new THREE.JSONLoader();
loader.load( 'app.json', function ( geometry, materials ) {
var mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) );
loader.onLoadComplete=function(){scene.add( mesh )}
});
renderer=new THREE.WebGLRenderer();
renderer.setClearColor(0xaaaaaa);
renderer.setSize(width,height);
document.body.appendChild(renderer.domElement);
renderer.render(scene,camera);
}
function animate(){
requestAnimationFrame(animate);
control.update();
}
function render(){
renderer.render(scene,camera);
}
</script>
</body>
I guess this is pretty messy copy&paste&trial&error you´re looking at.
This is the app.json-file.
Can someone point me in the right direction?
I've made a box, applied MeshStanardMaterial with a texture, put directional light there and then I did File -> Export Scene. I got a "scene.json" file.
After this in code I loaded the scene with ObjectLoader
var loader = new THREE.ObjectLoader();
loader.load( 'scene.json', function(object){
scene.add(object);
console.log(scene.children);
});
as the result I got a scene with a box and a directional light.
example
And a small remark, in your example code you don't call render() function from animate() function.
Related
I was able to successfully integrate Threejs Effect composer in aframe as a component by exporting everything as THREE.Effectcomposer, THREE.SSAOPass etc. and adding the effect inside a aframe component and i tweaked the AFrame renderer to update the effects in the scene. OutlinePass from threejs worked fine in this code but SSAO is not working and i don't get any errors. Please someone help me figure out the problem. the code for SSAOPass looks like this
AFRAME.registerComponent('ssao', {
init: function () {
this.el.addEventListener('that', evt => this.onEnter());
this.el.addEventListener('mouseleave', evt => this.onLeave());
setTimeout(() => this.el.emit("that"), 2000);
},
onEnter: function () {
const scene = this.el.sceneEl.object3D;
const camera = this.el.sceneEl.camera;
const renderer = this.el.sceneEl.renderer;
const render = renderer.render;
const composer = new THREE.EffectComposer(renderer);
//let renderPass = new THREE.RenderPass(scene, camera);
//let outlinePass = new THREE.OutlinePass(new THREE.Vector2(window.innerWidth, window.innerHeight), scene, camera);
const ssaoPass = new THREE.SSAOPass( scene, camera, window.innerWidth, window.innerHeight );
//composer.addPass(renderPass);
//composer.addPass(outlinePass);
ssaoPass.kernelRadius = 16;
composer.addPass( ssaoPass );
// let objects = [];
// this.el.object3D.traverse(node => {
// if (!node.isMesh) return;
// objects.push(node);
// });
// outlinePass.selectedObjects = objects;
// outlinePass.renderToScreen = true;
// outlinePass.edgeStrength = this.data.strength;
// outlinePass.edgeGlow = this.data.glow;
// outlinePass.visibleEdgeColor.set(this.data.color);
// HACK the AFRAME render method (a bit ugly)
const clock = new THREE.Clock();
this.originalRenderMethod = render;
let calledByComposer = false;
renderer.render = function () {
if (calledByComposer) {
render.apply(renderer, arguments);
} else {
calledByComposer = true;
composer.render(clock.getDelta());
calledByComposer = false;
}
};
},
onLeave: function () {
this.el.sceneEl.renderer.render = this.originalRenderMethod;
},
remove: function () {
this.onLeave();
}
});
I have also created a glitch project which i am sharing here. Please feel free to join and collaborate in my project
Edit link: https://glitch.com/edit/#!/accessible-torpid-partridge
Site link:https://accessible-torpid-partridge.glitch.me
Thanks in advance
The code is correct, all you need is to tweak the exposed SSAOShader uniforms: SSAOPass.kernelRadius, SSAOPass.minDistance, SSAOPass.maxDistance - like in the Three.js example.
Keep in mind - the scale in the example is huge, so the values will need to be different in a default aframe scene.
It's a good idea to be able to dynamically update a component (via setAttribute() if you properly handle updates), so you can see what's going on in realtime. Something like I did here - SSAO in a-frame (also based on Don McCurdys gist.
I've used some basic HTML elements, most threejs examples use dat.GUI - it is made for demo / debug tweaks.
I am using the following loadmodel function to load a json into html. (jsons were exported from Blender)
(function init(){
console.log("Init")
loadmodel('object1');
loadmodel('object2');
loadmodel('object3');
loadmodel('object4');
requestAnimationFrame(rotate);
})();
function loadmodel(str){
var json = "{% static 'three/' %}" + str + '.json.gz';
var loader = new THREE.JSONLoader();
loader.load(json, function(geometry, materials){
alfaromeo = new THREE.Mesh(
geometry, new THREE.MeshFaceMaterial(materials)
);
alfaromeo.name = str;
names.push(str);
scene.add(alfaromeo);
});
}
My problem is that I have more than one json to load and when I call this function for each json, only the first one is getting loaded and the others are not. The same code is working well in my friends computer - all the jsons are loading well.
Is there anything I am missing?
As one of the comments stands, the JSONLoader is asynchronous, so the best way to be sure you are rendering what has been already downloaded is to trigger the render once you have download the JSON file in your onLoad method.
Actually what I would recommend is that you call just once to loadmodel to load just one JSON file, after the first download trigger again a new download, the last of your JSON file download should then trigger the scene render.
(function init(){
console.log("Init")
loadmodel('object1');
//this should be called when your last object has been added to the scene
//requestAnimationFrame(rotate);
})();
Just a quick n dirty example from your code:
function loadmodel(str)
{
var json = "{% static 'three/' %}" + str + '.json.gz';
var loader = new THREE.JSONLoader();
loader.load(json, function(geometry, materials){
alfaromeo = new THREE.Mesh(
geometry, new THREE.MeshFaceMaterial(materials));
alfaromeo.name = str;
names.push(str);
scene.add(alfaromeo);
// Add here proper logic to load next model...
if(str=="object1")
loadmodel("object2");
else if()...
else
{
console.info("done with all downloads!");
requestAnimationFrame(rotate);
}
});
}
I'm new to three.js.
We're doing a project and I'm having a trouble in loading JSON model to the index file.
This is what I need.
This is my JSON model code
<html>
<head>
<title>My first Three.js app</title>
<style>
body { margin: 0; }
canvas { width: 100%; height: 100% }
</style>
</head>
<body>
<script src="js/three.js"></script>
<script>
var scene = new THREE.Scene();
var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 );
var renderer = new THREE.WebGLRenderer( { alpha: true });
renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0x000000, 0 ); // the default
document.body.appendChild( renderer.domElement );
camera.position.z = 5;
var render = function (){
renderer.render(scene, camera);
};
render();
</script>
</body>
And This is my JSON model
https://www.dropbox.com/s/ybztwwah9ncp68p/scene.json?dl=0
I exported this several times. So I'm pretty sure there's no problem with the JSON model.
But I'm having the problem on loading this JSON model using THREE.ObjectLoader.
It doesn't work.
This is the code function I used to import the JSON model.
var loader = new THREE.ObjectLoader();
Loader.load("scene.json",function(obj){
scene.add(obj);
});
How can this be corrected? I tried many times.
Any help is appreciated .
Thanks.
var loader = new THREE.JSONLoader();
loader.load( 'scene.json', function (o) {
scene.add(o);
});
*see the small "l" at loader.load
working example: http://threejs.org/examples/webgl_loader_json_claraio.html
if you want to use Object Loader, you must parse your json:
http://threejs.org/docs/api/loaders/ObjectLoader.html
I have an html5 basic presentation that was generated using Flash 6 and CreateJS.
The presentation is basically a bunch of flash keyframes with stop(); commands.
Now, here come my questions:
1. How do I target a specific frame on this presentation, using a link, located on a different page (something like the html anchor) ?
2. is there an easy way to add some cool frames transitions between those frames, using some kind of an open source library?
I'm a designer, not a programmer, so I have only little knowledge in coding.
Any help will be appreciate.
Thanks
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CreateJS export from main</title>
<script src="easeljs-0.6.0.min.js"></script>
<script src="tweenjs-0.4.0.min.js"></script>
<script src="movieclip-0.6.0.min.js"></script>
<script src="preloadjs-0.3.0.min.js"></script>
<script src="main.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
images = images||{};
var manifest = [
{src:"images/bg_b.jpg", id:"bg_b"},
];
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", handleFileLoad);
loader.addEventListener("complete", handleComplete);
loader.loadManifest(manifest);
}
function handleFileLoad(evt) {
if (evt.item.type == "image") { images[evt.item.id] = evt.result; }
}
function handleComplete() {
exportRoot = new lib.main();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener("tick", stage);
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4">
<canvas id="canvas" width="1024" height="768" style="background-color:#FFFFFF"></canvas>
</body>
</html>
CreateJS supports the use of basic actionscript by way of providing direct translations in javascript. For example, if you add the following bit of code to your timeline, the CreateJS publisher is smart enough to add a javascript call to stop the timeline at that position.
/* js
this.stop();
*/
To have a link skip to a location in the main timeline, you would need to use gotoAndPlay, or gotoAndStop depending on whether you want playback to continue. When CreateJS publishes your .fla, it creates a javascript instance of the main timeline movieclip called exportRoot. You can use this instance to manipulate the timeline via javascript.
Question 1: Changing location from another page
Using your code as an example now, notice the index.html page links to your Flash exported page (which I am calling target.html) with different hash tag locations for the frames. Also notice I have added the jquery library to your exported page, and a couple lines after the createjs.Ticker.addEventListener("tick", stage); to gotoAndStop based on the current hash, and to listen to future hash changes to gotoAndStop.
index.html
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title></title>
</head>
<body>
Goto frame 5
Goto frame 10
Goto frame 15
Goto frame 20
</body>
</html>
target.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>CreateJS export from main</title>
<script src="//code.jquery.com/jquery-1.10.2.min.js"></script>
<script src="easeljs-0.6.0.min.js"></script>
<script src="tweenjs-0.4.0.min.js"></script>
<script src="movieclip-0.6.0.min.js"></script>
<script src="preloadjs-0.3.0.min.js"></script>
<script src="main.js"></script>
<script>
var canvas, stage, exportRoot;
function init() {
canvas = document.getElementById("canvas");
images = images||{};
var manifest = [
{src:"images/bg_b.jpg", id:"bg_b"},
];
var loader = new createjs.LoadQueue(false);
loader.addEventListener("fileload", handleFileLoad);
loader.addEventListener("complete", handleComplete);
loader.loadManifest(manifest);
}
function handleFileLoad(evt) {
if (evt.item.type == "image") { images[evt.item.id] = evt.result; }
}
function handleComplete() {
exportRoot = new lib.main();
stage = new createjs.Stage(canvas);
stage.addChild(exportRoot);
stage.update();
createjs.Ticker.setFPS(30);
createjs.Ticker.addEventListener("tick", stage);
//When doc loads, check if there is a hash and gotoAndStop if there is
if(document.location.hash)
exportRoot.gotoAndStop(document.location.hash.replace('#', ''));
//Use jQUery to listen to the hash change event and gotoAndStop to new location when event fires
$(window).on('hashchange', function() {
exportRoot.gotoAndStop(document.location.hash.replace('#', ''));
});
}
</script>
</head>
<body onload="init();" style="background-color:#D4D4D4">
<canvas id="canvas" width="1024" height="768" style="background-color:#FFFFFF"></canvas>
</body>
</html>
Question 2: Transitions
As far as page transitions go, I would suggest either creating them in the timeline, and calling gotoAndPlay(FRAME_OF_THE_TRANSITION) until you start to get more comfortable with the CreateJS library to take a more object oriented approach.
How can one get the coordinates of a particular point on a map in OpenLayers?
Handle click event on map Click handler. Here is one of many sample codes you can find in OpenLayers mailing list archives:
map.events.register('click', map, handleMapClick);
function handleMapClick(e)
{
var lonlat = map.getLonLatFromViewPortPx(e.xy);
// use lonlat
// If you are using OpenStreetMap (etc) tiles and want to convert back
// to gps coords add the following line :-
// lonlat.transform( map.projection,map.displayProjection);
// Longitude = lonlat.lon
// Latitude = lonlat.lat
}
<html>
<head>
<script src="http://openlayers.org/api/OpenLayers.js"></script>
<script type="text/javascript">
function init(){
map = new OpenLayers.Map('map');
base_layer = new OpenLayers.Layer.WMS( "OpenLayers WMS",
"http://labs.metacarta.com/wms/vmap0", {layers: 'basic'} );
map.addLayer(base_layer);
map.zoomToMaxExtent();
map.events.register('click', map, handleMapClick);
}
function handleMapClick(evt)
{
var lonlat = map.getLonLatFromViewPortPx(evt.xy);
// use lonlat
alert(lonlat);
}
</script>
</head>
<body onload="init()">
Hello Map.<br />
<div id="map"></div>
</body>
</html>
#mloskot Your answer is great you had a mistake with the evt variable.
Just added the html markup to make it a working page.