一、建築點擊下沉
1、注意點:移動端瀏覽器點擊事件用touch事件,不用click事件
2、屏幕座標標準化
mouse.x = (e.touches[0].clientX / 屏幕寬度) * 2 - 1;
mouse.y = -(e.touches[0].clientY / 屏幕高度) * 2 + 1;
/*
系統自帶光標的座標是以屏幕左上角爲原點,向右和向下爲正的方的座標系
座標標準化的作用是將光標的座標轉化爲以屏幕中間爲原點的大小值在 -1~1的座標值
*/
詳解:
3、Raycaster原理
相關鏈接:https://segmentfault.com/a/1190000010490845
二、第一人稱視角相機
1、相關原理:
- 歐拉角:簡單說就是物體繞空間座標的三個軸xyz按一定的順序進行三次旋轉,最終得到想要的形態,軸的順序不同,旋轉的角度相同,最終的形態也不相同。歐拉角詳解https://blog.csdn.net/linuxheik/article/details/78842428 相關視頻:https://v.youku.com/v_show/id_XNzkyOTIyMTI=.html
- 球面座標:運用三個角度通過三角函數可以求出以座標空間座標某個點爲球心的球體的球面座標 https://baike.baidu.com/item/球座標系/8315363?fr=aladdin
2、球面算法
原理:利用相機的lookAt方法,以相機爲球心,特定長度爲半徑,計算球面的點調用相機lookAt方法,實現環視功能,球體座標軸的上方向以相機的up方向相同,up方向不同算法不同,以下代碼分別爲xyz軸向上時的算法
switch (this._cameraUpType) {
case 0:
targetPosition.x = position.x + 100 * Math.cos(this.phi);
targetPosition.y = position.y + 100 * Math.sin(this.phi) * Math.sin(this.theta);
targetPosition.z = position.z + 100 * Math.sin(this.phi) * Math.cos(this.theta);
break;
case 1:
targetPosition.x = position.x + 100 * Math.sin(this.phi) * Math.cos(this.theta);
targetPosition.y = position.y + 100 * Math.cos(this.phi);
targetPosition.z = position.z + 100 * Math.sin(this.phi) * Math.sin(this.theta);
break;
case 2:
targetPosition.x = position.x + 100 * Math.sin(this.phi) * Math.cos(this.theta);
targetPosition.y = position.y + 100 * Math.sin(this.phi) * Math.sin(this.theta);
targetPosition.z = position.z + 100 * Math.cos(this.phi);
break
}
3、歐拉算法
歐拉角度與四元數旋轉對應公式:
具體運用
// 轉動角度
this._euler.set(this._cameraBeta, this._cameraGamma, this._cameraAlpha, 'ZXY'); // 'ZXY' for the device, but 'ZXY' for us
// 設置轉動
this._cameraQuaternion.setFromEuler(this._euler); // orient the device
三、第三人稱視角相機
1、相關原理:
利用向量關係算相機進行旋轉的四元數軸,然後進行四元數旋轉
2、核心代碼
_eye.copy(_this.object.position).sub(_this.target);
eyeDirection.copy(_eye).normalize();
objectUpDirection.copy(_this.object.up).normalize();
objectSidewaysDirection.crossVectors(objectUpDirection, eyeDirection).normalize();
// 設置OUD長度與爲屏幕Y值移動距離,OSD爲長度爲屏幕X值移動距離
objectUpDirection.setLength(_moveCurr.y - _movePrev.y);
objectSidewaysDirection.setLength(_moveCurr.x - _movePrev.x);
moveDirection.copy(objectUpDirection.add(objectSidewaysDirection));
// 轉動軸
axis.crossVectors(moveDirection, _eye).normalize();
// 轉動角度
angle *= _this.rotateSpeed;
// 四元數轉動
quaternion.setFromAxisAngle(axis, angle);
3、圖解
四、重力感應
1、原理
調用陀螺儀三個參數,代入歐拉旋轉進行旋轉
相關鏈接:https://juejin.im/post/5854bca4128fe100698d7467
2、注意點
-
手機陀螺儀座標旋轉與一般的object旋轉不一樣,遵循歐拉旋轉,順序爲xyz,對應alpha,beta,gamma,手機平放爲初始狀態,z軸向上,Y軸向裏,手機由水平狀態切換至垂直狀態時Y軸方向不變,且當手機由水平狀態切換至垂直狀態的過程中,當手機越發趨近於垂直,alpha的值將逐漸增加90度,至垂直時加到90度,gamma值將相應減少90度,所以當object的座標沒有被人爲更改過,與陀螺儀的座標是一致的時候,當陀螺儀beta角度逐漸增加到90度時,alpha增加的值剛好能邊gamma增加的值所抵消,導致場景看起來沒有發生劇烈扭動(因爲beta增加90度後Y軸也同時發生位置變化,此時的Y軸與原本beta沒有轉動90度時的Z軸剛好接近重疊,而alpha和gamma的增加值又互爲負數,且遵循歐拉轉動,所以剛好可以互相抵消)
-
滑動與重力感應同時開啓:橫向滑動對應alpha值的疊加,對beta值不會產生影響,可以直接疊加到歐拉轉動之中,豎向滑動會使object的座標系與陀螺儀的座標系產生偏移,導致gamma值無法與alpha值進行抵消,使場景發生偏移,所以將豎向滑動調至場景進行一次歐拉轉動後再繞X軸進行一次歐拉轉動,這樣每次都是重新進行轉動,就不會對object的座標產生偏移影響(第一人稱視角相機解決方案)
五、部署
1、項目部署到IIS服務啓動後,無法獲取到Oracle數據,報400錯誤,request error
- 解決方案:當前電腦的Oracle客戶端爲32位,程序64位與32位的客戶端產生衝突,所以獲取數據,在當前電腦上再安裝一個Oracle 64位客戶端可解決問題,注意:64位客戶端安裝完成後最好重啓當前電腦。