Get coordinates of First Person Control - three.js

I'm new to Three.js and I would like to get the coordinates of the first person view to use in an keyboard event.
How do I get the coordinates? I tried to:
controls.position.x
But this is undefined.
I set up my FPControl with this code:
var controls = new THREE.FirstPersonControls(camera);
controls.movementSpeed = 2.5;
controls.lookSpeed = 0.075;
controls.lookVertical = false;
controls.noFly = true;

You should be looking at camera.position.x instead.

Related

Three.js Spotlight ShadowCameraHelper Position Incorrect

Three.js r76
I was building a JSFiddle example for a slightly different problem but now can't get the shadow CameraHelper in the correct place to continue setting up my demo.
The spotlight helper appears to be working correctly but the shadow camera helper just seems to be parked at (0, 0, 0) and looking down the z axis.
Can anyone see where I'm going wrong please? Thank you.
JS Fiddle of Shadow Camera Helper seemingly in the wrong place
Code:
spt.position.set(0, 1000, 1000);
spt.castShadow = true;
spt.angle = 0.3;
spt.exponent = 2.0;
spt.penumbra = 0.05;
spt.decay = 1;
spt.distance = 3000;
spt.shadow.mapSize.width = 512;
spt.shadow.mapSize.height = 512;
spt.shadow.camera.near = 10;
spt.shadow.camera.far = 6000;
spt.shadowCameraHelper = new THREE.CameraHelper(spt.shadow.camera);
lightHelper = new THREE.SpotLightHelper(spt);
scene.add(spt.shadowCameraHelper);
scene.add(lightHelper);
scene.add(spt);
You need to enable Shadows in the renderer to get the CameraHelper to work:
renderer.shadowMap.enabled = true;
https://jsfiddle.net/n57kjtcs/17/

Attach text above 3D Object

I'm wondering if it is possible to attach a text above a 3D Object?
If so, how would I do it?
So far I'm doing the following below to load a mesh with its material and lastly adding it to a THREE.Object3D(); and adding it to the scene. Works great without any problems.
Next step is I want to show a nice text above its this object that is always fixed and can be seen from every angle.
loader.load('assets/' + enemyUrl, function (geometry, materials) {
material = new THREE.MeshFaceMaterial( materials );
model = new THREE.SkinnedMesh( geometry, material );
var mats = model.material.materials;
for (var i = 0,length = mats.length; i < length; i++) {
var m = mats[i];
m.skinning = true;
}
ensureLoop(geometry.animations[0]);
function ensureLoop( tmp ) {
for ( var i = 0; i < tmp.hierarchy.length; i ++ ) {
var bone = tmp.hierarchy[ i ];
var first = bone.keys[ 0 ];
var last = bone.keys[ bone.keys.length - 1 ];
last.pos = first.pos;
last.rot = first.rot;
last.scl = first.scl;
}
}
model.scale.set(2.5,2.5,2.5);
// TODO: Randomize where to put it in the world
yawObject.position.y = spawnPosition.y;
yawObject.position.x = spawnPosition.x;
yawObject.position.z = spawnPosition.z;
yawObject.add(model);
scene.add(yawObject);
});
Something like this:
This is what my game looks like now:
sure its possible. you can create a canvas with text on it, which you use as a texture on a plane that always looks at the camera, you could also do it with a single particle, but im not quite sure how it would work since particle materials have a size parameter. something like:
var name = 'Rovdjuret';
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
ctx.font="20px Georgia";
ctx.fillText(name,10,50);
var texture = new THREE.Texture(canvas);
texture.needsUpdate = true; //just to make sure it's all up to date.
var label = new THREE.Mesh(new THREE.PlaneGeometry, new THREE.MeshBasicMaterial({map:texture}));
and inside the render/animation loop you make all the labels look at the camera:
label.lookAt(camera.position);

three js directional light shadow

i am new to three js , i can able to generate the shadows using spot light but i receive unnecessary shadows too. what i need to do to remove the unwanted shadow .i need the shadows only for car and the wall and i need to remove the shadow like rectangle in the ground .
my code is as follows
var ambientLight = new THREE.AmbientLight( 0xffffff );
scene.add( ambientLight );
var light1 = new THREE.SpotLight(0xff00000);
light1.position.set(200, 1200, 0);
light1.target.position.set(0,0,0);
light1.shadowCameraVisible = true;
light1.castShadow = true;
light1.shadowDarkness = 0.8;
light1.shadowCameraNear = 400;
light1.shadowCameraFar = 1600;
//light1.shadowCameraFov = 30;
light1.shadowCameraLeft = -750;
light1.shadowCameraBottom = -500;
light1.shadowCameraRight = 1000;
light1.shadowCameraTop = 600;
var firstLight = new THREE.Object3D();
firstLight.add(light1);
scene.add(firstLight);
Thanks in advance
I see this you want selective shadow of object for the performance tweak.
The best you can do is for car model you have either .obj,.dae or which ever format loader you can load the object into scene via THREE.Object3D which has property "castShadow". Try this out:
var obj3D = new THREE.Object3D();
obj3D.add(/*content from loader*/);
obj3D.castShadow = true;
or
var mesh = new THREE.Mesh();
mesh.castShadow =true;
Enable or disable castShadow property with Mesh too.
I think this solve your problem

