Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
avvy
web-app-avvy-shaderlib
Commits
3160325b
Commit
3160325b
authored
3 years ago
by
Andrey
Committed by
Vlad Gaydukov
3 years ago
Browse files
Options
Download
Email Patches
Plain Diff
Al 7351 grass
parent
df127c17
Changes
11
Hide whitespace changes
Inline
Side-by-side
Showing
11 changed files
build/avvy-shaderlib.js
+103
-4
build/avvy-shaderlib.js
public/js/avvy-shader-editor.js
+152
-39
public/js/avvy-shader-editor.js
src/editor/mocks/MockWind.js
+10
-0
src/editor/mocks/MockWind.js
src/editor/modules/MockController.js
+2
-0
src/editor/modules/MockController.js
src/editor/settings.js
+6
-12
src/editor/settings.js
src/library/ShaderLib.js
+2
-0
src/library/ShaderLib.js
src/library/glsl/vs/grass.vs.glsl
+9
-2
src/library/glsl/vs/grass.vs.glsl
src/library/glsl/vs/wind.vs.glsl
+34
-0
src/library/glsl/vs/wind.vs.glsl
src/library/glsl/vs/wind_pars.vs.glsl
+7
-0
src/library/glsl/vs/wind_pars.vs.glsl
src/library/materials/Grass.js
+5
-3
src/library/materials/Grass.js
src/library/materials/Wind.js
+74
-0
src/library/materials/Wind.js
with
404 additions
and
60 deletions
+404
-60
build/avvy-shaderlib.js
View file @
3160325b
...
...
@@ -136,6 +136,8 @@ Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */
var
__WEBPACK_IMPORTED_MODULE_7__materials_PBR__
=
__webpack_require__
(
27
);
/* harmony import */
var
__WEBPACK_IMPORTED_MODULE_8__materials_Colormap__
=
__webpack_require__
(
28
);
/* harmony import */
var
__WEBPACK_IMPORTED_MODULE_9__materials_Media__
=
__webpack_require__
(
33
);
/* harmony import */
var
__WEBPACK_IMPORTED_MODULE_10__materials_Wind__
=
__webpack_require__
(
38
);
...
...
@@ -160,6 +162,7 @@ function ShaderLib() {
'
PBR
'
:
__WEBPACK_IMPORTED_MODULE_7__materials_PBR__
[
"
a
"
/* PBR */
],
'
colormap
'
:
__WEBPACK_IMPORTED_MODULE_8__materials_Colormap__
[
"
a
"
/* ColorMap */
],
'
media
'
:
__WEBPACK_IMPORTED_MODULE_9__materials_Media__
[
"
a
"
/* Media */
],
'
wind
'
:
__WEBPACK_IMPORTED_MODULE_10__materials_Wind__
[
"
a
"
/* Wind */
],
};
this
.
matObjects
=
{};
...
...
@@ -306,9 +309,10 @@ function Grass(args) {
this
.
uniforms
=
{
uTime
:
{
value
:
0
},
uElevation
:
{
value
:
0.03
},
uFrequency
:
{
value
:
new
THREE
.
Vector2
(
4
,
3
)},
uSpeed
:
{
value
:
1.5
},
uElevation
:
{
value
:
0.3
},
uFrequency
:
{
value
:
new
THREE
.
Vector2
(
1
,
3
)},
uSpeed
:
{
value
:
0.7
},
uHeight
:
{
value
:
0.6
},
uMap
:
{
value
:
args
.
mesh
.
material
.
map
},
};
...
...
@@ -340,6 +344,7 @@ Grass.prototype.prepare = function () {
shader
.
uniforms
.
uElevation
=
this
.
userData
.
uniforms
.
uElevation
;
shader
.
uniforms
.
uFrequency
=
this
.
userData
.
uniforms
.
uFrequency
;
shader
.
uniforms
.
uSpeed
=
this
.
userData
.
uniforms
.
uSpeed
;
shader
.
uniforms
.
uHeight
=
this
.
userData
.
uniforms
.
uHeight
;
this
.
userData
.
shader
=
shader
;
shader
.
fragmentShader
=
__webpack_require__
(
6
)
+
shader
.
fragmentShader
;
...
...
@@ -385,7 +390,7 @@ module.exports = "uniform float uTime;\nuniform float uElevation;\nuniform vec2
/* 9 */
/***/
(
function
(
module
,
exports
)
{
module
.
exports
=
"
/* project_vertex */
\n\n
/*vec4 mvPosition = vec4( transformed, 1.0 );
\n\n
#ifdef USE_INSTANCING
\n
mvPosition = instanceMatrix * mvPosition;
\n
#endif
\n\n
mvPosition = modelViewMatrix * mvPosition;
\n
gl_Position = projectionMatrix * mvPosition;*/
\n\n\n
vec4 mvPosition = vec4( transformed, 1.0 );
\n\n
#ifdef USE_INSTANCING
\n
mvPosition = instanceMatrix * mvPosition;
\n
#endif
\n\n
vec4 modelPosition = modelMatrix * vec4(position, 1.0);
\n
#ifdef USE_INSTANCING
\n
modelPosition = instanceMatrix * modelPosition;
\n
#endif
\n\n
vec4 slWorldPosition = vec4( transformed, 1.0 );
\n\n
#ifdef USE_INSTANCING
\n
slWorldPosition = instanceMatrix * slWorldPosition;
\n
#endif
\n\n
slWorldPosition = modelMatrix * slWorldPosition;
\n\n
vWorldPosition = vec3(slWorldPosition);
\n\n\n\n
float elevationZ = sin(modelPosition.y * uFrequency.x + uTime * uSpeed) *
\n
sin(modelPosition.z * uFrequency.y + uTime * uSpeed) *
\n
uElevation;
\n\n
if (position.y > 0.6) {
\n
modelPosition.z += elevationZ;
\n
}
\n\n
if (position.y > 0.7) {
\n
modelPosition.x += elevationZ;
\n
}
\n\n
vec4 viewPosition = viewMatrix * modelPosition;
\n
vec4 projectedPosition = projectionMatrix * viewPosition;
\n
gl_Position = projectedPosition;
\n\n\n\n\n\n\n\n
/*
\n
uniform float uTime;
\n
uniform float uElevation;
\n
uniform vec2 uFrequency;
\n
uniform float uSpeed;
\n\n
varying vec2 vUv;
\n
varying vec3 worldPosition;
\n\n
void main() {
\n
vec4 modelPosition = modelMatrix * vec4(position, 1.0);
\n
vUv = uv;
\n\n
float elevationZ = sin(modelPosition.y * uFrequency.x + uTime * uSpeed) *
\n
sin(modelPosition.z * uFrequency.y + uTime * uSpeed) *
\n
uElevation;
\n\n
if (position.y > 0.6) {
\n
modelPosition.z += elevationZ;
\n
}
\n\n
if (position.y > 0.7) {
\n
modelPosition.x += elevationZ;
\n
}
\n\n
vec4 mvPosition = vec4( position, 1.0 );
\n
vec4 worldPosition4 = projectionMatrix * mvPosition;
\n
worldPosition = vec3(worldPosition4);
\n\n
vec4 viewPosition = viewMatrix * modelPosition;
\n
vec4 projectedPosition = projectionMatrix * viewPosition;
\n
gl_Position = projectedPosition;
\n
}
\n
*/
\n
"
module
.
exports
=
"
/* project_vertex */
\n\n
/*vec4 mvPosition = vec4( transformed, 1.0 );
\n\n
#ifdef USE_INSTANCING
\n
mvPosition = instanceMatrix * mvPosition;
\n
#endif
\n\n
mvPosition = modelViewMatrix * mvPosition;
\n
gl_Position = projectionMatrix * mvPosition;*/
\n\n\n
vec4 mvPosition = vec4( transformed, 1.0 );
\n\n
#ifdef USE_INSTANCING
\n
mvPosition = instanceMatrix * mvPosition;
\n
#endif
\n\n
vec4 modelPosition = modelMatrix * vec4(position, 1.0);
\n
#ifdef USE_INSTANCING
\n
modelPosition = instanceMatrix * modelPosition;
\n
#endif
\n\n
vec4 slWorldPosition = vec4( transformed, 1.0 );
\n\n
#ifdef USE_INSTANCING
\n
slWorldPosition = instanceMatrix * slWorldPosition;
\n
#endif
\n\n
slWorldPosition = modelMatrix * slWorldPosition;
\n\n
vWorldPosition = vec3(slWorldPosition);
\n\n\n\n
float elevationZ = sin(modelPosition.y * uFrequency.x + uTime * uSpeed) *
\n
sin(modelPosition.z * uFrequency.y + uTime * uSpeed) *
\n
uElevation;
\n\n
if
(uv.y <=0.01) {
\n
modelPosition.x += elevationZ;
\n
}
\n\n\n
/*
\n
if
(position.y > 0.6) {
\n
modelPosition.z += elevationZ;
\n
}
\n
*/
\n
\n
/*
if (position.y > 0.7) {
\n
modelPosition.x += elevationZ;
\n
}
*/
\n\n
vec4 viewPosition = viewMatrix * modelPosition;
\n
vec4 projectedPosition = projectionMatrix * viewPosition;
\n
gl_Position = projectedPosition;
\n\n\n\n\n\n\n\n
/*
\n
uniform float uTime;
\n
uniform float uElevation;
\n
uniform vec2 uFrequency;
\n
uniform float uSpeed;
\n\n
varying vec2 vUv;
\n
varying vec3 worldPosition;
\n\n
void main() {
\n
vec4 modelPosition = modelMatrix * vec4(position, 1.0);
\n
vUv = uv;
\n\n
float elevationZ = sin(modelPosition.y * uFrequency.x + uTime * uSpeed) *
\n
sin(modelPosition.z * uFrequency.y + uTime * uSpeed) *
\n
uElevation;
\n\n
if (position.y > 0.6) {
\n
modelPosition.z += elevationZ;
\n
}
\n\n
if (position.y > 0.7) {
\n
modelPosition.x += elevationZ;
\n
}
\n\n
vec4 mvPosition = vec4( position, 1.0 );
\n
vec4 worldPosition4 = projectionMatrix * mvPosition;
\n
worldPosition = vec3(worldPosition4);
\n\n
vec4 viewPosition = viewMatrix * modelPosition;
\n
vec4 projectedPosition = projectionMatrix * viewPosition;
\n
gl_Position = projectedPosition;
\n
}
\n
*/
\n
"
/***/
}),
/* 10 */
...
...
@@ -981,6 +986,100 @@ module.exports = "varying vec2 _vUV;\nvarying vec4 _vTexCoords;\nvarying vec3 _v
module
.
exports
=
"
vec3 transformed = vec3( position );
\n
_vUV = uv;
\n
"
/***/
}),
/* 38 */
/***/
(
function
(
module
,
__webpack_exports__
,
__webpack_require__
)
{
"
use strict
"
;
/* harmony export (binding) */
__webpack_require__
.
d
(
__webpack_exports__
,
"
a
"
,
function
()
{
return
Wind
;
});
/* harmony import */
var
__WEBPACK_IMPORTED_MODULE_0__core_BaseMaterial__
=
__webpack_require__
(
0
);
function
Wind
(
args
)
{
__WEBPACK_IMPORTED_MODULE_0__core_BaseMaterial__
[
"
a
"
/* BaseMaterial */
].
call
(
this
);
this
.
args
=
args
;
this
.
uniforms
=
{
uTime
:
{
value
:
0
},
uElevation
:
{
value
:
0.1
},
uFrequency
:
{
value
:
new
THREE
.
Vector2
(
10.1
,
10.1
)},
uSpeed
:
{
value
:
3
},
_uHeightCutOff
:
{
value
:
0.6
},
_uHeightFactor
:
{
value
:
1.0
},
uMap
:
{
value
:
args
.
mesh
.
material
.
map
},
};
// set uniforms for unique plants
if
(
this
.
args
.
mesh
.
name
.
toLowerCase
().
includes
(
"
grass
"
))
{
this
.
uniforms
.
uElevation
.
value
=
0.03
;
this
.
uniforms
.
uFrequency
.
value
=
new
THREE
.
Vector2
(
15.1
,
10.1
);
this
.
uniforms
.
uSpeed
.
value
=
1.2
;
this
.
uniforms
.
_uHeightCutOff
.
value
=
0.1
;
this
.
uniforms
.
_uHeightFactor
.
value
=
1.0
;
}
else
{
this
.
uniforms
.
uElevation
.
value
=
0.03
;
this
.
uniforms
.
uFrequency
.
value
=
new
THREE
.
Vector2
(
0.2
,
0.2
);
this
.
uniforms
.
uSpeed
.
value
=
1.5
;
this
.
uniforms
.
_uHeightCutOff
.
value
=
0.1
;
this
.
uniforms
.
_uHeightFactor
.
value
=
1.2
;
}
this
.
material
=
null
;
this
.
prepare
();
}
Wind
.
prototype
=
Object
.
create
(
__WEBPACK_IMPORTED_MODULE_0__core_BaseMaterial__
[
"
a
"
/* BaseMaterial */
].
prototype
);
Wind
.
prototype
.
constructor
=
Wind
;
Wind
.
prototype
.
prepare
=
function
()
{
if
(
!
this
.
args
.
mesh
.
name
.
toLowerCase
().
includes
(
"
ground
"
))
{
this
.
material
=
this
.
copy
(
this
.
args
.
mesh
.
material
);
this
.
material
.
userData
.
effect
=
'
Wind
'
;
this
.
material
.
userData
.
args
=
this
.
args
;
this
.
material
.
userData
.
uniforms
=
this
.
uniforms
;
this
.
material
.
onBeforeCompile
=
function
(
shader
)
{
shader
.
uniforms
.
uTime
=
this
.
userData
.
uniforms
.
uTime
;
shader
.
uniforms
.
uElevation
=
this
.
userData
.
uniforms
.
uElevation
;
shader
.
uniforms
.
uFrequency
=
this
.
userData
.
uniforms
.
uFrequency
;
shader
.
uniforms
.
uSpeed
=
this
.
userData
.
uniforms
.
uSpeed
;
shader
.
uniforms
.
_uHeightCutOff
=
this
.
userData
.
uniforms
.
_uHeightCutOff
;
shader
.
uniforms
.
_uHeightFactor
=
this
.
userData
.
uniforms
.
_uHeightFactor
;
this
.
userData
.
shader
=
shader
;
shader
.
vertexShader
=
__webpack_require__
(
39
)
+
'
\n
'
+
shader
.
vertexShader
;
shader
.
vertexShader
=
shader
.
vertexShader
.
replace
(
'
#include <project_vertex>
'
,
__webpack_require__
(
40
));
};
}
return
this
;
};
Wind
.
prototype
.
update
=
function
(
dt
)
{
this
.
uniforms
.
uTime
.
value
+=
dt
;
};
/***/
}),
/* 39 */
/***/
(
function
(
module
,
exports
)
{
module
.
exports
=
"
uniform float uTime;
\n
uniform float uElevation;
\n
uniform vec2 uFrequency;
\n
uniform float uSpeed;
\n
uniform float _uHeightCutOff;
\n
uniform float _uHeightFactor;
\n
varying vec3 vWorldPosition;
\n
"
/***/
}),
/* 40 */
/***/
(
function
(
module
,
exports
)
{
module
.
exports
=
"
/* project_vertex */
\n\n
/*vec4 mvPosition = vec4( transformed, 1.0 );
\n\n
#ifdef USE_INSTANCING
\n
mvPosition = instanceMatrix * mvPosition;
\n
#endif
\n\n
mvPosition = modelViewMatrix * mvPosition;
\n
gl_Position = projectionMatrix * mvPosition;*/
\n\n
vec4 mvPosition = vec4( transformed, 1.0 );
\n\n
#ifdef USE_INSTANCING
\n
mvPosition = instanceMatrix * mvPosition;
\n
#endif
\n\n\n
if (mvPosition.y > _uHeightCutOff) {
\n\n
float _uHeightFactorTemp = _uHeightFactor * pow(mvPosition.y, _uHeightFactor);
\n
float _time = uTime * (uSpeed );
\n\n
float sinX = sin(mvPosition.y * uFrequency.x + _time);
\n
float sinY = sin(mvPosition.x * uFrequency.x + _time);
\n
float sinZ = sin(mvPosition.z * uFrequency.x + _time);
\n\n
mvPosition.x += sinY * sinZ *uElevation *_uHeightFactorTemp;
\n
// mvPosition.z += sinX * sinZ *uElevation *_uHeightFactorTemp ;
\n\n
}
\n\n
mvPosition = modelViewMatrix * mvPosition;
\n
gl_Position = projectionMatrix * mvPosition;
\n
"
/***/
})
/******/
]);
});
\ No newline at end of file
This diff is collapsed.
Click to expand it.
public/js/avvy-shader-editor.js
View file @
3160325b
...
...
@@ -2167,26 +2167,20 @@ const STORAGE_URL = 'https://storage.avvyland.com/storage/';
const BLOCK_ID = [
"16931423808309446",
"1847627816334127697",
"5228118637965422810",
"1693498425197436682",
"1693498425197436682",
"5075465772448925158",
"17617086485307841930",
"7754572731808253331",
"15212218644260260682",
"17717244977373136322",
"3617736336555860836", // Butterfly
"1471741924937770818", // canna
"8805722609902303857", // tullti
"8580434025816511197", //grass
];
/* harmony export (immutable) */ __webpack_exports__["c"] = BLOCK_ID;
const ACTIVE_BLOCK = BLOCK_ID[
8
];
const ACTIVE_BLOCK = BLOCK_ID[
2
];
/* harmony export (immutable) */ __webpack_exports__["a"] = ACTIVE_BLOCK;
const ACTIVE_SHADER = '
media
';
const ACTIVE_SHADER = '
wind
';
/* harmony export (immutable) */ __webpack_exports__["b"] = ACTIVE_SHADER;
...
...
@@ -2199,8 +2193,8 @@ const ACTIVE_SHADER = 'media';
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_avvyland_editor_src_core__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__modules_Viewer__ = __webpack_require__(25);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__modules_AssetsLoader__ = __webpack_require__(6
6
);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__modules_MockController__ = __webpack_require__(
6
7);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__modules_AssetsLoader__ = __webpack_require__(6
9
);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__modules_MockController__ = __webpack_require__(7
0
);
...
...
@@ -16459,6 +16453,8 @@ var index = {
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__materials_PBR__ = __webpack_require__(55);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__materials_Colormap__ = __webpack_require__(56);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__materials_Media__ = __webpack_require__(61);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__materials_Wind__ = __webpack_require__(66);
...
...
@@ -16483,6 +16479,7 @@ function ShaderLib() {
'PBR': __WEBPACK_IMPORTED_MODULE_7__materials_PBR__["a" /* PBR */],
'colormap': __WEBPACK_IMPORTED_MODULE_8__materials_Colormap__["a" /* ColorMap */],
'media': __WEBPACK_IMPORTED_MODULE_9__materials_Media__["a" /* Media */],
'wind': __WEBPACK_IMPORTED_MODULE_10__materials_Wind__["a" /* Wind */],
};
this.matObjects = {};
...
...
@@ -16629,9 +16626,10 @@ function Grass(args) {
this.uniforms = {
uTime: {value: 0},
uElevation: {value: 0.03},
uFrequency: {value: new THREE.Vector2(4, 3)},
uSpeed: {value: 1.5},
uElevation: {value: 0.3},
uFrequency: {value: new THREE.Vector2(1, 3)},
uSpeed: {value: 0.7},
uHeight: {value: 0.6},
uMap: {value: args.mesh.material.map},
};
...
...
@@ -16663,6 +16661,7 @@ Grass.prototype.prepare = function () {
shader.uniforms.uElevation = this.userData.uniforms.uElevation;
shader.uniforms.uFrequency = this.userData.uniforms.uFrequency;
shader.uniforms.uSpeed = this.userData.uniforms.uSpeed;
shader.uniforms.uHeight = this.userData.uniforms.uHeight;
this.userData.shader = shader;
shader.fragmentShader = __webpack_require__(34) + shader.fragmentShader;
...
...
@@ -16708,7 +16707,7 @@ module.exports = "uniform float uTime;\nuniform float uElevation;\nuniform vec2
/* 37 */
/***/ (function(module, exports) {
module.exports = "/* project_vertex */\n\n/*vec4 mvPosition = vec4( transformed, 1.0 );\n\n#ifdef USE_INSTANCING\n mvPosition = instanceMatrix * mvPosition;\n#endif\n\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;*/\n\n\nvec4 mvPosition = vec4( transformed, 1.0 );\n\n#ifdef USE_INSTANCING\n mvPosition = instanceMatrix * mvPosition;\n#endif\n\nvec4 modelPosition = modelMatrix * vec4(position, 1.0);\n#ifdef USE_INSTANCING\n modelPosition = instanceMatrix * modelPosition;\n#endif\n\nvec4 slWorldPosition = vec4( transformed, 1.0 );\n\n#ifdef USE_INSTANCING\n slWorldPosition = instanceMatrix * slWorldPosition;\n#endif\n\nslWorldPosition = modelMatrix * slWorldPosition;\n\nvWorldPosition = vec3(slWorldPosition);\n\n\n\nfloat elevationZ = sin(modelPosition.y * uFrequency.x + uTime * uSpeed) *\n sin(modelPosition.z * uFrequency.y + uTime * uSpeed) *\n uElevation;\n\nif (position.y > 0.6) {\n modelPosition.z += elevationZ;\n}\n\nif (position.y > 0.7) {\n modelPosition.x += elevationZ;\n}\n\nvec4 viewPosition = viewMatrix * modelPosition;\nvec4 projectedPosition = projectionMatrix * viewPosition;\ngl_Position = projectedPosition;\n\n\n\n\n\n\n\n/*\nuniform float uTime;\nuniform float uElevation;\nuniform vec2 uFrequency;\nuniform float uSpeed;\n\nvarying vec2 vUv;\nvarying vec3 worldPosition;\n\nvoid main() {\n vec4 modelPosition = modelMatrix * vec4(position, 1.0);\n vUv = uv;\n\n float elevationZ = sin(modelPosition.y * uFrequency.x + uTime * uSpeed) *\n sin(modelPosition.z * uFrequency.y + uTime * uSpeed) *\n uElevation;\n\n if (position.y > 0.6) {\n modelPosition.z += elevationZ;\n }\n\n if (position.y > 0.7) {\n modelPosition.x += elevationZ;\n }\n\n vec4 mvPosition = vec4( position, 1.0 );\n vec4 worldPosition4 = projectionMatrix * mvPosition;\n worldPosition = vec3(worldPosition4);\n\n vec4 viewPosition = viewMatrix * modelPosition;\n vec4 projectedPosition = projectionMatrix * viewPosition;\n gl_Position = projectedPosition;\n}\n*/\n"
module.exports = "/* project_vertex */\n\n/*vec4 mvPosition = vec4( transformed, 1.0 );\n\n#ifdef USE_INSTANCING\n mvPosition = instanceMatrix * mvPosition;\n#endif\n\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;*/\n\n\nvec4 mvPosition = vec4( transformed, 1.0 );\n\n#ifdef USE_INSTANCING\n mvPosition = instanceMatrix * mvPosition;\n#endif\n\nvec4 modelPosition = modelMatrix * vec4(position, 1.0);\n#ifdef USE_INSTANCING\n modelPosition = instanceMatrix * modelPosition;\n#endif\n\nvec4 slWorldPosition = vec4( transformed, 1.0 );\n\n#ifdef USE_INSTANCING\n slWorldPosition = instanceMatrix * slWorldPosition;\n#endif\n\nslWorldPosition = modelMatrix * slWorldPosition;\n\nvWorldPosition = vec3(slWorldPosition);\n\n\n\nfloat elevationZ = sin(modelPosition.y * uFrequency.x + uTime * uSpeed) *\n sin(modelPosition.z * uFrequency.y + uTime * uSpeed) *\n uElevation;\n\nif
(uv.y <=0.01) {\n modelPosition.x += elevationZ;\n}\n\n\n/*\nif
(position.y > 0.6) {\n modelPosition.z += elevationZ;\n}\n
*/\n
\n
/*
if (position.y > 0.7) {\n modelPosition.x += elevationZ;\n}
*/
\n\nvec4 viewPosition = viewMatrix * modelPosition;\nvec4 projectedPosition = projectionMatrix * viewPosition;\ngl_Position = projectedPosition;\n\n\n\n\n\n\n\n/*\nuniform float uTime;\nuniform float uElevation;\nuniform vec2 uFrequency;\nuniform float uSpeed;\n\nvarying vec2 vUv;\nvarying vec3 worldPosition;\n\nvoid main() {\n vec4 modelPosition = modelMatrix * vec4(position, 1.0);\n vUv = uv;\n\n float elevationZ = sin(modelPosition.y * uFrequency.x + uTime * uSpeed) *\n sin(modelPosition.z * uFrequency.y + uTime * uSpeed) *\n uElevation;\n\n if (position.y > 0.6) {\n modelPosition.z += elevationZ;\n }\n\n if (position.y > 0.7) {\n modelPosition.x += elevationZ;\n }\n\n vec4 mvPosition = vec4( position, 1.0 );\n vec4 worldPosition4 = projectionMatrix * mvPosition;\n worldPosition = vec3(worldPosition4);\n\n vec4 viewPosition = viewMatrix * modelPosition;\n vec4 projectedPosition = projectionMatrix * viewPosition;\n gl_Position = projectedPosition;\n}\n*/\n"
/***/ }),
/* 38 */
...
...
@@ -17308,6 +17307,100 @@ module.exports = "vec3 transformed = vec3( position );\n_vUV = uv;\n"
/* 66 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return Wind; });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0__core_BaseMaterial__ = __webpack_require__(1);
function Wind(args) {
__WEBPACK_IMPORTED_MODULE_0__core_BaseMaterial__["a" /* BaseMaterial */].call(this);
this.args = args;
this.uniforms = {
uTime: {value: 0},
uElevation: {value: 0.1},
uFrequency: {value: new THREE.Vector2(10.1, 10.1)},
uSpeed: {value: 3},
_uHeightCutOff: {value: 0.6},
_uHeightFactor: {value: 1.0},
uMap: {value: args.mesh.material.map},
};
// set uniforms for unique plants
if (this.args.mesh.name.toLowerCase().includes("grass")) {
this.uniforms.uElevation.value = 0.03;
this.uniforms.uFrequency.value = new THREE.Vector2(15.1, 10.1);
this.uniforms.uSpeed.value = 1.2;
this.uniforms._uHeightCutOff.value = 0.1;
this.uniforms._uHeightFactor.value = 1.0;
} else {
this.uniforms.uElevation.value = 0.03;
this.uniforms.uFrequency.value = new THREE.Vector2(0.2, 0.2);
this.uniforms.uSpeed.value = 1.5;
this.uniforms._uHeightCutOff.value = 0.1;
this.uniforms._uHeightFactor.value = 1.2;
}
this.material = null;
this.prepare();
}
Wind.prototype = Object.create(__WEBPACK_IMPORTED_MODULE_0__core_BaseMaterial__["a" /* BaseMaterial */].prototype);
Wind.prototype.constructor = Wind;
Wind.prototype.prepare = function () {
if (!this.args.mesh.name.toLowerCase().includes("ground")) {
this.material = this.copy(this.args.mesh.material);
this.material.userData.effect = 'Wind';
this.material.userData.args = this.args;
this.material.userData.uniforms = this.uniforms;
this.material.onBeforeCompile = function (shader) {
shader.uniforms.uTime = this.userData.uniforms.uTime;
shader.uniforms.uElevation = this.userData.uniforms.uElevation;
shader.uniforms.uFrequency = this.userData.uniforms.uFrequency;
shader.uniforms.uSpeed = this.userData.uniforms.uSpeed;
shader.uniforms._uHeightCutOff = this.userData.uniforms._uHeightCutOff;
shader.uniforms._uHeightFactor = this.userData.uniforms._uHeightFactor;
this.userData.shader = shader;
shader.vertexShader = __webpack_require__(67) + '\n' + shader.vertexShader;
shader.vertexShader = shader.vertexShader.replace('#include <project_vertex>',
__webpack_require__(68));
};
}
return this;
};
Wind.prototype.update = function (dt) {
this.uniforms.uTime.value += dt;
};
/***/ }),
/* 67 */
/***/ (function(module, exports) {
module.exports = "uniform float uTime;\nuniform float uElevation;\nuniform vec2 uFrequency;\nuniform float uSpeed;\nuniform float _uHeightCutOff;\nuniform float _uHeightFactor;\nvarying vec3 vWorldPosition;\n"
/***/ }),
/* 68 */
/***/ (function(module, exports) {
module.exports = "/* project_vertex */\n\n/*vec4 mvPosition = vec4( transformed, 1.0 );\n\n#ifdef USE_INSTANCING\n mvPosition = instanceMatrix * mvPosition;\n#endif\n\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;*/\n\nvec4 mvPosition = vec4( transformed, 1.0 );\n\n#ifdef USE_INSTANCING\n mvPosition = instanceMatrix * mvPosition;\n#endif\n\n\nif (mvPosition.y > _uHeightCutOff) {\n\n float _uHeightFactorTemp = _uHeightFactor * pow(mvPosition.y, _uHeightFactor);\n float _time = uTime * (uSpeed );\n\n float sinX = sin(mvPosition.y * uFrequency.x + _time);\n float sinY = sin(mvPosition.x * uFrequency.x + _time);\n float sinZ = sin(mvPosition.z * uFrequency.x + _time);\n\n mvPosition.x += sinY * sinZ *uElevation *_uHeightFactorTemp;\n // mvPosition.z += sinX * sinZ *uElevation *_uHeightFactorTemp ;\n\n}\n\nmvPosition = modelViewMatrix * mvPosition;\ngl_Position = projectionMatrix * mvPosition;\n"
/***/ }),
/* 69 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return AssetsLoader; });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_avvyland_editor_src_core__ = __webpack_require__(2);
...
...
@@ -17393,22 +17486,24 @@ AssetsLoader.prototype = {
/***/ }),
/*
6
7 */
/* 7
0
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return MockController; });
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_0_avvyland_editor_src_core__ = __webpack_require__(2);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__mocks_MockSimple__ = __webpack_require__(68);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mocks_MockTestAnim__ = __webpack_require__(69);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__mocks_MockWater__ = __webpack_require__(70);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__mocks_MockGrass__ = __webpack_require__(71);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__mocks_MockTargetMesh__ = __webpack_require__(72);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__mocks_MockOutline__ = __webpack_require__(73);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__mocks_MockFlower__ = __webpack_require__(74);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__mocks_MockPBR__ = __webpack_require__(75);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__mocks_MockColorMap__ = __webpack_require__(76);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__mocks_MockMedia__ = __webpack_require__(77);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_1__mocks_MockSimple__ = __webpack_require__(71);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_2__mocks_MockTestAnim__ = __webpack_require__(72);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_3__mocks_MockWater__ = __webpack_require__(73);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_4__mocks_MockGrass__ = __webpack_require__(74);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_5__mocks_MockTargetMesh__ = __webpack_require__(75);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_6__mocks_MockOutline__ = __webpack_require__(76);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_7__mocks_MockFlower__ = __webpack_require__(77);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_8__mocks_MockPBR__ = __webpack_require__(78);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_9__mocks_MockColorMap__ = __webpack_require__(79);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_10__mocks_MockMedia__ = __webpack_require__(80);
/* harmony import */ var __WEBPACK_IMPORTED_MODULE_11__mocks_MockWind__ = __webpack_require__(81);
...
...
@@ -17434,6 +17529,7 @@ function MockController() {
'flower': new __WEBPACK_IMPORTED_MODULE_7__mocks_MockFlower__["a" /* MockFlower */](),
'colormap': new __WEBPACK_IMPORTED_MODULE_9__mocks_MockColorMap__["a" /* MockColorMap */](),
'media': new __WEBPACK_IMPORTED_MODULE_10__mocks_MockMedia__["a" /* MockMedia */](),
'wind': new __WEBPACK_IMPORTED_MODULE_11__mocks_MockWind__["a" /* MockWind */](),
};
const _this = this;
...
...
@@ -17447,7 +17543,7 @@ MockController.prototype.constructor = MockController;
/***/ }),
/*
68
*/
/*
71
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17464,7 +17560,7 @@ MockSimple.prototype.getMock = function () {
/***/ }),
/*
69
*/
/*
72
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17481,7 +17577,7 @@ MockTestAnim.prototype.getMock = function () {
/***/ }),
/* 7
0
*/
/* 7
3
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17498,7 +17594,7 @@ MockWater.prototype.getMock = function () {
/***/ }),
/* 7
1
*/
/* 7
4
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17531,7 +17627,7 @@ MockGrass.prototype.getMock = function () {
/***/ }),
/* 7
2
*/
/* 7
5
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17553,7 +17649,7 @@ MockTargetMesh.prototype.getMock = function () {
/***/ }),
/* 7
3
*/
/* 7
6
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17586,7 +17682,7 @@ MockOutline.prototype.getMock = function () {
/***/ }),
/* 7
4
*/
/* 7
7
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17606,7 +17702,7 @@ MockFlower.prototype.getMock = function () {
/***/ }),
/* 7
5
*/
/* 7
8
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17623,7 +17719,7 @@ MockPBR.prototype.getMock = function () {
/***/ }),
/* 7
6
*/
/* 7
9
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17645,7 +17741,7 @@ MockColorMap.prototype.getMock = function () {
/***/ }),
/*
77
*/
/*
80
*/
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
...
...
@@ -17666,5 +17762,22 @@ MockMedia.prototype.getMock = function () {
};
/***/ }),
/* 81 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "a", function() { return MockWind; });
function MockWind() {
}
MockWind.prototype.constructor = MockWind;
MockWind.prototype.getMock = function () {
return {}
};
/***/ })
/******/ ]);
\ No newline at end of file
This diff is collapsed.
Click to expand it.
src/editor/mocks/MockWind.js
0 → 100644
View file @
3160325b
function
MockWind
()
{
}
MockWind
.
prototype
.
constructor
=
MockWind
;
MockWind
.
prototype
.
getMock
=
function
()
{
return
{}
};
export
{
MockWind
}
\ No newline at end of file
This diff is collapsed.
Click to expand it.
src/editor/modules/MockController.js
View file @
3160325b
...
...
@@ -9,6 +9,7 @@ import {MockFlower} from "../mocks/MockFlower";
import
{
MockPBR
}
from
"
../mocks/MockPBR
"
;
import
{
MockColorMap
}
from
"
../mocks/MockColorMap
"
;
import
{
MockMedia
}
from
"
../mocks/MockMedia
"
;
import
{
MockWind
}
from
"
../mocks/MockWind
"
;
function
MockController
()
{
...
...
@@ -23,6 +24,7 @@ function MockController() {
'
flower
'
:
new
MockFlower
(),
'
colormap
'
:
new
MockColorMap
(),
'
media
'
:
new
MockMedia
(),
'
wind
'
:
new
MockWind
(),
};
const
_this
=
this
;
...
...
This diff is collapsed.
Click to expand it.
src/editor/settings.js
View file @
3160325b
...
...
@@ -2,19 +2,13 @@
export
const
STORAGE_URL
=
'
https://storage.avvyland.com/storage/
'
;
export
const
BLOCK_ID
=
[
"
16931423808309446
"
,
"
1847627816334127697
"
,
"
5228118637965422810
"
,
"
1693498425197436682
"
,
"
1693498425197436682
"
,
"
5075465772448925158
"
,
"
17617086485307841930
"
,
"
7754572731808253331
"
,
"
15212218644260260682
"
,
"
17717244977373136322
"
,
"
3617736336555860836
"
,
// Butterfly
"
1471741924937770818
"
,
// canna
"
8805722609902303857
"
,
// tullti
"
8580434025816511197
"
,
//grass
];
export
const
ACTIVE_BLOCK
=
BLOCK_ID
[
8
];
export
const
ACTIVE_SHADER
=
'
media
'
;
export
const
ACTIVE_BLOCK
=
BLOCK_ID
[
2
];
export
const
ACTIVE_SHADER
=
'
wind
'
;
This diff is collapsed.
Click to expand it.
src/library/ShaderLib.js
View file @
3160325b
...
...
@@ -8,6 +8,7 @@ import {Simple} from "./materials/Simple";
import
{
PBR
}
from
"
./materials/PBR
"
;
import
{
ColorMap
}
from
"
./materials/Colormap
"
;
import
{
Media
}
from
"
./materials/Media
"
;
import
{
Wind
}
from
"
./materials/Wind
"
;
function
ShaderLib
()
{
...
...
@@ -22,6 +23,7 @@ function ShaderLib() {
'
PBR
'
:
PBR
,
'
colormap
'
:
ColorMap
,
'
media
'
:
Media
,
'
wind
'
:
Wind
,
};
this
.
matObjects
=
{};
...
...
This diff is collapsed.
Click to expand it.
src/library/glsl/vs/grass.vs.glsl
View file @
3160325b
...
...
@@ -37,13 +37,20 @@ float elevationZ = sin(modelPosition.y * uFrequency.x + uTime * uSpeed) *
sin
(
modelPosition
.
z
*
uFrequency
.
y
+
uTime
*
uSpeed
)
*
uElevation
;
if
(
uv
.
y
<=
0
.
01
)
{
modelPosition
.
x
+=
elevationZ
;
}
/*
if (position.y > 0.6) {
modelPosition.z += elevationZ;
}
*/
if
(
position
.
y
>
0
.
7
)
{
/*
if (position.y > 0.7) {
modelPosition.x += elevationZ;
}
}
*/
vec4
viewPosition
=
viewMatrix
*
modelPosition
;
vec4
projectedPosition
=
projectionMatrix
*
viewPosition
;
...
...
This diff is collapsed.
Click to expand it.
src/library/glsl/vs/wind.vs.glsl
0 → 100644
View file @
3160325b
/* project_vertex */
/*vec4 mvPosition = vec4( transformed, 1.0 );
#ifdef USE_INSTANCING
mvPosition = instanceMatrix * mvPosition;
#endif
mvPosition = modelViewMatrix * mvPosition;
gl_Position = projectionMatrix * mvPosition;*/
vec4
mvPosition
=
vec4
(
transformed
,
1
.
0
);
#ifdef USE_INSTANCING
mvPosition
=
instanceMatrix
*
mvPosition
;
#endif
if
(
mvPosition
.
y
>
_uHeightCutOff
)
{
float
_uHeightFactorTemp
=
_uHeightFactor
*
pow
(
mvPosition
.
y
,
_uHeightFactor
);
float
_time
=
uTime
*
(
uSpeed
);
float
sinX
=
sin
(
mvPosition
.
y
*
uFrequency
.
x
+
_time
);
float
sinY
=
sin
(
mvPosition
.
x
*
uFrequency
.
x
+
_time
);
float
sinZ
=
sin
(
mvPosition
.
z
*
uFrequency
.
x
+
_time
);
mvPosition
.
x
+=
sinY
*
sinZ
*
uElevation
*
_uHeightFactorTemp
;
// mvPosition.z += sinX * sinZ *uElevation *_uHeightFactorTemp ;
}
mvPosition
=
modelViewMatrix
*
mvPosition
;
gl_Position
=
projectionMatrix
*
mvPosition
;
This diff is collapsed.
Click to expand it.
src/library/glsl/vs/wind_pars.vs.glsl
0 → 100644
View file @
3160325b
uniform
float
uTime
;
uniform
float
uElevation
;
uniform
vec2
uFrequency
;
uniform
float
uSpeed
;
uniform
float
_uHeightCutOff
;
uniform
float
_uHeightFactor
;
varying
vec3
vWorldPosition
;
This diff is collapsed.
Click to expand it.
src/library/materials/Grass.js
View file @
3160325b
...
...
@@ -7,9 +7,10 @@ function Grass(args) {
this
.
uniforms
=
{
uTime
:
{
value
:
0
},
uElevation
:
{
value
:
0.03
},
uFrequency
:
{
value
:
new
THREE
.
Vector2
(
4
,
3
)},
uSpeed
:
{
value
:
1.5
},
uElevation
:
{
value
:
0.3
},
uFrequency
:
{
value
:
new
THREE
.
Vector2
(
1
,
3
)},
uSpeed
:
{
value
:
0.7
},
uHeight
:
{
value
:
0.6
},
uMap
:
{
value
:
args
.
mesh
.
material
.
map
},
};
...
...
@@ -41,6 +42,7 @@ Grass.prototype.prepare = function () {
shader
.
uniforms
.
uElevation
=
this
.
userData
.
uniforms
.
uElevation
;
shader
.
uniforms
.
uFrequency
=
this
.
userData
.
uniforms
.
uFrequency
;
shader
.
uniforms
.
uSpeed
=
this
.
userData
.
uniforms
.
uSpeed
;
shader
.
uniforms
.
uHeight
=
this
.
userData
.
uniforms
.
uHeight
;
this
.
userData
.
shader
=
shader
;
shader
.
fragmentShader
=
require
(
'
../glsl/fs/grass_pars.fs.glsl
'
)
+
shader
.
fragmentShader
;
...
...
This diff is collapsed.
Click to expand it.
src/library/materials/Wind.js
0 → 100644
View file @
3160325b
import
{
BaseMaterial
}
from
"
../core/BaseMaterial
"
;
function
Wind
(
args
)
{
BaseMaterial
.
call
(
this
);
this
.
args
=
args
;
this
.
uniforms
=
{
uTime
:
{
value
:
0
},
uElevation
:
{
value
:
0.1
},
uFrequency
:
{
value
:
new
THREE
.
Vector2
(
10.1
,
10.1
)},
uSpeed
:
{
value
:
3
},
_uHeightCutOff
:
{
value
:
0.6
},
_uHeightFactor
:
{
value
:
1.0
},
uMap
:
{
value
:
args
.
mesh
.
material
.
map
},
};
// set uniforms for unique plants
if
(
this
.
args
.
mesh
.
name
.
toLowerCase
().
includes
(
"
grass
"
))
{
this
.
uniforms
.
uElevation
.
value
=
0.03
;
this
.
uniforms
.
uFrequency
.
value
=
new
THREE
.
Vector2
(
15.1
,
10.1
);
this
.
uniforms
.
uSpeed
.
value
=
1.2
;
this
.
uniforms
.
_uHeightCutOff
.
value
=
0.1
;
this
.
uniforms
.
_uHeightFactor
.
value
=
1.0
;
}
else
{
this
.
uniforms
.
uElevation
.
value
=
0.03
;
this
.
uniforms
.
uFrequency
.
value
=
new
THREE
.
Vector2
(
0.2
,
0.2
);
this
.
uniforms
.
uSpeed
.
value
=
1.5
;
this
.
uniforms
.
_uHeightCutOff
.
value
=
0.1
;
this
.
uniforms
.
_uHeightFactor
.
value
=
1.2
;
}
this
.
material
=
null
;
this
.
prepare
();
}
Wind
.
prototype
=
Object
.
create
(
BaseMaterial
.
prototype
);
Wind
.
prototype
.
constructor
=
Wind
;
Wind
.
prototype
.
prepare
=
function
()
{
if
(
!
this
.
args
.
mesh
.
name
.
toLowerCase
().
includes
(
"
ground
"
))
{
this
.
material
=
this
.
copy
(
this
.
args
.
mesh
.
material
);
this
.
material
.
userData
.
effect
=
'
Wind
'
;
this
.
material
.
userData
.
args
=
this
.
args
;
this
.
material
.
userData
.
uniforms
=
this
.
uniforms
;
this
.
material
.
onBeforeCompile
=
function
(
shader
)
{
shader
.
uniforms
.
uTime
=
this
.
userData
.
uniforms
.
uTime
;
shader
.
uniforms
.
uElevation
=
this
.
userData
.
uniforms
.
uElevation
;
shader
.
uniforms
.
uFrequency
=
this
.
userData
.
uniforms
.
uFrequency
;
shader
.
uniforms
.
uSpeed
=
this
.
userData
.
uniforms
.
uSpeed
;
shader
.
uniforms
.
_uHeightCutOff
=
this
.
userData
.
uniforms
.
_uHeightCutOff
;
shader
.
uniforms
.
_uHeightFactor
=
this
.
userData
.
uniforms
.
_uHeightFactor
;
this
.
userData
.
shader
=
shader
;
shader
.
vertexShader
=
require
(
'
../glsl/vs/wind_pars.vs.glsl
'
)
+
'
\n
'
+
shader
.
vertexShader
;
shader
.
vertexShader
=
shader
.
vertexShader
.
replace
(
'
#include <project_vertex>
'
,
require
(
'
../glsl/vs/wind.vs.glsl
'
));
};
}
return
this
;
};
Wind
.
prototype
.
update
=
function
(
dt
)
{
this
.
uniforms
.
uTime
.
value
+=
dt
;
};
export
{
Wind
};
\ No newline at end of file
This diff is collapsed.
Click to expand it.
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
Menu
Projects
Groups
Snippets
Help