天堂国产午夜亚洲专区-少妇人妻综合久久蜜臀-国产成人户外露出视频在线-国产91传媒一区二区三区

當前位置:主頁 > 論文百科 > 英文數據庫 >

unity webgl 手機 demo_webgl的坑_《webgl入門指南》的學習筆記一three.js與sim.js

發(fā)布時間:2016-08-22 19:22

  本文關鍵詞:WebGL入門指南,由筆耕文化傳播整理發(fā)布。


最近又一次很久木有更新博客了,但是不是停了,而是一次性更新了太多,想清楚了自己水平有限,不想誤導大家,所以就把這里單純的當做自己的學習筆記。

上次讓立方體轉起來了,這次我們就直接介紹一個框架《WebGL入門指南》的sim.js 這個東西是什么玩意呢,,就是一個模擬器(官方說法),實際上就是簡化了three.js里面的各種初始化,比如設置渲染器,循環(huán)重繪,處理DOM事件,基本的層級(層次模型)操作,作者沒有對這個進行詳解,只是說了,一句代碼很易讀,的確很易讀,唯一的缺點就是,真有人不懂,比如我,現在看了《webgl編程指南》還好點,以后也會把《webgl編程指南的讀書筆記貼出來,和大家交流下,這次貼的只是部分注釋,關于dom操作的沒有寫,因為大家應該都比我懂,


