Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
Ablesons
three.js
提交
e3586288
T
three.js
项目概览
Ablesons
/
three.js
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
T
three.js
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
e3586288
编写于
4月 20, 2021
作者:
M
Mr.doob
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Examples: Refactored OimoPhysics example.
上级
1da44f66
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
267 addition
and
87 deletion
+267
-87
examples/jsm/physics/OimoPhysics.js
examples/jsm/physics/OimoPhysics.js
+243
-0
examples/physics_oimo_instancing.html
examples/physics_oimo_instancing.html
+24
-87
未找到文件。
examples/jsm/physics/OimoPhysics.js
0 → 100644
浏览文件 @
e3586288
import
{
oimo
}
from
'
../libs/OimoPhysics.js
'
;
async
function
OimoPhysics
()
{
const
Vec3
=
oimo
.
common
.
Vec3
;
const
World
=
oimo
.
dynamics
.
World
;
const
RigidBodyType
=
oimo
.
dynamics
.
rigidbody
.
RigidBodyType
;
const
RigidBodyConfig
=
oimo
.
dynamics
.
rigidbody
.
RigidBodyConfig
;
const
ShapeConfig
=
oimo
.
dynamics
.
rigidbody
.
ShapeConfig
;
const
RigidBody
=
oimo
.
dynamics
.
rigidbody
.
RigidBody
;
const
Shape
=
oimo
.
dynamics
.
rigidbody
.
Shape
;
const
OBoxGeometry
=
oimo
.
collision
.
geometry
.
BoxGeometry
;
const
OSphereGeometry
=
oimo
.
collision
.
geometry
.
SphereGeometry
;
const
frameRate
=
60
;
const
world
=
new
World
(
2
,
new
Vec3
(
0
,
-
9.8
,
0
)
);
//
function
getShape
(
geometry
)
{
const
parameters
=
geometry
.
parameters
;
// TODO change type to is*
if
(
geometry
.
type
===
'
BoxGeometry
'
)
{
const
sx
=
parameters
.
width
!==
undefined
?
parameters
.
width
/
2
:
0.5
;
const
sy
=
parameters
.
height
!==
undefined
?
parameters
.
height
/
2
:
0.5
;
const
sz
=
parameters
.
depth
!==
undefined
?
parameters
.
depth
/
2
:
0.5
;
return
new
OBoxGeometry
(
new
Vec3
(
sx
,
sy
,
sz
)
);
}
else
if
(
geometry
.
type
===
'
SphereGeometry
'
||
geometry
.
type
===
'
IcosahedronGeometry
'
)
{
const
radius
=
parameters
.
radius
!==
undefined
?
parameters
.
radius
:
1
;
return
new
OSphereGeometry
(
radius
);
}
return
null
;
}
const
meshes
=
[];
const
meshMap
=
new
WeakMap
();
function
addMesh
(
mesh
,
mass
=
0
)
{
const
shape
=
getShape
(
mesh
.
geometry
);
if
(
shape
!==
null
)
{
if
(
mesh
.
isInstancedMesh
)
{
handleInstancedMesh
(
mesh
,
mass
,
shape
);
}
else
if
(
mesh
.
isMesh
)
{
handleMesh
(
mesh
,
mass
,
shape
);
}
}
}
function
handleMesh
(
mesh
,
mass
,
shape
)
{
const
shapeConfig
=
new
ShapeConfig
();
shapeConfig
.
geometry
=
shape
;
const
bodyConfig
=
new
RigidBodyConfig
();
bodyConfig
.
type
=
mass
===
0
?
RigidBodyType
.
STATIC
:
RigidBodyType
.
DYNAMIC
;
bodyConfig
.
position
=
new
Vec3
(
mesh
.
position
.
x
,
mesh
.
position
.
y
,
mesh
.
position
.
z
);
const
body
=
new
RigidBody
(
bodyConfig
);
body
.
addShape
(
new
Shape
(
shapeConfig
)
);
world
.
addRigidBody
(
body
);
if
(
mass
>
0
)
{
meshes
.
push
(
mesh
);
meshMap
.
set
(
mesh
,
body
);
}
}
function
handleInstancedMesh
(
mesh
,
mass
,
shape
)
{
const
array
=
mesh
.
instanceMatrix
.
array
;
const
bodies
=
[];
for
(
let
i
=
0
;
i
<
mesh
.
count
;
i
++
)
{
const
index
=
i
*
16
;
const
shapeConfig
=
new
ShapeConfig
();
shapeConfig
.
geometry
=
shape
;
const
bodyConfig
=
new
RigidBodyConfig
();
bodyConfig
.
type
=
mass
===
0
?
RigidBodyType
.
STATIC
:
RigidBodyType
.
DYNAMIC
;
bodyConfig
.
position
=
new
Vec3
(
array
[
index
+
12
],
array
[
index
+
13
],
array
[
index
+
14
]
);
const
body
=
new
RigidBody
(
bodyConfig
);
body
.
addShape
(
new
Shape
(
shapeConfig
)
);
world
.
addRigidBody
(
body
);
bodies
.
push
(
body
);
}
if
(
mass
>
0
)
{
meshes
.
push
(
mesh
);
meshMap
.
set
(
mesh
,
bodies
);
}
}
//
function
setMeshPosition
(
mesh
,
position
,
index
=
0
)
{
if
(
mesh
.
isInstancedMesh
)
{
const
bodies
=
meshMap
.
get
(
mesh
);
const
body
=
bodies
[
index
];
body
.
setPosition
(
new
Vec3
(
position
.
x
,
position
.
y
,
position
.
z
)
);
}
else
if
(
mesh
.
isMesh
)
{
const
body
=
meshMap
.
get
(
mesh
);
body
.
setPosition
(
new
Vec3
(
position
.
x
,
position
.
y
,
position
.
z
)
);
}
}
//
let
lastTime
=
0
;
function
step
()
{
const
time
=
performance
.
now
();
if
(
lastTime
>
0
)
{
const
delta
=
(
time
-
lastTime
)
/
1000
;
// console.time( 'world.step' );
world
.
step
(
delta
);
// console.timeEnd( 'world.step' );
}
lastTime
=
time
;
//
for
(
let
i
=
0
,
l
=
meshes
.
length
;
i
<
l
;
i
++
)
{
const
mesh
=
meshes
[
i
];
if
(
mesh
.
isInstancedMesh
)
{
const
array
=
mesh
.
instanceMatrix
.
array
;
const
bodies
=
meshMap
.
get
(
mesh
);
for
(
let
j
=
0
;
j
<
bodies
.
length
;
j
++
)
{
const
body
=
bodies
[
j
];
compose
(
body
.
getPosition
(),
body
.
getOrientation
(),
array
,
j
*
16
);
}
mesh
.
instanceMatrix
.
needsUpdate
=
true
;
}
else
if
(
mesh
.
isMesh
)
{
const
body
=
meshMap
.
get
(
mesh
);
mesh
.
position
.
copy
(
body
.
getPosition
()
);
mesh
.
quaternion
.
copy
(
body
.
getOrientation
()
);
}
}
}
// animate
setInterval
(
step
,
1000
/
frameRate
);
return
{
addMesh
:
addMesh
,
setMeshPosition
:
setMeshPosition
// addCompoundMesh
};
}
function
compose
(
position
,
quaternion
,
array
,
index
)
{
const
x
=
quaternion
.
x
,
y
=
quaternion
.
y
,
z
=
quaternion
.
z
,
w
=
quaternion
.
w
;
const
x2
=
x
+
x
,
y2
=
y
+
y
,
z2
=
z
+
z
;
const
xx
=
x
*
x2
,
xy
=
x
*
y2
,
xz
=
x
*
z2
;
const
yy
=
y
*
y2
,
yz
=
y
*
z2
,
zz
=
z
*
z2
;
const
wx
=
w
*
x2
,
wy
=
w
*
y2
,
wz
=
w
*
z2
;
array
[
index
+
0
]
=
(
1
-
(
yy
+
zz
)
);
array
[
index
+
1
]
=
(
xy
+
wz
);
array
[
index
+
2
]
=
(
xz
-
wy
);
array
[
index
+
3
]
=
0
;
array
[
index
+
4
]
=
(
xy
-
wz
);
array
[
index
+
5
]
=
(
1
-
(
xx
+
zz
)
);
array
[
index
+
6
]
=
(
yz
+
wx
);
array
[
index
+
7
]
=
0
;
array
[
index
+
8
]
=
(
xz
+
wy
);
array
[
index
+
9
]
=
(
yz
-
wx
);
array
[
index
+
10
]
=
(
1
-
(
xx
+
yy
)
);
array
[
index
+
11
]
=
0
;
array
[
index
+
12
]
=
position
.
x
;
array
[
index
+
13
]
=
position
.
y
;
array
[
index
+
14
]
=
position
.
z
;
array
[
index
+
15
]
=
1
;
}
export
{
OimoPhysics
};
examples/physics_oimo_instancing.html
浏览文件 @
e3586288
...
...
@@ -17,42 +17,23 @@
import
*
as
THREE
from
'
../build/three.module.js
'
;
import
{
OrbitControls
}
from
'
./jsm/controls/OrbitControls.js
'
;
import
{
OimoPhysics
}
from
'
./jsm/physics/OimoPhysics.js
'
;
import
Stats
from
'
./jsm/libs/stats.module.js
'
;
// Or use latest version from NPM `oimophysics`
import
{
oimo
}
from
'
./jsm/libs/OimoPhysics.js
'
;
const
Vec3
=
oimo
.
common
.
Vec3
;
const
World
=
oimo
.
dynamics
.
World
;
const
RigidBodyType
=
oimo
.
dynamics
.
rigidbody
.
RigidBodyType
;
const
RigidBodyConfig
=
oimo
.
dynamics
.
rigidbody
.
RigidBodyConfig
;
const
ShapeConfig
=
oimo
.
dynamics
.
rigidbody
.
ShapeConfig
;
const
RigidBody
=
oimo
.
dynamics
.
rigidbody
.
RigidBody
;
const
Shape
=
oimo
.
dynamics
.
rigidbody
.
Shape
;
const
OBoxGeometry
=
oimo
.
collision
.
geometry
.
BoxGeometry
;
const
OSphereGeometry
=
oimo
.
collision
.
geometry
.
SphereGeometry
;
let
camera
,
scene
,
renderer
,
stats
;
let
physics
,
position
;
let
world
;
let
boxes
,
spheres
;
let
boxesPhys
,
spheresPhys
;
const
dummy
=
new
THREE
.
Object3D
();
init
();
async
function
init
()
{
world
=
new
World
(
2
,
new
Vec3
(
0
,
-
9.8
,
0
));
boxesPhys
=
[];
spheresPhys
=
[];
physics
=
await
OimoPhysics
();
position
=
new
THREE
.
Vector3
();
//
camera
=
new
THREE
.
PerspectiveCamera
(
50
,
window
.
innerWidth
/
window
.
innerHeight
,
0.1
,
100
);
camera
.
position
.
set
(
-
1
,
1.5
,
2
);
camera
.
lookAt
(
0
,
0.5
,
0
);
...
...
@@ -76,8 +57,10 @@
);
floor
.
position
.
y
=
-
2.5
;
floor
.
receiveShadow
=
true
;
floor
.
userData
.
physics
=
addRigidBody
(
world
,
vec3FromVector3
(
floor
.
position
),
new
OBoxGeometry
(
new
Vec3
(
10
/
2
,
5
/
2
,
10
/
2
)),
true
);
scene
.
add
(
floor
);
physics
.
addMesh
(
floor
);
//
const
material
=
new
THREE
.
MeshLambertMaterial
();
...
...
@@ -85,8 +68,8 @@
const
color
=
new
THREE
.
Color
();
// Boxes
const
boxSideSize
=
0.1
;
const
geometryBox
=
new
THREE
.
BoxGeometry
(
boxSideSize
,
boxSideSize
,
boxSideSize
);
const
geometryBox
=
new
THREE
.
BoxGeometry
(
0.1
,
0.1
,
0.1
);
boxes
=
new
THREE
.
InstancedMesh
(
geometryBox
,
material
,
100
);
boxes
.
instanceMatrix
.
setUsage
(
THREE
.
DynamicDrawUsage
);
// will be updated every frame
boxes
.
castShadow
=
true
;
...
...
@@ -94,16 +77,17 @@
scene
.
add
(
boxes
);
for
(
let
i
=
0
;
i
<
boxes
.
count
;
i
++
)
{
position
.
set
(
Math
.
random
()
-
0.5
,
Math
.
random
()
*
10
,
Math
.
random
()
-
0.5
);
matrix
.
setPosition
(
position
.
x
,
position
.
y
,
position
.
z
);
matrix
.
setPosition
(
Math
.
random
()
-
0.5
,
Math
.
random
()
*
2
,
Math
.
random
()
-
0.5
);
boxes
.
setMatrixAt
(
i
,
matrix
);
boxes
.
setColorAt
(
i
,
color
.
setHex
(
0xffffff
*
Math
.
random
()
)
);
// size of the side of the cube should be 2 times smaller
boxesPhys
.
push
(
addRigidBody
(
world
,
vec3FromVector3
(
position
),
new
OBoxGeometry
(
new
Vec3
(
boxSideSize
/
2
,
boxSideSize
/
2
,
boxSideSize
/
2
)),
false
));
}
physics
.
addMesh
(
boxes
,
1
);
// Spheres
const
geometrySphere
=
new
THREE
.
IcosahedronGeometry
(
0.075
,
3
);
spheres
=
new
THREE
.
InstancedMesh
(
geometrySphere
,
material
,
100
);
spheres
.
instanceMatrix
.
setUsage
(
THREE
.
DynamicDrawUsage
);
// will be updated every frame
...
...
@@ -112,13 +96,14 @@
scene
.
add
(
spheres
);
for
(
let
i
=
0
;
i
<
spheres
.
count
;
i
++
)
{
position
.
set
(
Math
.
random
()
-
0.5
,
Math
.
random
()
*
10
,
Math
.
random
()
-
0.5
);
matrix
.
setPosition
(
position
.
x
,
position
.
y
,
position
.
z
);
matrix
.
setPosition
(
Math
.
random
()
-
0.5
,
Math
.
random
()
*
2
,
Math
.
random
()
-
0.5
);
spheres
.
setMatrixAt
(
i
,
matrix
);
spheres
.
setColorAt
(
i
,
color
.
setHex
(
0xffffff
*
Math
.
random
()
)
);
spheresPhys
.
push
(
addRigidBody
(
world
,
vec3FromVector3
(
position
),
new
OSphereGeometry
(
0.075
),
false
));
}
physics
.
addMesh
(
spheres
,
1
);
//
...
...
@@ -138,80 +123,32 @@
controls
.
target
.
y
=
0.5
;
controls
.
update
();
window
.
addEventListener
(
'
resize
'
,
onWindowResize
);
animate
();
}
function
onWindowResize
()
{
camera
.
aspect
=
document
.
body
.
clientWidth
/
document
.
body
.
clientHeight
;
camera
.
updateProjectionMatrix
();
renderer
.
setSize
(
document
.
body
.
clientWidth
,
document
.
body
.
clientHeight
);
}
function
animate
()
{
requestAnimationFrame
(
animate
);
world
.
step
(
1
/
60
);
// updating data of visual objects from physical objects
// BOXES
boxesPhys
.
forEach
((
elPhys
,
index
)
=>
{
const
posVec3
=
elPhys
.
getPosition
();
dummy
.
position
.
set
(
posVec3
.
x
,
posVec3
.
y
,
posVec3
.
z
);
dummy
.
setRotationFromQuaternion
(
quaternionFromQuat
(
elPhys
.
getOrientation
()));
dummy
.
updateMatrix
();
boxes
.
setMatrixAt
(
index
,
dummy
.
matrix
);
});
//
let
index
=
Math
.
floor
(
Math
.
random
()
*
boxes
.
count
);
boxesPhys
[
index
].
setPosition
(
new
Vec3
(
0
,
Math
.
random
()
+
1
,
0
)
);
boxes
.
instanceMatrix
.
needsUpdate
=
true
;
position
.
set
(
0
,
Math
.
random
()
+
1
,
0
);
physics
.
setMeshPosition
(
boxes
,
position
,
index
);
// SPHERES
spheresPhys
.
forEach
((
elPhys
,
index
)
=>
{
const
posVec3
=
elPhys
.
getPosition
();
dummy
.
position
.
set
(
posVec3
.
x
,
posVec3
.
y
,
posVec3
.
z
);
dummy
.
setRotationFromQuaternion
(
quaternionFromQuat
(
elPhys
.
getOrientation
()));
dummy
.
updateMatrix
();
spheres
.
setMatrixAt
(
index
,
dummy
.
matrix
);
});
//
index
=
Math
.
floor
(
Math
.
random
()
*
spheres
.
count
);
spheresPhys
[
index
].
setPosition
(
new
Vec3
(
0
,
Math
.
random
()
+
1
,
0
)
);
spheres
.
instanceMatrix
.
needsUpdate
=
true
;
position
.
set
(
0
,
Math
.
random
()
+
1
,
0
);
physics
.
setMeshPosition
(
spheres
,
position
,
index
);
renderer
.
render
(
scene
,
camera
);
stats
.
update
();
}
// adding a physical object to the world of physics
function
addRigidBody
(
w
,
center
,
geom
,
wall
)
{
const
shapeConfig
=
new
ShapeConfig
();
shapeConfig
.
geometry
=
geom
;
const
bodyConfig
=
new
RigidBodyConfig
();
bodyConfig
.
type
=
wall
?
RigidBodyType
.
STATIC
:
RigidBodyType
.
DYNAMIC
;
bodyConfig
.
position
=
center
;
let
body
=
new
RigidBody
(
bodyConfig
);
body
.
addShape
(
new
Shape
(
shapeConfig
));
w
.
addRigidBody
(
body
);
return
body
;
}
// convert threejs Vector3 to oimo Vec3
function
vec3FromVector3
(
position
)
{
return
new
Vec3
(...
position
.
toArray
());
}
// convert oimo Quat to threejs quaternion
function
quaternionFromQuat
(
quat
)
{
return
new
THREE
.
Quaternion
(
quat
.
x
,
quat
.
y
,
quat
.
z
,
quat
.
w
);
}
</script>
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录