使用 Android 和 Intel XDK 探索 Three.js





5.00/5 (5投票s)
使用 Intel XDK 和 three.js 的 Android 应用 文章 #3
介绍
本文将介绍如何使用 Intel XDK 和 three.js 开发 Android 应用。它将概述如何使用这个强大的工具为 Android 架构开发基于 GUI 的应用。
背景
对 Android 平台比较陌生
在过去的 15 个月里,我一直在为 Windows 桌面开发应用,所以我对 Android 平台非常陌生。因此,当我探索(对我而言)未知的 Android 世界时,这次经历对我来说是新的。我将涵盖的内容可能不是新鲜事物,但我已经尝试了。
我为什么选择 Intel XDK
我对 HTML 了解不多,我希望使用一个 IDE,我可以在其中运用我的 HTML 技能。整个 IDE 体验对我来说是全新的,因为我以前从未用过 Intel XDK。它是一个基于云的 IDE,在创建分发包的整个过程中,您需要始终连接到互联网。Intel XDK 的**优点**在于您无需配置 Android ADT bundle,并且它内置了模拟器来测试您的应用。在这里,您可以选择不同的设备外形,例如 Google Nexus 4、Google Nexus 7、联想 K900 等。我发现的**缺点**是,如果您长时间使用 IDE,它有时会冻结。这时我不得不重启 IDE,然后重新开始我的工作。*总的来说,我使用 Intel XDK 的体验很好,因为我在开发应用时遇到的麻烦很少。*
探索 Three.js
Three.js!事实上,当我搜索网上的一些基于处理的示例时,我发现了它。它本质上是另一个创意编码者的乐趣(http://threejs.org/),它拥有大量由 WebGL 驱动的选项,它在创建精美的 GUI 应用和享受乐趣方面非常有帮助。它是开源的,有大量的示例可供使用。现在有一个问题,当您为 Android 开发时,并非所有浏览器都支持 WebGL。在这种情况下,您需要做的是使用 Canvas 渲染器,这样您就可以继续进行。
什么是 Intel XDK?
Intel XDK 是一个跨平台 IDE,用于在开发环境中开发强大的 HTML 5 应用,并且在连接互联网的情况下可以更新您的代码。构建应用后,您可以将其分发到不同的平台。Android 应用也可以用同样的方式创建,在构建选项中您可以创建 apk。这个 IDE 能够一次编写代码,然后分发到不同的平台。在新的更新的 XDK 中,有一个适用于 Android 的 CROSSWALK 构建选项,目前处于 Beta 阶段,它有助于移植您的原生功能 HTML 5、JavaScript 和 CSS 3 应用。在开发阶段,您可以使用模拟器测试不同外形设备的应用程序。总而言之,这是一个开发 HTML 5 应用并进行分发的绝佳平台
下载链接 http://xdk-software.intel.com/index.html
带图的 Intel XDK 下载分步过程
下一步将检测您的操作系统
保存文件,exe 文件将被保存。按照以下步骤进行安装和启动 exe
下面显示了 Intel XDK 和 Android 项目的项目生命周期
打开 Intel XDK 后,您将看到一个启动新项目的选项。您可以在此处从空白模板开始,也可以重新使用任何演示并对其进行修改。可用的选项有:
- i) 从空白项目开始
- ii) 使用演示
- iii) 导入现有应用:- 您可以在此处移植使用 XDK、PhoneGap 应用、AppMob 应用、HTML 5 API 应用制作的旧应用,但不能移植 Java 应用。
- iv) 使用 App Starter 它使用 App Framework 2.0。完整详情请访问http://app-framework-software.intel.com/
- v) 从 App Designer 开始 App Designer 允许您使用 App Framework、BootStrap API、jQuery Mobile 或 Top Coat 开始项目。
由于我们的目标是 Three.js,我们将使用演示,特别是 Cross Walk 演示,并通过在 index.html 文件中插入其他代码并添加所需的 three.js 文件来修改演示。Intel 网站上有一个很好的信息,解释并概述了 CrossWalk 运行时http://software.intel.com/en-us/html5/articles/crosswalk-application-runtime
什么是 Three.js?
Three.js 是一个库,可以非常轻松地在浏览器中实现 WebGL - 3D。虽然用原始 WebGL 创建一个简单的立方体需要数百行 JavaScript 和着色器代码,但 Three.js 的等效代码只有其中一小部分。**Three.js** 是一个轻量级的跨浏览器JavaScript 库/ API,用于在Web 浏览器上创建和显示动画3D 计算机图形。Three.js 脚本可以与 HTML5 canvas 元素、SVG 或 WebGL 一起使用
从头开始
**解码****GITHUB 上的示例并创建一个新的 apk。Three.js 的创始人做得非常出色,所有功劳归于他们,我正在使用其中一个示例来开始。** **https://github.com/mrdoob/three.js/blob/master/examples/canvas_interactive_voxelpainter.html** **
- 打开 Intel XDK
- 点击项目
- 点击启动新项目
点击使用演示
选择 CrossWalk 并点击下一步
点击创建。项目创建后,您将收到一条祝贺消息。
根据您的喜好修改 index.html 页面,它将反映应用的主要更改,并且
还要添加所需的 JavaScript。
根据您的喜好修改 index.html 页面,它将反映应用的主要更改,并添加所需的 Three.js JavaScript。
近距离查看 index.html 页面
根据链接:http://aerotwist.com/tutorials/getting-started-with-three-js/
我根据以下描述创建了 index.html 页面的流程,并将在下面进行说明。
让我们看看 Intel XDK 中 index.html 文件的流程
在修改 index.html 文件并向 threejs 文件夹添加所需的 js 文件后(您需要
从项目的 Windows 目录结构访问文件,然后手动添加文件。在我的例子中,我将文件手动添加到主项目文件夹E:\IntelXDK_Projects\eXAMPLE2\threejs),然后需要点击模拟(您可以从许多可用的模拟器中选择来检查项目)。
构建过程
这是创建 apk 的主要操作。构建菜单提供了将应用分发到多个平台的所有选项。您可以在此处编辑要添加到应用中的资源和图像。对于 Android,有两个选项:
- Android:- 您可以创建可以分发的普通 APK...
- Android 的 CrossWalk(它处于 Beta 阶段):- 这是一个构建,用于创建一个 CrossWalk 运行时 Android APK,您可以在其中选择为 ARM 设备或 X86 架构进行构建。
带图的构建过程
您会看到构建即将完成。您需要点击立即构建应用。
下一张图显示了构建过程
您将收到一条构建成功的消息
整个应用开发过程的改变都发生在 index.html 页面上。在此处的任何更新都会反映更改,并且整个流程都会改变。修改 index.html 页面并包含必要的 Three.js 文件。调整 GITHUB 中的代码将帮助您进行探索。还有一个 CROSSWALK 构建,允许以 x86 或 ARM 架构创建包,它处于 Beta 阶段,但您可以尝试此构建。
根据链接:- http://aerotwist.com/tutorials/getting-started-with-three-js/
我使用了描述,并以如何在 Intel XDK 中用于创建 Android 应用的方式进行了展示。
index.html 页面的结构(创建新项目)
对 index.html 所做的任何更改都会反映应用最终的外观。因此,我们需要包含必要的 Three.js 文件,并且整个逻辑都需要在此实现。我深入研究了 three.js GITHUB 存储库,并检查了可以使用的示例,然后将其引入 Intel XDK 并最终从中生成 apk。所以我所做的是分解 index.html 页面及其修改,以提供项目的正确视图。*在学习的背景下,我从 https://github.com/mrdoob/three.js/ 存储库中获得了帮助。它在探索 three.js 方面非常有用。这个库的主要贡献者是 Mr Droob https://github.com/mrdoob 和 theo-armour https://github.com/theo-armour。向这些人致以崇高的敬意(他们在 Three.js 现在的样子方面做得非常出色)*我正在探索这些存储库以进行学习、分享和贡献。
让我们开始吧
为了更好地兼容不同的移动平台,我们需要声明 viewport,并设置 device-width height。
设备宽度允许根据不断变化的设备进行调整,无论是平板电脑还是不同模式的手机。
声明
<meta name="viewport" width, user-scalable=no, minimum-scale=1.0, max content="width=device-imum-scale=1.0">
这也意味着当我们改变设备的朝向时,它能提供对应用的正确访问
样式标签
样式标签允许控制应用在设备上的渲染方式。这是显示应用外观的修改。因此,现在对于这个项目,我们将相应地修改样式标签
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
为了方便重新加载,避免反复重新加载页面,我们将 three.min.js 包含在 html 的 head 标签中,并将脚本包含在 script 标签中。
<script></script>
当我们把 three.js 脚本标签包含在 body 中时,我们就允许重要的操作在 three.min.js 脚本中执行。这里是实现 three.js 的逻辑所在,因此我们需要将其包含在 head 标签中。
现在轮到初始化变量,或者实现 3D GUI 结构的行为方式,我们实现诸如对象移动、交互、靠近对象或移出对象等动画,我们通过调用 init() 方法开始。
在 three.js 脚本的入口点,我们需要附加元素和子行为。为了使 Geometry 生效,我们需要在此处实现变量及其实现逻辑。
当我们看到 Three.js 脚本时,我们发现它本质上是涉及 3D GUI 描绘的:
- 场景
- 摄像头
- 投影仪
- 渲染器和对象。
Three.js 脚本中的一些修改允许实现平面 Geometry 到法线,我们使用 var normalMatrix= new Three.Matrix3();
要创建相机透视的阴影效果,我们使用此
camera= new THREE.perspectiveCamera();
修改自定义网格涉及 Geometry 的更改,因此我们执行以下操作:
var size = 500, step = 50;
var geometry = new THREE.Geometry();
for ( var i = - size; i <= size; i += step ) {
geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
geometry.vertices.push( new THREE.Vector3( size, 0, i ) );
geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
geometry.vertices.push( new THREE.Vector3( i, 0, size ) );
}
var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } );
var line = new THREE.Line( geometry, material );
line.type = THREE.LinePieces;
scene.add( line );
我们使用投影仪来改变对象的行为,并实现鼠标移动和选择特定对象。这也有助于在屏幕空间中进行投影。
这里的代码行控制着光线反射和环境光效果。这也显示了灯光效果会是什么样的。
//
// var ambientLight = new THREE.AmbientLight( 0x606060 );
//
查看变量声明
target=new THREE.Vector3(0,200,0);
在上面的声明中,我们声明了一个 3D 向量。3D 向量通常是一个具有大小和方向的几何量。
var normalMatrix=new THREE.Matrix 3();
这是一个 3*3 矩阵。
为了投影目的,我们使用鼠标 2D 和鼠标 3D。
更多修改和整个 html 代码如下所示,它创建了一个网格,您可以放置方块并进行设计。这是摘录自 https://github.com/mrdoob/three.js/ 的修改。
<!DOCTYPE html>
<html lang="en">
<head>
<title>three.js canvas - interactive - voxel painter</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
<style>
body {
font-family: Monospace;
background-color: #f0f0f0;
margin: 0px;
overflow: hidden;
}
</style>
</head>
<body>
<script src="../build/three.min.js"></script>
<script src="js/libs/stats.min.js"></script>
<script>
var container, stats;
var camera, scene, renderer;
var projector, plane;
var mouse2D, mouse3D, raycaster, theta = 45,
isShiftDown = false, isCtrlDown = false,
target = new THREE.Vector3( 0, 200, 0 );
var normalMatrix = new THREE.Matrix3();
var ROLLOVERED;
init();
animate();
function init() {
container = document.createElement( 'div' );
document.body.appendChild( container );
var info = document.createElement( 'div' );
info.style.position = 'absolute';
info.style.top = '10px';
info.style.width = '100%';
info.style.textAlign = 'center';
info.innerHTML = '<a href="http://threejs.org" target="_blank">three.js</a> - voxel painter<br><strong>click</strong>: add voxel, <strong>control + click</strong>: remove voxel, <strong>shift</strong>: rotate, <a href="javascript:save()">save .png</a>';
container.appendChild( info );
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 );
camera.position.y = 800;
scene = new THREE.Scene();
// Grid
var size = 500, step = 50;
var geometry = new THREE.Geometry();
for ( var i = - size; i <= size; i += step ) {
geometry.vertices.push( new THREE.Vector3( - size, 0, i ) );
geometry.vertices.push( new THREE.Vector3( size, 0, i ) );
geometry.vertices.push( new THREE.Vector3( i, 0, - size ) );
geometry.vertices.push( new THREE.Vector3( i, 0, size ) );
}
var material = new THREE.LineBasicMaterial( { color: 0x000000, opacity: 0.2 } );
var line = new THREE.Line( geometry, material );
line.type = THREE.LinePieces;
scene.add( line );
//
projector = new THREE.Projector();
plane = new THREE.Mesh( new THREE.PlaneGeometry( 1000, 1000 ), new THREE.MeshBasicMaterial() );
plane.rotation.x = - Math.PI / 2;
plane.visible = false;
scene.add( plane );
mouse2D = new THREE.Vector3( 0, 10000, 0.5 );
// Lights
var ambientLight = new THREE.AmbientLight( 0x606060 );
scene.add( ambientLight );
var directionalLight = new THREE.DirectionalLight( 0xffffff );
directionalLight.position.x = Math.random() - 0.5;
directionalLight.position.y = Math.random() - 0.5;
directionalLight.position.z = Math.random() - 0.5;
directionalLight.position.normalize();
scene.add( directionalLight );
var directionalLight = new THREE.DirectionalLight( 0x808080 );
directionalLight.position.x = Math.random() - 0.5;
directionalLight.position.y = Math.random() - 0.5;
directionalLight.position.z = Math.random() - 0.5;
directionalLight.position.normalize();
scene.add( directionalLight );
renderer = new THREE.CanvasRenderer();
renderer.setSize( window.innerWidth, window.innerHeight );
container.appendChild(renderer.domElement);
stats = new Stats();
stats.domElement.style.position = 'absolute';
stats.domElement.style.top = '0px';
container.appendChild( stats.domElement );
document.addEventListener( 'mousemove', onDocumentMouseMove, false );
document.addEventListener( 'mousedown', onDocumentMouseDown, false );
document.addEventListener( 'keydown', onDocumentKeyDown, false );
document.addEventListener( 'keyup', onDocumentKeyUp, false );
//
window.addEventListener( 'resize', onWindowResize, false );
}
function onWindowResize() {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize( window.innerWidth, window.innerHeight );
}
function onDocumentMouseMove( event ) {
event.preventDefault();
mouse2D.x = ( event.clientX / window.innerWidth ) * 2 - 1;
mouse2D.y = - ( event.clientY / window.innerHeight ) * 2 + 1;
var intersects = raycaster.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
if ( ROLLOVERED ) ROLLOVERED.color.setHex( 0x00ff80 );
ROLLOVERED = intersects[ 0 ].face;
ROLLOVERED.color.setHex( 0xff8000 )
}
}
function onDocumentMouseDown( event ) {
event.preventDefault();
var intersects = raycaster.intersectObjects( scene.children );
if ( intersects.length > 0 ) {
var intersect = intersects[ 0 ];
if ( isCtrlDown ) {
if ( intersect.object != plane ) {
scene.remove( intersect.object );
}
} else {
normalMatrix.getNormalMatrix( intersect.object.matrixWorld );
var normal = intersect.face.normal.clone();
normal.applyMatrix3( normalMatrix ).normalize();
var position = new THREE.Vector3().addVectors( intersect.point, normal );
var geometry = new THREE.CubeGeometry( 50, 50, 50 );
for ( var i = 0; i < geometry.faces.length; i ++ ) {
geometry.faces[ i ].color.setHex( 0x00ff80 );
}
var material = new THREE.MeshLambertMaterial( { vertexColors: THREE.FaceColors } );
var voxel = new THREE.Mesh( geometry, material );
voxel.position.x = Math.floor( position.x / 50 ) * 50 + 25;
voxel.position.y = Math.floor( position.y / 50 ) * 50 + 25;
voxel.position.z = Math.floor( position.z / 50 ) * 50 + 25;
voxel.matrixAutoUpdate = false;
voxel.updateMatrix();
scene.add( voxel );
}
}
}
function onDocumentKeyDown( event ) {
switch( event.keyCode ) {
case 16: isShiftDown = true; break;
case 17: isCtrlDown = true; break;
}
}
function onDocumentKeyUp( event ) {
switch( event.keyCode ) {
case 16: isShiftDown = false; break;
case 17: isCtrlDown = false; break;
}
}
function save() {
window.open( renderer.domElement.toDataURL('image/png'), 'mywindow' );
return false;
}
//
function animate() {
requestAnimationFrame( animate );
render();
stats.update();
}
function render() {
if ( isShiftDown ) {
theta += mouse2D.x * 3;
}
camera.position.x = 1400 * Math.sin( theta * Math.PI / 360 );
camera.position.z = 1400 * Math.cos( theta * Math.PI / 360 );
camera.lookAt( target );
raycaster = projector.pickingRay( mouse2D.clone(), camera );
renderer.render( scene, camera );
}
</script>
</body>
</html>
项目在模拟器中的外观
实验后,我们发现向 index.html 添加简单的修改并添加所需的 three.js 文件可以为您提供一些您可以在项目中使用得很酷的 GUI 效果。
- three.js 的可能性是无限的,您也可以用它来开发游戏。
- Three.js 是一个出色的 WebGL 工具,可帮助您以创新的方式探索 3D GUI 应用程序。
现在,当您结合 Intel XDK IDE 时,您可以用它创建一些很棒的 APK。
Nexus7 模拟器图片
本文旨在展示如何使用 Intel XDK IDE 开发基于 WebGL 的精美 GUI Android 应用 Three.js。整个项目过程需要互联网连接。随着我学习的深入,我将尝试做出更多贡献。Three.js 的 GITHUB 存储库https://github.com/mrdoob/three.js 检查示例并进行实验。我喜欢调整代码。
参考文献
- http://aerotwist.com/tutorials/getting-started-with-three-js/
- http://threejs.org/docs/
- http://xdk-software.intel.com/
- http://learningthreejs.com/
- http://code.tutsplus.com/tutorials/webgl-with-threejs-basics--net-35688
- http://blog.teamtreehouse.com/the-beginners-guide-to-three-js
- http://www.johannes-raida.de/tutorials/three.js/tutorial02/tutorial02.htm
- http://en.wikipedia.org/wiki/Main_Page
- https://github.com/mrdoob/three.js/
优质资源
您将在 StackOverflow 上关于 Three.js 的问题中了解到很多东西,并获得良好的知识。
http://stackoverflow.com/search?q=Three.js
Intel XDK 文档
http://software.intel.com/en-us/html5/articles/xdkdocs
Three.js 文档
关注点
我花了大量时间学习 three.js 和 Intel XDK,这是我分享所学知识的唯一机会,因此写了这篇文章。Intel XDK 是一个非常有用的工具,用于为 Android 和其他架构构建 HTML 5 应用。Intel 还包含一个用于创建 WebGL 基于 Android 项目和其他针对 Android 的构建的 CrossWalk Android Beta 构建。
历史
第一篇文章已更新代码和 APK