Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
T
three.js-projector
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Дмитрий Никулин
three.js-projector
Commits
57219920
Commit
57219920
authored
Jun 20, 2016
by
Dmitry
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Working BSP tree
parent
af595692
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
323 additions
and
215 deletions
+323
-215
index.js
index.js
+323
-215
No files found.
index.js
View file @
57219920
...
@@ -4,9 +4,7 @@
...
@@ -4,9 +4,7 @@
* @author julianwa / https://github.com/julianwa
* @author julianwa / https://github.com/julianwa
*/
*/
define
(
function
(
require
,
exports
,
module
){
define
([
'three'
],
function
(
THREE
,
BSPTree
){
var
THREE
=
require
(
"three"
);
var
Projector
=
{};
var
Projector
=
{};
var
i
,
l
,
o
;
// counters
var
i
,
l
,
o
;
// counters
...
@@ -42,6 +40,22 @@ define(function(require, exports, module){
...
@@ -42,6 +40,22 @@ define(function(require, exports, module){
};
};
Projector
.
RenderableFace
.
prototype
.
copy
=
function
(
face
){
this
.
v1
.
copy
(
face
.
v1
);
this
.
v2
.
copy
(
face
.
v2
);
this
.
v3
.
copy
(
face
.
v3
);
this
.
normalModel
.
copy
(
face
.
normalModel
);
this
.
vertexNormalsModel
=
face
.
vertexNormalsModel
;
this
.
vertexNormalsLength
=
face
.
vertexNormalsLength
;
this
.
color
=
face
.
color
;
this
.
material
=
face
.
material
;
this
.
uvs
=
face
.
uvs
;
this
.
priority
=
face
.
priority
;
};
Projector
.
RenderableVertex
=
function
()
{
Projector
.
RenderableVertex
=
function
()
{
this
.
position
=
new
THREE
.
Vector3
();
this
.
position
=
new
THREE
.
Vector3
();
...
@@ -73,6 +87,14 @@ define(function(require, exports, module){
...
@@ -73,6 +87,14 @@ define(function(require, exports, module){
};
};
Projector
.
RenderableLine
.
prototype
.
copy
=
function
(
line
){
this
.
v1
.
copy
(
line
.
v1
);
this
.
v2
.
copy
(
line
.
v2
);
this
.
vertexColors
=
line
.
vertexColors
;
this
.
material
=
line
.
material
;
};
Projector
.
RenderableSprite
=
function
()
{
Projector
.
RenderableSprite
=
function
()
{
this
.
id
=
0
;
this
.
id
=
0
;
...
@@ -656,6 +678,7 @@ define(function(require, exports, module){
...
@@ -656,6 +678,7 @@ define(function(require, exports, module){
if
(
vertices
.
length
===
0
)
continue
;
if
(
vertices
.
length
===
0
)
continue
;
var
v1
=
getNextVertexInPool
();
var
v1
=
getNextVertexInPool
();
v1
.
positionWorld
.
copy
(
vertices
[
0
]
);
v1
.
positionScreen
.
copy
(
vertices
[
0
]
).
applyMatrix4
(
_modelViewProjectionMatrix
);
v1
.
positionScreen
.
copy
(
vertices
[
0
]
).
applyMatrix4
(
_modelViewProjectionMatrix
);
// Handle LineStrip and LinePieces
// Handle LineStrip and LinePieces
...
@@ -664,6 +687,7 @@ define(function(require, exports, module){
...
@@ -664,6 +687,7 @@ define(function(require, exports, module){
for
(
var
v
=
1
,
vl
=
vertices
.
length
;
v
<
vl
;
v
++
)
{
for
(
var
v
=
1
,
vl
=
vertices
.
length
;
v
<
vl
;
v
++
)
{
v1
=
getNextVertexInPool
();
v1
=
getNextVertexInPool
();
v1
.
positionWorld
.
copy
(
vertices
[
v
]
);
v1
.
positionScreen
.
copy
(
vertices
[
v
]
).
applyMatrix4
(
_modelViewProjectionMatrix
);
v1
.
positionScreen
.
copy
(
vertices
[
v
]
).
applyMatrix4
(
_modelViewProjectionMatrix
);
if
(
(
v
+
1
)
%
step
>
0
)
continue
;
if
(
(
v
+
1
)
%
step
>
0
)
continue
;
...
@@ -683,7 +707,10 @@ define(function(require, exports, module){
...
@@ -683,7 +707,10 @@ define(function(require, exports, module){
_line
.
id
=
object
.
id
;
_line
.
id
=
object
.
id
;
_line
.
v1
.
positionScreen
.
copy
(
_clippedVertex1PositionScreen
);
_line
.
v1
.
positionScreen
.
copy
(
_clippedVertex1PositionScreen
);
_line
.
v1
.
positionWorld
.
copy
(
v1
.
positionWorld
);
_line
.
v2
.
positionScreen
.
copy
(
_clippedVertex2PositionScreen
);
_line
.
v2
.
positionScreen
.
copy
(
_clippedVertex2PositionScreen
);
_line
.
v2
.
positionWorld
.
copy
(
v2
.
positionWorld
);
_line
.
z
=
Math
.
max
(
_clippedVertex1PositionScreen
.
z
,
_clippedVertex2PositionScreen
.
z
);
_line
.
z
=
Math
.
max
(
_clippedVertex1PositionScreen
.
z
,
_clippedVertex2PositionScreen
.
z
);
...
@@ -741,20 +768,106 @@ define(function(require, exports, module){
...
@@ -741,20 +768,106 @@ define(function(require, exports, module){
if
(
sortElements
===
true
)
{
if
(
sortElements
===
true
)
{
_renderData
.
elements
.
sort
(
customSort
);
//
_renderData.elements.sort( customSort );
}
}
// Build the BSP tree
// Build the BSP tree
//var btree = buildBSPTree(_renderData.elements);
var
btree
=
new
BSPTree
(
_renderData
.
elements
);
_renderData
.
elements
=
btree
.
toArray
();
//_renderData.elements.length = 15;
return
_renderData
;
return
_renderData
;
};
};
// Pools
function
getNextObjectInPool
()
{
if
(
_objectCount
===
_objectPoolLength
)
{
var
object
=
new
Projector
.
RenderableObject
();
_objectPool
.
push
(
object
);
_objectPoolLength
++
;
_objectCount
++
;
return
object
;
}
return
_objectPool
[
_objectCount
++
];
}
function
getNextVertexInPool
()
{
if
(
_vertexCount
===
_vertexPoolLength
)
{
var
vertex
=
new
Projector
.
RenderableVertex
();
_vertexPool
.
push
(
vertex
);
_vertexPoolLength
++
;
_vertexCount
++
;
return
vertex
;
}
return
_vertexPool
[
_vertexCount
++
];
}
function
getNextFaceInPool
()
{
if
(
_faceCount
===
_facePoolLength
)
{
var
face
=
new
Projector
.
RenderableFace
();
_facePool
.
push
(
face
);
_facePoolLength
++
;
_faceCount
++
;
return
face
;
}
return
_facePool
[
_faceCount
++
];
}
function
getNextLineInPool
()
{
if
(
_lineCount
===
_linePoolLength
)
{
var
line
=
new
Projector
.
RenderableLine
();
_linePool
.
push
(
line
);
_linePoolLength
++
;
_lineCount
++
;
return
line
;
}
return
_linePool
[
_lineCount
++
];
}
function
getNextSpriteInPool
()
{
if
(
_spriteCount
===
_spritePoolLength
)
{
var
sprite
=
new
Projector
.
RenderableSprite
();
_spritePool
.
push
(
sprite
);
_spritePoolLength
++
;
_spriteCount
++
;
return
sprite
;
}
return
_spritePool
[
_spriteCount
++
];
}
function
BSPTree
(
data
){
function
BSPTree
(
data
){
if
(
data
.
length
){
if
(
data
.
length
){
this
.
root
=
BSPTree
.
createNode
(
data
[
0
]);
this
.
root
=
BSPTree
.
utils
.
createNode
(
data
[
0
]);
for
(
var
i
=
1
;
i
<
data
.
length
;
i
++
){
for
(
var
i
=
1
;
i
<
data
.
length
;
i
++
){
this
.
insert
(
data
[
i
]);
this
.
insert
(
data
[
i
]);
}
}
...
@@ -765,29 +878,35 @@ define(function(require, exports, module){
...
@@ -765,29 +878,35 @@ define(function(require, exports, module){
compareWith
=
compareWith
||
this
.
root
;
compareWith
=
compareWith
||
this
.
root
;
var
node
=
(
element
instanceof
BSPTree
.
Node
)
?
var
node
=
(
element
instanceof
BSPTree
.
Node
)
?
element
:
element
:
BSPTree
.
createNode
(
element
);
BSPTree
.
utils
.
createNode
(
element
);
var
comparison
=
compareWith
.
isBehind
(
node
);
var
comparison
=
node
.
isBehind
(
compareWith
);
if
(
comparison
===
undefined
){
if
(
comparison
===
undefined
){
var
fragments
=
node
.
separate
(
compareWith
);
var
fragments
=
node
.
separate
(
compareWith
.
getNormal
(),
compareWith
.
getPointOnPlane
()
);
var
self
=
this
;
fragments
.
forEach
(
function
(
f
){
fragments
.
forEach
(
function
(
f
){
this
.
insert
(
f
,
compareWith
);
self
.
insert
(
f
,
compareWith
);
});
});
return
;
return
;
}
}
if
(
comparison
){
if
(
comparison
){
if
(
!
compareWith
.
front
){
compareWith
.
front
=
node
;
}
else
{
this
.
insert
(
node
,
compareWith
.
front
);
}
}
else
{
if
(
!
compareWith
.
back
){
if
(
!
compareWith
.
back
){
compareWith
.
back
=
node
;
compareWith
.
back
=
node
;
}
else
{
}
else
{
this
.
insert
(
node
,
compareWith
.
back
);
this
.
insert
(
node
,
compareWith
.
back
);
}
}
}
else
{
if
(
!
compareWith
.
front
){
compareWith
.
front
=
node
;
}
else
{
this
.
insert
(
node
,
compareWith
.
front
);
}
}
}
};
};
...
@@ -796,7 +915,7 @@ define(function(require, exports, module){
...
@@ -796,7 +915,7 @@ define(function(require, exports, module){
function
traverse
(
node
){
function
traverse
(
node
){
if
(
node
){
if
(
node
){
traverse
(
node
.
back
);
traverse
(
node
.
back
);
output
.
push
(
node
);
output
.
push
(
node
.
element
);
traverse
(
node
.
front
);
traverse
(
node
.
front
);
}
}
}
}
...
@@ -804,29 +923,70 @@ define(function(require, exports, module){
...
@@ -804,29 +923,70 @@ define(function(require, exports, module){
return
output
;
return
output
;
}
}
BSPTree
.
createNode
=
function
(
element
){
BSPTree
.
utils
=
{
return
new
(
element
.
v3
?
BSPTree
.
LineNode
:
BSPTree
.
TriangleNode
)(
element
);
createNode
:
function
(
element
){
};
return
new
(
element
.
v3
?
BSPTree
.
TriangleNode
:
BSPTree
.
LineNode
)(
element
);
},
getPointSign
:
function
(
normal
,
point
,
pointOnPlane
){
return
this
.
sign
(
normal
.
dot
(
point
.
clone
().
sub
(
pointOnPlane
)));
},
isPointInSegment
:
function
(
point
,
p1
,
p2
){
// This function assumes that point lies on the line
// and determines whether it is in line _segment_
var
minX
=
Math
.
min
(
p1
.
x
,
p2
.
x
);
var
minY
=
Math
.
min
(
p1
.
y
,
p2
.
y
);
var
minZ
=
Math
.
min
(
p1
.
z
,
p2
.
z
);
var
maxX
=
Math
.
max
(
p1
.
x
,
p2
.
x
);
var
maxY
=
Math
.
max
(
p1
.
y
,
p2
.
y
);
var
maxZ
=
Math
.
max
(
p1
.
z
,
p2
.
z
);
return
(
point
.
x
>=
minX
&&
point
.
x
<=
maxX
)
&&
(
point
.
y
>=
minY
&&
point
.
y
<=
maxY
)
&&
(
point
.
z
>=
minZ
&&
point
.
z
<=
maxZ
);
},
isZero
:
function
(
x
){
return
Math
.
abs
(
x
)
<
this
.
EPSILON
;
},
linePlaneIntersection
:
function
(
normal
,
pointOnPlane
,
p1
,
p2
){
var
upper
=
pointOnPlane
.
clone
().
sub
(
p1
);
upper
=
upper
.
dot
(
normal
);
BSPTree
.
getPointSign
=
function
(
normal
,
point
,
pointOnPlane
){
var
l
=
p2
.
clone
().
sub
(
p1
);
return
BSPTree
.
sign
(
normal
.
dot
(
point
.
clone
().
sub
(
pointOnPlane
)));
var
lower
=
l
.
dot
(
normal
);
}
BSPTree
.
isZero
=
function
(
x
){
if
(
lower
===
0
)
return
undefined
;
return
Math
.
abs
(
x
)
<
BSPTree
.
SIGN_EPSILON
;
}
BSPTree
.
sign
=
function
(
x
){
var
d
=
upper
/
lower
;
if
(
Math
.
abs
(
x
)
<
BSPTree
.
SIGN_EPSILON
){
var
intersectionPoint
=
l
.
multiplyScalar
(
d
).
add
(
p1
);
return
BSPTree
.
utils
.
isPointInSegment
(
intersectionPoint
,
p1
,
p2
)
?
intersectionPoint
:
undefined
;
},
pointsEqual
:
function
(
p1
,
p2
){
return
this
.
isZero
(
p2
.
distanceTo
(
p1
));
},
projectVertex
:
function
(
vertex
){
var
oldModelMatrix
=
_modelMatrix
;
_modelMatrix
=
this
.
IDENTITY_MATRIX
;
renderList
.
projectVertex
(
vertex
);
vertex
.
positionScreen
.
w
=
1
;
_modelMatrix
=
oldModelMatrix
;
},
sign
:
function
(
x
){
if
(
this
.
isZero
(
x
)){
return
0
;
return
0
;
}
else
if
(
x
>
0
)
{
}
else
if
(
x
>
0
)
{
return
1
;
return
1
;
}
else
{
}
else
{
return
-
1
;
return
-
1
;
}
}
}
},
BSPTree
.
SIGN_EPSILON
=
1
e
-
6
;
EPSILON
:
1
e
-
6
,
IDENTITY_MATRIX
:
new
THREE
.
Matrix4
()
}
BSPTree
.
Node
=
function
(){
BSPTree
.
Node
=
function
(){
...
@@ -835,16 +995,16 @@ define(function(require, exports, module){
...
@@ -835,16 +995,16 @@ define(function(require, exports, module){
}
}
BSPTree
.
Node
.
prototype
.
isBehind
=
function
(
node
){
BSPTree
.
Node
.
prototype
.
isBehind
=
function
(
node
){
var
normal
=
this
.
getNormal
();
var
normal
=
node
.
getNormal
();
var
point
=
this
.
getPointOnPlane
();
var
point
=
node
.
getPointOnPlane
();
var
viewer
=
_camera
.
position
;
var
viewer
=
_camera
.
position
;
var
viewerSign
=
BSPTree
.
getPointSign
(
normal
,
viewer
,
point
);
var
viewerSign
=
BSPTree
.
utils
.
getPointSign
(
normal
,
viewer
,
point
);
var
nodeSign
=
node
.
getSign
(
normal
,
point
);
var
thisSign
=
this
.
getSign
(
normal
,
point
);
if
(
node
Sign
===
undefined
)
return
undefined
;
if
(
this
Sign
===
undefined
)
return
undefined
;
return
(
viewerSign
!==
node
Sign
);
return
(
viewerSign
!==
this
Sign
);
}
}
...
@@ -854,7 +1014,7 @@ define(function(require, exports, module){
...
@@ -854,7 +1014,7 @@ define(function(require, exports, module){
};
};
BSPTree
.
LineNode
.
prototype
=
Object
.
create
(
BSPTree
.
Node
.
prototype
);
BSPTree
.
LineNode
.
prototype
=
Object
.
create
(
BSPTree
.
Node
.
prototype
);
BSPTree
.
LineNod
e
.
getNormal
=
function
(){
BSPTree
.
LineNode
.
prototyp
e
.
getNormal
=
function
(){
var
l
=
new
THREE
.
Line3
(
var
l
=
new
THREE
.
Line3
(
this
.
element
.
v1
.
positionWorld
,
this
.
element
.
v1
.
positionWorld
,
this
.
element
.
v2
.
positionWorld
this
.
element
.
v2
.
positionWorld
...
@@ -868,42 +1028,49 @@ define(function(require, exports, module){
...
@@ -868,42 +1028,49 @@ define(function(require, exports, module){
}
}
BSPTree
.
LineNode
.
prototype
.
getSign
=
function
(
normal
,
pointOnPlane
){
BSPTree
.
LineNode
.
prototype
.
getSign
=
function
(
normal
,
pointOnPlane
){
var
sign
=
BSPTree
.
getPointSign
(
normal
,
this
.
element
.
v1
.
positionWorld
,
pointOnPlane
);
var
s1
=
BSPTree
.
utils
.
getPointSign
(
normal
,
this
.
element
.
v1
.
positionWorld
,
pointOnPlane
);
var
signTmp
=
BSPTree
.
getPointSign
(
normal
,
this
.
element
.
v2
.
positionWorld
,
pointOnPlane
);
var
s2
=
BSPTree
.
utils
.
getPointSign
(
normal
,
this
.
element
.
v2
.
positionWorld
,
pointOnPlane
);
if
(
signTmp
!==
sign
)
return
undefined
;
return
sign
;
var
sMax
=
Math
.
max
(
s1
,
s2
);
var
sMin
=
Math
.
min
(
s1
,
s2
);
switch
(
Math
.
abs
(
sMax
-
sMin
)){
case
0
:
return
sMax
;
case
1
:
return
sMax
||
sMin
;
case
2
:
return
undefined
;
default
:
throw
new
Error
(
'It looks like some unexpected FP error!'
);
}
}
BSPTree
.
LineNode
.
prototype
.
isBehind
=
function
(
node
){
var
normal
=
this
.
getNormal
();
var
point
=
this
.
element
.
v1
.
positionWorld
;
var
viewer
=
_camera
.
position
;
var
viewerSign
=
BSPTree
.
getPointSign
(
normal
,
viewer
,
point
);
var
nodeSign
=
node
.
getSign
(
normal
,
point
);
if
(
nodeSign
===
undefined
)
return
undefined
;
return
(
viewerSign
!==
nodeSign
);
}
}
BSPTree
.
LineNode
.
prototype
.
separate
=
function
(
normal
,
point
){
BSPTree
.
LineNode
.
prototype
.
separate
=
function
(
normal
,
point
){
var
upper
=
point
.
clone
().
sub
(
this
.
element
.
v1
.
positionWorld
);
var
intersectionPoint
=
BSPTree
.
utils
.
linePlaneIntersection
(
upper
=
upper
.
dot
(
normal
);
normal
,
point
,
this
.
element
.
v1
.
positionWorld
,
var
l0
=
this
.
element
.
v2
.
positionWorld
;
this
.
element
.
v2
.
positionWorld
);
var
l
=
l0
.
clone
().
sub
(
this
.
element
.
v1
.
positionWorld
);
var
lower
=
l
.
dot
(
normal
);
if
(
lower
===
0
)
return
this
;
if
(
intersectionPoint
){
var
newLine
=
getNextLineInPool
();
newLine
.
copy
(
this
.
element
);
var
d
=
upper
/
lower
;
var
vertex
=
getNextVertexInPool
();
vertex
.
position
.
copy
(
intersectionPoint
);
BSPTree
.
utils
.
projectVertex
(
vertex
);
var
intersectionPoint
=
l
.
multiplyScalar
(
d
).
add
(
l0
);
newLine
.
v1
.
copy
(
vertex
);
newLine
.
v2
=
this
.
element
.
v2
;
this
.
element
.
v2
=
vertex
;
return
intersectionPoint
;
return
[
this
,
BSPTree
.
utils
.
createNode
(
newLine
)];
}
else
{
return
[
this
];
}
}
}
BSPTree
.
TriangleNode
=
function
(
element
){
BSPTree
.
TriangleNode
=
function
(
element
){
this
.
element
=
element
;
this
.
element
=
element
;
...
@@ -911,7 +1078,7 @@ define(function(require, exports, module){
...
@@ -911,7 +1078,7 @@ define(function(require, exports, module){
};
};
BSPTree
.
TriangleNode
.
prototype
=
Object
.
create
(
BSPTree
.
Node
.
prototype
);
BSPTree
.
TriangleNode
.
prototype
=
Object
.
create
(
BSPTree
.
Node
.
prototype
);
BSPTree
.
TriangleNod
e
.
getNormal
=
function
(){
BSPTree
.
TriangleNode
.
prototyp
e
.
getNormal
=
function
(){
return
this
.
element
.
normalModel
;
return
this
.
element
.
normalModel
;
}
}
...
@@ -920,182 +1087,123 @@ define(function(require, exports, module){
...
@@ -920,182 +1087,123 @@ define(function(require, exports, module){
}
}
BSPTree
.
TriangleNode
.
prototype
.
getSign
=
function
(
normal
,
pointOnPlane
){
BSPTree
.
TriangleNode
.
prototype
.
getSign
=
function
(
normal
,
pointOnPlane
){
var
sign
=
BSPTree
.
getPointSign
(
normal
,
this
.
element
.
v1
.
positionWorld
,
pointOnPlane
);
var
s1
=
BSPTree
.
utils
.
getPointSign
(
normal
,
this
.
element
.
v1
.
positionWorld
,
pointOnPlane
);
var
signTmp
=
BSPTree
.
getPointSign
(
normal
,
this
.
element
.
v2
.
positionWorld
,
pointOnPlane
);
var
s2
=
BSPTree
.
utils
.
getPointSign
(
normal
,
this
.
element
.
v2
.
positionWorld
,
pointOnPlane
);
if
(
signTmp
!==
sign
)
return
undefined
;
var
s3
=
BSPTree
.
utils
.
getPointSign
(
normal
,
this
.
element
.
v3
.
positionWorld
,
pointOnPlane
);
var
signTmp
=
BSPTree
.
getPointSign
(
normal
,
this
.
element
.
v3
.
positionWorld
,
pointOnPlane
);
if
(
signTmp
!==
sign
)
return
undefined
;
var
sMax
=
Math
.
max
(
s1
,
s2
,
s3
);
return
sign
;
var
sMin
=
Math
.
min
(
s1
,
s2
,
s3
);
}
switch
(
Math
.
abs
(
sMax
-
sMin
)){
// Pools
case
0
:
return
sMax
;
function
getNextObjectInPool
()
{
case
1
:
return
sMax
||
sMin
;
if
(
_objectCount
===
_objectPoolLength
)
{
case
2
:
return
undefined
;
var
object
=
new
Projector
.
RenderableObject
();
default
:
_objectPool
.
push
(
object
);
throw
new
Error
(
'It looks like some unexpected FP error!'
);
_objectPoolLength
++
;
_objectCount
++
;
return
object
;
}
return
_objectPool
[
_objectCount
++
];
}
function
getNextVertexInPool
()
{
if
(
_vertexCount
===
_vertexPoolLength
)
{
var
vertex
=
new
Projector
.
RenderableVertex
();
_vertexPool
.
push
(
vertex
);
_vertexPoolLength
++
;
_vertexCount
++
;
return
vertex
;
}
return
_vertexPool
[
_vertexCount
++
];
}
function
getNextFaceInPool
()
{
if
(
_faceCount
===
_facePoolLength
)
{
var
face
=
new
Projector
.
RenderableFace
();
_facePool
.
push
(
face
);
_facePoolLength
++
;
_faceCount
++
;
return
face
;
}
}
return
_facePool
[
_faceCount
++
];
}
}
function
getNextLineInPool
()
{
BSPTree
.
TriangleNode
.
prototype
.
separate
=
function
(
normal
,
pointOnPlane
){
var
p1
=
this
.
element
.
v1
.
positionWorld
;
var
p2
=
this
.
element
.
v2
.
positionWorld
;
var
p3
=
this
.
element
.
v3
.
positionWorld
;
if
(
_lineCount
===
_linePoolLength
)
{
// Intersection points
var
i12
=
BSPTree
.
utils
.
linePlaneIntersection
(
normal
,
pointOnPlane
,
p1
,
p2
);
var
i23
=
BSPTree
.
utils
.
linePlaneIntersection
(
normal
,
pointOnPlane
,
p2
,
p3
);
var
i31
=
BSPTree
.
utils
.
linePlaneIntersection
(
normal
,
pointOnPlane
,
p3
,
p1
);
var
line
=
new
Projector
.
RenderableLine
();
if
(
i12
&&
i23
&&
i31
){
_linePool
.
push
(
line
);
// Special case, one split point is a vertex
_linePoolLength
++
;
// In this case we split triangle into two
_lineCount
++
;
var
iVertex
,
iSide
;
return
line
;
}
var
vertex
=
getNextVertexInPool
();
var
newTriangle
=
getNextFaceInPool
();
newTriangle
.
copy
(
this
.
element
);
return
_linePool
[
_lineCount
++
];
if
(
BSPTree
.
utils
.
pointsEqual
(
i12
,
i23
)){
vertex
.
position
=
i31
;
BSPTree
.
utils
.
projectVertex
(
vertex
);
}
this
.
element
.
v3
.
copy
(
vertex
);
newTriangle
.
v1
=
vertex
;
}
else
if
(
BSPTree
.
utils
.
pointsEqual
(
i23
,
i31
)){
vertex
.
position
=
i12
;
BSPTree
.
utils
.
projectVertex
(
vertex
);
function
getNextSpriteInPool
()
{
this
.
element
.
v1
.
copy
(
vertex
);
newTriangle
.
v2
=
vertex
;
if
(
_spriteCount
===
_spritePoolLength
)
{
}
else
{
vertex
.
position
=
i23
;
var
sprite
=
new
Projector
.
RenderableSprite
();
BSPTree
.
utils
.
projectVertex
(
vertex
);
_spritePool
.
push
(
sprite
);
_spritePoolLength
++
;
_spriteCount
++
;
return
sprite
;
this
.
element
.
v2
.
copy
(
vertex
);
newTriangle
.
v3
=
vertex
;
}
}
return
_spritePool
[
_spriteCount
++
];
return
[
this
,
BSPTree
.
utils
.
createNode
(
newTriangle
)];
}
else
{
var
t1
=
getNextFaceInPool
();
var
t2
=
getNextFaceInPool
();
}
t1
.
copy
(
this
.
element
);
t2
.
copy
(
this
.
element
);
// ----------
var
v1
=
getNextVertexInPool
();
// This sorting algorithm uses a combination of 'painter sort' and
var
v2
=
getNextVertexInPool
();
// binary space partition methods
// See https://users.cs.jmu.edu/bernstdh/web/common/lectures/slides_hidden-visible-3d.php
// on slide 12 for specific BSP formulas used
// ----------
// Returns true for points on one side of plane and false for points
// Split triangle into three triangles
// on another side
if
(
!
i12
){
function
getPointSign
(
planeNormal
,
point
,
pointOnPlane
){
this
.
element
.
v1
.
position
=
i31
;
return
planeNormal
.
dot
(
point
.
clone
().
sub
(
pointOnPlane
))
>
0
;
this
.
element
.
v2
.
position
=
i23
;
}
BSPTree
.
utils
.
projectVertex
(
this
.
element
.
v1
);
BSPTree
.
utils
.
projectVertex
(
this
.
element
.
v2
);
function
compareFaces
(
a
,
b
){
t1
.
v2
.
copy
(
this
.
element
.
v2
);
var
normal
=
b
.
normalModel
;
t1
.
v3
.
copy
(
this
.
element
.
v1
);
if
(
!
normal
)
{
var
l
=
new
THREE
.
Line3
(
b
.
v1
.
positionWorld
,
b
.
v2
.
positionWorld
);
var
pt
=
l
.
closestPointToPoint
(
_camera
.
position
,
false
);
normal
=
pt
.
sub
(
_camera
.
position
);
}
var
point
=
b
.
v1
.
positionWorld
;
t2
.
v3
.
copy
(
this
.
element
.
v2
);
if
(
!
point
)
return
undefined
;
}
else
if
(
!
i23
){
this
.
element
.
v2
.
position
=
i12
;
this
.
element
.
v3
.
position
=
i31
;
BSPTree
.
utils
.
projectVertex
(
this
.
element
.
v2
);
BSPTree
.
utils
.
projectVertex
(
this
.
element
.
v3
);
var
viewer
=
_camera
.
position
;
t1
.
v1
.
copy
(
this
.
element
.
v2
);
t1
.
v3
.
copy
(
this
.
element
.
v3
);
var
viewerSign
=
getPointSign
(
normal
,
viewer
,
point
);
t2
.
v1
.
copy
(
this
.
element
.
v3
);
var
aSign
,
signTmp
;
}
else
{
this
.
element
.
v1
.
position
=
i12
;
this
.
element
.
v3
.
position
=
i23
;
BSPTree
.
utils
.
projectVertex
(
this
.
element
.
v1
);
BSPTree
.
utils
.
projectVertex
(
this
.
element
.
v3
);
try
{
t1
.
v1
.
copy
(
this
.
element
.
v1
);
var
aSign
=
getPointSign
(
normal
,
a
.
v1
.
positionWorld
,
point
);
t1
.
v2
.
copy
(
this
.
element
.
v3
);
var
signTmp
=
getPointSign
(
normal
,
a
.
v2
.
positionWorld
,
point
);
if
(
signTmp
!==
aSign
)
return
undefined
;
// For lines that don't have .v3 we do not check it
if
(
a
.
v3
){
var
signTmp
=
getPointSign
(
normal
,
a
.
v3
.
positionWorld
,
point
);
if
(
signTmp
!==
aSign
)
return
undefined
;
}
return
(
viewerSign
===
aSign
);
t2
.
v2
.
copy
(
this
.
element
.
v1
);
}
catch
(
e
)
{
return
undefined
;
}
}
}
return
[
// Output:
this
,
// - positive means a is in front of b;
BSPTree
.
utils
.
createNode
(
t1
),
// - negative means b is in front of a;
BSPTree
.
utils
.
createNode
(
t2
)
// - 0 means 'leave as is'
]
function
customSort
(
a
,
b
)
{
function
priority
(
x
){
if
(
typeof
x
.
priority
!==
'number'
)
return
-
Infinity
;
return
x
.
priority
;
}
}
if
(
priority
(
a
)
!==
priority
(
b
)){
var
r
=
priority
(
a
)
-
priority
(
b
);
if
(
r
>
1
)
return
1
;
if
(
r
<
1
)
return
-
1
;
return
r
;
}
}
// If this is true, a is fully in front of b, if this is false,
// a is fully behind b. If this is undefined, some points of a
// are in front of b and some are behind.
var
isAInFrontOfB
=
compareFaces
(
a
,
b
);
// If not undefined, we have got a defined result that we'll use
if
(
isAInFrontOfB
!==
undefined
)
{
return
isAInFrontOfB
?
1
:
-
1
;
}
else
{
// Try to compare b with a, it may give defined result when
// compareFaces(a, b) failed
var
isBInFrontOfA
=
compareFaces
(
b
,
a
);
if
(
isBInFrontOfA
!==
undefined
)
{
return
isBInFrontOfA
?
-
1
:
1
;
}
}
// If we are here, it means that BSP without splitting failed.
// Trying 'painter sort' algorithm, based on average
// z-coordinate of triangle points.
return
painterSort
(
a
,
b
);
}
function
painterSort
(
a
,
b
){
function
painterSort
(
a
,
b
){
if
(
a
.
z
!==
b
.
z
)
{
if
(
a
.
z
!==
b
.
z
)
{
...
@@ -1187,6 +1295,6 @@ define(function(require, exports, module){
...
@@ -1187,6 +1295,6 @@ define(function(require, exports, module){
};
};
module
.
exports
=
Projector
;
return
Projector
;
});
});
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment