Skip to content

Commit

Permalink
Merge pull request #1389 from xeokit/fix-transparent-object-picking
Browse files Browse the repository at this point in the history
Fix transparent DTX mesh picking
  • Loading branch information
xeolabs committed Feb 29, 2024
2 parents 20aeff3 + 1e7738d commit f2935a6
Show file tree
Hide file tree
Showing 3 changed files with 625 additions and 5 deletions.
313 changes: 313 additions & 0 deletions examples/scenemodel/picking_dtx_batching_opacity.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,313 @@
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>xeokit Example</title>
<link href="../css/pageStyle.css" rel="stylesheet"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.13.0/js/all.min.js"></script>
</head>
<body>
<input type="checkbox" id="info-button"/>
<label for="info-button" class="info-button"><i class="far fa-3x fa-question-circle"></i></label>
<canvas id="myCanvas"></canvas>
<div class="slideout-sidebar">
<img class="info-icon" src="../../assets/images/performance_model_icon.png"/>
<h1>SceneModel</h1>
<p>Test Picking Transparent DTX Meshes</p>
<ul>
<li>
<a href="../../docs/class/src/viewer/Viewer.js~Viewer.html"
target="_other">Viewer</a>
</li>
<li>
<a href="../../docs/class/src/viewer/scene/model/SceneModel.js~SceneModel.html"
target="_other">SceneModel</a>
</li>


</ul>
</div>
</body>

<script type="module">

//------------------------------------------------------------------------------------------------------------------
// Import the modules we need for this example
//------------------------------------------------------------------------------------------------------------------

import {Viewer, SceneModel} from "../../dist/xeokit-sdk.es.js";

//------------------------------------------------------------------------------------------------------------------
// Create a Viewer and arrange the camera
//------------------------------------------------------------------------------------------------------------------

const viewer = new Viewer({
canvasId: "myCanvas",
transparent: true,
dtxEnabled: true
});

viewer.scene.camera.eye = [-21.80, 4.01, 6.56];
viewer.scene.camera.look = [0, -5.75, 0];
viewer.scene.camera.up = [0.37, 0.91, -0.11];

//------------------------------------------------------------------------------------------------------------------
// Create a SceneModel representing a table with four legs, using geometry batching
//------------------------------------------------------------------------------------------------------------------

const sceneModel = new SceneModel(viewer.scene, {
id: "table",
isModel: true, // <--------------------- Represents a model, registers SceneModel by ID on viewer.scene.models
position: [0, 0, 0],
scale: [1, 1, 1],
rotation: [0, 0, 0],
edges: true
});

//-----------------------------------------------------------
// Create a red table leg object
// Each object is comprised of a mesh, which belongs to a node
//-----------------------------------------------------------

sceneModel.createMesh({
id: "redLegMesh",

// The primitive type - allowed values are "points", "lines" and "triangles".
// See the OpenGL/WebGL specification docs for how the coordinate arrays are supposed to be laid out.
primitive: "triangles",

// The vertices - eight for our cube, each one spanning three array elements for X,Y and Z
positions: [
1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, // v0-v1-v2-v3 front
1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, // v0-v3-v4-v1 right
1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, // v0-v1-v6-v1 top
-1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, // v1-v6-v7-v2 left
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1,// v7-v4-v3-v2 bottom
1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1 // v4-v7-v6-v1 back
],

// Normal vectors, one for each vertex
normals: [
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1,// v0-v1-v2-v3 front
1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0,// v0-v3-v4-v5 right
0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,// v0-v5-v6-v1 top
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0,// v1-v6-v7-v2 left
0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0,// v7-v4-v3-v2 bottom
0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1// v4-v7-v6-v5 back
],

// Indices - these organise the positions and and normals
// into geometric primitives in accordance with the "primitive" parameter,
// in this case a set of three indices for each triangle.
//
// Note that each triangle is specified in counter-clockwise winding order.
//
indices: [
0, 1, 2, 0, 2, 3, // front
4, 5, 6, 4, 6, 7, // right
8, 9, 10, 8, 10, 11, // top
12, 13, 14, 12, 14, 15, // left
16, 17, 18, 16, 18, 19, // bottom
20, 21, 22, 20, 22, 23
],

position: [-4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1, 0.3, 0.3],
opacity: 0
});

sceneModel.createEntity({
id: "redLeg",
meshIds: ["redLegMesh"],
isObject: true // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
});

