-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add Silo and Ditch PROTO models (#6295)
* Add Ditch PROTO * Add Silo * Update documentation url * Update Changelog * Update projects/objects/buildings/protos/Silo.proto Co-authored-by: Benjamin Délèze <benjamin.deleze@cyberbotics.com> * Update projects/objects/floors/protos/Ditch.proto Co-authored-by: Benjamin Délèze <benjamin.deleze@cyberbotics.com> * Update Silo.proto * Update Silo.proto * Improve JS in Silo.proto * Update paramete descriptions in Ditch.proto * Add new PROTO objects in boomer.wbt * Update Silo PROTO --------- Co-authored-by: Benjamin Délèze <benjamin.deleze@cyberbotics.com>
- Loading branch information
1 parent
46f8efa
commit 281e6a9
Showing
8 changed files
with
517 additions
and
1,781 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,182 @@ | ||
#VRML_SIM R2023b utf8 | ||
# license: Copyright Cyberbotics Ltd. Licensed for use only with Webots. | ||
# license url: https://cyberbotics.com/webots_assets_license | ||
# documentation url: https://webots.cloud/run?url=https://github.com/cyberbotics/webots/blob/released/projects/objects/buildings/protos/Silo.proto | ||
# keywords: building/farm | ||
# A steel grain silo. | ||
# template language: javascript | ||
|
||
EXTERNPROTO "webots://projects/appearances/protos/CorrugatedMetal.proto" | ||
|
||
PROTO Silo [ | ||
field SFVec3f translation 0 0 0 # Is `Pose.translation`. | ||
field SFRotation rotation 0 0 1 0 # Is `Pose.rotation`. | ||
field SFFloat radius 3 # Defines the radius of the silo. | ||
field SFFloat height 17 # Defines the height of the silo. | ||
field SFFloat roofHeight 2 # Defines the height of the silo's roof. | ||
field SFString name "silo" # Is `Solid.name`. | ||
field SFBool enableBoundingObject TRUE # Defines whether the silo should have a bounding object. | ||
field SFBool locked FALSE # Is `Solid.locked`. | ||
] | ||
{ | ||
%< | ||
let roofHeight = fields.roofHeight.value; | ||
let height = fields.height.value; | ||
let radius = fields.radius.value; | ||
|
||
if (radius <= 0) { | ||
radius = fields.radius.defaultValue; | ||
console.error('\'radius\' must be strictly positive. Value reset to ' + radius + '.'); | ||
} | ||
|
||
if (height <= 2) { | ||
height = fields.height.defaultValue; | ||
console.error('\'height\' must be greater than 2. Value reset to ' + height + '.'); | ||
} | ||
|
||
if (roofHeight <= 0 || roofHeight >= height) { | ||
roofHeight = fields.roofHeight.defaultValue; | ||
console.error('\'roofHeight\' must be strictly positive and lower than `height`. Value reset to ' + roofHeight + '.'); | ||
} | ||
|
||
const cylinderHeight = height - roofHeight; | ||
const ladderWidth = 0.7; | ||
const ladderHeight = cylinderHeight * 2 / 3; | ||
const ladderStepSize = 0.5; | ||
const ladderSteps = Math.trunc(ladderHeight / ladderStepSize); | ||
const barHeight = ladderHeight + ladderStepSize; | ||
>% | ||
Solid { | ||
translation IS translation | ||
rotation IS rotation | ||
children [ | ||
DEF BODY Pose { | ||
translation 0 0 %<= cylinderHeight * 0.5 >% | ||
children [ | ||
Shape { | ||
appearance CorrugatedMetal { | ||
colorOverride 1 0.9696 0.82 | ||
textureTransform TextureTransform { | ||
rotation 1.5708 | ||
scale %<= cylinderHeight>% %<= 3 * radius >% | ||
} | ||
} | ||
geometry Cylinder { | ||
height %<= cylinderHeight >% | ||
radius %<= radius >% | ||
} | ||
} | ||
] | ||
} | ||
DEF ROOF Pose { | ||
translation 0 0 %<= cylinderHeight + roofHeight * 0.5 >% | ||
children [ | ||
Shape { | ||
appearance CorrugatedMetal { | ||
colorOverride 1 0.9696 0.82 | ||
textureTransform TextureTransform { | ||
rotation 1.5708 | ||
scale %<= radius >% %<= 3 * roofHeight>% | ||
} | ||
} | ||
geometry Cone { | ||
bottomRadius %<= radius >% | ||
height %<= roofHeight >% | ||
subdivision 40 | ||
} | ||
} | ||
] | ||
} | ||
DEF LADDER Pose { | ||
translation %<= radius + 0.04 >% 0 0 | ||
children [ | ||
DEF LEFT_POLE Pose { | ||
translation 0 %<= -ladderWidth * 0.5 - 0.025 >% %<= cylinderHeight + 0.1 + ladderStepSize - barHeight * 0.5 >% | ||
children [ | ||
DEF SIDE_POLE Shape { | ||
appearance DEF LADDER_APPEARANCE PBRAppearance { | ||
baseColor 0.603922 0.6 0.588235 | ||
roughness 0.8 | ||
} | ||
geometry Box { | ||
size 0.05 0.05 %<= barHeight >% | ||
} | ||
} | ||
] | ||
} | ||
DEF RIGHT_POLE Pose { | ||
translation 0 %<= ladderWidth * 0.5 + 0.025 >% %<= cylinderHeight + 0.1 + ladderStepSize - barHeight * 0.5 >% | ||
children [ | ||
USE SIDE_POLE | ||
] | ||
} | ||
DEF LEFT_TOP_POLE Pose { | ||
translation %<= -radius * 0.5 - 0.025 >% %<= -ladderWidth * 0.5 - 0.025 >% %<= cylinderHeight + 0.3 >% | ||
children [ | ||
DEF TOP_POLE Shape { | ||
appearance DEF LADDER_APPEARANCE PBRAppearance { | ||
baseColor 0.603922 0.6 0.588235 | ||
roughness 0.8 | ||
} | ||
geometry Box { | ||
size %<= radius >% 0.05 0.1 | ||
} | ||
} | ||
] | ||
} | ||
DEF RIGHT_TOP_POLE Pose { | ||
translation %<= -radius * 0.5 - 0.025 >% %<= ladderWidth * 0.5 + 0.025 >% %<= cylinderHeight + 0.3 >% | ||
children [ | ||
USE TOP_POLE | ||
] | ||
} | ||
Pose { | ||
translation 0 0 %<= cylinderHeight + 0.1 >% | ||
children [ | ||
DEF FOOL Shape { | ||
appearance USE LADDER_APPEARANCE | ||
geometry Box { | ||
size 0.05 %<= ladderWidth >% 0.05 | ||
} | ||
} | ||
] | ||
} | ||
%< | ||
let h = cylinderHeight + 0.1; | ||
for (let n = 1; n < ladderSteps; n++) { | ||
h -= ladderStepSize; | ||
>% | ||
Pose { | ||
translation 0 0 %<= h >% | ||
children [ | ||
USE FOOL | ||
] | ||
} | ||
%< | ||
} | ||
>% | ||
] | ||
} | ||
] | ||
name IS name | ||
%< | ||
if (fields.enableBoundingObject.value) { | ||
>% | ||
boundingObject Pose { | ||
translation 0 0 %<= height * 0.5>% | ||
children [ | ||
Cylinder { | ||
height %<= height >% | ||
radius %<= radius >% | ||
} | ||
] | ||
} | ||
%< | ||
} | ||
>% | ||
locked IS locked | ||
recognitionColors [ | ||
0.89 0.89 0.89 | ||
] | ||
} | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
#VRML_SIM R2023b utf8 | ||
# license: Copyright Cyberbotics Ltd. Licensed for use only with Webots. | ||
# license url: https://cyberbotics.com/webots_assets_license | ||
# documentation url: https://webots.cloud/run?url=https://github.com/cyberbotics/webots/blob/released/projects/objects/floors/protos/Ditch.proto | ||
# tags: nonDeterministic | ||
# keywords: primitive/ground | ||
# Randomly generated ditch with optional water. | ||
# template language: javascript | ||
|
||
EXTERNPROTO "webots://projects/appearances/protos/SandyGround.proto" | ||
|
||
PROTO Ditch [ | ||
field SFVec3f translation 0 0 0 # Is `Pose.translation`. | ||
field SFRotation rotation 0 0 1 0 # Is `Solid.rotation`. | ||
field SFString name "ditch" # Is `Solid.name`. | ||
field SFVec3f size 20 5 2 # Defines the size of the ditch. | ||
field SFFloat waterHeight 0.3 # Defines the height of the water in the ditch. | ||
field SFNode appearance SandyGround { textureTransform TextureTransform { scale 5 5 } } # Defines the appearance of the terrain. | ||
field SFInt32 randomSeed 1 # Defines whether the bounds of the terrain should be flat. | ||
] | ||
{ | ||
%< | ||
// reference: https://stackoverflow.com/a/42543313/2210777 | ||
import * as wbrandom from 'wbrandom.js'; | ||
|
||
if (fields.randomSeed.value <= 0) | ||
wbrandom.seed(Date.now()); | ||
else | ||
wbrandom.seed(fields.randomSeed.value); | ||
|
||
function gaussian2d(x, y, amp, cx, cy, sx, sy) { | ||
return amp * Math.exp( - ( ( Math.pow(x - cx, 2) / (2.0 * Math.pow(sx, 2)) ) + (Math.pow(y - cy, 2) / (2.0 * Math.pow(sy, 2)) ) )); | ||
} | ||
|
||
// create 256 shuffled numbers repeated twice. | ||
let perm = []; | ||
for (let i = 1; i <= 256; ++i) | ||
perm.splice(wbrandom.integer(i) -1, 0, i); | ||
|
||
for (let i = 0; i < 256; ++i) | ||
perm.push(perm[i]); | ||
|
||
// generate 256 directions | ||
let dirs = []; | ||
for (let a = 0; a < 256; ++a) | ||
dirs.push([Math.cos(a * 2.0 * Math.PI / 256), Math.sin(a * 2.0 * Math.PI / 256)]); | ||
|
||
function noise (x, y, per, dirs, perm) { | ||
function surflet (grid_x, grid_y, dirs, perm) { | ||
const dist_x = Math.abs(x - grid_x); | ||
const dist_y = Math.abs(y - grid_y); | ||
const poly_x = 1 - 6 * Math.pow(dist_x, 5) + 15 * Math.pow(dist_x, 4) - 10 * Math.pow(dist_x, 3); | ||
const poly_y = 1 - 6 * Math.pow(dist_y, 5) + 15 * Math.pow(dist_y, 4) - 10 * Math.pow(dist_y, 3); | ||
const hashed = perm[(perm[(Math.floor(grid_x) % per)] + Math.floor(grid_y) % per)]; | ||
const grad = (x - grid_x) * dirs[hashed-1][0] + (y - grid_y) * dirs[hashed-1][1]; | ||
|
||
return poly_x * poly_y * grad; | ||
} | ||
|
||
let int_x = Math.floor(x); | ||
let int_y = Math.floor(y); | ||
|
||
return surflet(int_x + 0, int_y + 0, dirs, perm) + surflet(int_x + 1, int_y + 0, dirs, perm) + surflet(int_x + 0, int_y + 1, dirs, perm) + surflet(int_x + 1, int_y + 1, dirs, perm); | ||
} | ||
|
||
function fBm (x, y, per, octs, dirs, perm) { // Fractional Brownian motion | ||
let val = 0; | ||
for (let o = 0; o <= octs - 1; ++o) | ||
val = val + (Math.pow(0.5, o) * noise(x * Math.pow(2, o), y * Math.pow(2, o), per * Math.pow(2, o), dirs, perm)); | ||
|
||
return val; | ||
} | ||
|
||
const perlinSize = 128; | ||
const nOctave = 3; | ||
|
||
let size = fields.size.value; | ||
if (size.x <= 0 || size.y <= 0 || size.z <= 0) { | ||
size = fields.size.defaultValue; | ||
console.error('\'size\' must be strictly positive. Value reset to ' + size + '.'); | ||
} | ||
|
||
let yDimension = 10; | ||
const hValues = [0, 0, -size.z * 0.5, -size.z, -size.z, -size.z, -size.z, -size.z * 0.5, 0, 0]; | ||
|
||
let xDimension = Math.floor(size.x / 0.5); | ||
if (xDimension < 8) | ||
xDimension = 2; | ||
|
||
const ySpacing = size.y / (yDimension - 1); | ||
|
||
let waterHeight = fields.waterHeight.value; | ||
if (waterHeight >= size.z) { | ||
waterHeight = fields.waterHeight.defaultValue; | ||
console.error('\'waterHeight\' should be lower than `size.z`. Value reset to ' + waterHeight + '.'); | ||
} | ||
|
||
let heights = [] | ||
let minHeight = 0; | ||
for (let i = 0; i < 9; ++i) { | ||
const x = i / xDimension; | ||
for (let j = 0; j < xDimension; ++j) { | ||
let height = hValues[i]; | ||
if (i > 0 && i < 7 && nOctave > 0) { | ||
const y = j / yDimension; | ||
height += 0.2 * fBm(x, y, perlinSize, nOctave, dirs, perm); | ||
} | ||
if (height < minHeight) | ||
minHeight = height; | ||
heights.push(height); | ||
} | ||
} | ||
>% | ||
%< if (waterHeight >= 0) { >% | ||
Fluid { | ||
%< } else { >% | ||
Solid { | ||
%< } >% | ||
translation IS translation | ||
rotation IS rotation | ||
children [ | ||
%< if (waterHeight >= 0) { >% | ||
DEF WATER_BOX Pose { | ||
translation 0 0 %<= minHeight + waterHeight * 0.5>% | ||
children [ | ||
Shape { | ||
appearance PBRAppearance { | ||
baseColor 0.30985 0.464424 0.636667 | ||
transparency 0.3 | ||
roughness 0.05 | ||
metalness 0.9 | ||
} | ||
geometry Box { | ||
size %<= size.x >% %<= size.y - 2 * ySpacing >% %<= waterHeight >% | ||
} | ||
} | ||
] | ||
} | ||
Solid { | ||
children [ | ||
%< } >% | ||
DEF DITCH_ELEVATION_GRID Pose { | ||
translation %<= - size.x * 0.5 >% %<= -size.y * 0.5 >% 0 | ||
children [ | ||
Shape { | ||
appearance IS appearance | ||
geometry ElevationGrid { | ||
xDimension %<= xDimension >% | ||
xSpacing %<= size.x / (xDimension - 1) >% | ||
yDimension %<= yDimension >% | ||
ySpacing %<= ySpacing >% | ||
height [ | ||
%<= heights.join(', ') >% | ||
] | ||
} | ||
} | ||
] | ||
} | ||
] | ||
name IS name | ||
model "ditch" | ||
boundingObject USE DITCH_ELEVATION_GRID | ||
} | ||
%< if (waterHeight >= 0) { >% | ||
] | ||
viscosity 0.01 | ||
boundingObject USE WATER_BOX | ||
} | ||
%< } >% | ||
} |
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Oops, something went wrong.