@damienmortini/three 0.1.131
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +5 -0
- package/copyExamples.js +15 -0
- package/ecs/THREEView.js +31 -0
- package/examples/loaders/BasisTextureLoader.js +783 -0
- package/examples/loaders/DRACOLoader.js +587 -0
- package/examples/loaders/GLTFLoader.js +4237 -0
- package/examples/objects/Lensflare.js +389 -0
- package/examples/utils/BufferGeometryUtils.js +943 -0
- package/gpgpu/THREEGPGPUSystem.js +175 -0
- package/loader/THREELoader.js +112 -0
- package/loader/meshoptimizerdecoder/THREE.EXT_meshopt_compression.js +41 -0
- package/loader/meshoptimizerdecoder/meshopt_decoder.js +129 -0
- package/material/THREEBaseMaterial.js +68 -0
- package/material/THREEPBRMaterial.js +107 -0
- package/material/THREEShaderMaterial.js +95 -0
- package/object/THREELine.js +113 -0
- package/object/THREEMotionVectorObject.js +284 -0
- package/object/THREERibbon.js +49 -0
- package/object/THREESky.js +279 -0
- package/object/THREESprite.js +96 -0
- package/object/THREESpriteAnimation.js +103 -0
- package/object/THREEText.js +240 -0
- package/package.json +33 -0
- package/renderer/THREERenderer.js +121 -0
- package/renderer/THREEStereoRenderer.js +60 -0
- package/renderer/THREEWebGLRenderTarget2D.js +63 -0
- package/shader/THREEBaseShader.js +33 -0
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { ShaderMaterial } from '../../../three/src/materials/ShaderMaterial.js'
|
|
2
|
+
import { ShaderLib } from '../../../three/src/renderers/shaders/ShaderLib.js'
|
|
3
|
+
import { UniformsUtils } from '../../../three/src/renderers/shaders/UniformsUtils.js'
|
|
4
|
+
import DEFAULT_VERTEX from '../../../three/src/renderers/shaders/ShaderChunk/default_vertex.glsl.js'
|
|
5
|
+
import DEFAULT_FRAGMENT from '../../../three/src/renderers/shaders/ShaderChunk/default_fragment.glsl.js'
|
|
6
|
+
|
|
7
|
+
import Shader from '../../core/3d/Shader.js'
|
|
8
|
+
|
|
9
|
+
const toWebGL1 = (source, type) => {
|
|
10
|
+
source = source.replace(/#version.*?\n/g, '')
|
|
11
|
+
source = source.replace(/\btexture\b/g, 'texture2D')
|
|
12
|
+
if (type === 'vertex') {
|
|
13
|
+
source = source.replace(/(^\s*)\bin\b/gm, '$1attribute')
|
|
14
|
+
source = source.replace(/(^\s*)\bout\b/gm, '$1varying')
|
|
15
|
+
} else {
|
|
16
|
+
source = source.replace(/(^\s*)\bin\b/gm, '$1varying')
|
|
17
|
+
const results = /out vec4 (.*?);/.exec(source)
|
|
18
|
+
if (results) {
|
|
19
|
+
const fragColorName = results[1]
|
|
20
|
+
source = source.replace(/out.*?;/, '')
|
|
21
|
+
source = source.replace(new RegExp(`\\b${fragColorName}\\b`, 'g'), 'gl_FragColor')
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
return source
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export default class THREEShaderMaterial extends ShaderMaterial {
|
|
28
|
+
constructor({
|
|
29
|
+
type = '',
|
|
30
|
+
vertex = undefined,
|
|
31
|
+
fragment = undefined,
|
|
32
|
+
vertexChunks = [],
|
|
33
|
+
fragmentChunks = [],
|
|
34
|
+
uniforms = {},
|
|
35
|
+
...options
|
|
36
|
+
} = {}) {
|
|
37
|
+
const shader = new Shader({
|
|
38
|
+
vertex: vertex || (type ? ShaderLib[type].vertexShader : DEFAULT_VERTEX),
|
|
39
|
+
fragment: fragment || (type ? ShaderLib[type].fragmentShader : DEFAULT_FRAGMENT),
|
|
40
|
+
uniforms,
|
|
41
|
+
vertexChunks,
|
|
42
|
+
fragmentChunks,
|
|
43
|
+
})
|
|
44
|
+
|
|
45
|
+
const threeUniforms = {}
|
|
46
|
+
for (const [key, value] of Object.entries(shader.uniforms)) {
|
|
47
|
+
if (value.value !== undefined) {
|
|
48
|
+
continue
|
|
49
|
+
}
|
|
50
|
+
threeUniforms[key] = {
|
|
51
|
+
value,
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
super({
|
|
56
|
+
fragmentShader: toWebGL1(shader.fragment, 'fragment'),
|
|
57
|
+
vertexShader: toWebGL1(shader.vertex, 'vertex'),
|
|
58
|
+
uniforms: {
|
|
59
|
+
...(type ? UniformsUtils.clone(ShaderLib[type].uniforms) : {}),
|
|
60
|
+
...threeUniforms,
|
|
61
|
+
},
|
|
62
|
+
...options,
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
this.lights = /lambert|phong|standard/.test(type)
|
|
66
|
+
|
|
67
|
+
for (const key of Object.keys(this.uniforms)) {
|
|
68
|
+
Object.defineProperty(this, key, {
|
|
69
|
+
configurable: true,
|
|
70
|
+
get: function () {
|
|
71
|
+
return this.uniforms[key].value
|
|
72
|
+
},
|
|
73
|
+
set: function (value) {
|
|
74
|
+
this.uniforms[key].value = value
|
|
75
|
+
},
|
|
76
|
+
})
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
clone() {
|
|
81
|
+
const clone = super.clone()
|
|
82
|
+
for (const key of Object.keys(clone.uniforms)) {
|
|
83
|
+
Object.defineProperty(clone, key, {
|
|
84
|
+
configurable: true,
|
|
85
|
+
get: function () {
|
|
86
|
+
return this.uniforms[key].value
|
|
87
|
+
},
|
|
88
|
+
set: function (value) {
|
|
89
|
+
this.uniforms[key].value = value
|
|
90
|
+
},
|
|
91
|
+
})
|
|
92
|
+
}
|
|
93
|
+
return clone
|
|
94
|
+
}
|
|
95
|
+
}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import FrenetSerretFrame from '../../core/math/FrenetSerretFrame.js'
|
|
2
|
+
|
|
3
|
+
import THREEShaderMaterial from './THREEShaderMaterial.js'
|
|
4
|
+
|
|
5
|
+
export default class THREELine extends THREE.Mesh {
|
|
6
|
+
constructor({
|
|
7
|
+
points = [new THREE.Vector3(0, -1, 0), new THREE.Vector3(0, 1, 0)],
|
|
8
|
+
material = new THREEShaderMaterial(),
|
|
9
|
+
detail = 3,
|
|
10
|
+
thickness = .1,
|
|
11
|
+
geometry = new THREE.CylinderBufferGeometry(1, 1, points.length - 1, detail, points.length - 1),
|
|
12
|
+
} = {}) {
|
|
13
|
+
super(geometry, material)
|
|
14
|
+
|
|
15
|
+
this.points = points
|
|
16
|
+
|
|
17
|
+
this.userData._thickness = thickness
|
|
18
|
+
this.userData._lineNormals = new Float32Array(this.points.length * 3)
|
|
19
|
+
this.userData._linePositions = new Float32Array(this.points.length * 3)
|
|
20
|
+
|
|
21
|
+
this.frustumCulled = false
|
|
22
|
+
|
|
23
|
+
const positions = this.geometry.getAttribute('position').array
|
|
24
|
+
const verticesNumber = positions.length / 3
|
|
25
|
+
const ids = new Float32Array(verticesNumber)
|
|
26
|
+
const offsetY = (points.length - 1) / 2
|
|
27
|
+
for (let i = 0; i < verticesNumber; i++) {
|
|
28
|
+
ids[i] = positions[i * 3 + 1] + offsetY
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
this.geometry.addAttribute('linePointId', new THREE.BufferAttribute(ids, 1))
|
|
32
|
+
|
|
33
|
+
if (!material.linePositions) {
|
|
34
|
+
material.add({
|
|
35
|
+
vertexShaderChunks: [
|
|
36
|
+
['start', `
|
|
37
|
+
uniform float lineThickness;
|
|
38
|
+
uniform vec3 linePositions[${this.points.length}];
|
|
39
|
+
uniform vec3 lineNormals[${this.points.length}];
|
|
40
|
+
|
|
41
|
+
attribute float linePointId;
|
|
42
|
+
`],
|
|
43
|
+
['main', `
|
|
44
|
+
vec3 position = position;
|
|
45
|
+
vec3 normal = normal;
|
|
46
|
+
|
|
47
|
+
vec3 linePosition = linePositions[int(linePointId)];
|
|
48
|
+
vec3 lineDirection = normalize(linePointId == ${this.points.length - 1}. ? linePosition - linePositions[int(linePointId) - 1] : linePositions[int(linePointId) + 1] - linePosition);
|
|
49
|
+
vec3 lineNormal = lineNormals[int(linePointId)];
|
|
50
|
+
vec3 lineBinormal = cross(lineNormal, lineDirection);
|
|
51
|
+
|
|
52
|
+
mat3 lineRotationMatrix = mat3(
|
|
53
|
+
lineNormal,
|
|
54
|
+
lineDirection,
|
|
55
|
+
lineBinormal
|
|
56
|
+
);
|
|
57
|
+
position.y = 0.;
|
|
58
|
+
position = linePosition + lineRotationMatrix * position * lineThickness;
|
|
59
|
+
normal = lineRotationMatrix * normal;
|
|
60
|
+
`],
|
|
61
|
+
],
|
|
62
|
+
})
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
this.update()
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
onBeforeRender(renderer, scene, camera, geometry, material, group) {
|
|
69
|
+
this.material.lineThickness = this.userData._thickness
|
|
70
|
+
this.material.lineNormals = this.userData._lineNormals
|
|
71
|
+
this.material.linePositions = this.userData._linePositions
|
|
72
|
+
|
|
73
|
+
const threeProgram = renderer.properties.get(material).program
|
|
74
|
+
|
|
75
|
+
if (!threeProgram) {
|
|
76
|
+
return
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
const gl = renderer.getContext()
|
|
80
|
+
const uniforms = threeProgram.getUniforms()
|
|
81
|
+
|
|
82
|
+
gl.useProgram(threeProgram.program)
|
|
83
|
+
uniforms.setValue(gl, 'lineThickness', this.userData._thickness)
|
|
84
|
+
uniforms.setValue(gl, 'lineNormals', this.userData._lineNormals)
|
|
85
|
+
uniforms.setValue(gl, 'linePositions', this.userData._linePositions)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
set thickness(value) {
|
|
89
|
+
this.userData._thickness = value
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
get thickness() {
|
|
93
|
+
return this.userData._thickness
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
update({
|
|
97
|
+
range = [0, this.points.length - 1],
|
|
98
|
+
} = {}) {
|
|
99
|
+
const end = range[1]
|
|
100
|
+
for (let i = range[0]; i <= end; i++) {
|
|
101
|
+
const point = this.points[i]
|
|
102
|
+
this.userData._linePositions[i * 3] = point.x
|
|
103
|
+
this.userData._linePositions[i * 3 + 1] = point.y
|
|
104
|
+
this.userData._linePositions[i * 3 + 2] = point.z
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
FrenetSerretFrame.compute({
|
|
108
|
+
positions: this.userData._linePositions,
|
|
109
|
+
normals: this.userData._lineNormals,
|
|
110
|
+
range,
|
|
111
|
+
})
|
|
112
|
+
}
|
|
113
|
+
}
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
import { Object3D, BufferGeometry, BufferAttribute, AnimationMixer, DataTexture, RGBAFormat, FloatType, RGBFormat, Points, Color, Matrix4 } from '../../../three/src/Three.js'
|
|
2
|
+
import TransformShader from '../../core/shader/TransformShader.js'
|
|
3
|
+
import THREEGPGPUSystem from '../../three/gpgpu/THREEGPGPUSystem.js'
|
|
4
|
+
import THREEShaderMaterial from '../../three/material/THREEShaderMaterial.js'
|
|
5
|
+
|
|
6
|
+
export default class THREEMotionVectorObject extends Object3D {
|
|
7
|
+
constructor({
|
|
8
|
+
renderer,
|
|
9
|
+
gltfData,
|
|
10
|
+
pointsAttributes = undefined,
|
|
11
|
+
material = new THREEShaderMaterial({
|
|
12
|
+
skinning: true,
|
|
13
|
+
type: 'basic',
|
|
14
|
+
uniforms: {
|
|
15
|
+
diffuse: new Color('#ff0000'),
|
|
16
|
+
},
|
|
17
|
+
vertexChunks: [
|
|
18
|
+
['main', `
|
|
19
|
+
gl_PointSize = 2.;
|
|
20
|
+
`],
|
|
21
|
+
],
|
|
22
|
+
}),
|
|
23
|
+
pointCount = undefined,
|
|
24
|
+
}) {
|
|
25
|
+
super()
|
|
26
|
+
|
|
27
|
+
this.loop = false
|
|
28
|
+
|
|
29
|
+
this._pointCount = pointCount
|
|
30
|
+
|
|
31
|
+
this._initialized = false
|
|
32
|
+
|
|
33
|
+
const object = gltfData.scene
|
|
34
|
+
this._mesh = object
|
|
35
|
+
object.traverse((object) => {
|
|
36
|
+
if (object.skeleton) {
|
|
37
|
+
this._mesh = object
|
|
38
|
+
this._mesh.frustumCulled = false
|
|
39
|
+
}
|
|
40
|
+
})
|
|
41
|
+
// this._mesh.visible = false;
|
|
42
|
+
this._mesh.scale.set(0, 0, 0)
|
|
43
|
+
if (!pointsAttributes) {
|
|
44
|
+
pointsAttributes = new Map()
|
|
45
|
+
for (const [name, value] of Object.entries(this._mesh.geometry.attributes)) {
|
|
46
|
+
pointsAttributes.set(name, {
|
|
47
|
+
data: value.array,
|
|
48
|
+
size: value.itemSize,
|
|
49
|
+
})
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
this.add(object)
|
|
53
|
+
|
|
54
|
+
if (this._pointCount) {
|
|
55
|
+
for (const attributeData of pointsAttributes.values()) {
|
|
56
|
+
const newArray = new attributeData.data.constructor(this._pointCount * attributeData.size)
|
|
57
|
+
const stride = attributeData.size
|
|
58
|
+
const difference = Math.floor(attributeData.data.length / newArray.length)
|
|
59
|
+
for (let index = 0; index < this._pointCount; index++) {
|
|
60
|
+
for (let componentIndex = 0; componentIndex < stride; componentIndex++) {
|
|
61
|
+
newArray[index * stride + componentIndex] = attributeData.data[index * stride * difference + componentIndex]
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
attributeData.data = newArray
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
const firstAttribute = pointsAttributes.values().next().value
|
|
68
|
+
this._pointCount = firstAttribute.data.length / firstAttribute.size
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
this._skeleton = this._mesh.skeleton
|
|
72
|
+
|
|
73
|
+
// Create bonesTexture manually
|
|
74
|
+
// https://github.com/mrdoob/three.js/blob/cd41804aa436bb2cfd79797c04985f75c4c63e63/src/renderers/WebGLRenderer.js#L1632
|
|
75
|
+
|
|
76
|
+
// let size = Math.sqrt(this._skeleton.bones.length * 4); // 4 pixels needed for 1 matrix
|
|
77
|
+
// size = MathUtils.ceilPowerOfTwo(size);
|
|
78
|
+
// size = Math.max(size, 4);
|
|
79
|
+
|
|
80
|
+
// const boneMatrices = new Float32Array(size * size * 4); // 4 floats per RGBA pixel
|
|
81
|
+
// boneMatrices.set(this._skeleton.boneMatrices); // copy current values
|
|
82
|
+
|
|
83
|
+
// let boneTexture;
|
|
84
|
+
// if (renderer.capabilities.isWebGL2) {
|
|
85
|
+
// boneTexture = new DataTexture(boneMatrices, size, size, RGBAFormat, FloatType);
|
|
86
|
+
// } else {
|
|
87
|
+
// boneTexture = new DataTexture(Float16.fromFloat32Array(boneMatrices), size, size, RGBAFormat, HalfFloatType);
|
|
88
|
+
// }
|
|
89
|
+
|
|
90
|
+
// this._skeleton.boneMatrices = boneMatrices;
|
|
91
|
+
// this._skeleton.boneTexture = boneTexture;
|
|
92
|
+
// this._skeleton.boneTextureSize = size;
|
|
93
|
+
|
|
94
|
+
//
|
|
95
|
+
|
|
96
|
+
const geometry = new BufferGeometry()
|
|
97
|
+
|
|
98
|
+
for (const [name, attributeData] of pointsAttributes) {
|
|
99
|
+
geometry.setAttribute(name, new BufferAttribute(attributeData.data, attributeData.size))
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
this._points = new Points(geometry, material)
|
|
103
|
+
this._points.isSkinnedMesh = true
|
|
104
|
+
this._points.skeleton = this._skeleton
|
|
105
|
+
this._points.bindMatrix = new Matrix4()
|
|
106
|
+
this._points.bindMatrixInverse = new Matrix4()
|
|
107
|
+
this._points.visible = false
|
|
108
|
+
this._points.frustumCulled = false
|
|
109
|
+
this.add(this._points)
|
|
110
|
+
|
|
111
|
+
const animation = gltfData.animations[0]
|
|
112
|
+
this._animationMixer = new AnimationMixer(object)
|
|
113
|
+
this._animationClip = animation
|
|
114
|
+
this._animationAction = this._animationMixer.clipAction(this._animationClip)
|
|
115
|
+
this._animationAction.play()
|
|
116
|
+
|
|
117
|
+
const pointTextures = new Map()
|
|
118
|
+
const pointTextureSize = Math.ceil(Math.sqrt(this._pointCount))
|
|
119
|
+
for (const [name, attributeData] of pointsAttributes) {
|
|
120
|
+
const textureData = new Float32Array(pointTextureSize * pointTextureSize * attributeData.size)
|
|
121
|
+
textureData.set(attributeData.data)
|
|
122
|
+
const texture = new DataTexture(textureData, pointTextureSize, pointTextureSize, attributeData.size === 3 ? RGBFormat : RGBAFormat, FloatType)
|
|
123
|
+
pointTextures.set(name, texture)
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
this._gpgpuSystem = new THREEGPGPUSystem({
|
|
127
|
+
data: new Float32Array((4 * 3) * this._pointCount),
|
|
128
|
+
stride: 3,
|
|
129
|
+
renderer: renderer,
|
|
130
|
+
format: RGBAFormat,
|
|
131
|
+
uniforms: {
|
|
132
|
+
pointsTextureSize: pointTextureSize,
|
|
133
|
+
pointPositionTexture: pointTextures.get('position'),
|
|
134
|
+
pointSkinIndexTexture: pointTextures.get('skinIndex'),
|
|
135
|
+
pointSkinWeightTexture: pointTextures.get('skinWeight'),
|
|
136
|
+
pointNormalTexture: pointTextures.get('normal'),
|
|
137
|
+
},
|
|
138
|
+
fragmentChunks: [
|
|
139
|
+
['start', `
|
|
140
|
+
uniform float pointsTextureSize;
|
|
141
|
+
uniform highp sampler2D pointPositionTexture;
|
|
142
|
+
uniform highp sampler2D pointNormalTexture;
|
|
143
|
+
uniform highp sampler2D pointSkinIndexTexture;
|
|
144
|
+
uniform highp sampler2D pointSkinWeightTexture;
|
|
145
|
+
|
|
146
|
+
uniform highp sampler2D boneTexture;
|
|
147
|
+
uniform int boneTextureSize;
|
|
148
|
+
|
|
149
|
+
${TransformShader.quaternionFromMatrix()}
|
|
150
|
+
|
|
151
|
+
mat4 getBoneMatrix( const in float i ) {
|
|
152
|
+
float j = i * 4.0;
|
|
153
|
+
float x = mod( j, float( boneTextureSize ) );
|
|
154
|
+
float y = floor( j / float( boneTextureSize ) );
|
|
155
|
+
float dx = 1.0 / float( boneTextureSize );
|
|
156
|
+
float dy = 1.0 / float( boneTextureSize );
|
|
157
|
+
y = dy * ( y + 0.5 );
|
|
158
|
+
vec4 v1 = texture2D( boneTexture, vec2( dx * ( x + 0.5 ), y ) );
|
|
159
|
+
vec4 v2 = texture2D( boneTexture, vec2( dx * ( x + 1.5 ), y ) );
|
|
160
|
+
vec4 v3 = texture2D( boneTexture, vec2( dx * ( x + 2.5 ), y ) );
|
|
161
|
+
vec4 v4 = texture2D( boneTexture, vec2( dx * ( x + 3.5 ), y ) );
|
|
162
|
+
mat4 bone = mat4( v1, v2, v3, v4 );
|
|
163
|
+
return bone;
|
|
164
|
+
}
|
|
165
|
+
`],
|
|
166
|
+
['end', `
|
|
167
|
+
vec3 previousPosition = getDataChunk(0).xyz;
|
|
168
|
+
int chunkIndex = getChunkIndex();
|
|
169
|
+
|
|
170
|
+
float pointID = float(getDataIndex());
|
|
171
|
+
|
|
172
|
+
float x = mod(pointID, pointsTextureSize);
|
|
173
|
+
float y = floor(pointID / pointsTextureSize);
|
|
174
|
+
float dx = 1. / pointsTextureSize;
|
|
175
|
+
float dy = 1. / pointsTextureSize;
|
|
176
|
+
x = dx * (x + .5);
|
|
177
|
+
y = dy * (y + .5);
|
|
178
|
+
|
|
179
|
+
vec3 position = texture(pointPositionTexture, vec2(x, y)).rgb;
|
|
180
|
+
vec3 normal = texture(pointNormalTexture, vec2(x, y)).rgb;
|
|
181
|
+
vec4 skinIndex = texture(pointSkinIndexTexture, vec2(x, y));
|
|
182
|
+
vec4 skinWeight = texture(pointSkinWeightTexture, vec2(x, y));
|
|
183
|
+
|
|
184
|
+
mat4 boneMatX = getBoneMatrix( skinIndex.x );
|
|
185
|
+
mat4 boneMatY = getBoneMatrix( skinIndex.y );
|
|
186
|
+
mat4 boneMatZ = getBoneMatrix( skinIndex.z );
|
|
187
|
+
mat4 boneMatW = getBoneMatrix( skinIndex.w );
|
|
188
|
+
|
|
189
|
+
vec4 data;
|
|
190
|
+
if(chunkIndex < 2) {
|
|
191
|
+
vec4 skinVertex = vec4( position, 1.0 );
|
|
192
|
+
vec4 skinned = vec4( 0.0 );
|
|
193
|
+
skinned += boneMatX * skinVertex * skinWeight.x;
|
|
194
|
+
skinned += boneMatY * skinVertex * skinWeight.y;
|
|
195
|
+
skinned += boneMatZ * skinVertex * skinWeight.z;
|
|
196
|
+
skinned += boneMatW * skinVertex * skinWeight.w;
|
|
197
|
+
|
|
198
|
+
position = skinned.xyz;
|
|
199
|
+
|
|
200
|
+
vec3 velocity = position - previousPosition;
|
|
201
|
+
|
|
202
|
+
if(chunkIndex == 0) {
|
|
203
|
+
data = vec4(position, 0.);
|
|
204
|
+
} else if(chunkIndex == 1) {
|
|
205
|
+
data = vec4(velocity, 0.);
|
|
206
|
+
}
|
|
207
|
+
} else if(chunkIndex == 2) {
|
|
208
|
+
mat4 rotationMatrix = mat4(0.);
|
|
209
|
+
rotationMatrix += skinWeight.x * boneMatX;
|
|
210
|
+
rotationMatrix += skinWeight.y * boneMatY;
|
|
211
|
+
rotationMatrix += skinWeight.z * boneMatZ;
|
|
212
|
+
rotationMatrix += skinWeight.w * boneMatW;
|
|
213
|
+
vec4 quaternion = quaternionFromMatrix(rotationMatrix);
|
|
214
|
+
data = quaternion;
|
|
215
|
+
}
|
|
216
|
+
gl_FragColor = data;
|
|
217
|
+
`],
|
|
218
|
+
],
|
|
219
|
+
})
|
|
220
|
+
this._gpgpuSystem.onBeforeRender = () => {
|
|
221
|
+
this._gpgpuSystem.material.boneTexture = this._skeleton.boneTexture
|
|
222
|
+
this._gpgpuSystem.material.boneTextureSize = this._skeleton.boneTextureSize
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
get pointCount() {
|
|
227
|
+
return this._pointCount
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
get dataTexture() {
|
|
231
|
+
return this._gpgpuSystem.dataTexture
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
get dataTextureStride() {
|
|
235
|
+
return this._gpgpuSystem.stride
|
|
236
|
+
}
|
|
237
|
+
|
|
238
|
+
get dataTextureSize() {
|
|
239
|
+
return this._gpgpuSystem.dataTextureSize
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
get meshVisible() {
|
|
243
|
+
return this._mesh.visible
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
set meshVisible(value) {
|
|
247
|
+
this._mesh.visible = value
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
get pointsVisible() {
|
|
251
|
+
return this._points.visible
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
set pointsVisible(value) {
|
|
255
|
+
this._points.visible = value
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
get currentTime() {
|
|
259
|
+
return this._animationMixer.time
|
|
260
|
+
}
|
|
261
|
+
|
|
262
|
+
set currentTime(value) {
|
|
263
|
+
if (value >= this._animationClip.duration) {
|
|
264
|
+
if (this.loop) {
|
|
265
|
+
value = 0
|
|
266
|
+
} else {
|
|
267
|
+
value = this._animationClip.duration
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
this._animationMixer.setTime(Math.min(value, this._animationClip.duration - .01))
|
|
271
|
+
this._update()
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
_update() {
|
|
275
|
+
if (!this._points.visible && !this._mesh.visible) {
|
|
276
|
+
this._skeleton.update()
|
|
277
|
+
}
|
|
278
|
+
if (!this._initialized) {
|
|
279
|
+
this._gpgpuSystem.update()
|
|
280
|
+
this._initialized = true
|
|
281
|
+
}
|
|
282
|
+
this._gpgpuSystem.update()
|
|
283
|
+
}
|
|
284
|
+
}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Vector3,
|
|
3
|
+
} from '../../../three/build/three.module.js'
|
|
4
|
+
|
|
5
|
+
import THREELine from './THREELine.js'
|
|
6
|
+
|
|
7
|
+
import FrenetSerretFrame from '../math/FrenetSerretFrame.js'
|
|
8
|
+
|
|
9
|
+
export default class THREERibbon extends THREELine {
|
|
10
|
+
constructor({
|
|
11
|
+
points,
|
|
12
|
+
thickness,
|
|
13
|
+
detail,
|
|
14
|
+
geometry,
|
|
15
|
+
material,
|
|
16
|
+
} = {}) {
|
|
17
|
+
super({
|
|
18
|
+
points,
|
|
19
|
+
thickness,
|
|
20
|
+
detail,
|
|
21
|
+
geometry,
|
|
22
|
+
material,
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
this.head = points[this.points.length - 1].clone()
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
update() {
|
|
29
|
+
if (!this._initialized) {
|
|
30
|
+
super.update()
|
|
31
|
+
this._initialized = true
|
|
32
|
+
return
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
this.userData._linePositions.copyWithin(0, 3)
|
|
36
|
+
this.userData._lineNormals.copyWithin(0, 3)
|
|
37
|
+
|
|
38
|
+
const headId = this.points.length - 1
|
|
39
|
+
this.userData._linePositions[headId * 3] = this.head.x
|
|
40
|
+
this.userData._linePositions[headId * 3 + 1] = this.head.y
|
|
41
|
+
this.userData._linePositions[headId * 3 + 2] = this.head.z
|
|
42
|
+
|
|
43
|
+
FrenetSerretFrame.compute({
|
|
44
|
+
positions: this.userData._linePositions,
|
|
45
|
+
normals: this.userData._lineNormals,
|
|
46
|
+
range: [headId - 3, headId],
|
|
47
|
+
})
|
|
48
|
+
}
|
|
49
|
+
}
|