123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283 |
- import {GLCubeFaces} from '../../../defines'
- import MathLight from '../../../utils/MathLight'
- import * as THREE from "../../../../libs/three.js/build/three.module.js";
- var TileUtils = {};
- TileUtils.TILE_SIZE = 512,
- TileUtils.FACES_PER_PANO = 6,
- TileUtils.LocationOnTile = {
- Center: 0,
- UpperLeft: 1,
- UpperRight: 2,
- LowerRight: 3,
- LowerLeft: 4
- },
- /*
- * 获取某tile在cube中的方向 direction (向量起点在cube中心,终点在tile图的指定位置)。spherical通过先求uv,再直接得到dir
- * @param {*} size 面分辨率
- * @param {*} cubeFace 所在面
- * @param {*} Center 在tile上的目标位置,默认为中心,其他位置就是四个顶点
- * @param {*} c 似乎是在tile的缩进百分比,根据所在面的不同,分别向不同方向缩进,但都是向tile的中心
- * @param {*} dir 所求方向
- */
- TileUtils.getTileVector = function() {//获取某tile在cube中的方向 direction (向量起点在cube中心,终点在tile图的中心)
- return function(size, tileSize, cubeFace, tileX, tileY, Center, c, dir) {//c似乎是缩进百分比
-
- Center = Center || TileUtils.LocationOnTile.Center;
-
- //假设该cube边长为2:
- var u = size / tileSize
- , d = tileX / u;
- tileY = -tileY + (u - 1);
- var p = tileY / u
- , f = tileSize / size
- , g = 2 * f //一个tile的宽度 (乘以2是因为cube边长是2)
- , m = g / 2
- , v = 2 * d - 1 + m
- , A = 2 * p - 1 + m;
-
- switch (Center) {//计算在tile中指定位置带来的偏移
- case TileUtils.LocationOnTile.UpperLeft: //1
- v -= m,
- A += m,
- v += c * g; //似乎是向内缩进
- break;
- case TileUtils.LocationOnTile.UpperRight:
- v += m,
- A += m,
- A -= c * g;
- break;
- case TileUtils.LocationOnTile.LowerRight:
- v += m,
- A -= m,
- v -= c * g;
- break;
- case TileUtils.LocationOnTile.LowerLeft:
- v -= m,
- A -= m,
- A += c * g;
- break;
- case TileUtils.LocationOnTile.Center: //0
- }
- switch (cubeFace) {
- case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_X:
- MathLight.setVector(dir, -1, A, -v);
- break;
- case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_X:
- MathLight.setVector(dir, 1, A, v);
- break;
- case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Y: //顶面
- MathLight.setVector(dir, -v, 1, -A);
- break;
- case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y:
- MathLight.setVector(dir, -v, -1, A);
- break;
- case GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Z:
- MathLight.setVector(dir, -v, A, 1);
- break;
- case GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z:
- MathLight.setVector(dir, v, A, -1)
- }
- MathLight.normalize(dir)
- }
- }(),
- /*
- * 获取该tile在第几个面(简易装载法)
- */
- TileUtils.getFaceForTile = function(size, index) {//获取该tile在第几个面
- var tileSize = TileUtils.TILE_SIZE;
- size < TileUtils.TILE_SIZE && (tileSize = size);
- var n = Math.floor(size / tileSize)
- , sum = n * n; //得每个面tile总数
- return Math.floor(index / sum)
- }
- ,
- TileUtils.getTileLocation = function(size, t, result) {
- var tileSize = TileUtils.TILE_SIZE;
- size < TileUtils.TILE_SIZE && (tileSize = size);
- var r = TileUtils.getFaceForTile(size, t)
- , a = Math.floor(size / tileSize)
- , s = a * a
- , l = t - r * s;
- result.tileX = l % a;
- result.tileY = Math.floor(l / a);
- result.face = r;
- result.faceTileIndex = l;
- return result
- }
- ,
- /*
- * 求size分辨率需要多少张tile
- */
- TileUtils.getTileCountForSize = function(e) {
- if (e <= TileUtils.TILE_SIZE)
- return TileUtils.FACES_PER_PANO;
- var t = Math.floor(e / TileUtils.TILE_SIZE)
- , i = t * t
- , n = i * TileUtils.FACES_PER_PANO;
- return n
- }
- ,
- TileUtils.getRelativeDirection = function() {
- var e = new MathLight.Matrix4
- , t = new MathLight.Quaternion;
- return function(i, n) {//i是pano.quaternion, n是camera的direction
- t.copy(i),
- t.inverse(),
- e.makeRotationFromQuaternion(t),
- e.applyToVector3(n),
- MathLight.normalize(n)
- }
- }(),
- /*
- * 根据方向寻找合适的tile加载
- */
- TileUtils.matchingTilesInDirection = function() {
- var e = new MathLight.Vector3
- , t = new MathLight.Vector3(0,0,-1)
- , i = new MathLight.Quaternion
- , n = function(e, t) {
- e.push({
- face: t.face,
- faceTileIndex: t.faceTileIndex,
- tileX: t.tileX,
- tileY: t.tileY
- })
- }
- , a = function() {
- var e = {
- face: -1,
- faceTileIndex: -1,
- tileX: -1,
- tileY: -1
- };
- return function(size, i, r) {
- for (var a = TileUtils.getTileCountForSize(size), s = 0, l = 0; l < a; l++)
- TileUtils.getTileLocation(size, l, e),
- i && !i(e) || (s++,
- r && n(r, e));
- return s
- }
- }();
- return function(pano, size, dir, hFov, vFov, result) {
- var d = size < TileUtils.TILE_SIZE ? size : TileUtils.TILE_SIZE;
- //TileUtils.getTileCountForSize(size);
- if (!hFov && !vFov)
- return a(size, null, result);
- var p = !!vFov;
- vFov = vFov || hFov,
- vFov = Math.max(0, Math.min(vFov, 360)),
- hFov = Math.max(0, Math.min(hFov, 360)),
- MathLight.copyVector(dir, e),
- TileUtils.getRelativeDirection(pano.quaternion4dkk, e)
- if(p){//如果有vFov hFov
- i.setFromUnitVectors(e, t);
- var f = function(e) {
- return TileUtils.isTileWithinFrustum(size, d, e.face, e.tileX, e.tileY, i, hFov, vFov)//在视野中的
- };
- return a(size, f, result)
- }
- var g = function(t) {//如果仅有hFov
- return TileUtils.isTileWithinFOV(size, d, t.face, t.tileX, t.tileY, e, hFov)
- };
- return a(size, g, result)
- }
- }(),
- /*
- * 是否在屏幕范围内
- */
- TileUtils.isTileWithinFrustum = function() {
- var e = new MathLight.Vector3
- , t = 1e-5;
- return function(i, n, a, s, l, c, h, u) {
- for (var d = Math.tan(.5 * u * MathLight.RADIANS_PER_DEGREE), p = -d, f = Math.tan(.5 * h * MathLight.RADIANS_PER_DEGREE), g = -f, m = TileUtils.mapFaceToCubemapFace(a), v = 0, A = 0, y = 0, C = 0, I = 0, E = 0, b = TileUtils.LocationOnTile.Center; b <= TileUtils.LocationOnTile.LowerLeft; b++){
- TileUtils.getTileVector(i, n, m, s, l, b, 0, e),//get e // size, tileSize, cubeFace, tileX, tileY, Center, c, dir
- MathLight.applyQuaternionToVector(c, e)
- if (e.z >= -t)//似乎是在相机背面
- I++;
- else {
- var w = -1 / e.z
- , _ = e.x * w
- , T = e.y * w;
- T > d ? v++ : T < p && A++, //这四种似乎代表在这个画框之外,如在左、在上、在下、在右
- _ > f ? y++ : _ < g && C++,
- E++
- }
- }
- return A !== E && v !== E && y !== E && C !== E //如果有一项和E相等代表要么是在相机背面要么是tile的四个顶点都画在画布的同一边,所以肯定不在画布上
- }
- }(),
- /*
- * 是否在FOV范围内
- */
- TileUtils.isTileWithinFOV = function() {
- var e = new MathLight.Vector3
- , t = new MathLight.Vector3(0,1,0)
- , i = new MathLight.Vector3(1,0,0);
- return function(panoSize, tileSize, face, tileX, tileY, direction, fov) {//direction是作用了pano.quaternion的camera.direction
- var d = TileUtils.mapFaceToCubemapFace(face);
- MathLight.cross(direction, t, i) //get i 好像没用到
- TileUtils.getTileVector(panoSize, tileSize, d, tileX, tileY, TileUtils.LocationOnTile.Center, 0, e)
- if (TileUtils.isWithinFOV(e, direction, fov, null))//先判断tile中心在不在FOV内
- return !0;
- for (var p = fov / 360, f = Math.floor(1 / p), g = 0, m = 0; m < f; m++) {
- for (var v = TileUtils.LocationOnTile.UpperLeft; v <= TileUtils.LocationOnTile.LowerLeft; v++)
- if (TileUtils.getTileVector(panoSize, tileSize, d, tileX, tileY, v, g, e),
- TileUtils.isWithinFOV(e, direction, fov, null))
- return !0;
- g += p //可能是考虑到有可能tile比fov覆盖了fov(虽然一般不可能,除非fov特别小),所以将tile分成若干段,取tile中的点再检测下
- }
- return !1
- }
- }(),
- TileUtils.isWithinFOV = function() {
- var e = new MathLight.Vector3
- , t = new MathLight.Vector3;
- return function(dir, cameraDir, fov, a) {
- if (MathLight.copyVector(dir, t),
- a) {
- MathLight.copyVector(a, e),
- MathLight.normalize(e);
- var s = MathLight.dot(e, dir);
- e.x *= s,
- e.y *= s,
- e.z *= s,
- MathLight.subVector(t, e)
- }
- var l = fov / 2 * MathLight.RADIANS_PER_DEGREE
- , c = Math.cos(l)
- , h = MathLight.dot(t, cameraDir);
- return h >= c
- }
- }(),
- TileUtils.mapFaceToCubemapFace = function() {
- var e = {
- 0: GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Y,
- 1: GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_Z,
- 2: GLCubeFaces.GL_TEXTURE_CUBE_MAP_POSITIVE_X,
- 3: GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z,
- 4: GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_X,
- 5: GLCubeFaces.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
- };
- return function(t) {
- return e[t]
- }
- }();
- export default TileUtils
|