Related
i’m new to three.js and i was creating a custom shape using multiple objects. But the problem i’m facing is that when i add all the objects to the scene its working fine.
but whenever i merged all the object in a single geometry and then add to a scene, it becomes like this. see the image
don't know why it is getting darker but the bottom and back part seems to be fine.
The code i’ve used is shown below
var loader = new THREE.TextureLoader();
if(globalTextureImage != null)
{
var texture = loader.load( globalTextureImage );
}
else
{
var texture = loader.load( 'my_texture/1.jpg' );
}
var topGeometry = new THREE.CubeGeometry( 175, 0, 40, 0, 0, 0 );
var top = new THREE.Mesh( topGeometry, new THREE.MeshBasicMaterial({map:texture}) );
top.position.x = -0.01;
top.position.y = 0.99;
top.position.z = -0.003;
top.scale.x = 0.0198;
top.scale.y = -0.008;
top.scale.z = 0.0355;
top.updateMatrix();
var bottomGeometry = new THREE.CubeGeometry( 175, 0, 40, 1, 1, 1);
var bottom = new THREE.Mesh( bottomGeometry, new THREE.MeshBasicMaterial({map:texture}) );
bottom.position.x = -0.01;
bottom.position.y = -0.01;
bottom.position.z = -0.003;
bottom.scale.x = 0.0198;
bottom.scale.y = -0.008;
bottom.scale.z = 0.0355;
bottom.updateMatrix();
var leftGeometry = new THREE.CubeGeometry( 1, 100, 40, 1, 1, 1 );
var left = new THREE.Mesh( leftGeometry, new THREE.MeshBasicMaterial({map:texture}) );
left.position.x = -1.74;
left.position.y = 0.49;
left.position.z = -0.003;
left.scale.x = 0.01;
left.scale.y = -0.01;
left.scale.z = 0.035;
left.updateMatrix();
var rightGeometry = new THREE.CubeGeometry( 0, 100, 40, 1, 1, 1 );
var right = new THREE.Mesh( rightGeometry, new THREE.MeshBasicMaterial({map:texture}) );
right.position.x = 1.719;
right.position.y = 0.49;
right.position.z = -0.003;
right.scale.x = 0.01;
right.scale.y = -0.01;
right.scale.z = 0.035;
right.updateMatrix();
var middleGeometry = new THREE.CubeGeometry( 346, 100, 0, 1, 1, 1 );
var middle = new THREE.Mesh( middleGeometry, new THREE.MeshBasicMaterial({map:texture}) );
middle.position.x = -0.01;
middle.position.y = 0.49;
middle.position.z = 0.69;
middle.scale.x = 0.01;
middle.scale.y = -0.01;
middle.scale.z = 0.035;
middle.updateMatrix();
var backGeometry = new THREE.CubeGeometry( 345, 100, 0, 1, 1, 1 );
var back = new THREE.Mesh( backGeometry, new THREE.MeshBasicMaterial({map:texture}) );
back.position.x = -0.02;
back.position.y = 0.49;
back.position.z = -0.69;
back.scale.x = 0.01;
back.scale.y = -0.01;
back.scale.z = 0.035;
back.updateMatrix();
var geometry = new THREE.CylinderGeometry( 1, 1, 20, 32 );
var material = new THREE.MeshBasicMaterial( {color: 0xffffff} );
var cylinder = new THREE.Mesh( geometry, material );
cylinder.scale.set(0.02,0.02, 0.02);
cylinder.position.x = -0;
cylinder.position.y = 0.45;
cylinder.position.z = 0.82;
cylinder.rotation.x = 1.86;
cylinder.rotation.y = 3.14;
cylinder.rotation.z = 1.56;
cylinder.updateMatrix();
var geometry = new THREE.CylinderGeometry( 1, 1, 8, 32 );
var material = new THREE.MeshBasicMaterial( {color: 0xffffff} );
var cylinderleft = new THREE.Mesh( geometry, material );
cylinderleft.scale.set(0.02,0.02, 0.02);
cylinderleft.position.x = -0.18;
cylinderleft.position.y = 0.45;
cylinderleft.position.z = 0.74;
cylinderleft.rotation.x = 1.6;
cylinderleft.updateMatrix();
var geometry = new THREE.CylinderGeometry( 1, 1, 8, 32 );
var material = new THREE.MeshBasicMaterial( {color: 0xffffff} );
var cylinderRight = new THREE.Mesh( geometry, material );
cylinderRight.scale.set(0.02,0.02, 0.02);
cylinderRight.position.x = 0.18;
cylinderRight.position.y = 0.45;
cylinderRight.position.z = 0.74;
cylinderRight.rotation.x = 1.6;
cylinderRight.updateMatrix();
// scene.add( cylinder );
// scene.add( cylinderleft );
// scene.add( cylinderRight );
// scene.add(top);
// scene.add(bottom);
// scene.add(left);
// scene.add(right);
// scene.add(middle);
// scene.add(back);
var singleGeometry = new THREE.Geometry();
singleGeometry.merge(top.geometry, top.matrix);
singleGeometry.merge(bottom.geometry, bottom.matrix);
singleGeometry.merge(left.geometry, left.matrix);
singleGeometry.merge(right.geometry, right.matrix);
singleGeometry.merge(middle.geometry, middle.matrix);
singleGeometry.merge(back.geometry, back.matrix);
singleGeometry.merge(cylinder.geometry, cylinder.matrix);
singleGeometry.merge(cylinderleft.geometry, cylinderleft.matrix);
singleGeometry.merge(cylinderRight.geometry, cylinderRight.matrix);
var material = new THREE.MeshLambertMaterial({map:texture});
var mesh = new THREE.Mesh(singleGeometry, material);
mesh.scale.set(0.5,0.5,0.5);
objects.push(mesh);
scene.add(mesh);
Any help would be really appreciated
When you draw the object separately, the you create a THREE.Mesh for each object, each with a THREE.MeshBasicMaterial. The behaviour of a THREE.MeshBasicMaterial that the object appears with the brightness on each side, independent on the light of the scene.
But when you merge the object the you use a THREE.MeshLambertMaterial for the THREE.Geometry. This causes that the brightness of the object depends on the light of the scene. The parts of the object which face the light appear bright. Areas away from the light are dark.
If you would use THREE.MeshBasicMaterial for the merged geometry too, then the appearance would be the same as when you draw all the objects separately.
I am using the playback plugin and i am using it on an image overlay.
https://github.com/hallahan/LeafletPlayback
I need to scale the floor map before placing the marker. with the plugin the marker is placed some where outside of the floor map.
I am able to solve the issue for GPS tracking, where i have written a function to scale the map and place the marker inside pointToLayer method of layer property.
I want to do the same for marker too. any help is appreciated.
const playbackOptions = {
playControl: true,
dateControl: true,
orientIcons: true,
fadeMarkersWhenStale: true,
// layer and marker options
layer: {
pointToLayer(featureData, latlng) {
const { lat, lng } = latlng;
let result = {};
if (featureData && featureData.properties && featureData.properties.path_options) {
result = featureData.properties.path_options;
}
if (!result.radius) {
result.radius = 5;
}
const scaleX = width / details.width;
const scaleY = height / details.length;
const m = {
x: lat * scaleX,
y: lng * scaleY,
};
const iconCls = 'asset-icon';
const item = L.marker(self.map.unproject([m.x, m.y], self.map.getMaxZoom()), {
icon: makeMarker(iconCls, 0),
opacity: 0.9,
type: 'asset',
lat,
lng,
});
item.bindTooltip(`<p>${lat}, ${lng}`, { className: 'asset-label', offset: [0, 0] });
return item;
}
},
marker: {
getPopup(featureData) {
let result = '';
if (featureData && featureData.properties && featureData.properties.title) {
result = featureData.properties.title;
}
return result;
}
}
};
If you retrieve actual GPS coordinates, it would probably be easier to actually do the reverse, i.e. to georeference your image overlay once for good, instead of trying to fiddle with the geographic coordinates of each of the feature you try to show relatively to your image.
I want to have several geometries merged together and then apply a texture to make it look like a real piece of wood.
Is it possible? Here what I got for result:
Here's what I tried:
var texture = new THREE.TextureLoader().load( 'Escaliers 3D/1-3-2-5-Bois.jpg' );
var mesh = [], no = 0;
var meshes = [];
var geometry = new THREE.CubeGeometry( 2, 10, 1 );
mesh[no] = new THREE.Mesh( geometry );
meshes.push(mesh[no]);
no++;
geometry = new THREE.CylinderGeometry( 0.5, 0.5, 10, 32 );
mesh[no] = new THREE.Mesh( geometry );
mesh[no].position.set( 1, 0, 0 );
mesh[no].rotation.x = 0;
mesh[no].rotation.y = Math.PI/2;
mesh[no].rotation.z = 0;
meshes.push(mesh[no]);
no++;
geometry = new THREE.CubeGeometry( 5, 10, 1 );
mesh[no] = new THREE.Mesh( geometry );
mesh[no].position.set( -3.5, 0, 0 );
meshes.push(mesh[no]);
no++;
geometry = mergeMeshes(meshes);
var material = new THREE.MeshBasicMaterial( { map: texture } );
mesh = new THREE.Mesh( geometry, material );
scene.add( mesh );
function mergeMeshes (meshes) {
var combined = new THREE.Geometry();
for (var i = 0; i < meshes.length; i++) {
meshes[i].updateMatrix();
combined.merge(meshes[i].geometry, meshes[i].matrix);
}
return combined;
}
Thank you.
Merging the two meshes used to create this was the answer.
I need help with this code about Three.js. I do not know why it does not work, since everything is correct and copied from other codes that do work. The problem is that no Mouse Hovering effect works.
<html>
<head>
<title>NUEVO</title>
<style>canvas { width: 100%; height: 100% }</style>
</head>
<body>
<script src="js/libs/Tween.js"></script>
<script src="js/libs/stats.min.js"></script>
<script src="https://raw.github.com/mrdoob/three.js/master/build/three.js"></script>
<script>
var scene,camera,rendered,projector;
var mouseX, mouseY, stats, container;
var objects=[];
var INTERSECTED;
var theta = 0;
init();
animate();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 20000);
camera.position.set( 0, 150, 400 );
camera.lookAt(scene.position);
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
projector = new THREE.Projector();
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
for (var i=0; i<3; i++)
{
var geometry = new THREE.CubeGeometry(40,40,40);
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
cube.position.x = (i*200) -200
objects.push(cube);
scene.add(cube);
}
window.addEventListener( 'resize', onWindowResize, false );
}
function onDocumentMouseDown( event )
{
event.preventDefault();
mouseX = ( event.clientX / window.innerWidth ) * 2 - 1;
mouseY = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate()
{
requestAnimationFrame(animate);
render();
update();
}
function update()
{
var vector = new THREE.Vector3( mouseX, mouseY, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
if ( intersects[ 0 ].object != INTERSECTED )
{
if ( INTERSECTED )
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
// store reference to closest object as current intersection object
INTERSECTED = intersects[ 0 ].object;
// store color of closest object (for later restoration)
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
// set a new color for closest object
INTERSECTED.material.color.setHex( 0xffff00 );
} else {// there are no intersections
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED )
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
}
/* for(var i=0; i<3; i++)
{
objects[i].rotation.y += 0.05;
}*/
}
}
function render()
{
//theta += 0.4;
camera.position.x = 300 * Math.sin( theta * Math.PI / 360 );
camera.position.y = 300 * Math.sin( theta * Math.PI / 360 );
camera.position.z = 300 * Math.cos( theta * Math.PI / 360 );
camera.lookAt( scene.position );
renderer.render(scene, camera);
}
</script>
</body>
</html>
This is what You want:
http://jsfiddle.net/Lx6nE/4/
What was wrong:
The link to Three.js should be towards the minified source.
The braces should be indented right becuase of flickering
The mousedown event should be captured.
The code:
var scene,camera,rendered,projector;
var mouseX, mouseY, stats, container;
var objects=[];
var INTERSECTED;
var theta = 0;
init();
animate();
function init(){
scene = new THREE.Scene();
camera = new THREE.PerspectiveCamera(45, window.innerWidth/window.innerHeight, 1, 20000);
camera.position.set( 0, 150, 400 );
camera.lookAt(scene.position);
renderer = new THREE.CanvasRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement );
projector = new THREE.Projector();
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.bottom = '0px';
stats.domElement.style.zIndex = 100;
container.appendChild( stats.domElement );
for (var i=0; i<3; i++)
{
var geometry = new THREE.CubeGeometry(40,40,40);
var material = new THREE.MeshBasicMaterial({color: 0x00ff00});
var cube = new THREE.Mesh(geometry, material);
cube.position.x = (i*50) -60
objects.push(cube);
scene.add(cube);
}
window.addEventListener( 'resize', onWindowResize, false );
window.addEventListener( 'mousedown', onDocumentMouseDown, false );
}
function onDocumentMouseDown( event )
{
event.preventDefault();
mouseX = ( event.clientX / window.innerWidth ) * 2 - 1;
mouseY = - ( event.clientY / window.innerHeight ) * 2 + 1;
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function animate()
{
requestAnimationFrame(animate);
render();
update();
}
function update()
{
var vector = new THREE.Vector3( mouseX, mouseY, 1 );
projector.unprojectVector( vector, camera );
var ray = new THREE.Ray( camera.position, vector.subSelf( camera.position ).normalize() );
var intersects = ray.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
if ( intersects[ 0 ].object != INTERSECTED )
{
if ( INTERSECTED )
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
// store reference to closest object as current intersection object
INTERSECTED = intersects[ 0 ].object;
// store color of closest object (for later restoration)
INTERSECTED.currentHex = INTERSECTED.material.color.getHex();
// set a new color for closest object
INTERSECTED.material.color.setHex( 0xffff00 );
}
} else {// there are no intersections
// restore previous intersection object (if it exists) to its original color
if ( INTERSECTED )
INTERSECTED.material.color.setHex( INTERSECTED.currentHex );
// remove previous intersection object reference
// by setting current intersection object to "nothing"
INTERSECTED = null;
/* for(var i=0; i<3; i++)
{
objects[i].rotation.y += 0.05;
}*/
}
}
function render()
{
//theta += 0.4;
camera.position.x = 300 * Math.sin( theta * Math.PI / 360 );
camera.position.y = 300 * Math.sin( theta * Math.PI / 360 );
camera.position.z = 300 * Math.cos( theta * Math.PI / 360 );
camera.lookAt( scene.position );
renderer.render(scene, camera);
}
I am creating an interactive map for a non profit association "Friends of Knox Mountain Park" but I am getting trouble with the Google Earth view.
I've been searching on the web for weeks and none of the solutions I found works for me. Can someone take a look of the code and let me know what I should do to include Google Earth View in the map? Thanks in advance.
The online project: http://www.virtualbc.ca/knoxmountain/
And this is the javascript file (mapa2.js) containing the google map's code:
google.load('earth', '1');
var map;
var googleEarth;
var gmarkers = [];
var iconShadow = new google.maps.MarkerImage('icons/shadow.png',
new google.maps.Size(46, 42),
new google.maps.Point(0,0),
new google.maps.Point(13, 42));
var sites = [
['Apex Trail - Shelter',49.91174271, -119.48507050, 4, '<img src="images/apex_point_high.jpg">','magenta','14'],
['Apex Trail',49.91286999, -119.48413424, 3, '<img src="images/apex_point_low.jpg">','lemon','1'],
['Gordon Trail',49.91971281, -119.47954356, 2, '<img src="images/apex_point_low.jpg">','lemon','1'],
['Paul Tomb Bay',49.92555541, -119.47710250, 1, '<img src="images/tomb_bay.jpg">','lemon','1']
];
var infowindow = null;
var overlay;
// Used to make Google Map quard coords to MapCruncher/BingMaps quard coords
function TileToQuadKey ( x, y, zoom)
{
var quad = "";
for (var i = zoom; i > 0; i--)
{
var mask = 1 << (i - 1);
var cell = 0;
if ((x & mask) != 0)
cell++;
if ((y & mask) != 0)
cell += 2;
quad += cell;
}
return quad;
}
function init() {
var centerMap = new google.maps.LatLng(49.909671, -119.482241);
var myOptions = {
zoom: 10,
center: centerMap,
mapTypeId: google.maps.MapTypeId.SATELLITE
}
map = new google.maps.Map(document.getElementById("map_canvas"), myOptions);
// Create the tile layers
// ASTER Tile Layer
myASTEROptions = {
getTileUrl : function (a,b) {
return "http://www.virtualbc.ca/knoxmountain/map/" + TileToQuadKey(a.x,a.y,b) + ".png";
},
isPng: true,
opacity: 1.0,
tileSize: new google.maps.Size(256,256),
name: "ASTER",
minZoom:13,
maxZoom:20
}
ASTERMapType = new google.maps.ImageMapType( myASTEROptions );
map.overlayMapTypes.insertAt(0, ASTERMapType);
// Aerial Tile Layer
myAerialOptions = {
getTileUrl : function (a,b) {
return "http://www.virtualbc.ca/knoxmountain/map/" + TileToQuadKey(a.x,a.y,b) + ".png";
},
isPng: true,
opacity: 1.0,
tileSize: new google.maps.Size(256,256),
name: "Aerial",
minZoom:15,
maxZoom:21
}
AerialMapType = new google.maps.ImageMapType( myAerialOptions );
map.overlayMapTypes.insertAt(1, AerialMapType);
var panorama = new google.maps.StreetViewPanorama(map.getDiv());
panorama.setVisible(false);
panorama.set('enableCloseButton', true);
map.setStreetView(panorama);
panorama.setPosition(centerMap);
setMarkers(map, sites);
setZoom(map, sites);
infowindow = new google.maps.InfoWindow({
content: "Loading..."
});
googleEarth = new GoogleEarth(map);
google.maps.event.addListenerOnce(map, 'tilesloaded', addOverlays);
}
/*
This functions sets the markers (array)
*/
function setMarkers(map, markers) {
for (var i = 0; i < markers.length; i++) {
var site = markers[i];
var siteLatLng = new google.maps.LatLng(site[1], site[2]);
var marker = new google.maps.Marker({
position: siteLatLng,
map: map,
title: site[0],
zIndex: site[3],
html: site[4],
// Markers drop on the map
animation: google.maps.Animation.DROP,
icon: 'http://www.virtualbc.ca/knoxmountain/icons/icon.png',
shadow: iconShadow
});
gmarkers.push(marker);
google.maps.event.addListener(marker, "click", function () {
infowindow.setContent(this.html);
infowindow.open(map, this);
});
}
}
/*
Set the zoom to fit comfortably all the markers in the map
*/
function setZoom(map, markers) {
var boundbox = new google.maps.LatLngBounds();
for ( var i = 0; i < markers.length; i++ )
{
boundbox.extend(new google.maps.LatLng(markers[i][1], markers[i][2]));
}
map.setCenter(boundbox.getCenter());
map.fitBounds(boundbox);
}
// This function picks up the click and opens the corresponding info window
function myclick(i) {
google.maps.event.trigger(gmarkers[i-1], "click");
}
google.maps.event.addDomListener(window, 'load', init);
The first issue I notice with your site is you are linking to http://www.virtualbc.ca/src/googleearth-compiled.js which does not exist.