// Sim.js - A Simple Simulator for WebGL (based on Three.js)Sim = {};//空對象,用來構建后續(xù)的框架// Sim.Publisher - base class for event publishers// 以下為一個訂閱者模式的基類,也稱為觀察者模式,是幾乎sim.js對象的基類Sim.Publisher = function() {//Publisher的構造函數 this.messageTypes = {};//構造函數的屬性}Sim.Publisher.prototype.subscribe = function(message, subscriber, callback) {//Publisher的原型方法 var subscribers = this.messageTypes[message]; if (subscribers) { if (this.findSubscriber(subscribers, subscriber) != -1)//若是在數組里面找到了,說明之前注冊了,直接退出 { return; } } else { subscribers = []; this.messageTypes[message] = subscribers; } subscribers.push({ subscriber : subscriber, callback : callback });//這句才是這個函數的關鍵,將訂閱的函數 //以及回調函數壓入subscribers這個棧}Sim.Publisher.prototype.unsubscribe = function(message, subscriber, callback) { if (subscriber) { var subscribers = this.messageTypes[message]; if (subscribers) { var i = this.findSubscriber(subscribers, subscriber, callback);//為何這里是三個參數 //下面定義的明明是兩個參數 //js對傳入的參數無所謂? //解決:的確無所謂,js都傳入的參數個數無所謂 //對于多了的參數自動忽略,但不能使未定義的參數 //對于少傳了參數的函數也能運行,只是這個參數默認為未定義 if (i != -1) { this.messageTypes[message].splice(i, 1);//從數組中刪除該 } } } else { delete this.messageTypes[message]; }}Sim.Publisher.prototype.publish = function(message) { var subscribers = this.messageTypes[message]; if (subscribers) { for (var i = 0; i < subscribers.length; i++) { var args = []; for (var j = 0; j < arguments.length - 1; j++)//這里的arguments到底是從哪里來的argument屬于誰? //為什么不直接傳入到下面的apply中?作用域問題? { args.push(arguments[j + 1]);//這里為什么要+1?? } // subscribers[i].callback.apply(subscribers[i].subscriber, args);//什么意思? //subcribers里面的回調函數被執(zhí)行同時傳入參數 ,apply是調用函數 第一個參數為callback的作用域 //第二個是傳入的參數數組(js的參數列表本身就是一個“類似數組”) } }}Sim.Publisher.prototype.findSubscriber = function (subscribers, subscriber) {//找到指定索引的位置 for (var i = 0; i < subscribers.length; i++) { if (subscribers[i] == subscriber) { return i; } } return -1;}// Sim.App - application class (singleton)這里是個單體模式???????不懂//這里不是標準的單體設計模式 Sim.App = function(){ Sim.Publisher.call(this); this.renderer = null; //入口在Sim.App.prototype.init this.scene = null; //入口在Sim.App.prototype.init this.camera = null; //入口在Sim.App.prototype.init this.objects = []; //入口在Sim.App.prototype.addObject}Sim.App.prototype = new Sim.Publisher;//這里和前面的call一起,采用的是組合繼承模式,(還有一種是采用three.js //的方法,Object.create();)但是這里的new會出現兩個問題, //1.call已經繼承了實例對象的屬性,但是這里Sim.App.prototype不但繼承了原型對象對象 //還再次繼承了實例對象 //2.這里的Sim.App的construtor直接指向了Sim.Publisher 會造成原型鏈紊亂 //解決方案:使用寄生組合繼承. 詳見javascript高級程序設計E3 6.3.6 以及阮一峰博客 = function(param)//初始化,this會被綁定{ param = param || {}; var container = param.container; var canvas = param.canvas; // Create the Three.js renderer, add it to our div var renderer = new THREE.WebGLRenderer( { antialias: true, canvas: canvas } ); renderer.setSize(container.offsetWidth, container.offsetHeight); container.appendChild( renderer.domElement ); // Create a new Three.js scene var scene = new THREE.Scene(); scene.add( new THREE.AmbientLight( 0x505050 ) ); scene.data = this; // Put in a camera at a good default location camera = new THREE.PerspectiveCamera( 45, container.offsetWidth / container.offsetHeight, 1, 10000 ); camera.position.set( 0, 0, 3.3333 ); scene.add(camera); // Create a root object to contain all other scene objects var root = new THREE.Object3D(); scene.add(root); // Create a projector to handle picking var projector = new THREE.Projector(); // Save away a few things那么問題來了,這里的this是指的哪里的this????作用域是整個Sim.App //還是Sim.App下面的 ??? //問題解決:首先是尋找自己作用域(原型函數)下面的,然后是自己所在構造函數下面的 //然后再是父類,依次尋找。 //對于其他原型函數里面的,只有綁定到了實例對象 里面以后才行也就是說那個原型函數必須調用后 //里面的this.XX 屬性才能被其他prototype 調用/*如下圖所示 ** 所在位置 若出現this.** 其依次搜尋位置優(yōu)先級依次為為12345 所用繼承方式為 為寄生組合繼承 |super| / / / | / |5構造| | |3原型| | |sub| / | / / | / |4構造| | |1 原型a 屬性**| | |2原型b|*///由于原型函數下的init()會被調用用來初始化,所以以下屬性在APP全局可被引用,無論,構造對象下,還是原型對象//那么問題來了???? 既然絕對會用為何不直接聲明在sim.APP下面?? this.container = container; this.renderer = renderer; this.scene = scene; this.camera = camera; this.projector = projector; this.root = root; //可被渲染的object3D存在這里 // Set up event handlers this.initMouse(); this.initKeyboard(); this.addDomHandlers();}//Core run loop循環(huán)Sim.App.prototype.run = function()//this會被綁定{ this.update(); //Sim.App下的原型對象,可以調用其他原型對象? 調用自己所在的構造函數下的原型函數,?????? //問題解決:這個run()會在后期調用,自己會被綁定到this上面,所以可以 this.renderer.render( this.scene, this.camera );//這里的兩個this和上面一個道理 var that = this; requestAnimationFrame(function() { that.run(); }); }// Update method - called once per tickSim.App.prototype.update = function()//這個在App原型對象里面的run()里面調用 ??問題:同一個對象下面的原型函數可以互相調用?? //問題解決:同一個對象下面的原型函數的確可以互相調用,就像這里的run()可以調用update(){ var i, len; len = this.objects.length; for (i = 0; i < len; i++) { this.objects[i].update();//這里的update什么意思?從哪里來的? //問題解決:這里的update是object自帶的;object來自繼承Sim.Object }}// Add/remove objects//以下是this.object的入口Sim.App.prototype.addObject = function(obj)//因為前面的scene camera renderer全部在原型對象的init里面初始化了, //所以這里主要是mesh { this.objects.push(obj); // If this is a renderable object, add it to the root scene //若從obj里面檢查到object3D說明其可被渲染 if (obj.object3D) { this.root.add(obj.object3D); }}Sim.App.prototype.removeObject = function(obj){ var index = this.objects.indexOf(obj); if (index != -1) { this.objects.splice(index, 1);//刪除object[]中的元素 // If this is a renderable object, remove it from the root scene if (obj.object3D) { this.root.remove(obj.object3D);//這里的this屬于原型調用原型 } }}// Event handlingSim.App.prototype.initMouse = function(){ var dom = this.renderer.domElement; var that = this; //添加鼠標移動的事件 dom.addEventListener( 'mousemove', function(e) { that.onDocumentMouseMove(e); }, false ); //添加鼠標按下的事件 dom.addEventListener( 'mousedown', function(e) { that.onDocumentMouseDown(e); }, false ); //添加鼠標彈起的事件 dom.addEventListener( 'mouseup', function(e) { that.onDocumentMouseUp(e); }, false ); //中鍵滑輪?? $(dom).mousewheel( function(e, delta) { that.onDocumentMouseScroll(e, delta); } ); this.overObject = null; this.clickedObject = null;}Sim.App.prototype.initKeyboard = function(){ var dom = this.renderer.domElement; var that = this; dom.addEventListener( 'keydown', function(e) { that.onKeyDown(e); }, false ); dom.addEventListener( 'keyup', function(e) { that.onKeyUp(e); }, false ); dom.addEventListener( 'keypress', function(e) { that.onKeyPress(e); }, false ); // so it can take focus dom.setAttribute("tabindex", 1); dom.style.outline='none';}Sim.App.prototype.addDomHandlers = function(){ var that = this; window.addEventListener( 'resize', function(event) { that.onWindowResize(event); }, false );}Sim.App.prototype.onDocumentMouseMove = function(event){ event.preventDefault(); if (this.clickedObject && this.clickedObject.handleMouseMove) { var hitpoint = null, hitnormal = null; var intersected = this.objectFromMouse(event.pageX, event.pageY); if (intersected.object == this.clickedObject) { hitpoint = intersected.point; hitnormal = intersected.normal; } this.clickedObject.handleMouseMove(event.pageX, event.pageY, hitpoint, hitnormal); } else { var handled = false; var oldObj = this.overObject; var intersected = this.objectFromMouse(event.pageX, event.pageY); this.overObject = intersected.object; if (this.overObject != oldObj) { if (oldObj) { this.container.style.cursor = 'auto'; if (oldObj.handleMouseOut) { oldObj.handleMouseOut(event.pageX, event.pageY); } } if (this.overObject) { if (this.overObject.overCursor) { this.container.style.cursor = this.overObject.overCursor; } if (this.overObject.handleMouseOver) { this.overObject.handleMouseOver(event.pageX, event.pageY); } } handled = true; } if (!handled && this.handleMouseMove) { this.handleMouseMove(event.pageX, event.pageY); } }}Sim.App.prototype.onDocumentMouseDown = function(event){ event.preventDefault();//阻止元素默認動作,好用來執(zhí)行以下代碼 var handled = false; var intersected = this.objectFromMouse(event.pageX, event.pageY); if (intersected.object) { if (intersected.object.handleMouseDown) { intersected.object.handleMouseDown(event.pageX, event.pageY, intersected.point, intersected.normal); this.clickedObject = intersected.object; handled = true; } } if (!handled && this.handleMouseDown) { this.handleMouseDown(event.pageX, event.pageY); }}Sim.App.prototype.onDocumentMouseUp = function(event){ event.preventDefault(); var handled = false; var intersected = this.objectFromMouse(event.pageX, event.pageY); if (intersected.object) { if (intersected.object.handleMouseUp) { intersected.object.handleMouseUp(event.pageX, event.pageY, intersected.point, intersected.normal); handled = true; } } if (!handled && this.handleMouseUp) { this.handleMouseUp(event.pageX, event.pageY); } this.clickedObject = null;}Sim.App.prototype.onDocumentMouseScroll = function(event, delta){ event.preventDefault(); if (this.handleMouseScroll) { this.handleMouseScroll(delta); }}Sim.App.prototype.objectFromMouse = function(pagex, pagey){ // Translate page coords to element coords var offset = $(this.renderer.domElement).offset(); var eltx = pagex - offset.left; var elty = pagey - offset.top; // Translate client coords into viewport x,y var vpx = ( eltx / this.container.offsetWidth ) * 2 - 1; var vpy = - ( elty / this.container.offsetHeight ) * 2 + 1; var vector = new THREE.Vector3( vpx, vpy, 0.5 ); this.projector.unprojectVector( vector, this.camera ); var ray = new THREE.Ray( this.camera.position, vector.subSelf( this.camera.position ).normalize() ); var intersects = ray.intersectScene( this.scene ); if ( intersects.length > 0 ) { var i = 0; while(!intersects[i].object.visible) { i++; } var intersected = intersects[i]; var mat = new THREE.Matrix4().getInverse(intersected.object.matrixWorld); var point = mat.multiplyVector3(intersected.point); return (this.findObjectFromIntersected(intersected.object, intersected.point, intersected.face.normal)); } else { return { object : null, point : null, normal : null }; }}Sim.App.prototype.findObjectFromIntersected = function(object, point, normal){ if (object.data) { return { object: object.data, point: point, normal: normal }; } else if (object.parent) { return this.findObjectFromIntersected(object.parent, point, normal); } else { return { object : null, point : null, normal : null }; }}Sim.App.prototype.onKeyDown = function(event){ // N.B.: Chrome doesn't deliver keyPress if we don't bubble... keep an eye on this event.preventDefault(); if (this.handleKeyDown) { this.handleKeyDown(event.keyCode, event.charCode); }}Sim.App.prototype.onKeyUp = function(event){ // N.B.: Chrome doesn't deliver keyPress if we don't bubble... keep an eye on this event.preventDefault(); if (this.handleKeyUp) { this.handleKeyUp(event.keyCode, event.charCode); }} Sim.App.prototype.onKeyPress = function(event){ // N.B.: Chrome doesn't deliver keyPress if we don't bubble... keep an eye on this event.preventDefault(); if (this.handleKeyPress) { this.handleKeyPress(event.keyCode, event.charCode); }}Sim.App.prototype.onWindowResize = function(event) { this.renderer.setSize(this.container.offsetWidth, this.container.offsetHeight); this.camera.aspect = this.container.offsetWidth / this.container.offsetHeight; this.camera.updateProjectionMatrix();}Sim.App.prototype.focus = function(){ if (this.renderer && this.renderer.domElement) { this.renderer.domElement.focus(); }}// Sim.Object - base class for all objects in our simulationSim.Object = function(){ Sim.Publisher.call(this); this.object3D = null; //入口在Sim.Object.prototype.setObject3D this.children = []; //入口在Sim.Object.prototype.addChild}Sim.Object.prototype = new Sim.Publisher;Sim.Object.prototype.init = function(){}Sim.Object.prototype.update = function() //那么現在大問題來了有兩個Sim.Object.prototype.update{ this.updateChildren();}// setPosition - move the object to a new positionSim.Object.prototype.setPosition = function(x, y, z){ if (this.object3D) { this.object3D.position.set(x, y, z); }}//setScale - scale the objectSim.Object.prototype.setScale = function(x, y, z){ if (this.object3D) { this.object3D.scale.set(x, y, z); }}//setScale - scale the objectSim.Object.prototype.setVisible = function(visible){ function setVisible(obj, visible) { obj.visible = visible; var i, len = obj.children.length; for (i = 0; i < len; i++) { setVisible(obj.children[i], visible); } } if (this.object3D) { setVisible(this.object3D, visible); }}// updateChildren - update all child objectsSim.Object.prototype.update = function() //那么現在大問題來了有兩個Sim.Object.prototype.update{ var i, len; len = this.children.length; for (i = 0; i < len; i++) { this.children[i].update(); }}Sim.Object.prototype.setObject3D = function(object3D){ object3D.data = this; //原型對象中的this,到底指的是那個this?到底是Sim.Object還是Sim.Object.prototype.setObject3D //解決:經試驗是Sim.Object的this this.object3D = object3D;}//Add/remove childrenSim.Object.prototype.addChild = function(child){ this.children.push(child); // If this is a renderable object, add its object3D as a child of mine if (child.object3D) { this.object3D.add(child.object3D); }}Sim.Object.prototype.removeChild = function(child){ var index = this.children.indexOf(child); if (index != -1) { this.children.splice(index, 1); // If this is a renderable object, remove its object3D as a child of mine if (child.object3D) { this.object3D.remove(child.object3D); } }}// Some utility methodsSim.Object.prototype.getScene = function(){ var scene = null; if (this.object3D) { var obj = this.object3D; while (obj.parent) { obj = obj.parent;//若obj一直存在parent則,一直把obj.parent賦值給obj,直到obj不存在parent, //說明找到了最上面的那個obj //那么問題來了:所有的object的父節(jié)點就是scene??? } scene = obj; } return scene;}Sim.Object.prototype.getApp = function(){ var scene = this.getScene(); return scene ? scene.data : null;}// Some constants/* key codes37: left38: up39: right40: down*//** * [KeyCodes description]以下為sim.js的鍵盤keycode編號,直接定義為全局變量方便使用,也便于理解 * @type {Object} */Sim.KeyCodes = {};Sim.KeyCodes.KEY_LEFT = 37;//左鍵Sim.KeyCodes.KEY_UP = 38;//上鍵Sim.KeyCodes.KEY_RIGHT = 39;//右鍵Sim.KeyCodes.KEY_DOWN = 40;//下鍵

