`
wjlgryx
  • 浏览: 306879 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

创建一个HTML5的3D引擎

阅读更多

我们知道三维投影平面上的点映射到一个二维,三维点定义一个对象….不幸的是,计算三维可能会是相当复杂的代码。我们怎样才能简化它?



如果我们定义平面旋转角与theta 相关,三维投影计算忽然变得简单!

任何在三维平面点可以定义为具有以下两个方程描述沿着一个椭圆的边缘点:

x = A  * cos(theta)
y = B * sin(theta)
其中A是椭圆的宽/2,B是椭圆的高/2
 
下面是平面示意图:


这种特殊的三维形状是由三横截面– 上,中,底平面组成,这些是我们遐想的所有使用的点,也是我们需要渲染的3d对象。

下面是看下HTML5的3D引擎的代码:

<style>
body {
margin:0px;
padding:0px;
}
#myCanvas {
border:2px solid #D2D2D2;
}
</style>

<script>


var canvas=null;
var c=null;
var canvasWidth=576;
var canvasHeight=400;
var t=0;

var myShape = null;

function Shape(topPlane, centerPlane, bottomPlane) {
this.topPlane=topPlane;
this.centerPlane=centerPlane;
this.bottomPlane=bottomPlane;

this.rotate = function(newTheta) {
topPlane.rotate(newTheta);
centerPlane.rotate(newTheta);
bottomPlane.rotate(newTheta);
}

this.generatePlanes = function() {
topPlane.generate();
centerPlane.generate();
bottomPlane.generate();
}
}

// This simple 3-d engine was provided by www.crazyfrom.com for the purpose of creating 3-d HTML5 renderings.
// December 20, 2010
function Plane(centerX,centerY, planeLength, planeWidth, planeTilt, planeTheta) {
this.centerX = centerX;
this.centerY = centerY;
this.planeLength = planeLength;
this.planeTheta = planeTheta;

var lastPerspectiveX = null;
var lastPerspectiveX2 = null;
var planeNextCornerAngle = 2*Math.asin(planeWidth/planeLength);

this.rotate = function(newTheta) {
planeTheta = newTheta - planeNextCornerAngle/2;
}

this.translate = function(newCenterX, newCenterY) {
centerX = newCenterX;
centerY = newCenterY;
}

this.generate = function() {
var ovalLength = planeLength;
var ovalWidth = ovalLength * planeTilt;

var perspectiveX = (ovalLength / 2) * Math.cos(planeTheta);
var perspectiveY = (ovalWidth / 2) * Math.sin(planeTheta);
var perspectiveX2 = (ovalLength / 2) * Math.cos(planeTheta + planeNextCornerAngle);
var perspectiveY2 = (ovalWidth / 2) * Math.sin(planeTheta + planeNextCornerAngle);

this.topLeftX = (perspectiveX *1) + centerX;
this.topLeftY = (perspectiveY * -1) + centerY;
this.bottomRightX = (perspectiveX*-1) + centerX;
this.bottomRightY = (perspectiveY*1) + centerY
this.topRightX = (perspectiveX2 *1) + centerX;
this.topRightY = (perspectiveY2 *-1) + centerY;
this.bottomLeftX = (perspectiveX2 *-1) + centerX;
this.bottomLeftY = (perspectiveY2 *1) + centerY;
}
}

function clearCanvas() {
canvas.width = 1;
canvas.width = canvasWidth;
}

function init () {
canvas=document.getElementById("myCanvas");
c=canvas.getContext("2d");
canvas.width = canvasWidth;
canvas.height = canvasHeight;

var topPlane = new Plane(288,150, 100,70,0.5,theta);
var centerPlane = new Plane(288,200,600,70,0.5,theta);
var bottomPlane = new Plane(288,250, 100,70,0.5,theta);

myShape = new Shape(topPlane, centerPlane, bottomPlane);

//drawScreen();

updateScreen();
}

var theta = 0; // top left

function drawScreen() {

var lineWidth = 2;

myShape.rotate(theta);
//myPlane.translate(tankX, 100);
myShape.generatePlanes();

// draw front bottom of tank
c.beginPath();
c.moveTo(myShape.centerPlane.topLeftX, myShape.centerPlane.topLeftY); // top left
c.lineTo(myShape.centerPlane.topRightX, myShape.centerPlane.topRightY); // top right
c.lineTo(myShape.bottomPlane.topRightX, myShape.bottomPlane.topRightY); // bottom right
c.lineTo(myShape.bottomPlane.topLeftX, myShape.bottomPlane.topLeftY); // bottom left
c.closePath();

c.lineJoin="round";
c.strokeStyle="black";
c.lineWidth=lineWidth;
c.stroke();
c.fillStyle="blue";
c.fill();

// draw back bottom of tank
c.beginPath();
c.moveTo(myShape.centerPlane.bottomLeftX, myShape.centerPlane.bottomLeftY); // top left
c.lineTo(myShape.centerPlane.bottomRightX, myShape.centerPlane.bottomRightY); // top right
c.lineTo(myShape.bottomPlane.bottomRightX, myShape.bottomPlane.bottomRightY); // bottom right
c.lineTo(myShape.bottomPlane.bottomLeftX, myShape.bottomPlane.bottomLeftY); // bottom left
c.closePath();

c.lineJoin="round";
c.strokeStyle="black";
c.lineWidth=lineWidth;
c.stroke();
c.fillStyle="blue";
c.fill();

// draw front top of tank
c.beginPath();
c.moveTo(myShape.topPlane.topLeftX, myShape.topPlane.topLeftY); // top left
c.lineTo(myShape.topPlane.topRightX, myShape.topPlane.topRightY); // top right
c.lineTo(myShape.centerPlane.topRightX, myShape.centerPlane.topRightY); // bottom right
c.lineTo(myShape.centerPlane.topLeftX, myShape.centerPlane.topLeftY); // bottom left
c.closePath();

c.lineJoin="round";
c.strokeStyle="black";
c.lineWidth=lineWidth;
c.stroke();
c.fillStyle="blue";
c.fill();

// draw back top of tank
c.beginPath();
c.moveTo(myShape.topPlane.bottomLeftX, myShape.topPlane.bottomLeftY); // top left
c.lineTo(myShape.topPlane.bottomRightX, myShape.topPlane.bottomRightY); // top right
c.lineTo(myShape.centerPlane.bottomRightX, myShape.centerPlane.bottomRightY); // bottom right
c.lineTo(myShape.centerPlane.bottomLeftX, myShape.centerPlane.bottomLeftY); // bottom left
c.closePath();

c.lineJoin="round";
c.strokeStyle="black";
c.lineWidth=lineWidth;
c.stroke();
c.fillStyle="blue";
c.fill();

// draw top of tank
c.beginPath();
c.moveTo(myShape.topPlane.topLeftX, myShape.topPlane.topLeftY); // top left
c.lineTo(myShape.topPlane.topRightX, myShape.topPlane.topRightY); // top right
c.lineTo(myShape.topPlane.bottomRightX, myShape.topPlane.bottomRightY); // bottom right
c.lineTo(myShape.topPlane.bottomLeftX, myShape.topPlane.bottomLeftY); // bottom left
c.closePath();

c.strokeStyle="black";
c.lineWidth=lineWidth;
c.stroke();
c.fillStyle="blue";
c.fill();

if (isRightSideOfShapeInFront(myShape)) {
// draw right of tank
c.beginPath();
c.moveTo(myShape.topPlane.topRightX, myShape.topPlane.topRightY); // front
c.lineTo(myShape.centerPlane.topRightX, myShape.centerPlane.topRightY); // front
c.lineTo(myShape.bottomPlane.topRightX, myShape.bottomPlane.topRightY); // front
c.lineTo(myShape.bottomPlane.bottomRightX, myShape.bottomPlane.bottomRightY); // back
c.lineTo(myShape.centerPlane.bottomRightX, myShape.centerPlane.bottomRightY); // back
c.lineTo(myShape.topPlane.bottomRightX, myShape.topPlane.bottomRightY); // back
c.closePath();

c.strokeStyle="black";
c.lineWidth=lineWidth;
c.stroke();
c.fillStyle="blue";
c.fill();
}
else {
// draw left of tank
c.beginPath();
c.moveTo(myShape.topPlane.topLeftX, myShape.topPlane.topLeftY); // front
c.lineTo(myShape.centerPlane.topLeftX, myShape.centerPlane.topLeftY); // front
c.lineTo(myShape.bottomPlane.topLeftX, myShape.bottomPlane.topLeftY); // front
c.lineTo(myShape.bottomPlane.bottomLeftX, myShape.bottomPlane.bottomLeftY); // back
c.lineTo(myShape.centerPlane.bottomLeftX, myShape.centerPlane.bottomLeftY); // back
c.lineTo(myShape.topPlane.bottomLeftX, myShape.topPlane.bottomLeftY); // back
c.closePath();

c.strokeStyle="black";
c.lineWidth=lineWidth;
c.stroke();
c.fillStyle="blue";
c.fill();
}

}

function isRightSideOfShapeInFront(tankObj) {
if (tankObj.topPlane.topRightY > tankObj.topPlane.topLeftY) {
return true;
}
else {
return false;
}
}

function updateScreen() {
theta += .01 ; // radians
clearCanvas();
drawScreen();
setTimeout("updateScreen()", 10);
}

function handleMouseDown(e) {
var mouseX = e.clientX;
var mouseY = e.clientY;
}

function handleMouseMove(e) {
var mouseX = e.clientX;
var mouseY = e.clientY;
}

function handleMouseUp(e) {

}

</script>

<body onload="init()">
<canvas id="myCanvas"></canvas>
</body>

可以点击下载demos

 

分享到:
评论

相关推荐

    flash 3D 引擎

    从压缩文件中的"alternativa3d_fp9"和"alternativa3d_fp10"来看,似乎这个包包含Alternativa3D的版本,它是一个流行的开源Flash 3D引擎。Alternativa3D提供了API,使得开发者可以通过ActionScript 3.0来创建3D对象、...

    基于HTML5原生WebGL实现的轻量级Google Earth三维地图引擎.zip

    而WebGL是HTML5的一个重要组成部分,它允许在浏览器中进行硬件加速的3D图形渲染,无需任何插件。这个项目显然旨在创建一个轻量级的、类似Google Earth的3D地图应用,通过WebGL技术实现在网页上展示地球的三维视图。 ...

    HTML5 游戏引擎 csdn

    CSDN(China Software Developer Network)是中国的一个知名IT社区,提供了丰富的资源和讨论区,其中包括关于HTML5游戏引擎的学习资料和技术交流。 在这些压缩包文件中,我们可以看到一些关键的组件和资源,它们是...

    完全基于FLEX的WEB3D引擎例子源码及教程.rar

    通过这个全面的教程和实例源码,开发者不仅可以深入了解基于Flex的Web3D引擎工作原理,还能掌握实际开发中的技巧和策略,为创建富有创新性和吸引力的Web3D应用打下坚实基础。无论是对新手还是有一定经验的开发者,这...

    3D游戏引擎irrlicht

    以上代码简单地展示了如何初始化Irrlicht引擎,创建一个OpenGL渲染设备,设置一个第一人称视角的相机,并在主循环中绘制场景。这只是一个基础的HelloWorld示例,实际的游戏开发中,你还需要加载模型、纹理、处理用户...

    FLASH AS3 3D引擎

    3D环绕效果的实现,则是通过对视角、投影和环境交互的精确控制,使用户仿佛置身于一个三维世界之中。 在实际应用中,Flash AS3 3D引擎常用于游戏开发、虚拟现实展示、数据可视化等多个领域。例如,它可以用于创建...

    silverlight 3d 引擎

    Babylon.js是一个被提及的文件,这可能是指一个示例项目或库,它是基于WebGL的开源3D引擎,广泛应用于HTML5环境。在Silverlight中,虽然Babylon.js本身并不直接适用,但它代表了一种现代的、跨平台的3D解决方案,...

    使用3D引擎threeJS实现星空粒子移动效果

    在实现星空粒子移动效果的场景下,Three.js可以用来创建一个包含无数小点的粒子系统,模拟出星空背景。每个粒子代表一颗星星,它们的移动可以通过JavaScript控制,并通过Three.js提供的渲染器渲染到网页中。 首先,...

    HTML5兼容电脑手机端3D翻页电子书特效.zip

    综上所述,这个压缩包提供了学习和实践HTML5、CSS3和JavaScript协同工作的机会,特别是对于那些希望创建具有视觉冲击力的3D电子书效果的开发者来说,这是一个宝贵的学习资源。通过深入研究和理解其中的代码,可以...

    【FLASH3D】开发引擎Alternativa3D_8.32.0

    Alternativa3D_8.32.0是该引擎的一个版本,包含了多个改进和新特性。版本号中的数字8.32.0代表了开发团队在不断优化和更新过程中达到的一个里程碑,这通常意味着性能提升、bug修复以及对新功能的支持。 使用...

    HTML5制作的3D相册

    另外,WebGL是HTML5中的一个强大工具,它为浏览器提供了硬件加速的3D图形渲染能力。通过WebGL,开发者可以直接在浏览器上构建复杂的3D场景,包括3D相册。虽然WebGL的学习曲线相对较陡,但它能带来更丰富的3D体验,如...

    Threejs开发指南:基于WebGL和HTML5在网页上渲染3D图形和动画.docx

    首先,Threejs 是一款基于 WebGL 技术的 3D 图形和动画引擎,可以帮助开发者在网页上快速创建和呈现 3D 场景。它提供了一系列的 API,使得开发者可以通过简单的代码实现复杂的 3D 效果,而无需对 WebGL 编程有深入的...

    基于Canvas的HTML5游戏引擎.zip

    "基于Canvas的HTML5游戏引擎.zip"这个压缩包可能包含了一个名为CanJS-master的项目或库,CanJS是一个流行的JavaScript库,虽然通常它不是专门针对游戏开发的,但其组件化和事件驱动的特性使得它在某些情况下可以用于...

    HTML5实现3D樱花飘落搜索引擎背景特效.zip

    在这个“HTML5实现3D樱花飘落搜索引擎背景特效”的项目中,我们将深入探讨如何利用HTML5的特性来构建一个具有3D樱花飘落效果的搜索引擎背景。 首先,3D效果在HTML5中主要通过CSS3的3D变换和WebGL技术来实现。CSS3的...

    HTML5 3D相册(图片街)

    本项目“HTML5 3D相册(图片街)”是一个创新的应用实例,展示了HTML5如何用来构建交互式的、具有立体效果的图片展示平台,宛如一个3D的图片街道,给用户带来独特的浏览体验。 1. **HTML5 Canvas**: 3D相册的核心是...

    html5 3d拳王游戏制作3D拳击游戏源码下载

    "HTML5 3D拳王游戏制作3D拳击游戏源码下载"是一个与游戏开发相关的资源,它提供了使用HTML5技术制作的一款3D拳击游戏的源代码。这个资源对于想要学习或者研究HTML5游戏开发,特别是3D游戏开发的开发者来说是非常宝贵...

    three.js(r108)前端web3d引擎 20190930更新

    【标题】"three.js(r108)前端Web3D引擎 20190930更新"指的是一个特定版本的three.js库,这是在2019年9月30日更新到r108版本的前端3D渲染引擎。three.js是JavaScript的一个开源库,专门用于在Web浏览器中创建和展示3D...

    3D模型导入 CanvasMatrix.js引擎 demo(一)

    这是一个基于HTML5 Canvas的3D图形渲染引擎,利用WebGL技术,能够在浏览器中创建高性能的3D场景。WebGL是一种JavaScript API,它允许在浏览器内进行硬件加速的三维图形渲染,无需任何插件。CanvasMatrix.js简化了...

Global site tag (gtag.js) - Google Analytics