Does THREE.Raycaster perform intersection checks on CSS3DObject objects?

I need to run raycast off mouse coordinates and check for intersections on a group of Three CSS3DObject objects.
Here is the function:
RayCastCheck = function(event, objects){
var vector = new THREE.Vector3((event.clientX / window.innerWidth)*2 - 1, -(event.clientX / window.innerHeight )*2 + 1, 0.5);
new THREE.Projector().unprojectVector( vector, camera);
var raycaster = new THREE.Raycaster(camera.position, vector.sub(camera.position).normalize());
var intersects = raycaster.intersectObjects(objects);
console.log(intersects.length);
};
The objects argument is an array of css3dobjects. I am able to use similar function to target drops on the scene to the correct mouse location so I believe my calculation of the mouse point in world space is correct. This led to believe that the Raycaster is does not check intersections on css3dobjects.
My css3dobjects are typically constructed with a div as its element.
createObject = function(){
var element = document.createElement("div");
var obj = new THREE.CSS3DObject(element);
scene.add(obj);
}
My scene is created via this function
//global
var scene;
var camera;
var renderer;
createScene = function(){
camera = new THREE.PerspectiveCamera( 75, 400 / 600, 1, 1000 );
camera.position.z = 500;
scene = new THREE.Scene();
renderer = new THREE.CSS3DRenderer();
renderer.setSize(400, 600);
$(#body).appendChild(renderer.domElement);
}
Do I have all the required elements in the scene to enable raycasting?
Is it possible to perform raycasting on css3dobjects with the css3drenderer?
Thank you for your help
You can just use the usual events with the dom elements. You can even get the relative coordinates:
var x = e.offsetX==undefined?e.layerX:e.offsetX;
var y = e.offsetY==undefined?e.layerY:e.offsetY;
Using Raycaster on css3dobjects won't work. At least this is what I figured out.
Take a look at three.js r76 line 8933. There is the definition of the "raycast" function of the css3dobject.
It is empty so it isn't implemented and won't work because of this of course. probably on a further version. would need this function too
Still isn't implemented in r78.

Can a plane cast shadow on another plane in Three.js?

I have a plane with a transparent PNG (a world map).
Can I cast shadows from one plane onto another plane?
I am having no success with this code:
plane = new THREE.Mesh(new THREE.PlaneGeometry(200,200), new THREE.MeshLambertMaterial({color: 0xcccccc}));
var mapTexture = new THREE.ImageUtils.loadTexture("img/map_transp2.png");
mapTexture.needsUpdate = true;
var mapMaterial = new THREE.MeshBasicMaterial({
color:0xaaaaaa,
transparent:true,
map:mapTexture,
side:THREE.DoubleSide
});
mapPlane = new THREE.Mesh(new THREE.PlaneGeometry(800/5,370/5), mapMaterial);
plane.receiveShadow = true;
mapPlane.castShadow = true;
Transparent parts of the mesh should be handled differently if they're written in texture.
Take a look at this example: http://threejs.org/examples/webgl_animation_cloth.html
Your two planes are on the same z value. Give them some distance with:
mapPlane.position.z = 100;
// You need also to set this:
renderer.shadowMapEnabled = true;
// and also you need to add a light and enable its shadow, for example,
sLight = new THREE.SpotLight(0xFFF4E5,1);
sLight.position.set( 250, 250, 250);
sLight.castShadow = true;
sLight.shadowMapWidth = 1024;
sLight.shadowMapHeight = 1024;
sLight.shadowCameraNear = 300;
sLight.shadowCameraFar = 600;
sLight.shadowCameraFov = 45;
scene.add(sLight);
I have had a similar problem.
I don't know why this happens, but I solved it changing the planeGeometry to a cubeGeometry (in the plane casting the shadow)
See https://github.com/mrdoob/three.js/issues/9315
Set
renderer.shadowMap.renderReverseSided = false
or/and
renderer.shadowMap.renderSingleSided = false
can solve the problem.
When disabled, an appropriate shadow.bias must be set on the light source for surfaces that can both cast and receive shadows at the same time to render correctly:
let dl = new THREE.DirectionalLight()
dl.shadow.bias = -0.0001
three.js r.85

Resources