peterqliu / threebox Goto Github PK
View Code? Open in Web Editor NEWA three.js plugin for Mapbox GL JS, with support for basic animation and advanced 3D rendering.
License: MIT License
A three.js plugin for Mapbox GL JS, with support for basic animation and advanced 3D rendering.
License: MIT License
Heyo! I tried upgrading my version of threebox to check out the tube example mentioned in #56. It seems like something changed with the units that threebox expects from my geometry coordinates.
In the version of threebox I was previously using (not sure what version), my map looked like this:
In the new version (0.3.0), my map looks like this:
I.e. everything is bigger, and the tube positions are incorrect.
Did something change with the way threebox interprets mesh coordinates?
Figure out a syntax to make these optional and keep support for uniform scaling as the default.
Looking for object aircraft
whenever mouse moves on the map
object. If intersection exists, returns a JS object with the object, and point of intersection
map.on('mousemove', function(e){
// scale mouse pixel position to a percentage of the screen's width and height
mouse.x = ( e.point.x / threebox.map.transform.width ) * 2 - 1;
mouse.y = - ( e.point.y / threebox.map.transform.height ) * 2 + 1;
// update the picking ray with the camera and mouse position
raycaster.ray.origin.setFromMatrixPosition( threebox.camera.projectionMatrix );
raycaster.ray.direction
.set( mouse.x, mouse.y, 0.5 )
.unproject( threebox.camera )
.sub( raycaster.ray.origin )
.normalize();
// calculate objects intersecting the picking ray
var intersects = raycaster.intersectObject(aircraft)[0];
if (!intersects) return;
var t = map.transform;
var coords = {};
['x','y','z'].forEach(function(d){
var mapTransform = t[d] ? t[d] : 0;
var adjust = t[d] ? 256 : 0;
coords[d] = (intersects.point[d] + mapTransform) * Math.pow(0.5, t.zoom) - adjust
})
console.log({object: intersects, intersection: threebox.unprojectFromWorld(coords)})
})
does it work with react.js?
trying to use it inside a react app with mapboxgl (works fine with normal THREE.js) but gives me this error:
threebox.js:2596 Uncaught TypeError: Cannot read property 'matrixWorld' of undefined
at p.unproject (threebox.js:2596)
at r.eval (Map.js:216)
at r.dt.fire (mapbox-gl.js:28)
at HTMLDivElement.eval (mapbox-gl.js:32)
code:
map.on("load", function() {
map.addLayer({
id: 'custom_layer',
type: 'custom',
onAdd: function(map, mbxContext){
window.threebox = new Threebox(map, mbxContext);
threebox.setupDefaultLights();
var geometry = new THREE.BoxGeometry(20, 20, 20);
var redMaterial = new THREE.MeshPhongMaterial( {
color: 0xff0000,
side: THREE.DoubleSide
});
let cube = new THREE.Mesh(geometry, redMaterial);
threebox.addAtCoordinate(cube, origin);
},
render: function(gl, matrix){
threebox.update(true);
}
});
I test mapbox version 51 and 52, but it don't work. All demos don't show anything.
I add "renderingMode: '3d'" in the custom layer, but the same, the objects aren't on the position.
Transitions on:
Is there any reason why it wouldn't be possible to use threebox as you've documented, but also add a THREE.PlaneGeometry
terrain mesh to the MapBox GL map (as described by Peter here)?
I have make a 3d model file by 3d max ,output .obj and .mtl format. The 3d model has its height and width.
The mapbox basemap has its 3d building layer,and also with height and width.
And how can I see the effect between the obj model and mapbox building .
but now It is look like this
Can it “penetrate” when the building is heigher than the 3d model(obj)?
@peterqliu Thanks
Is threebox compatible with GTLF loader. I cannot seem to get it to work.
When use the mapbox gl v0.47.0 version api, 3d models are not fixed. When move the map 3d models moveing also.
@kronick 05f9934 seems to have broken the build. I needed to do andrewharvey@bd610cf to get it working.
Hello
I like the project to combine mapbox and threebox, congrats.
I try to draw a bar on top of a country to symbolize some information. Therefore I used Three.BoxGeometry. But the box is not positioned write. When I move, turn or pitch the map, the box is moving around.
Do you have any recommendations?
var map, frame_setting;
$(document).ready(function() {
var map_canvas = $("#map");
frame_setting = {
"map": {
container: 'map',
style: 'mapbox://styles/mapbox/light-v9',
width: '100%',
height: '100%',
center: [8.541566, 47.363846],
zoom: 5,
maxZoom: 18,
pitch: 60,
heading: 41
}
};
map_canvas.width(frame_setting.map.width);
map_canvas.height(frame_setting.map.height);
mapboxgl.accessToken = '123';
//Load Mapbox GL
map = new mapboxgl.Map(frame_setting.map);
map.resize();
//Add Controls
map.addControl(new mapboxgl.NavigationControl());
map.on("load", loadThree);
});
function loadThree()
{
window.threebox = new Threebox(map);
threebox.setupDefaultLights();
// initialize geometry and material of our cube object
var geometry = new THREE.BoxGeometry(100000, 100000, 400000);
var greenMaterial = new THREE.MeshPhongMaterial( {color: 0xaaffaa, side: THREE.DoubleSide});
var redMaterial = new THREE.MeshPhongMaterial( {color: 0xffaaaa, side: THREE.DoubleSide});
cube = new THREE.Mesh(geometry, greenMaterial);
cube.userData.name = "Red cube";
threebox.addAtCoordinate(cube, [8.541566, 47.363846, 0], {scaleToLatitude: true, preScale: 1});
}
I'd love an example with a transparent object :)
when add one ConeGeometry, it`s orientation is wrong, how should i do to erect one ConeGeometry?
changing the device orientation breaks the scale relationship between the mapbox layer and the three.js overlay - any idea how to fix this?
As we nail down the core features for our alpha release, let's move documentation of the API to a separate documentation.md
file and keep the readme.md
clean.
I see there's a stub for addGeoReferencedMesh
. I'd like to render some georeferenced meshes, so I'm interested in filling this out :)
I could use some pointers though. What would an outline of this function look like?
My current plan to render a mesh from a bunch of geo-referenced points is to convert my [lng, lat] pairs to [x, y] pairs measured in meters from the object's origin point. Does that sound right? Are there currently utility functions that do this conversion?
Hi,
I'm extending a bit the "truck" example. There is a "heading" option there which I think is supposed to be where the truck is heading geographically. I can change the heading of the truck dynamically (i.e. trough updateSourceData) and it works fine. However, if I change the orientation of the map interactively with the mouse, and then update the heading of the truck, it appears that the new heading is not correct. In short, it looks like the camera orientation of the map is affecting the geographic heading of the truck.
I hope this explanation was clear enough. Is this the intended behaviour?
Thanks
Marco
After viewing the source code, it seems that the Three.js Object you add using 'addAtCoordinate' gets inserted into a group. Therefore to get the remove method to work, I had to pass in the object's parent:
threebox.remove(3dObject.parent);
Create an example of animating a 3D object using a requestAnimationFrame
loop
previous version has supported the glft loader,why it was removed from souce code? Now, how should we add a gltf model?
I'm trying to get shadows working using the latest threebox (with mapbox custom layers). When setting castShadow
on a DirectionalLight
, threebox does not render anything.
Is this a limitation of threebox or has anyone had any luck getting them to work?
Hello First off this is a great library and very useful for doing visualizations on mapbox. Thank you for that.
I was wondering if it's possible to create convex geometry in threebox?
(https://threejs.org/examples/webgl_geometry_convex.html)
I add a SpotLight with SpotLightHelper to three box use tb.Object3D({obj:spotLight}),and setCoords(coords),but the SpotLightHelper `s coordinates looks like at the (0,0) even I set any coords, here is the code can be use to test.
`<!doctype html>
<title>Raycaster</title> <script src="js/threebox.js" type="text/javascript"></script><script src='https://api.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>
<link href='https://api.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.css' rel='stylesheet' />
<script src='https://unpkg.com/[email protected]/build/three.min.js'></script>
<style>
body,
html {
width: 100%;
height: 100%;
margin: 0;
}
#map {
width: 100%;
height: 100%;
}
</style>
<script>
var mesh;
mapboxgl.accessToken = 'pk.eyJ1IjoiaHVvaHVsaTAwOCIsImEiOiJjanM3Z3B1eHMwNG0zNDRtajhhcXNnanQwIn0.7gLFPHv_tXytt_JYLMze4w';
var origin = [1, 1, 50];
var map = new mapboxgl.Map({
container: 'map',
style: 'mapbox://styles/mapbox/dark-v9',
center: origin,
zoom: 15.95,
pitch: 60,
heading: 41,
hash: true,
});
var active = false
map.on('load', function () {
map.addLayer({
id: 'custom_layer',
type: 'custom',
onAdd: function (map, mbxContext) {
window.tb = new Threebox(
map,
mbxContext,
{ defaultLights: true, passiveRendering: false }
);
var geometry = new THREE.BoxGeometry(1000, 1000, 1000);
var material = new THREE.MeshLambertMaterial({
color: 0x0000ff
});
mesh = new THREE.Mesh(geometry, material);
cube = tb.Object3D({ obj: mesh })
.setCoords(origin);
tb.add(cube)
addLight(cube);
},
render: function (gl, matrix) {
tb.update();
render123();
}
});
});
function render123() {
mesh.rotateX(0.01);
}
function addLight(cube) {
var spotLight = new THREE.SpotLight('red');
spotLight.intensity = 500000;
spotLight.angle = 0.1;
spotLight.castShadow = true;
spotLight.distance = 100000;
spotLight.target = cube;
setCoords(spotLight);
var spotLightHelper = new THREE.SpotLightHelper(spotLight);
setCoords(spotLightHelper);
}
function setCoords(obj, coords = origin) {
var obj3D = window.tb.Object3D({ obj: obj })
.setCoords(coords);
window.tb.add(obj3D);
}
</script>
Seems to stem from left-handed coordinate system used by Mapbox GL JS (camera flips in y-direction)
Kudos on this handy plugin. However, I'm having trouble loading a custom JSON, is there a particular exporter/converter compatable with threebox? I've tried the Threejs Blender exporter and command line converter from mrdoob without success.
I receive the following error...
THREE.JSONLoader: x should be loaded with THREE.ObjectLoader instead.
and upon switching loaders I get...
Uncaught TypeError: Cannot read property 'type' of undefined
Please see demo.
Would there be scope to add gltf support? Since gltf with draco can result in very small file sizes.
Many thanks
I have the following code for adding a line
function createLine(start, end) {
const geometry = new THREE.Geometry();
geometry.vertices.push(threebox.projectToWorld(start), threebox.projectToWorld(end));
return new THREE.Line(geometry, new THREE.LineBasicMaterial({ color: 0xff0000 }));
}
// the function is called from inside the `map.addLayer` `onAdd` event
const line1 = createLine(origin, [-100, 40]);
threebox.world.add(line1);
The line draws in the proper place, but when I pan or zoom it jumps around and looks very jittery.
addAtCoordinate()
does not work for features that are already in lng/lat coordinates so that's why i'm adding directly to the world
group.
Is there a better way to do this?
I have used threebox to add custom models
const loader = new GLTFLoader();
loader.load('/assets/test.glb',function(obj){
obj.scene.rotation.x = 90 * Math.PI / 180;
obj.scene.scale.set(50,50,50);
threebox.addAtCoordinate(obj.scene,[112.5609,37.85418]);
})
In chrome . the models has added successful. But the console appeared a warning
THREE.Matrix3: getInverse() can't invert matrix , determinant is 0
if i drag the map , the console has appeared a lot of warnings.
the second question
const data = [
[112.5609,37.85418],
[112.5109,37.85418],
[112.5309,37.85418],
]
for(let i = 0; i < data.length; i++) {
threebox.addAtCoordinate(obj.scene,data[i]);
}
I use the above code,It only shows one model on the map.
const data = [
[112.5609,37.85418],
[112.5109,37.85418],
[112.5309,37.85418],
]
for(let i = 0; i < data.length; i++) {
threebox.addAtCoordinate(obj.scene.clone(),data[i]);
}
It has worked, But It also appears a lot of warnings.
thx.
My Problem:
I use floor (geojson) layers and 3D marker layers (placed between those layers to hide them).
After I change the pitch of the map, my markers are rendered wrong.
If I reload the map with another pitch there is no problem, only on active change.
Your library is great for someone like me, having no idea about matrix transformation and stuff, thanks. Any help will be greatly appreciated.
I load the same obj model with three.js and threebox,the former can load it ,but threebox throw error 1、'threebox.js:2297 THREE.WebGLShader: Shader couldn't compile.'
2、threebox.js:2314 THREE.WebGLProgram: shader error: 0 gl.VALIDATE_STATUS false gl.getProgramInfoLog invalid shaders
I use three94.js in src to load model,it worked!
Both should be data-driven with a property
or generator
.
Translation offset units should be in meters.
Hi,
Firstly - this is a really great library! Thank you.
I want to use setCoords() on an object returned from QueryRenderedFeatures(). However, the object returned from QueryRenderedFeatures() doesn't contain this function/property.
The use case is for the user to drag/move a feature...so I want to use QueryRenderedFeatures to get the feature under the mouse, then setCoords to change it's position.
Thanks!
Joe
Given a GeoJSON FeatureCollection
of Point
features, add 3D symbols to a map.
If we want to!
Needs a license.
Create a minimal example of adding a 3D symbol layer from a GeoJSON source.
Examples and all core code should not change the underlying geometry buffers (by rotation, scaling, etc). All project/unproject and higher level animation code should only change the Object3D instances managed by threebox.
For example, this won't work: https://github.com/peterqliu/threebox/blob/master/src/Threebox.js#L72 (I wrote it and will fix it)
Right now if a new model file is specified for a feature in update to a symbol layer, there is no provision to load the new file.
Also loading multiple model files in the first place seems to be broken.
Create a minimal example that shows how to set up mouse interactions to hover/highlight and click/select 3D objects
I'm trying to recreate the example https://github.com/peterqliu/threebox/blob/master/examples/logistics.html and I end up getting a warning on my console
threebox.js:4644 THREE.MeshPhongMaterial: .shading has been removed. Use the boolean .flatShading instead.
threebox.js:4675 THREE.MultiMaterial has been removed. Use an Array instead.
I do not see the truck object as well.
map.addLayer({
id: 'custom_layer',
type: 'custom',
renderingMode: '3d',
onAdd: function(map, mbxContext){
window.tb = new Threebox(
map,
mbxContext,
{defaultLights: true}
);
// import truck from an external obj file, scaling up its size 10x
var options = {
obj: 'Truck.obj',
mtl: 'Truck.mtl',
scale: 10
}
tb.loadObj(options, function(model) {
// console.log(model)
var truck = model.setCoords(origin);
console.log(truck)
tb.add(truck);
})
},
render: function(gl, matrix){
tb.update();
}
})
This is the snippet I'm using to load the model
Hey there! I'm rendering a (TubeBufferGeometry, ShaderMaterial) object with threebox. The ShaderMaterial animates some flowing colors over time. When I leave the rotation of the object alone, everything looks dandy:
When I add:
mesh.rotation.z += 0.02;
mesh.rotation.y += 0.07;
to my animation loop, I start to see some weirdness:
It looks to me like several tubes are getting rendered, slightly displaced in time. Any idea what's going on?
If in my animation loop I use:
threebox.update(true);
the tube looks fine, but the map disappears.
when add one ConeGeometry, it`s orientation is wrong, how should i do to erect one ConeGeometry?
Given a specific date/time and the center position of the map, we should be able to create a lighting setup that simulates the sun's path using a DirectionalLight
This will only be realistic at high zoom levels since the map is not a sphere
var loader = new THREE.GLTFLoader();
loader.load(model3DSrc, (function (gltf) {
gltf.scene.rotation.x = modelRotate[0];
threebox.addAtCoordinate(gltf.scene, modelOrigin);
}
the above works for and the model can be seen added to the mapbox map canvas:
<script src='https://api.mapbox.com/mapbox-gl-js/v0.50.0/mapbox-gl.js'></script>but after updating the mapbox version to v0.51.0 onwards to v0.53.0, the model is added but it cannot be seen on the map anymore.
Will this library have a minified version?
At this moment the package is 1000kb.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.