-
Notifications
You must be signed in to change notification settings - Fork 314
Description
When using the picking on a gtlf, we don't get any result.
This is the case when the background color is left at the default value (#000000 <- black)
view.mainLoop.gfxEngine.renderer.setClearColor(
Your Environment
branch master
Context
When calling view.pickObjectsAt(event, 0, gtlfObj);, the return value is always empty.
Even though i'm clicking on the object.
It works if I set the background color to a different value, using view.mainLoop.gfxEngine.renderer.setClearColor(...)
Steps to Reproduce
- Don't call
view.mainLoop.gfxEngine.renderer.setClearColor() - Import GLTF
- Enable Picking on the gltf by click with a radius >= 0
- Click and see that no value is returned
Expected Behavior
Return the gltf object
Actual Behavior
Nothing is returned
Possible Cause/Fix/Solution
When calling view.pickObjectsAt() for a gltf with a radius >= 0, we go directly to Picking.js pickObjectsAt
In this method, we render a circular zone to a buffer and reads the pixel colors back based on the 3d object (gltf). BUT it always returns RGB values closed to 0 and then we compare those values with the background color view.mainLoop.gfxEngine.renderer.getClearColor(clearColor); which is, by default, black. So the picking area is considered as being part of the background because they are both black ...
The issue is that when we read the pixels colors values from the rendering, we shouldn't not get the color black. Currently, I think we get this wrong values because in the rendering, we are missing a light, so the scene is just black...
To correct this, we could either create a temporary scene containing only the object and a light and use it for the render.
Or just render the full scene and not only the object.
IMO the second option is the way to go
Reprod Script
<html>
<head>
<title>Itowns - Instancing</title>
<script type="importmap">
{
"imports": {
"itowns": "../dist/itowns.js",
"three": "https://unpkg.com/three@0.182.0/build/three.module.js",
"three/addons/": "https://unpkg.com/three@0.182.0/examples/jsm/"
}
}
</script>
<meta charset="UTF-8" />
<link rel="stylesheet" type="text/css" href="css/example.css" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
</head>
<body>
<div id="description">
<p>
<b>
Render a large number of objects with the same geometry<br/>
by importing your 3D models
</b>
</p>
</div>
<div id="viewerDiv" class="viewer"></div>
<script type="module">
import * as THREE from 'three';
import * as itowns from 'itowns';
// Define initial camera position
var placement = {
coord: new itowns.Coordinates("EPSG:4326", -0.57918, 44.837789),
range: 1000,
tilt: 45,
};
// `viewerDiv` will contain iTowns' rendering area (`<canvas>`)
var viewerDiv = document.getElementById("viewerDiv");
// Instanciate iTowns GlobeView*
var view = new itowns.GlobeView(viewerDiv, placement);
// view.mainLoop.gfxEngine.renderer.setClearColor(0x999999);
var ambLight = new THREE.AmbientLight(0xffffff, 0.2);
view.scene.add(ambLight);
// Add one imagery layer to the scene
itowns.Fetcher.json("./layers/JSONLayers/Ortho.json").then(
function _(config) {
config.source = new itowns.WMTSSource(config.source);
var layer = new itowns.ColorLayer("Ortho", config);
view.addLayer(layer).then(
);
}
);
var parentObj = new THREE.Group();
var parentParentObj = new THREE.Group();
// Load a glTF resource
var gltfLoader = new itowns.iGLTFLoader();
gltfLoader.load(
// resource URL
// "https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/models/lampadaire/scene.gltf",
"https://raw.githubusercontent.com/iTowns/iTowns2-sample-data/master/models/tree/tree.glb",
// "./bim.glb",
// called when the resource is loaded
(gltf) => {
var model = gltf.scene;
// Position the model at the placement coordinates
model.position.copy(placement.coord.as(view.referenceCrs).toVector3());
// Apply rotation and scale
model.rotateX(Math.PI / 2.0);
model.position.z += 2; // Offset from ground
model.scale.set(10, 10, 10);
// Update model matrix
model.updateMatrixWorld(true);
// Add the model directly to the scene
// view.scene.add(model);
parentObj.add(model);
parentParentObj.add(parentObj);
view.scene.add(parentParentObj);
// Notify view to render the changes
view.notifyChange();
},
// called while loading is progressing
() => {
},
// called when loading has errors
(error) => {
// eslint-disable-next-line no-console
console.log("An error happened :");
// eslint-disable-next-line no-console
console.log(error);
}
);
function clickHandler(event) {
var pick = view.pickObjectsAt(event, 0, parentParentObj);
// for (const p of pick) {
console.info('Selected point ' + pick);
// }
}
view.domElement.addEventListener('click', clickHandler);
window.view = view;
window.itowns = itowns;
window.THREE = THREE;
</script>
</body>
</html>