版權聲明:本文為博主原創(chuàng)文章,未經博主允許不得轉載。


  本文關鍵詞:WebGL入門指南,由筆耕文化傳播整理發(fā)布。



本文編號:100537

資料下載
論文發(fā)表

本文鏈接:http://sikaile.net/wenshubaike/mishujinen/100537.html


Copyright(c)文論論文網All Rights Reserved | 網站地圖 |

版權申明:資料由用戶95ff8***提供,本站僅收錄摘要或目錄,作者需要刪除請E-mail郵箱bigeng88@qq.com
大香蕉大香蕉手机在线视频| 欧美胖熟妇一区二区三区| 中文字幕av诱惑一区二区| 韩日黄片在线免费观看| 亚洲午夜精品视频在线| 亚洲专区中文字幕在线| 国产免费无遮挡精品视频| 国产精品丝袜美腿一区二区| 亚洲中文字幕高清视频在线观看| 日韩欧美91在线视频| av在线免费观看在线免费观看| 不卡视频在线一区二区三区| 国产午夜在线精品视频| 国产目拍亚洲精品区一区| 亚洲另类女同一二三区| 午夜免费精品视频在线看| 搡老熟女老女人一区二区| 国产成人av在线免播放观看av| 色好吊视频这里只有精| 亚洲第一香蕉视频在线| 欧美精品中文字幕亚洲| 在线观看视频日韩精品| 欧美一区二区口爆吞精| 最近最新中文字幕免费| 亚洲一区二区三区在线中文字幕 | 婷婷开心五月亚洲综合| 国产一级片内射视频免费播放| 国产又粗又猛又爽色噜噜| 国产精品二区三区免费播放心| 欧美午夜伦理在线观看| 熟女中文字幕一区二区三区| 日韩欧美国产三级在线观看| 欧美黑人在线精品极品| 国产韩国日本精品视频| 99久久国产综合精品二区| 国产99久久精品果冻传媒| 中文字幕在线区中文色| 有坂深雪中文字幕亚洲中文| 亚洲中文字幕高清乱码毛片| 亚洲一区二区三区中文久久| 国产av天堂一区二区三区粉嫩|