-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Instancing models 3d tiles #3059
Changes from 19 commits
3415df3
aecfb3c
37276da
5bab8d6
a65a038
a5add4e
791a555
b938c61
33c4acd
02781ce
12904b8
a416ee8
4f14143
b48b4f2
b820a55
13d14c0
77b2547
61d5607
bab0ba9
d5ce3b2
88efe56
be59252
bc10897
948ad72
69b858d
9ae609d
a49b6fd
e19f70a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> <!-- Use Chrome Frame in IE --> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> | ||
<meta name="description" content="Create 3D models using glTF."> | ||
<meta name="cesium-sandcastle-labels" content="Development"> | ||
<title>Cesium Demo</title> | ||
<script type="text/javascript" src="../Sandcastle-header.js"></script> | ||
<script type="text/javascript" src="../../../ThirdParty/requirejs-2.1.9/require.js"></script> | ||
<script type="text/javascript"> | ||
require.config({ | ||
baseUrl : '../../../Source', | ||
waitSeconds : 60 | ||
}); | ||
</script> | ||
</head> | ||
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html"> | ||
<style> | ||
@import url(../templates/bucket.css); | ||
</style> | ||
<div id="cesiumContainer" class="fullSize"></div> | ||
<div id="loadingOverlay"><h1>Loading...</h1></div> | ||
<div id="toolbar"></div> | ||
<script id="cesium_sandcastle_script"> | ||
function startup(Cesium) { | ||
"use strict"; | ||
//Sandcastle_Begin | ||
|
||
var globeVisible = false; | ||
|
||
var viewer = new Cesium.Viewer('cesiumContainer', { | ||
globe : globeVisible ? undefined : false, | ||
skyAtmosphere : globeVisible ? undefined : false | ||
}); | ||
|
||
var scene = viewer.scene; | ||
var camera = viewer.camera; | ||
|
||
function orientCamera(center, radius) { | ||
var controller = scene.screenSpaceCameraController; | ||
var r = Math.max(radius, camera.frustum.near); | ||
controller.minimumZoomDistance = r * 0.5; | ||
|
||
var heading = Cesium.Math.toRadians(230.0); | ||
var pitch = Cesium.Math.toRadians(-20.0); | ||
camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, r * 2.0)); | ||
} | ||
|
||
function loadInstanced3DTile() { | ||
// TODO : create real tileset later | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We'll be able to delete this entire example since the user's code will just load a 3D tileset regardless of the tile format(s) it contains. |
||
var tileset; | ||
var contentHeader = {}; | ||
var url = 'http://localhost:8002/tilesets/Instances/instance3DTileTest.i3dm'; | ||
var content = new Cesium.Instanced3DModel3DTileContentProvider(tileset, url, contentHeader); | ||
content.request(); | ||
content.processingPromise.then(function(content) { | ||
var collection = content._modelInstanceCollection; | ||
scene.primitives.add(collection); | ||
collection.readyPromise.then(function(collection) { | ||
// Play and loop all animations at half-speed | ||
collection._model.activeAnimations.addAll({ | ||
speedup : 0.5, | ||
loop : Cesium.ModelAnimationLoop.REPEAT | ||
}); | ||
orientCamera(collection._boundingVolume.center, collection._boundingVolume.radius); | ||
}).otherwise(function(error) { | ||
window.alert(error); | ||
}); | ||
}).otherwise(function(error) { | ||
window.alert(error); | ||
}); | ||
} | ||
|
||
loadInstanced3DTile(); | ||
|
||
//Sandcastle_End | ||
Sandcastle.finishedLoading(); | ||
} | ||
if (typeof Cesium !== "undefined") { | ||
startup(Cesium); | ||
} else if (typeof require === "function") { | ||
require(["Cesium"], startup); | ||
} | ||
</script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,267 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<meta http-equiv="X-UA-Compatible" content="IE=Edge,chrome=1"> <!-- Use Chrome Frame in IE --> | ||
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no"> | ||
<meta name="description" content="Create 3D models using glTF."> | ||
<meta name="cesium-sandcastle-labels" content="Development"> | ||
<title>Cesium Demo</title> | ||
<script type="text/javascript" src="../Sandcastle-header.js"></script> | ||
<script type="text/javascript" src="../../../ThirdParty/requirejs-2.1.9/require.js"></script> | ||
<script type="text/javascript"> | ||
require.config({ | ||
baseUrl : '../../../Source', | ||
waitSeconds : 60 | ||
}); | ||
</script> | ||
</head> | ||
<body class="sandcastle-loading" data-sandcastle-bucket="bucket-requirejs.html"> | ||
<style> | ||
@import url(../templates/bucket.css); | ||
</style> | ||
<div id="cesiumContainer" class="fullSize"></div> | ||
<div id="loadingOverlay"><h1>Loading...</h1></div> | ||
<div id="toolbar"></div> | ||
<script id="cesium_sandcastle_script"> | ||
function startup(Cesium) { | ||
"use strict"; | ||
//Sandcastle_Begin | ||
|
||
var debugShowBoundingVolume = false; | ||
var debugWireframe = false; | ||
var globeVisible = true; | ||
|
||
var viewer = new Cesium.Viewer('cesiumContainer', { | ||
globe : globeVisible ? undefined : false, | ||
skyAtmosphere : globeVisible ? undefined : false | ||
}); | ||
|
||
var scene = viewer.scene; | ||
var context = scene.context; | ||
var camera = viewer.camera; | ||
scene.debugShowFramesPerSecond = true; | ||
|
||
var instancedArraysExtension = context._instancedArrays; | ||
var count = 1024; | ||
var spacing = 0.0002; | ||
var url = '../../SampleData/models/CesiumAir/Cesium_Air.bgltf'; | ||
var dynamic = false; | ||
var useCollection = true; | ||
|
||
var centerLongitude = -123.0744619; | ||
var centerLatitude = 44.0503706; | ||
var height = 5000.0; | ||
|
||
function orientCamera(center, radius) { | ||
var controller = scene.screenSpaceCameraController; | ||
var r = Math.max(radius, camera.frustum.near); | ||
controller.minimumZoomDistance = r * 0.5; | ||
|
||
var heading = Cesium.Math.toRadians(230.0); | ||
var pitch = Cesium.Math.toRadians(-20.0); | ||
camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, r * 2.0)); | ||
} | ||
|
||
function createCollection(instances) { | ||
var collection = scene.primitives.add(new Cesium.ModelInstanceCollection({ | ||
url : url, | ||
instances : instances, | ||
dynamic : dynamic, | ||
debugShowBoundingVolume : debugShowBoundingVolume, | ||
debugWireframe : debugWireframe | ||
})); | ||
|
||
collection.readyPromise.then(function(collection) { | ||
// Play and loop all animations at half-speed | ||
collection._model.activeAnimations.addAll({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know |
||
speedup : 0.5, | ||
loop : Cesium.ModelAnimationLoop.REPEAT | ||
}); | ||
orientCamera(collection._boundingVolume.center, collection._boundingVolume.radius); | ||
}).otherwise(function(error){ | ||
window.alert(error); | ||
}); | ||
} | ||
|
||
function createModels(instances) { | ||
var points = []; | ||
var model; | ||
|
||
var length = instances.length; | ||
for (var i = 0; i < length; ++i) { | ||
var instance = instances[i]; | ||
var modelMatrix = instance.modelMatrix; | ||
var translation = new Cesium.Cartesian3(); | ||
Cesium.Matrix4.getTranslation(modelMatrix, translation); | ||
points.push(translation); | ||
|
||
model = Cesium.Model.fromGltf({ | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just style. We can write:
as
|
||
url : url, | ||
modelMatrix : modelMatrix, | ||
debugShowBoundingVolume : debugShowBoundingVolume, | ||
debugWireframe : debugWireframe | ||
}); | ||
|
||
scene.primitives.add(model); | ||
|
||
model.readyPromise.then(function(model) { | ||
// Play and loop all animations at half-speed | ||
model.activeAnimations.addAll({ | ||
speedup : 0.5, | ||
loop : Cesium.ModelAnimationLoop.REPEAT | ||
}); | ||
}).otherwise(function(error){ | ||
window.alert(error); | ||
}); | ||
} | ||
|
||
model.readyPromise.then(function(model) { | ||
var boundingSphere = new Cesium.BoundingSphere(); | ||
Cesium.BoundingSphere.fromPoints(points, boundingSphere); | ||
orientCamera(boundingSphere.center, boundingSphere.radius + model.boundingSphere.radius); | ||
}); | ||
} | ||
|
||
function reset() { | ||
scene.primitives.removeAll(); | ||
var instances = []; | ||
var gridSize = Math.sqrt(count); | ||
|
||
for (var y = 0; y < gridSize; ++y) { | ||
for (var x = 0; x < gridSize; ++x) { | ||
var longitude = centerLongitude + spacing * (x - gridSize/2); | ||
var latitude = centerLatitude + spacing * (y - gridSize/2); | ||
var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height); | ||
|
||
var heading = Math.random(); | ||
var pitch = Math.random(); | ||
var roll = Math.random(); | ||
var scale = (Math.random() + 1.0)/2.0; | ||
var color = Cesium.Color.fromRandom(); | ||
var show = (Math.random() > 0.5); | ||
|
||
var modelMatrix = Cesium.Transforms.headingPitchRollToFixedFrame(position, heading, pitch, roll); | ||
Cesium.Matrix4.multiplyByUniformScale(modelMatrix, scale, modelMatrix); | ||
|
||
instances.push({ | ||
modelMatrix : modelMatrix, | ||
color : color, | ||
show : show | ||
}); | ||
} | ||
} | ||
|
||
useCollection ? createCollection(instances) : createModels(instances); | ||
} | ||
|
||
Sandcastle.addToolbarMenu([ { | ||
text : '1024 instances', | ||
onselect : function() { | ||
count = 1024; | ||
reset(); | ||
} | ||
}, { | ||
text : '100 instances', | ||
onselect : function() { | ||
count = 100; | ||
reset(); | ||
} | ||
}, { | ||
text : '25 instances', | ||
onselect : function() { | ||
count = 25; | ||
reset(); | ||
} | ||
}, { | ||
text : '4 instances', | ||
onselect : function() { | ||
count = 4; | ||
reset(); | ||
} | ||
}, { | ||
text : '10000 instances', | ||
onselect : function() { | ||
count = 10000; | ||
reset(); | ||
} | ||
}]); | ||
|
||
Sandcastle.addToolbarMenu([ { | ||
text : 'Aircraft', | ||
onselect : function() { | ||
url = '../../SampleData/models/CesiumAir/Cesium_Air.bgltf'; | ||
spacing = 0.0002; | ||
reset(); | ||
} | ||
}, { | ||
text : 'Ground vehicle', | ||
onselect : function() { | ||
url = '../../SampleData/models/CesiumGround/Cesium_Ground.bgltf'; | ||
spacing = 0.00008; | ||
reset(); | ||
} | ||
}, { | ||
text : 'Milk truck', | ||
onselect : function() { | ||
url = '../../SampleData/models/CesiumMilkTruck/CesiumMilkTruck.bgltf'; | ||
spacing = 0.00008; | ||
reset(); | ||
} | ||
}, { | ||
text : 'Skinned character', | ||
onselect : function() { | ||
url = '../../SampleData/models/CesiumMan/Cesium_Man.bgltf'; | ||
spacing = 0.00001; | ||
reset(); | ||
} | ||
}]); | ||
|
||
|
||
Sandcastle.addToolbarMenu([ { | ||
text : 'Instancing Enabled', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When instancing is disabled, I suspect we are allocating an array or something per frame since the garbage collector is at 21.7% in the profile. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @lilleyse did you look at this performance issue? I do not want to merge this until we track it down. |
||
onselect : function() { | ||
context._instancedArrays = instancedArraysExtension; | ||
useCollection = true; | ||
reset(); | ||
} | ||
}, { | ||
text : 'Instancing Disabled', | ||
onselect : function() { | ||
context._instancedArrays = undefined; | ||
useCollection = true; | ||
reset(); | ||
} | ||
}, { | ||
text : 'Individual models', | ||
onselect : function() { | ||
useCollection = false; | ||
reset(); | ||
} | ||
}]); | ||
|
||
Sandcastle.addToolbarMenu([ { | ||
text : 'Static', | ||
onselect : function() { | ||
dynamic = false; | ||
reset(); | ||
} | ||
}, { | ||
text : 'Dynamic', | ||
onselect : function() { | ||
dynamic = true; | ||
reset(); | ||
} | ||
}]); | ||
|
||
//Sandcastle_End | ||
Sandcastle.finishedLoading(); | ||
} | ||
if (typeof Cesium !== "undefined") { | ||
startup(Cesium); | ||
} else if (typeof require === "function") { | ||
require(["Cesium"], startup); | ||
} | ||
</script> | ||
</body> | ||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,15 +6,17 @@ define([ | |
'../Core/destroyObject', | ||
'../Core/DeveloperError', | ||
'../Core/IndexDatatype', | ||
'./BufferUsage' | ||
'./BufferUsage', | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In order to get more 3D Tiles code into master sooner, can you open a separate pull request into master for these changes and the changes to ShaderProgram.js? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. And maybe even the changes to ShaderSource.js (and code that uses it). |
||
'./WebGLConstants' | ||
], function( | ||
defaultValue, | ||
defined, | ||
defineProperties, | ||
destroyObject, | ||
DeveloperError, | ||
IndexDatatype, | ||
BufferUsage) { | ||
BufferUsage, | ||
WebGLConstants) { | ||
"use strict"; | ||
|
||
/** | ||
|
@@ -123,7 +125,7 @@ define([ | |
|
||
return new Buffer({ | ||
context: options.context, | ||
bufferTarget: options.context._gl.ARRAY_BUFFER, | ||
bufferTarget: WebGLConstants.ARRAY_BUFFER, | ||
typedArray: options.typedArray, | ||
sizeInBytes: options.sizeInBytes, | ||
usage: options.usage | ||
|
@@ -195,7 +197,7 @@ define([ | |
var bytesPerIndex = IndexDatatype.getSizeInBytes(indexDatatype); | ||
var buffer = new Buffer({ | ||
context : context, | ||
bufferTarget : context._gl.ELEMENT_ARRAY_BUFFER, | ||
bufferTarget : WebGLConstants.ELEMENT_ARRAY_BUFFER, | ||
typedArray : options.typedArray, | ||
sizeInBytes : options.sizeInBytes, | ||
usage : options.usage | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can't we just use the cities.html example for this? Just point it to a tiles.json with i3dm tiles?