//--------------------------------------------------------
// Green table leg object
//--------------------------------------------------------

sceneModel.createMesh({
id: "greenLegMesh",
primitive: "triangles",
positions: [
1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1,
1, 1, 1, 1, 1, -1, -1, 1, -1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1,
-1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1, -1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1
],
normals: [
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1
],
indices: [
0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15,
16, 17, 18, 16, 18, 19, 20, 21, 22, 20, 22, 23
],
position: [4, -6, -4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 1.0, 0.3],
opacity: 0
});

sceneModel.createEntity({
id: "greenLeg",
meshIds: ["greenLegMesh"],
isObject: true // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
});

//--------------------------------------------------------
// Blue table leg object
//--------------------------------------------------------

sceneModel.createMesh({
id: "blueLegMesh",
positions: [
1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1,
-1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1,
-1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1
],
normals: [
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0,
-1, 0, 0, -1
],
indices: [
0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19,
20, 21, 22, 20, 22, 23
],
position: [4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [0.3, 0.3, 1.0],
opacity: 0
});

sceneModel.createEntity({
id: "blueLeg",
meshIds: ["blueLegMesh"],
isObject: true // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
});

//--------------------------------------------------------
// Yellow table leg object
//--------------------------------------------------------

sceneModel.createMesh({
id: "yellowLegMesh",
positions: [
1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1,
-1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1,
-1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1
],
normals: [
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1
],
indices: [
0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19,
20, 21, 22, 20, 22, 23
],
position: [-4, -6, 4],
scale: [1, 3, 1],
rotation: [0, 0, 0],
color: [1.0, 1.0, 0.0],
opacity: 0
});

sceneModel.createEntity({
id: "yellowLeg",
meshIds: ["yellowLegMesh"],
isObject: true // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
});

//--------------------------------------------------------
// Purple table top object
//--------------------------------------------------------

sceneModel.createMesh({
id: "purpleTableTopMesh",
positions: [
1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, 1, 1, -1, -1, 1, 1, -1, 1, 1, 1, 1, 1, -1, -1, 1,
-1, -1, 1, 1, -1, 1, 1, -1, 1, -1, -1, -1, -1, -1, -1, 1, -1, -1, -1, 1, -1, -1, 1, -1, 1, -1, -1, 1, 1,
-1, -1, -1, -1, -1, -1, 1, -1, 1, 1, -1
],
normals: [
0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0,
-1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, -1
],
indices: [
0, 1, 2, 0, 2, 3, 4, 5, 6, 4, 6, 7, 8, 9, 10, 8, 10, 11, 12, 13, 14, 12, 14, 15, 16, 17, 18, 16, 18, 19,
20, 21, 22, 20, 22, 23
],
position: [0, -3, 0],
scale: [6, 0.5, 6],
rotation: [0, 0, 0],
color: [1.0, 0.3, 1.0],
opacity: 0
});

sceneModel.createEntity({
id: "purpleTableTop",
meshIds: ["purpleTableTopMesh"],
isObject: true // <----------------- Represents an object, registers Entity by ID on viewer.scene.objects
});

//------------------------------------------------------------
// Finalize the SceneModel.
//
// Internally, this builds any geometry batches or instanced
// arrays that are currently under construction within it.
//------------------------------------------------------------

sceneModel.finalize();

//------------------------------------------------------------------------------------------------------------------
// Find Entities by their IDs
//------------------------------------------------------------------------------------------------------------------

// Get the whole table model
var table = viewer.scene.models["table"];

// Get some leg objects
var redLeg = viewer.scene.objects["redLeg"];
var greenLeg = viewer.scene.objects["greenLeg"];
var blueLeg = viewer.scene.objects["blueLeg"];

//------------------------------------------------------------------------------------------------------------------
// Mouse over Entities to highlight them
//------------------------------------------------------------------------------------------------------------------

var lastEntity = null;

viewer.scene.input.on("mousemove", function (coords) {

var hit = viewer.scene.pick({
canvasPos: coords
});

if (hit) {
console.log(hit);
if (!lastEntity || hit.entity.id !== lastEntity.id) {

if (lastEntity) {
lastEntity.opacity = 0.0;
}

lastEntity = hit.entity;
lastEntity.opacity = 1.0;
}
} else {

if (lastEntity) {
lastEntity.opacity = 0.0;
lastEntity = null;
}
}
});

</script>
</html>
Loading

0 comments on commit f2935a6

Please sign in to comment.