Table of contents:
1 Clearing
1.1 [Clearing](#clearing/clearing)
2 Basics of working with meshes
2.1 [Creating and deleting](#mesh/mesh)
2.2 [What happens when you create mesh that exists?](#mesh/meshReplace)
3 Mesh geomerty
3.1 [Drawing 1 triangle](#meshShape/shapeXY)
3.2 [Drawing 2 triangles](#meshShape/shapeXY2)
3.3 [Indexed vertices](#meshShape/shapeIndices)
3.4 [Triangle strips](#meshShape/shapeTriStrip)
3.5 [Triangle fans](#meshShape/shapeTriFan)
3.6 [Every primitive type](#meshShape/shapePrimitiveTypes)
3.7 [Interrupting triangle strips/fans, line strips/loops](#meshShape/shapeRestartIndex)
3.8 [Reusing lists](#meshShape/shapeRepurposeLists)
4 Mesh colors
4.1 [Vertex colors](#meshColors/colorRGB)
4.2 [Vertex colors with transparency](#meshColors/colorRGBA)
5 Nothing is drawn
5.1 [Forgetting about depth](#meshNothing/forgotDepth)
6 Mesh is not valid for drawing
6.1 [Missing vertex positions](#meshNotValid/mistakeNoPositions)
6.2 [Length mismatch when setting](#meshNotValid/mistakeLengthMismatchEarly)
6.3 [Length mismatch of different properties](#meshNotValid/mistakeLengthMismatchLate)
7 Mesh textures
7.1 [Textures and UVs](#meshTextures/texturesUV)
7.2 [UV out of bounds](#meshTextures/texturesUVOutOfBounds)
7.3 [UV offset and scrolling textures](#meshTextures/texturesUVOffset)
7.4 [UV precision issues](#meshTextures/texturesUVOffsetTooBig)
7.5 [Textures and UVs (demo)](#meshTextures/texturesUVInteractive)
7.6 [Why are textures vertically flipped?](#meshTextures/texturesFlippedY)
8 Transforms
8.1 [Using scratch coordinate system](#transforms/scratchCoords1)
8.2 [Using scratch coordinate system with other transforms](#transforms/scratchCoords2)
8.3 [Using -1 to 1 with aspect ratio correction](#transforms/normCoords1)
8.4 [Adding Z dimensions, but it's cut-off](#transforms/normCoords2)
8.5 [Simple, but ugly solution](#transforms/normCoords3)
8.6 [Built-in solution: orthographic projection block for 2D](#transforms/normCoords4)
8.7 [Perspective projection for 3D](#transforms/perspective1)
8.8 [Moving the mesh in 3D](#transforms/perspective2)
8.9 [Moving the camera in 3D](#transforms/perspective3)
8.10 [Rotating the camera in 3D](#transforms/perspective4)
8.11 [Incorrectly rotating the camera in 3D](#transforms/perspective5)
8.12 [Moving both the mesh and the camera. Drawing the mesh in multiple locations at once](#transforms/perspective6)
8.13 [Adding mesh rotation](#transforms/perspective7)
8.14 [Simplifying code with a 'wrapper' block](#transforms/perspective8)
8.15 [Futher simplifying code with 'configure transformation' blocks](#transforms/perspective9)
9 Manual transforms
9.1 [Preparations](#manualTransforms/setup)
9.2 [Getting world coordinates of a point on a transformed mesh](#manualTransforms/posModelToWorld)
9.3 [Getting scratch on-screen coordinates of a point on a transformed mesh](#manualTransforms/posModelToScratch)
9.4 [Getting absolute in-world direction of direction provided in the model space](#manualTransforms/dirModelToWorld)
9.5 [Implementing simple 4-directional first person movement](#manualTransforms/controllerSimple)
9.6 [Implementing 6-directional movement](#manualTransforms/controllerSixDir)
10 Importing models from files
10.1 [Importing example](#import/import4)
10.2 [Waiting for import to finish](#import/importWait)
10.3 [Transforming imported meshes](#import/importTransform)
11 Text rendering
11.1 [Starting with simple text](#textureText/text1)
11.2 [Fixing upsidedown and aspect ratio](#textureText/text2)
11.3 [Changing resolutions changes text scale](#textureText/text3)
11.4 [Solving the issue, but text is small now](#textureText/text4)
11.5 [Re-adding scaling](#textureText/text5)
11.6 [Centering text with move block](#textureText/centered1)
11.7 [Centering text by changing mesh to be centered](#textureText/centered2)
11.8 [Un-centering centered mesh](#textureText/centered3)
11.9 [Increasing resolution to make text less blurry](#textureText/edges1)
11.10 [Better solution for sharp text edges](#textureText/edges2)
11.11 [It's also useful for vegetation](#textureText/edges3)
12 Animated textures
12.1 [Changing texture directly (AVOID THIS!)](#meshTextureAnimated/uploadEveryFrame)
12.2 [Pre-creating multiple meshes that all inherit from the same base mesh](#meshTextureAnimated/inheritShapeCustomTexture)
12.3 [Storing textures in meshes and using inheritance to switch between textures](#meshTextureAnimated/inheritTexture)
12.4 [Directly changing UV offset](#meshTextureAnimated/directUVoffset)
12.5 [Inherited UV offset](#meshTextureAnimated/inheritUVoffset)
13 Common mistakes while loading textures
13.1 [Drawing before texture loads](#meshTextureLoading/textureBeforeLoads)
13.2 [Blocked by CORS](#meshTextureLoading/textureCORS)
13.3 [What is [texture data] anyways?](#meshTextureLoading/texturePassing)
14 Instancing
14.1 [No instancing](#meshInstancing/instancingWithout)
14.2 [Transforms instancing](#meshInstancing/instancingTransforms1)
14.3 [Transforms instancing with world transform](#meshInstancing/instancingTransforms2)
14.4 [Inheritance with instancing](#meshInstancing/instancingTextures)
14.5 [Chunk LOD system using instacing](#meshInstancing/instancingChunks)
14.6 [Positions instancing](#meshInstancing/instancingPos)
14.7 [Changing all instanced data every frame](#meshInstancing/instancingMoveAll)
14.8 [Changing some instanced data every frame](#meshInstancing/instancingMoveOne)
14.9 [Deleting and adding instances](#meshInstancing/instancingDeleteOne)
14.10 [Instanced boxes of different sizes with tiling textures](#meshInstancing/instancingTiling2)
14.11 [Extra: Simple 2D instancing demo](#meshInstancing/instancing2D)
15 Modifying parts of the mesh lists
15.1 [Updating vertex data](#partialUpdate/vertex1)
15.2 [Updating vertex index data](#partialUpdate/index1)
15.3 [Updating instance data](#partialUpdate/instance1)
15.4 [Inserting and removing triangles example](#partialUpdate/index2)
16 Miscellaneous
16.1 [Holding 3D item in hand and UI](#misc/holdingAnItem)
16.2 [Portals via oblique projection](#misc/obliqueProjection)
17 Overdraw
17.1 [With overdraw](#overdraw/overdrawWith)
17.2 [Without overdraw](#overdraw/overdrawWithout)
18 Simple3D + Skins extension
18.1 [Simple text skins](#extSkins/textSimple)
18.2 [Textured text skins with gradient](#extSkins/textTextured)
18.3 [Turning 2D costumes into pre-rendered 3D block skins](#extSkins/blocks)
19 Simple3D + Pen+ extension
19.1 [Using transformation blocks with Pen+ v7 shaders](#extPenPlus/v7)
19.2 [Using transformation blocks with Pen+ v6 textured triangle blocks](#extPenPlus/v6)
20 Simple3D + Augmented Reality extension
# Section: Clearing
# Project: Clearing
# Start of clearing/clearing.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - 'Press number keys from 0 to 9'
### Blocks
```scratchblocks
when [1 v] key pressed
Simple3D | set clear color R:(1) G:(0) B:(0) A:(1)
Simple3D | clear (color and depth v)
when [2 v] key pressed
Simple3D | set clear color R:(0) G:(1) B:(0) A:(1)
Simple3D | clear (color and depth v)
when [3 v] key pressed
Simple3D | set clear color R:(0) G:(0) B:(1) A:(1)
Simple3D | clear (color and depth v)
when [4 v] key pressed
Simple3D | set clear color R:(1) G:(1) B:(0) A:(1)
Simple3D | clear (color and depth v)
when [5 v] key pressed
Simple3D | set clear color R:(1) G:(1) B:(1) A:(1)
Simple3D | clear (color and depth v)
when [0 v] key pressed
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
when [6 v] key pressed
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | clear (color and depth v)
when [7 v] key pressed
Simple3D | set clear color R:(1) G:(0.5) B:(0) A:(1)
Simple3D | clear (color and depth v)
when [8 v] key pressed
Simple3D | set clear color R:(1) G:(0.5) B:(0) A:(0.5)
Simple3D | clear (color and depth v)
when [9 v] key pressed // #32a852
Simple3D | set clear color R:((join [0x] [32]) / (255)) G:((join [0x] [a8]) / (255)) B:((join [0x] [52]) / (255)) A:(1)
Simple3D | clear (color and depth v)
```
# End of clearing/clearing.sb3
# Section: Basics of working with meshes
# Project: Creating and deleting
# Start of mesh/mesh.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Blocks
```scratchblocks
Simple3D | create mesh [my mesh a]
(Simple3D | allMeshes)
Simple3D | create mesh [my mesh b]
Simple3D | create mesh [my mesh c]
Simple3D | delete mesh [my mesh a]
Simple3D | delete mesh [my mesh b]
Simple3D | delete mesh [my mesh c]
```
# End of mesh/mesh.sb3
# Project: What happens when you create mesh that exists?
# Start of mesh/meshReplace.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
1 has positions = true
1 has colors = false
2 has positions = false
2 has colors = true
### Global Lists
zero = [0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [zero v] [zero v]
set [1 has positions v] to (Simple3D | mesh [has positions v] [my mesh])
set [1 has colors v] to (Simple3D | mesh [has colors v] [my mesh])
Simple3D | create mesh [my mesh] // When you create a mesh, the name of which is already taken, the old one with the same name gets fully and properly deleted first, before the new one is created.\n\nIf your project reuses the same hardcoded mesh names every time it is launched, you don't have to worry about clearing them manually - they will just get recreated when needed and it wouldn't cause any memory leaks.
Simple3D | set [my mesh] colors RGB [zero v] [zero v] [zero v]
set [2 has positions v] to (Simple3D | mesh [has positions v] [my mesh])
set [2 has colors v] to (Simple3D | mesh [has colors v] [my mesh])
```
# End of mesh/meshReplace.sb3
# Section: Mesh geomerty
# Project: Drawing 1 triangle
# Start of meshShape/shapeXY.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right
### Global Lists
x list = [0,1,0]
y list = [0,0,1]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | draw mesh [my mesh]
```
# End of meshShape/shapeXY.sb3
# Project: Drawing 2 triangles
# Start of meshShape/shapeXY2.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right. items #1,#2,#3 from 'x list' and 'y list' are grouped and the arrow points to the top triangle. items #4,#5,#6 are grouped and the arrow points to the bottom triangle.
### Global Lists
x list = [0.1,1,0.1,-0.1,-1,-0.1]
y list = [0.1,0.1,1,-0.1,-0.1,-2]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | draw mesh [my mesh]
```
# End of meshShape/shapeXY2.sb3
# Project: Indexed vertices
# Start of meshShape/shapeIndices.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right. items #1-3 (1,2,3) from 'indices list' are grouped and arrow points to the upper triangle. items #4-6 (1,2,4) from 'indices list' are grouped and arrow points to the bottom triangle.
### Global Lists
x list = [0,1,0,0.5]
y list = [0.4,0.4,1,-0.5]
indices list = [1,2,3,1,2,4]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] indices [indices list v]
Simple3D | draw mesh [my mesh]
```
# End of meshShape/shapeIndices.sb3
# Project: Triangle strips
# Start of meshShape/shapeTriStrip.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right. items #1,#2,#3 from 'x list' and 'y list' are grouped. items #2,#3,#4 are grouped. items #3,#4,#5 are grouped.
### Global Lists
x list = [0,0,1,0.5,0.4]
y list = [0.4,1,0.4,-0.5,-1]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | draw mesh [my mesh]
```
# End of meshShape/shapeTriStrip.sb3
# Project: Triangle fans
# Start of meshShape/shapeTriFan.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right. items #1,#2,#3 from 'x list' and 'y list' are grouped. items #1,#3,#4 are grouped. items #1,#4,#5 are grouped.
### Global Lists
x list = [0,0,1,0.5,0.4]
y list = [0.4,1,0.4,-0.5,-1]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] primitives (triangle fan v)
Simple3D | draw mesh [my mesh]
```
# End of meshShape/shapeTriFan.sb3
# Project: Every primitive type
# Start of meshShape/shapePrimitiveTypes.sb3
## Sprite: "Stage"
### Costumes
1. "" - 6 points labeled 1-6 between which primitives will appear. text saying 'Press number keys: 1,2,3,4,5,6,7'
### Global Variables
primitive type = "points"
### Global Lists
x list = [-0.75,-0.45,-0.15,0.15,0.45,0.75]
y list = [0.9,0.1,0.9,0.1,0.9,0.1]
### Blocks
```scratchblocks
when flag clicked
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
draw (primitive type) :: custom
when [1 v] key pressed
draw [points] :: custom
when [2 v] key pressed
draw [lines] :: custom
define draw (type)
set [primitive type v] to (type)
Simple3D | clear (color and depth v)
Simple3D | set [my mesh] primitives (type)
Simple3D | draw mesh [my mesh]
when [3 v] key pressed
draw [line strip] :: custom
when [4 v] key pressed
draw [line loop] :: custom
when [5 v] key pressed
draw [triangles] :: custom
when [6 v] key pressed
draw [triangle strip] :: custom
when [7 v] key pressed
Simple3D | depth test (everything v) write (false v)
Simple3D | set global color [multiplier v] R:(1) G:(1) B:(1) A:(0.5)
draw [triangle fan] :: custom
Simple3D | set global color [multiplier v] R:(1) G:(1) B:(1) A:(1)
```
# End of meshShape/shapePrimitiveTypes.sb3
# Project: Interrupting triangle strips/fans, line strips/loops
# Start of meshShape/shapeRestartIndex.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right. items #1,#2,#3 (1,2,3) from 'indices list' are grouped. items #1,#3,#4 (1,3,4) are grouped. red arrow is pointing to the item #5 (0) which serves as a separator (0 is the primitive restart index in Simple3D). items #6,#7,#8 (5,6,7) are grouped. items #6,#8,#9 (5,7,8) are grouped.
### Global Lists
x list = [-1,-0.5,0,-0.5,0.5,0,0.5,1]
y list = [0.5,1,0.5,0,0,-0.5,-1,-0.5]
index list = [1,2,3,4,0,5,6,7,8]
### Blocks
```scratchblocks
when flag clicked
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] indices [index list v]
Simple3D | set [my mesh] primitives (triangle fan v)
Simple3D | draw mesh [my mesh]
Simple3D | set [my mesh] primitives (line loop v) // Also try this
when stage clicked
Simple3D | clear (color and depth v)
```
# End of meshShape/shapeRestartIndex.sb3
# Project: Reusing lists
# Start of meshShape/shapeRepurposeLists.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right
### Global Lists
x list = []
y list = []
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
clear points :: custom
add point X: [0] Y: [0] :: custom
add point X: [1] Y: [0] :: custom
add point X: [0] Y: [1] :: custom
Simple3D | create mesh [my mesh 1]
Simple3D | set [my mesh 1] positions XY [x list v] [y list v] // When activated, this block uploads the list data to the GPU by COPYING it. After it has been called, it is safe for blocks after it to immediately start changing data and re-purpose the list for something else
clear points :: custom
add point X: [0] Y: [0] :: custom
add point X: [-1] Y: [0] :: custom
add point X: [0] Y: [-1] :: custom
Simple3D | create mesh [my mesh 2]
Simple3D | set [my mesh 2] positions XY [x list v] [y list v]
Simple3D | draw mesh [my mesh 1]
Simple3D | draw mesh [my mesh 2]
define add point X: (x) Y: (y)
add (x) to [x list v]
add (y) to [y list v]
define clear points
delete all of [x list v]
delete all of [y list v]
```
# End of meshShape/shapeRepurposeLists.sb3
# Section: Mesh colors
# Project: Vertex colors
# Start of meshColors/colorRGB.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right
### Global Lists
x list = [0,1,0]
y list = [0,0,1]
red list = [255,0,0]
green list = [0,255,0]
blue list = [0,0,255]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] colors RGB [red list v] [green list v] [blue list v]
Simple3D | draw mesh [my mesh]
```
# End of meshColors/colorRGB.sb3
# Project: Vertex colors with transparency
# Start of meshColors/colorRGBA.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right
### Global Lists
x list = [0,1,0]
y list = [0,0,1]
red list = [255,0,0]
green list = [0,255,0]
blue list = [0,0,255]
alpha list = [0,64,255]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] colors RGBA [red list v] [green list v] [blue list v] [alpha list v]
Simple3D | draw mesh [my mesh]
```
# End of meshColors/colorRGBA.sb3
# Section: Nothing is drawn
# Project: Forgetting about depth
# Start of meshNothing/forgotDepth.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right
### Global Lists
x list = [0,1,0]
y list = [0,0,1]
red list = [0,0,0]
green list = [0,0,0]
blue list = [255,255,255]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
update R: [255] G: [0] B: [0] :: custom
Simple3D | set [my mesh] colors RGB [red list v] [green list v] [blue list v]
Simple3D | draw mesh [my mesh]
wait (1) seconds
update R: [0] G: [255] B: [0] :: custom
Simple3D | set [my mesh] colors RGB [red list v] [green list v] [blue list v]
Simple3D | draw mesh [my mesh]
wait (1) seconds
update R: [0] G: [0] B: [255] :: custom
Simple3D | set [my mesh] colors RGB [red list v] [green list v] [blue list v]
Simple3D | draw mesh [my mesh]
define update R: (red) G: (green) B: (blue)
replace item (1) of [red list v] with (red)
replace item (2) of [red list v] with (red)
replace item (3) of [red list v] with (red)
replace item (1) of [green list v] with (green)
replace item (2) of [green list v] with (green)
replace item (3) of [green list v] with (green)
replace item (1) of [blue list v] with (blue)
replace item (2) of [blue list v] with (blue)
replace item (3) of [blue list v] with (blue)
Simple3D | depth test (closer v) write (true v) // The answer is, that by default new pixels are only drawn, when they are closer than the already drawn ones at those locations.
Simple3D | depth test (everything v) write (false v) // You can make this example work as intended by either disable depth tracking like this
Simple3D | clear (color and depth v) // or by clearing depth every time before re-drawing the triangle.
Simple3D | clear (depth v)
// Why isn't it working?
// Try out both ways to fix it
```
# End of meshNothing/forgotDepth.sb3
# Section: Mesh is not valid for drawing
# Project: Missing vertex positions
# Start of meshNotValid/mistakeNoPositions.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
is valid = false
### Global Lists
red list = [255,0,0]
green list = [0,255,0]
blue list = [0,0,255]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] colors RGB [red list v] [green list v] [blue list v]
Simple3D | draw mesh [my mesh]
set [is valid v] to (Simple3D | mesh [is valid for drawing v] [my mesh])
// Mesh has not vertex positions
```
# End of meshNotValid/mistakeNoPositions.sb3
# Project: Length mismatch when setting
# Start of meshNotValid/mistakeLengthMismatchEarly.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right
### Global Variables
is valid = false
### Global Lists
x list = [0,1,0]
y list = [0,0,1,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v] // This block does nothing because lists have different sizes. Since no positions are set, the mesh is invalid
Simple3D | draw mesh [my mesh]
set [is valid v] to (Simple3D | mesh [is valid for drawing v] [my mesh])
(Simple3D | mesh [has positions v] [my mesh])
```
# End of meshNotValid/mistakeLengthMismatchEarly.sb3
# Project: Length mismatch of different properties
# Start of meshNotValid/mistakeLengthMismatchLate.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right
### Global Variables
is valid = false
### Global Lists
x list = [0,1,0]
y list = [0,0,1]
red list = [255,0,0,0]
green list = [0,255,0,0]
blue list = [0,0,255,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] colors RGB [red list v] [green list v] [blue list v] // Both positions and colors get set successfully, but mesh can't be drawn because they have different lengths
Simple3D | draw mesh [my mesh]
set [is valid v] to (Simple3D | mesh [is valid for drawing v] [my mesh])
(Simple3D | mesh [has positions v] [my mesh])
(Simple3D | mesh [has colors v] [my mesh])
```
# End of meshNotValid/mistakeLengthMismatchLate.sb3
# Section: Mesh textures
# Project: Textures and UVs
# Start of meshTextures/texturesUV.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "grid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient. Top left corner has label U:0 V:0, top right corner has label U:1 V:0, bottom left corner has label U:0 V:1, bottom right corner has label U:1 V:1.
### Global Lists
x list = [0,1,0]
y list = [0,0,1]
u list = [0,0,0.75]
v list = [0,1,0.5]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume grid)) [clamp to edge v] [pixelated v]
wait until
Simple3D | draw mesh [my mesh]
```
# End of meshTextures/texturesUV.sb3
# Project: UV out of bounds
# Start of meshTextures/texturesUVOutOfBounds.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "grid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient. Top left corner has label U:0 V:0, top right corner has label U:1 V:0, bottom left corner has label U:0 V:1, bottom right corner has label U:1 V:1.
### Global Variables
repeat = 0
### Global Lists
x list = [0,1,0]
y list = [-0.9,-0.9,1]
u list = [-0.3,-0.3,1.75]
v list = [-1,2,0.5]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
if <(repeat) = [0]> then
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume grid)) [clamp to edge v] [pixelated v]
else
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
end
wait until
Simple3D | draw mesh [my mesh]
```
# End of meshTextures/texturesUVOutOfBounds.sb3
# Project: UV offset and scrolling textures
# Start of meshTextures/texturesUVOffset.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "grid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient. Top left corner has label U:0 V:0, top right corner has label U:1 V:0, bottom left corner has label U:0 V:1, bottom right corner has label U:1 V:1.
### Global Lists
x list = [0,1,0]
y list = [-0.9,-0.9,1]
u list = [-0.3,-0.3,1.75]
v list = [-1,2,0.5]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
forever
Simple3D | clear (color and depth v)
Simple3D | set [my mesh] texture coordinate offset UV ((timer) * (0.5)) ((timer) * (0.2))
Simple3D | draw mesh [my mesh]
end
```
# End of meshTextures/texturesUVOffset.sb3
# Project: UV precision issues
# Start of meshTextures/texturesUVOffsetTooBig.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "grid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient. Top left corner has label U:0 V:0, top right corner has label U:1 V:0, bottom left corner has label U:0 V:1, bottom right corner has label U:1 V:1.
### Global Variables
timer = 2000005.187
### Global Lists
x list = [0,1,0]
y list = [-0.9,-0.9,1]
u list = [-0.3,-0.3,1.75]
v list = [-1,2,0.5]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
forever
set [timer v] to ((timer) + (2000000))
Simple3D | clear (color and depth v)
Simple3D | set [my mesh] texture coordinate offset UV ((timer) * (0.5)) ((timer) * (0.2))
Simple3D | draw mesh [my mesh]
end
Simple3D | set [my mesh] texture coordinate offset UV (((timer) * (0.5)) mod (1)) (((timer) * (0.2)) mod (1))
// Note that rendering uses 32-bit floating point values in all the calculations, which with the increase in values, start to lose precision much sooner than 64-bit floats that scratch uses. In this case, you can fix it by using code below. In real projects you may run into other cases which aren't as trivial to fix.\n\nTry to fix it here by swapping out the block.
```
# End of meshTextures/texturesUVOffsetTooBig.sb3
# Project: Textures and UVs (demo)
# Start of meshTextures/texturesUVInteractive.sb3
## Sprite: "Stage"
### Costumes
1. "" - 'X:-1 Y:-1' in bottom left, 'X:1 Y:1' in top right, 'X:-1 Y:1' in top left, 'X:1 Y:-1' in bottom right
2. "grid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient. Top left corner has label U:0 V:0, top right corner has label U:1 V:0, bottom left corner has label U:0 V:1, bottom right corner has label U:1 V:1.
### Global Variables
tex x = 106
tex y = -46
### Global Lists
x list = [-0.118,0.667,0.158]
y list = [-0.042,-0.03,0.753]
u list = [0,0,1]
v list = [0,1,0.243]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(0)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume grid)) [clamp to edge v] [pixelated v]
Simple3D | [my mesh] optimize next uploaded list for being (frequently fully v) updated
forever
Simple3D | clear (color and depth v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | draw mesh [my mesh]
end
```
## Sprite: "Dst Point"
### Costumes
1. "" - orange circle
### Local Variables
index = 3
### Blocks
```scratchblocks
when I start as a clone
go to x: ((item (index) of [x list v]) * (240)) y: ((item (index) of [y list v]) * (180))
set drag mode [draggable v]
show
forever
replace item (index) of [x list v] with (round ((x position) / (240)) :: custom)
replace item (index) of [y list v] with (round ((y position) / (180)) :: custom)
if then
set [BRIGHTNESS v] effect to (25)
else
set [BRIGHTNESS v] effect to (0)
end
end
when flag clicked
set [index v] to [1]
create clone of (_myself_ v)
set [index v] to [2]
create clone of (_myself_ v)
set [index v] to [3]
create clone of (_myself_ v)
define round (value)
return ((round ((value) * (1000))) / (1000)) :: custom
```
## Sprite: "Src Point"
### Costumes
1. "dot" - purple circle
2. "grid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient. Top left corner has label U:0 V:0, top right corner has label U:1 V:0, bottom left corner has label U:0 V:1, bottom right corner has label U:1 V:1.
### Local Variables
index = 2
### Blocks
```scratchblocks
when I start as a clone
go to x: ((tex x) + ((item (index) of [u list v]) * (128))) y: ((tex y) - ((item (index) of [v list v]) * (128)))
set drag mode [draggable v]
show
forever
replace item (index) of [u list v] with (round (((x position) - (tex x)) / (128)) :: custom)
replace item (index) of [v list v] with (round (((tex y) - (y position)) / (128)) :: custom)
if <(item (index) of [u list v]) < [0]> then
replace item (index) of [u list v] with [0]
set x to ((tex x) + ((item (index) of [u list v]) * (128)))
end
if <(item (index) of [u list v]) > [1]> then
replace item (index) of [u list v] with [1]
set x to ((tex x) + ((item (index) of [u list v]) * (128)))
end
if <(item (index) of [v list v]) < [0]> then
replace item (index) of [v list v] with [0]
set y to ((tex y) - ((item (index) of [v list v]) * (128)))
end
if <(item (index) of [v list v]) > [1]> then
replace item (index) of [v list v] with [1]
set y to ((tex y) - ((item (index) of [v list v]) * (128)))
end
if then
set [BRIGHTNESS v] effect to (25)
else
set [BRIGHTNESS v] effect to (0)
end
end
when flag clicked
set [tex x v] to ((170) - (((256) / (2)) * (0.5)))
set [tex y v] to ((-110) + (((256) / (2)) * (0.5)))
set [index v] to [1]
create clone of (_myself_ v)
set [index v] to [2]
create clone of (_myself_ v)
set [index v] to [3]
create clone of (_myself_ v)
forever
erase all
Draw image :: custom
Draw lines :: custom
end
define Draw image
go to x: ((tex x) + (64)) y: ((tex y) - (64))
set size to (50) %
switch costume to (costume grid)
stamp
switch costume to (costume dot)
define round (value)
return ((round ((value) * (1000))) / (1000)) :: custom
define Draw lines
set pen color to (#000000)
set pen size to (2)
set [index v] to [1]
repeat (4)
go to x: ((tex x) + ((item (index) of [u list v]) * (128))) y: ((tex y) - ((item (index) of [v list v]) * (128)))
pen down
if <(index) = [3]> then
set [index v] to [1]
else
change [index v] by (1)
end
end
pen up
set size to (100) %
```
# End of meshTextures/texturesUVInteractive.sb3
# Project: Why are textures vertically flipped?
# Start of meshTextures/texturesFlippedY.sb3
## Sprite: "Stage"
### Costumes
1. "formats" - a diagram with 2 images: 1.The image on the left has red arrows going from left to right across each row of pixels, and blue arrows going from the ends of red arrows on the right, to left starts of red arrows 1 row down. It's also titled: 'Common 2D image formats bmp/png/jpg/gif/etc. - Y points down'. 2.The image on the right has red arrows going from left to right across each row of pixels, and blue arrows going from the ends of red arrows on the right, to left starts of red arrows 1 row up. It's also titled: 'Simple3D/WebGL/OpenGL - Y points up'
### Global Variables
camX = 27.535989428674267
camY = 17.424781425392762
camZ = 16.895906194044347
camRotX = 180
camRotY = 204
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
### Blocks
```scratchblocks
// QUESTION: Why are texture UVs upsidedown? Why the bigger V means lower within the image?\nANSWER: The images get vertically flipped while they are imported from external 2D sources due to their representation mismatch. Textures produced by Simple3D rendering to it's own textures, are not affected by this issue. In them, bigger V means higher within the texture.\n\nIn 2D it is common to represent images in a way, where Y is down.\nIn OpenGL/WebGL/Simple3D, Y is up.\n\nWhen importing, images get unrolled into an 1D list of pixel colors which then gets reassembled into the 2D image. This works fine when working within the same representation. However, when taking 1D list of colors made for one representation and trying to reassemble it in another representation, the resulting image flipped.\n\nThis problem is not exclusive to Simple3D.\nFor example: https://stackoverflow.com/questions/16875490/opengl-invert-textures-orientation-during-pixel-transfer\n\n\nThe suggested solution is to pre-filp the images in advance to not waste time programmatically doing it every time the image is needed.
```
# End of meshTextures/texturesFlippedY.sb3
# Section: Transforms
# Project: Using scratch coordinate system
# Start of transforms/scratchCoords1.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [-50,100,0]
y list = [-180,0,100]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with no transformation
Simple3D | scale X:((1) / (240)) Y:((1) / (180)) Z:(1) // Extension expects coordinates to be in range from -1 to 1. But what if we want to provide them in scratch coordinate system from -240 to 240 and -180 to 180?\n\nWe can set the extension to divide X by 240 and Y by 180 automatically when drawing using transformations. In particular, here we will use the scale block. Scale block does multiplication, not division, but that's okay because we can multiply by 1/240, which is the same as dividing by 240.\n\nAlso note the "start with no transformation" block. If you remove it, the new transformations will stack on top of existing ones every time the project is restarted.
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | draw mesh [my mesh]
```
# End of transforms/scratchCoords1.sb3
# Project: Using scratch coordinate system with other transforms
# Start of transforms/scratchCoords2.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [-50,100,0]
y list = [-180,0,100]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
forever
Simple3D | start with no transformation
Simple3D | scale X:((1) / (240)) Y:((1) / (180)) Z:(1)
Simple3D | move X:(mouse x) Y:(mouse y) Z:(0)
Simple3D | rotate around [Z v] by ((timer) * (180)) degrees
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
// You can apply multiple transformations one after another, and they will be applied in reverse order from which you specified them.\n\nHere, first rotation around Z axis will be applied, then offset by mouse coordinates (still in scratch coordinate system), and finally the coordinates will get rescaled range from -1 to 1.
```
# End of transforms/scratchCoords2.sb3
# Project: Using -1 to 1 with aspect ratio correction
# Start of transforms/normCoords1.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
forever
Simple3D | start with no transformation
Simple3D | scale X:((Simple3D | canvas height) / (Simple3D | canvas width)) Y:(1) Z:(1) // However, for most use cases, it usually makes more sense to not use scratch coordinate system and stick to -1 to 1 range. Especially in 3D, you probably don't want to have the higher field of view, the higher your stage size is.\n\nYou can't keep both coordinates in range from -1 to 1 because then the image will look stretched, so the solution is to keep only one.\nY is usually chosen to be kept as is, while X is adjusted to account for screen aspect ratio.
Simple3D | rotate around [Z v] by ((timer) * (180)) degrees
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
```
# End of transforms/normCoords1.sb3
# Project: Adding Z dimensions, but it's cut-off
# Start of transforms/normCoords2.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [0,0,2]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v] // And here comes the Z dimension.\n\nNotice how Z of one of the vertices is set to 2. Just like X and Y, the GPU expects Z to also be in range from -1 to 1.\n\nAnd as a result, you can only see the half of the triangle: the one with Z from 0 to 1. The half from 1 to 2 gets clipped.
forever
Simple3D | start with no transformation
Simple3D | scale X:((Simple3D | canvas height) / (Simple3D | canvas width)) Y:(1) Z:(1)
Simple3D | rotate around [Z v] by ((timer) * (180)) degrees
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
```
# End of transforms/normCoords2.sb3
# Project: Simple, but ugly solution
# Start of transforms/normCoords3.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [0,0,10]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | start with no transformation
Simple3D | scale X:((Simple3D | canvas height) / (Simple3D | canvas width)) Y:(1) Z:(0.1) // Lets's multiply Z by 0.1 so that we can use Z up to 10 without it getting clipped.\n\nIt works but there is a better way.
Simple3D | rotate around [Z v] by ((timer) * (180)) degrees
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
```
# End of transforms/normCoords3.sb3
# Project: Built-in solution: orthographic projection block for 2D
# Start of transforms/normCoords4.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [0,0,-2]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | start with orthographic near:(1) far:(10) // Introducing: orthographic projection block. It keeps Y as is, corrects X for aspect ratio, and remaps Z from the specified range to allowed range from -1 to 1.\n\nHere we once again have one of the vertices at -2 and others at 0, but the range is set to 1 to 10. Theoretically we shouldn't see anything, but we can see the part of the triangle from -1 to -2. How it that?\n\nIn computer graphics outside scratch camera is usually assumed to be facing negative Z direction, so things with positive Z are behind the camera, while things with negative Z are in front. This block follows the same convention. When you specify range from 1 to 10, you really specify range from -1 to -10.\n\nNow with that knowledge, try changing the range until the entire triangle can be seen.
Simple3D | rotate around [Z v] by ((timer) * (180)) degrees
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
```
# End of transforms/normCoords4.sb3
# Project: Perspective projection for 3D
# Start of transforms/perspective1.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [-5,-1,-1]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | start with perspective FOV: (90) near: (1) far: (10) // And on a similar topic, we've now reached the prespective projection.\n\nIt also assumes the negative Z look direction, so the specified range here is really -1 to -10.\nThis block additionally rescales X and Y so that Y has the specified field of view, as well as making it so that the lower Z is (below 0), the closer the vertex appears to 0,0 - the center of the screen. For multiple vertices it means that they get closer together and as a result, the drawn object appears smaller, the further it is.\n\nFor Z-buffer, this block also maps Z non-linearly, so that things nearby get higher Z-buffer precision and things further away have lower precision.
Simple3D | rotate around [Z v] by ((timer) * (180)) degrees
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
```
# End of transforms/perspective1.sb3
# Project: Moving the mesh in 3D
# Start of transforms/perspective2.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
offset X = 0
offset Y = 0
offset Z = 0
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [-5,-5,-5]
### Blocks
```scratchblocks
when flag clicked
set [offset X v] to [0]
set [offset Y v] to [0]
set [offset Z v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | move X:(offset X) Y:(offset Y) Z:(offset Z) // Added ability to move the triangle by specified offset
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
```
# End of transforms/perspective2.sb3
# Project: Moving the camera in 3D
# Start of transforms/perspective3.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [-5,-5,-5]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z)) // Moving the object is usually not what we want though, we want to move the camera. The movement of camera is the opposite as the movement of the object. If you've implemented any 2D scrolling projects you already know that.\n\nNow when we move camera up, the triangle goes down. When we move camera to higher X, the triangle shifts to the left, and so on.
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
```
# End of transforms/perspective3.sb3
# Project: Rotating the camera in 3D
# Start of transforms/perspective4.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 0
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [-5,-5,-5]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees // Same with camera. The value needs to be negated.\n\nHere we first offset by -camera position, then rotate by -camera orientation, and then do the perspective projection.
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
```
# End of transforms/perspective4.sb3
# Project: Incorrectly rotating the camera in 3D
# Start of transforms/perspective5.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 2.88
camera Z = 19.2
camera rot around Y???? no = 58.73
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [0,0,0]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [5]
set [camera rot around Y???? no v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y???? no)) degrees // If we do rotation first, it will spin the object instead
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
```
# End of transforms/perspective5.sb3
# Project: Moving both the mesh and the camera. Drawing the mesh in multiple locations at once
# Start of transforms/perspective6.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 0
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [0,0,0]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | clear (color and depth v)
draw triangle [0] [0] [-5] :: custom
draw triangle [-3] [0] [-5] :: custom
draw triangle [3] [0] [-5] :: custom
draw triangle [0] [0] [-10] :: custom
draw triangle [0] [3] [-10] :: custom
draw triangle [0] [-3] [-10] :: custom
end
define draw triangle (x) (y) (z)
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
Simple3D | move X:(x) Y:(y) Z:(z) // Now let's add an additional transformation to offset the triangle (mesh) itself and use it to draw multiple triangles.
Simple3D | draw mesh [my mesh]
```
# End of transforms/perspective6.sb3
# Project: Adding mesh rotation
# Start of transforms/perspective7.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 0
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [0,0,0]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | clear (color and depth v)
draw triangle [0] [0] [-5] :: custom
draw triangle [-3] [0] [-5] :: custom
draw triangle [3] [0] [-5] :: custom
draw triangle [0] [0] [-10] :: custom
draw triangle [0] [3] [-10] :: custom
draw triangle [0] [-3] [-10] :: custom
end
define draw triangle (x) (y) (z)
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | rotate around [Y v] by ((timer) * (180)) degrees // We can rotate them by correct angles as well.\n\nSo first we rotate them around 0,0,0 (their center), then offset to the correct location in the world space, then offset by -camera position to be relatively to the camera, then rotate it by -camera orientation around 0,0,0 (location of the camera), and finally project it.
Simple3D | rotate around [X v] by (20) degrees
Simple3D | draw mesh [my mesh]
```
# End of transforms/perspective7.sb3
# Project: Simplifying code with a 'wrapper' block
# Start of transforms/perspective8.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 0
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [0,0,0]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | clear (color and depth v)
Simple3D | start with perspective FOV: (90) near: (1) far: (100) // This code was calculated every time at the beginning and there is a way to avoid it. Simply doing it once at first.
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
draw triangle [0] [0] [-5] :: custom
draw triangle [-3] [0] [-5] :: custom
draw triangle [3] [0] [-5] :: custom
draw triangle [0] [0] [-10] :: custom
draw triangle [0] [3] [-10] :: custom
draw triangle [0] [-3] [-10] :: custom
end
define draw triangle (x) (y) (z)
Simple3D | wrapper {
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | rotate around [Y v] by ((timer) * (180)) degrees
Simple3D | rotate around [X v] by (20) degrees
Simple3D | draw mesh [my mesh]
} // Then doing everything else inside of a "wrapper" block which saves the current transformation when entering it and restores it when exiting, so that thing can be reused instead of having to recalculate it.
```
# End of transforms/perspective8.sb3
# Project: Futher simplifying code with 'configure transformation' blocks
# Start of transforms/perspective9.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 0
### Global Lists
x list = [-0.5,1,0]
y list = [-1.8,0,1]
z list = [0,0,0]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XYZ [x list v] [y list v] [z list v]
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation // Configuring how to turn 3D representation relative to the camera into a 2D image projected on the screen.
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | configure [worldToView v] transformation // Configuring how to turn absolutely positioned 3D representation (relative to the world origin (X:0,Y:0,Z:0)) into coordinates relative to the camera.
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
draw triangle [0] [0] [-5] :: custom
draw triangle [-3] [0] [-5] :: custom
draw triangle [3] [0] [-5] :: custom
draw triangle [0] [0] [-10] :: custom
draw triangle [0] [3] [-10] :: custom
draw triangle [0] [-3] [-10] :: custom
end
define draw triangle (x) (y) (z)
Simple3D | configure [modelToWorld v] transformation // Configuring how to turn 3D relative to the model's center, to coordinates in absolute world coordinates.
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | rotate around [Y v] by ((timer) * (180)) degrees
Simple3D | rotate around [X v] by (20) degrees
Simple3D | draw mesh [my mesh]
Simple3D | configure [viewToProjected v] transformation // However there is an even better way. Extension applies 3 transformations sequentially. Each of them can be configured independently. Doing so in not only usually cleaner, but it also lets extension know more about what is actually going on, which is required for it to correctly do effects like fog, billboarding, instancing, etc.\n\nUsing those blocks you can switch between which transformation you are currently configuring. By default it was "to projected from view space", so you were cramming everything in that, while the other 2 transformations did nothing.
Simple3D | configure [worldToView v] transformation
Simple3D | configure [modelToWorld v] transformation
```
# End of transforms/perspective9.sb3
# Section: Manual transforms
# Project: Preparations
# Start of manualTransforms/setup.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 0
### Global Lists
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [box] // Swapped out a single triangle for boxes. If you've saw all the previous examples, you should be familiar with what everything does.
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
draw box [0] [0] [-5] :: custom
draw box [-3] [0] [-5] :: custom
draw box [3] [0] [-5] :: custom
draw box [0] [0] [-10] :: custom
draw box [0] [3] [-10] :: custom
draw box [0] [-3] [-10] :: custom
end
define draw box (x) (y) (z)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | rotate around [Y v] by ((timer) * (180)) degrees
Simple3D | rotate around [X v] by (20) degrees
Simple3D | draw mesh [box]
```
# End of manualTransforms/setup.sb3
# Project: Getting world coordinates of a point on a transformed mesh
# Start of manualTransforms/posModelToWorld.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 0
### Global Lists
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
draw box [0] [0] [-5] [1] > :: custom
Simple3D | transform X:(1) Y:(1) Z:(1) from [model space v] to [world space v] // Cube has size of 2 units (from -1 to 1)\n\n1,1,1 is one of it's corners
draw box (Simple3D | transformed [X v]) (Simple3D | transformed [Y v]) (Simple3D | transformed [Z v]) [0.2] undefined :: custom
end
define draw box (x) (y) (z) (scale)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
if then
Simple3D | rotate around [Y v] by ((timer) * (180)) degrees
Simple3D | rotate around [X v] by ((timer) * (45)) degrees
end
Simple3D | scale X:(scale) Y:(scale) Z:(scale)
Simple3D | draw mesh [box]
```
# End of manualTransforms/posModelToWorld.sb3
# Project: Getting scratch on-screen coordinates of a point on a transformed mesh
# Start of manualTransforms/posModelToScratch.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 0
pointer X = 6.386589826788641
pointer Y = 7.213075089832019
pointer Z = 6.694582696707807
### Global Lists
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [box] // Swapped out a single triangle for boxes. If you've saw all the previous examples, you should be familiar with what everything does.
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
draw box [0] [0] [-5] :: custom
Simple3D | transform X:(1) Y:(1) Z:(1) from [model space v] to [projected (scratch units) v] // Cube has size of 2 units (from -1 to 1)\n\n1,1,1 is one of it's corners
set [pointer X v] to (Simple3D | transformed [X v])
set [pointer Y v] to (Simple3D | transformed [Y v])
set [pointer Z v] to (Simple3D | transformed [Z v])
end
define draw box (x) (y) (z)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | rotate around [Y v] by ((timer) * (180)) degrees
Simple3D | rotate around [X v] by ((timer) * (45)) degrees
Simple3D | draw mesh [box]
(scale)
```
## Sprite: "Pointer"
### Costumes
1. "pointer" - 'V' shaped arrow pointing to 0,0
### Blocks
```scratchblocks
when flag clicked
forever
if <(pointer Z) > [0]> then
go to x: (pointer X) y: (pointer Y)
show
else
hide
end
end
```
# End of manualTransforms/posModelToScratch.sb3
# Project: Getting absolute in-world direction of direction provided in the model space
# Start of manualTransforms/dirModelToWorld.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 2
camera rot around Y = 0
i = 0.9999999999999999
### Global Lists
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [2]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [box] // Swapped out a single triangle for boxes. If you've saw all the previous examples, you should be familiar with what everything does.
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
draw box ((2) + ((3) * ([sin v] of ((timer) * (100))))) [0.5] [-5] [1] > :: custom
Simple3D | transform direction X:(0) Y:(1) Z:(0) from [model space v] to [world space v] // Transforming UP direction from the cube's model space to the world space.\n\nThis gives direction in which cube's up side is pointing, regardless of cube's orientation.\n\n"transform direction from to" is like "transform from to", but it disregards offset present in the transformation. Like here, the cube is located at X:-2 to 5, Y:0.5 and Z:-5
draw line of boxes in direction (Simple3D | transformed [X v]) (Simple3D | transformed [Y v]) (Simple3D | transformed [Z v]) :: custom
end
define draw box (x) (y) (z) (scale)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
if then
Simple3D | rotate around [Y v] by ((timer) * (180)) degrees
Simple3D | rotate around [X v] by ((timer) * (45)) degrees
end
Simple3D | scale X:(scale) Y:(scale) Z:(scale)
Simple3D | draw mesh [box]
define draw line of boxes in direction (x) (y) (z)
set [i v] to [0]
repeat (10)
draw box ((x) * (i)) ((y) * (i)) ((z) * (i)) [0.1] undefined :: custom
change [i v] by (0.1)
end
Simple3D | transform X:(0) Y:(1) Z:(0) from [model space v] to [world space v] // You can try this to see that the offset here is not needed and messes everything up.
```
# End of manualTransforms/dirModelToWorld.sb3
# Project: Implementing simple 4-directional first person movement
# Start of manualTransforms/controllerSimple.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 146
camera rot around X = 180
### Global Lists
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
controls mouse :: custom
setup view transform :: custom
controls WASD :: custom
draw box [0] [0] [-5] :: custom
draw box [-3] [0] [-5] :: custom
draw box [3] [0] [-5] :: custom
draw box [0] [0] [-10] :: custom
draw box [0] [3] [-10] :: custom
draw box [0] [-3] [-10] :: custom
end
define draw box (x) (y) (z)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | rotate around [Y v] by ((timer) * (180)) degrees
Simple3D | rotate around [X v] by (20) degrees
Simple3D | draw mesh [box]
define controls WASD
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camera X v] by (Simple3D | transformed [X v])
change [camera Y v] by (Simple3D | transformed [Y v])
change [camera Z v] by (Simple3D | transformed [Z v])
define controls mouse
set [camera rot around Y v] to ((0) - (mouse x))
set [camera rot around X v] to (mouse y)
define setup view transform
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camera rot around X)) degrees
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
```
# End of manualTransforms/controllerSimple.sb3
# Project: Implementing 6-directional movement
# Start of manualTransforms/controllerSixDir.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 159
camera rot around X = 180
### Global Lists
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
set [camera rot around Y v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
controls mouse :: custom
setup fake view transform :: custom
controls WASD :: custom
setup view transform :: custom
draw box [0] [0] [-5] :: custom
draw box [-3] [0] [-5] :: custom
draw box [3] [0] [-5] :: custom
draw box [0] [0] [-10] :: custom
draw box [0] [3] [-10] :: custom
draw box [0] [-3] [-10] :: custom
end
define draw box (x) (y) (z)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | rotate around [Y v] by ((timer) * (180)) degrees
Simple3D | rotate around [X v] by (20) degrees
Simple3D | draw mesh [box]
define controls WASD
Simple3D | transform direction X:( - ) Y:( - ) Z:( - ) from [view space v] to [world space v]
change [camera X v] by (Simple3D | transformed [X v])
change [camera Y v] by (Simple3D | transformed [Y v])
change [camera Z v] by (Simple3D | transformed [Z v])
define controls mouse
set [camera rot around Y v] to ((0) - (mouse x))
set [camera rot around X v] to (mouse y)
define setup view transform
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camera rot around X)) degrees
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
define setup fake view transform
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
(w v)
```
# End of manualTransforms/controllerSixDir.sb3
# Section: Importing models from files
# Project: Importing example
# Start of import/import4.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "colgrid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient.
### Global Variables
camera X = 0
camera Y = 3
camera Z = 0
camera rot around Y = 169
camera rot around X = 180
### Global Lists
cube.off = ["OFF","","8 6 12","","-0.500000 -0.500000 0.500000","0.500000 -0.500000 0.500000","-0.500000 0.500000 0.500000","0.500000 0.500000 0.500000","-0.500000 0.500000 -0.500000","0.500000 0.500000 -0.500000","-0.500000 -0.500000 -0.500000","0.500000 -0.500000 -0.500000","","4 1 0 2 3 1.0 0.0 0.0","4 5 4 6 7 1.0 0.0 0.0","4 3 2 4 5 0.0 1.0 0.0","4 7 6 0 1 0.0 1.0 0.0","4 7 1 3 5 0.0 0.0 1.0","4 0 6 4 2 0.0 0.0 1.0"]
cube.mtl.off = ["newmtl Red","Kd 1.0 0.0 0.0","","newmtl Green","Kd 0.0 1.0 0.0","","newmtl Blue","Kd 0.0 0.0 1.0","","o cube","","v -0.5 -0.5 0.5","v 0.5 -0.5 0.5","v -0.5 0.5 0.5","v 0.5 0.5 0.5","v -0.5 0.5 -0.5","v 0.5 0.5 -0.5","v -0.5 -0.5 -0.5","v 0.5 -0.5 -0.5","","vt 0.0 0.0","vt 1.0 0.0","vt 0.0 1.0","vt 1.0 1.0","","vn 0.0 0.0 1.0","vn 0.0 1.0 0.0","vn 0.0 0.0 -1.0","vn 0.0 -1.0 0.0","vn 1.0 0.0 0.0","vn -1.0 0.0 0.0","","g cube","usemtl Red","f 2 1 3 4","f 6 5 7 8","usemtl Green","f 4 3 5 6","f 8 7 1 2","usemtl Blue","f 8 2 4 6","f 1 7 5 3",""]
cube.vertexcolors.obj = ["v 0.5 -0.5 -0.5 1.0 0.0 0.0","v -0.5 -0.5 -0.5 1.0 0.0 0.0","v 0.5 0.5 -0.5 1.0 0.0 0.0","v -0.5 0.5 -0.5 1.0 0.0 0.0","v -0.5 -0.5 0.5 1.0 0.0 0.0","v 0.5 -0.5 0.5 1.0 0.0 0.0","v -0.5 0.5 0.5 1.0 0.0 0.0","v 0.5 0.5 0.5 1.0 0.0 0.0","v -0.5 -0.5 -0.5 0.0 1.0 0.0","v 0.5 -0.5 -0.5 0.0 1.0 0.0","v -0.5 -0.5 0.5 0.0 1.0 0.0","v 0.5 -0.5 0.5 0.0 1.0 0.0","v 0.5 0.5 -0.5 0.0 1.0 0.0","v -0.5 0.5 -0.5 0.0 1.0 0.0","v 0.5 0.5 0.5 0.0 1.0 0.0","v -0.5 0.5 0.5 0.0 1.0 0.0","v -0.5 0.5 -0.5 0.0 0.0 1.0","v -0.5 -0.5 -0.5 0.0 0.0 1.0","v -0.5 0.5 0.5 0.0 0.0 1.0","v -0.5 -0.5 0.5 0.0 0.0 1.0","v 0.5 -0.5 -0.5 0.0 0.0 1.0","v 0.5 0.5 -0.5 0.0 0.0 1.0","v 0.5 -0.5 0.5 0.0 0.0 1.0","v 0.5 0.5 0.5 0.0 0.0 1.0","f 2 1 3 4","f 6 5 7 8","f 10 9 11 12","f 14 13 15 16","f 18 17 19 20","f 22 21 23 24"]
cube.textured.obj = ["# cube.obj","# https://gist.github.com/noonat/1131091/450ad7bbb6e0c8fba1854cc86a9f6b7a224fca56","","mtllib cube.mtl","o cube","","v -0.500000 -0.500000 0.500000","v 0.500000 -0.500000 0.500000","v -0.500000 0.500000 0.500000","v 0.500000 0.500000 0.500000","v -0.500000 0.500000 -0.500000","v 0.500000 0.500000 -0.500000","v -0.500000 -0.500000 -0.500000","v 0.500000 -0.500000 -0.500000","","vt 0.000000 0.000000","vt 1.000000 0.000000","vt 0.000000 1.000000","vt 1.000000 1.000000","","vn 0.000000 0.000000 1.000000","vn 0.000000 1.000000 0.000000","vn 0.000000 0.000000 -1.000000","vn 0.000000 -1.000000 0.000000","vn 1.000000 0.000000 0.000000","vn -1.000000 0.000000 0.000000","","g cube","usemtl cube","s 1","f 1/1/1 2/2/1 3/3/1","f 3/3/1 2/2/1 4/4/1","s 2","f 3/1/2 4/2/2 5/3/2","f 5/3/2 4/2/2 6/4/2","s 3","f 5/4/3 6/3/3 7/2/3","f 7/2/3 6/3/3 8/1/3","s 4","f 7/1/4 8/2/4 1/3/4","f 1/3/4 8/2/4 2/4/4","s 5","f 2/1/5 8/2/5 4/3/5","f 4/3/5 8/2/5 6/4/5","s 6","f 7/1/6 1/2/6 5/3/6","f 5/3/6 1/2/6 3/4/6",""]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [cube-off]
Simple3D | set [cube-off] from [off v] [cube.off v]
Simple3D | create mesh [cube-mtl-obj]
Simple3D | set [cube-mtl-obj] from [obj mtl v] [cube.mtl.off v]
Simple3D | create mesh [cube-vertex-colors-obj]
Simple3D | set [cube-vertex-colors-obj] from [obj mtl v] [cube.vertexcolors.obj v]
Simple3D | create mesh [cube-textured-obj]
Simple3D | set [cube-textured-obj] from [obj mtl v] [cube.textured.obj v]
Simple3D | set [cube-textured-obj] texture (Simple3D | texture from costume (costume colgrid)) [clamp to edge v] [pixelated v]
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
controls :: custom
Simple3D | configure [modelToWorld v] transformation
draw [cube-off] at [-7.5] [0] [-10] :: custom
draw [cube-mtl-obj] at [-2.5] [0] [-10] :: custom
draw [cube-vertex-colors-obj] at [2.5] [0] [-10] :: custom
draw [cube-textured-obj] at [7.5] [0] [-10] :: custom
end
define draw (mesh) at (x) (y) (z)
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | draw mesh (mesh)
define controls
set [camera rot around Y v] to ((0) - (mouse x))
set [camera rot around X v] to (mouse y)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | transform direction X:( - ) Y:( - ) Z:( - ) from [view space v] to [world space v]
change [camera X v] by (Simple3D | transformed [X v])
change [camera Y v] by (Simple3D | transformed [Y v])
change [camera Z v] by (Simple3D | transformed [Z v])
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camera rot around X)) degrees
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
```
# End of import/import4.sb3
# Project: Waiting for import to finish
# Start of import/importWait.sb3
## Sprite: "Stage"
### Costumes
1. "empty" - empty png
2. "loading" - 'Loading.... Please wait'
3. "colgrid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient.
### Global Variables
camera X = 0
camera Y = 0
camera Z = 0
camera rot around Y = 166
camera rot around X = 180
### Global Lists
cube.off = ["OFF","","8 6 12","","-0.500000 -0.500000 0.500000","0.500000 -0.500000 0.500000","-0.500000 0.500000 0.500000","0.500000 0.500000 0.500000","-0.500000 0.500000 -0.500000","0.500000 0.500000 -0.500000","-0.500000 -0.500000 -0.500000","0.500000 -0.500000 -0.500000","","4 1 0 2 3 1.0 0.0 0.0","4 5 4 6 7 1.0 0.0 0.0","4 3 2 4 5 0.0 1.0 0.0","4 7 6 0 1 0.0 1.0 0.0","4 7 1 3 5 0.0 0.0 1.0","4 0 6 4 2 0.0 0.0 1.0"]
cube.mtl.off = ["newmtl Red","Kd 1.0 0.0 0.0","","newmtl Green","Kd 0.0 1.0 0.0","","newmtl Blue","Kd 0.0 0.0 1.0","","o cube","","v -0.5 -0.5 0.5","v 0.5 -0.5 0.5","v -0.5 0.5 0.5","v 0.5 0.5 0.5","v -0.5 0.5 -0.5","v 0.5 0.5 -0.5","v -0.5 -0.5 -0.5","v 0.5 -0.5 -0.5","","vt 0.0 0.0","vt 1.0 0.0","vt 0.0 1.0","vt 1.0 1.0","","vn 0.0 0.0 1.0","vn 0.0 1.0 0.0","vn 0.0 0.0 -1.0","vn 0.0 -1.0 0.0","vn 1.0 0.0 0.0","vn -1.0 0.0 0.0","","g cube","usemtl Red","f 2 1 3 4","f 6 5 7 8","usemtl Green","f 4 3 5 6","f 8 7 1 2","usemtl Blue","f 8 2 4 6","f 1 7 5 3",""]
cube.vertexcolors.obj = ["v 0.5 -0.5 -0.5 1.0 0.0 0.0","v -0.5 -0.5 -0.5 1.0 0.0 0.0","v 0.5 0.5 -0.5 1.0 0.0 0.0","v -0.5 0.5 -0.5 1.0 0.0 0.0","v -0.5 -0.5 0.5 1.0 0.0 0.0","v 0.5 -0.5 0.5 1.0 0.0 0.0","v -0.5 0.5 0.5 1.0 0.0 0.0","v 0.5 0.5 0.5 1.0 0.0 0.0","v -0.5 -0.5 -0.5 0.0 1.0 0.0","v 0.5 -0.5 -0.5 0.0 1.0 0.0","v -0.5 -0.5 0.5 0.0 1.0 0.0","v 0.5 -0.5 0.5 0.0 1.0 0.0","v 0.5 0.5 -0.5 0.0 1.0 0.0","v -0.5 0.5 -0.5 0.0 1.0 0.0","v 0.5 0.5 0.5 0.0 1.0 0.0","v -0.5 0.5 0.5 0.0 1.0 0.0","v -0.5 0.5 -0.5 0.0 0.0 1.0","v -0.5 -0.5 -0.5 0.0 0.0 1.0","v -0.5 0.5 0.5 0.0 0.0 1.0","v -0.5 -0.5 0.5 0.0 0.0 1.0","v 0.5 -0.5 -0.5 0.0 0.0 1.0","v 0.5 0.5 -0.5 0.0 0.0 1.0","v 0.5 -0.5 0.5 0.0 0.0 1.0","v 0.5 0.5 0.5 0.0 0.0 1.0","f 2 1 3 4","f 6 5 7 8","f 10 9 11 12","f 14 13 15 16","f 18 17 19 20","f 22 21 23 24"]
cube.textured.obj = ["# cube.obj","# https://gist.github.com/noonat/1131091/450ad7bbb6e0c8fba1854cc86a9f6b7a224fca56","","mtllib cube.mtl","o cube","","v -0.500000 -0.500000 0.500000","v 0.500000 -0.500000 0.500000","v -0.500000 0.500000 0.500000","v 0.500000 0.500000 0.500000","v -0.500000 0.500000 -0.500000","v 0.500000 0.500000 -0.500000","v -0.500000 -0.500000 -0.500000","v 0.500000 -0.500000 -0.500000","","vt 0.000000 0.000000","vt 1.000000 0.000000","vt 0.000000 1.000000","vt 1.000000 1.000000","","vn 0.000000 0.000000 1.000000","vn 0.000000 1.000000 0.000000","vn 0.000000 0.000000 -1.000000","vn 0.000000 -1.000000 0.000000","vn 1.000000 0.000000 0.000000","vn -1.000000 0.000000 0.000000","","g cube","usemtl cube","s 1","f 1/1/1 2/2/1 3/3/1","f 3/3/1 2/2/1 4/4/1","s 2","f 3/1/2 4/2/2 5/3/2","f 5/3/2 4/2/2 6/4/2","s 3","f 5/4/3 6/3/3 7/2/3","f 7/2/3 6/3/3 8/1/3","s 4","f 7/1/4 8/2/4 1/3/4","f 1/3/4 8/2/4 2/4/4","s 5","f 2/1/5 8/2/5 4/3/5","f 4/3/5 8/2/5 6/4/5","s 6","f 7/1/6 1/2/6 5/3/6","f 5/3/6 1/2/6 3/4/6",""]
### Blocks
```scratchblocks
when flag clicked
Simple3D | reset everything
switch backdrop to (loading v)
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [cube-off]
Simple3D | set [cube-off] from [off v] [cube.off v]
Simple3D | create mesh [cube-mtl-obj]
Simple3D | set [cube-mtl-obj] from [obj mtl v] [cube.mtl.off v]
Simple3D | create mesh [cube-vertex-colors-obj]
Simple3D | set [cube-vertex-colors-obj] from [obj mtl v] [cube.vertexcolors.obj v]
Simple3D | create mesh [cube-textured-obj]
Simple3D | set [cube-textured-obj] from [obj mtl v] [cube.textured.obj v]
Simple3D | set [cube-textured-obj] texture (Simple3D | texture from costume (costume colgrid)) [clamp to edge v] [pixelated v]
wait until (Simple3D | mesh [is valid for drawing v] [cube-off])
wait until (Simple3D | mesh [is valid for drawing v] [cube-mtl-obj])
wait until (Simple3D | mesh [is valid for drawing v] [cube-mtl-obj])
wait until (Simple3D | mesh [is valid for drawing v] [cube-mtl-obj])
wait until // Mesh is considered valid for drawing (i.e. you can draw it and it will work) even without assigning it a texture or with texture that still haven't finished loading.\n\nSo if you don't want to show meshes with missing textures, you have to explicitly check for them as well.
switch backdrop to (empty v)
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
controls :: custom
Simple3D | configure [modelToWorld v] transformation
draw [cube-off] at [-7.5] [0] [-10] :: custom
draw [cube-mtl-obj] at [-2.5] [0] [-10] :: custom
draw [cube-vertex-colors-obj] at [2.5] [0] [-10] :: custom
draw [cube-textured-obj] at [7.5] [0] [-10] :: custom
end
define draw (mesh) at (x) (y) (z)
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | draw mesh (mesh)
define controls
set [camera rot around Y v] to ((0) - (mouse x))
set [camera rot around X v] to (mouse y)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | transform direction X:( - ) Y:( - ) Z:( - ) from [view space v] to [world space v]
change [camera X v] by (Simple3D | transformed [X v])
change [camera Y v] by (Simple3D | transformed [Y v])
change [camera Z v] by (Simple3D | transformed [Z v])
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camera rot around X)) degrees
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
```
# End of import/importWait.sb3
# Project: Transforming imported meshes
# Start of import/importTransform.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "colgrid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient.
### Global Variables
camera X = -8.614508164249042
camera Y = 4
camera Z = -8.820424310989928
camera rot around Y = 167
camera rot around X = 180
### Global Lists
cube.off = ["OFF","","8 6 12","","-0.500000 -0.500000 0.500000","0.500000 -0.500000 0.500000","-0.500000 0.500000 0.500000","0.500000 0.500000 0.500000","-0.500000 0.500000 -0.500000","0.500000 0.500000 -0.500000","-0.500000 -0.500000 -0.500000","0.500000 -0.500000 -0.500000","","4 1 0 2 3 1.0 0.0 0.0","4 5 4 6 7 1.0 0.0 0.0","4 3 2 4 5 0.0 1.0 0.0","4 7 6 0 1 0.0 1.0 0.0","4 7 1 3 5 0.0 0.0 1.0","4 0 6 4 2 0.0 0.0 1.0"]
cube.mtl.off = ["newmtl Red","Kd 1.0 0.0 0.0","","newmtl Green","Kd 0.0 1.0 0.0","","newmtl Blue","Kd 0.0 0.0 1.0","","o cube","","v -0.5 -0.5 0.5","v 0.5 -0.5 0.5","v -0.5 0.5 0.5","v 0.5 0.5 0.5","v -0.5 0.5 -0.5","v 0.5 0.5 -0.5","v -0.5 -0.5 -0.5","v 0.5 -0.5 -0.5","","vt 0.0 0.0","vt 1.0 0.0","vt 0.0 1.0","vt 1.0 1.0","","vn 0.0 0.0 1.0","vn 0.0 1.0 0.0","vn 0.0 0.0 -1.0","vn 0.0 -1.0 0.0","vn 1.0 0.0 0.0","vn -1.0 0.0 0.0","","g cube","usemtl Red","f 2 1 3 4","f 6 5 7 8","usemtl Green","f 4 3 5 6","f 8 7 1 2","usemtl Blue","f 8 2 4 6","f 1 7 5 3",""]
cube.vertexcolors.obj = ["v 0.5 -0.5 -0.5 1.0 0.0 0.0","v -0.5 -0.5 -0.5 1.0 0.0 0.0","v 0.5 0.5 -0.5 1.0 0.0 0.0","v -0.5 0.5 -0.5 1.0 0.0 0.0","v -0.5 -0.5 0.5 1.0 0.0 0.0","v 0.5 -0.5 0.5 1.0 0.0 0.0","v -0.5 0.5 0.5 1.0 0.0 0.0","v 0.5 0.5 0.5 1.0 0.0 0.0","v -0.5 -0.5 -0.5 0.0 1.0 0.0","v 0.5 -0.5 -0.5 0.0 1.0 0.0","v -0.5 -0.5 0.5 0.0 1.0 0.0","v 0.5 -0.5 0.5 0.0 1.0 0.0","v 0.5 0.5 -0.5 0.0 1.0 0.0","v -0.5 0.5 -0.5 0.0 1.0 0.0","v 0.5 0.5 0.5 0.0 1.0 0.0","v -0.5 0.5 0.5 0.0 1.0 0.0","v -0.5 0.5 -0.5 0.0 0.0 1.0","v -0.5 -0.5 -0.5 0.0 0.0 1.0","v -0.5 0.5 0.5 0.0 0.0 1.0","v -0.5 -0.5 0.5 0.0 0.0 1.0","v 0.5 -0.5 -0.5 0.0 0.0 1.0","v 0.5 0.5 -0.5 0.0 0.0 1.0","v 0.5 -0.5 0.5 0.0 0.0 1.0","v 0.5 0.5 0.5 0.0 0.0 1.0","f 2 1 3 4","f 6 5 7 8","f 10 9 11 12","f 14 13 15 16","f 18 17 19 20","f 22 21 23 24"]
cube.textured.obj = ["# cube.obj","# https://gist.github.com/noonat/1131091/450ad7bbb6e0c8fba1854cc86a9f6b7a224fca56","","mtllib cube.mtl","o cube","","v -0.500000 -0.500000 0.500000","v 0.500000 -0.500000 0.500000","v -0.500000 0.500000 0.500000","v 0.500000 0.500000 0.500000","v -0.500000 0.500000 -0.500000","v 0.500000 0.500000 -0.500000","v -0.500000 -0.500000 -0.500000","v 0.500000 -0.500000 -0.500000","","vt 0.000000 0.000000","vt 1.000000 0.000000","vt 0.000000 1.000000","vt 1.000000 1.000000","","vn 0.000000 0.000000 1.000000","vn 0.000000 1.000000 0.000000","vn 0.000000 0.000000 -1.000000","vn 0.000000 -1.000000 0.000000","vn 1.000000 0.000000 0.000000","vn -1.000000 0.000000 0.000000","","g cube","usemtl cube","s 1","f 1/1/1 2/2/1 3/3/1","f 3/3/1 2/2/1 4/4/1","s 2","f 3/1/2 4/2/2 5/3/2","f 5/3/2 4/2/2 6/4/2","s 3","f 5/4/3 6/3/3 7/2/3","f 7/2/3 6/3/3 8/1/3","s 4","f 7/1/4 8/2/4 1/3/4","f 1/3/4 8/2/4 2/4/4","s 5","f 2/1/5 8/2/5 4/3/5","f 4/3/5 8/2/5 6/4/5","s 6","f 7/1/6 1/2/6 5/3/6","f 5/3/6 1/2/6 3/4/6",""]
### Blocks
```scratchblocks
when flag clicked
set [camera X v] to [0]
set [camera Y v] to [0]
set [camera Z v] to [0]
setup import transform :: custom
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [cube-off]
Simple3D | set [cube-off] from [off v] [cube.off v]
Simple3D | create mesh [cube-mtl-obj]
Simple3D | set [cube-mtl-obj] from [obj mtl v] [cube.mtl.off v]
Simple3D | create mesh [cube-vertex-colors-obj]
Simple3D | set [cube-vertex-colors-obj] from [obj mtl v] [cube.vertexcolors.obj v]
Simple3D | create mesh [cube-textured-obj]
Simple3D | set [cube-textured-obj] from [obj mtl v] [cube.textured.obj v]
Simple3D | set [cube-textured-obj] texture (Simple3D | texture from costume (costume colgrid)) [clamp to edge v] [pixelated v]
forever
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (1) far: (100)
controls :: custom
Simple3D | configure [modelToWorld v] transformation
draw [cube-off] at [-7.5] [0] [-10] :: custom
draw [cube-mtl-obj] at [-2.5] [0] [-10] :: custom
draw [cube-vertex-colors-obj] at [2.5] [0] [-10] :: custom
draw [cube-textured-obj] at [7.5] [0] [-10] :: custom
end
define draw (mesh) at (x) (y) (z)
Simple3D | start with no transformation
Simple3D | move X:(x) Y:(y) Z:(z)
Simple3D | draw mesh (mesh)
define controls
set [camera rot around Y v] to ((0) - (mouse x))
set [camera rot around X v] to (mouse y)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | transform direction X:( - ) Y:( - ) Z:( - ) from [view space v] to [world space v]
change [camera X v] by (Simple3D | transformed [X v])
change [camera Y v] by (Simple3D | transformed [Y v])
change [camera Z v] by (Simple3D | transformed [Z v])
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camera rot around X)) degrees
Simple3D | rotate around [Y v] by ((0) - (camera rot around Y)) degrees
Simple3D | move X:((0) - (camera X)) Y:((0) - (camera Y)) Z:((0) - (camera Z))
define setup import transform
Simple3D | configure [import v] transformation // Models can be immediately transformed when importing from a file.\n\nCan be useful for importing models made in software that has Z as up.
Simple3D | start with no transformation
Simple3D | scale X:(0.1) Y:(2) Z:(1)
Simple3D | rotate around [X v] by (45) degrees
```
# End of import/importTransform.sb3
# Section: Text rendering
# Project: Starting with simple text
# Start of textureText/text1.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [0,1,0,1]
y list = [0,0,1,1]
u list = [0,1,0,1]
v list = [0,0,1,1]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (32)) color (#ffff00)) [clamp to edge v] [pixelated v]
Simple3D | draw mesh [my mesh]
// Drawing text!\n\nLet's start simple. Text is upside-down and squished.
```
# End of textureText/text1.sb3
# Project: Fixing upsidedown and aspect ratio
# Start of textureText/text2.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "grid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient. Top left corner has label U:0 V:0, top right corner has label U:1 V:0, bottom left corner has label U:0 V:1, bottom right corner has label U:1 V:1.
### Global Lists
x list = [0,1,0,1]
y list = [0,0,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (32)) color (#ffff00)) [clamp to edge v] [pixelated v]
Simple3D | scale X:((Simple3D | mesh [texture width v] [my mesh]) / (100)) Y:((Simple3D | mesh [texture height v] [my mesh]) / (100)) Z:(1) // Next, to make text not squished, it can be scaled horizontally and vertically by text texture's width and height
Simple3D | draw mesh [my mesh]
// The text was upside-down because positive Y is UP, while in texture space positive V is DOWN. We can fix it by wither scaling Y by -1, or by simply flipping V values in UVs.\n\nHere we've done the later
```
# End of textureText/text2.sb3
# Project: Changing resolutions changes text scale
# Start of textureText/text3.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [0,1,0,1]
y list = [0,0,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (128)) color (#ffff00)) [clamp to edge v] [pixelated v]
Simple3D | scale X:((Simple3D | mesh [texture width v] [my mesh]) / (100)) Y:((Simple3D | mesh [texture height v] [my mesh]) / (100)) Z:(1) // Though doing this isn't very convenient, as currently if we decide to change text resolution, it's size will also change.
Simple3D | draw mesh [my mesh]
```
# End of textureText/text3.sb3
# Project: Solving the issue, but text is small now
# Start of textureText/text4.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Lists
x list = [0,1,0,1]
y list = [0,0,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (128)) color (#ffff00)) [clamp to edge v] [pixelated v]
Simple3D | scale X:((Simple3D | mesh [texture width v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh])) Y:(1) Z:(1) // A better would be to keep Y constant, but scale X by text's aspect ratio.
Simple3D | draw mesh [my mesh]
Simple3D | scale X:((Simple3D | mesh [texture width v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh])) Y:((Simple3D | mesh [texture height v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh])) Z:(1) // Or you could imagine this as taking what we had before and dividing both scaling factors by texture's height.\n\nSame thing
```
# End of textureText/text4.sb3
# Project: Re-adding scaling
# Start of textureText/text5.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
desired height = 0.25
### Global Lists
x list = [0,1,0,1]
y list = [0,0,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (128)) color (#ffff00)) [clamp to edge v] [pixelated v]
Simple3D | scale X:((desired height) * ((Simple3D | mesh [texture width v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh]))) Y:(desired height) Z:(1) // And finally, you can also multiply both parts by some scaling factor
Simple3D | draw mesh [my mesh]
```
# End of textureText/text5.sb3
# Project: Centering text with move block
# Start of textureText/centered1.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
desired height = 0.46
### Global Lists
x list = [0,1,0,1]
y list = [0,0,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (128)) color (#ffff00)) [clamp to edge v] [pixelated v]
Simple3D | scale X:((desired height) * ((Simple3D | mesh [texture width v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh]))) Y:(desired height) Z:(1)
Simple3D | move X:(-0.5) Y:(-0.5) Z:(0) // If the text positions are defined in range from 0 to 1, you can shift them by -0.5 as the first applied transformation, and you'll get centered text.\n\nRemember that transformations are applied in reversed order, so defining this at the end means it will be applied first.\n\nOr if you don't want to deal with transformations, you can also just edit the "x list" and "y list" to have values "-0.5" and "0.5" instead of "0" and "1" to achieve exact same effect.\n\nAt that point you might as well make it "-1" and "1" to make it cleaner.
Simple3D | draw mesh [my mesh]
// Now imagine you want to center the text.
```
# End of textureText/centered1.sb3
# Project: Centering text by changing mesh to be centered
# Start of textureText/centered2.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
desired height = 0.2
### Global Lists
x list = [-1,1,-1,1]
y list = [-1,-1,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (128)) color (#ffff00)) [clamp to edge v] [pixelated v]
Simple3D | scale X:((desired height) * ((Simple3D | mesh [texture width v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh]))) Y:(desired height) Z:(1)
Simple3D | draw mesh [my mesh]
// Here is the example of that - making "x list" and "y list" have values "-1" and "1" to center text.
```
# End of textureText/centered2.sb3
# Project: Un-centering centered mesh
# Start of textureText/centered3.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
desired height = 0.14
### Global Lists
x list = [-1,1,-1,1]
y list = [-1,-1,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (128)) color (#ffff00)) [clamp to edge v] [pixelated v]
Simple3D | scale X:((desired height) * ((Simple3D | mesh [texture width v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh]))) Y:(desired height) Z:(1)
Simple3D | scale X:(0.5) Y:(0.5) Z:(1)
Simple3D | move X:(1) Y:(1) Z:(0)
Simple3D | draw mesh [my mesh]
// And if you want to un-center the text defined with -1 and 1, you can shift it by 1 as the first transformation, then scale it by 0.5.\n\nIt will convert values from range -1 to 1 to range 0 to 1.
```
# End of textureText/centered3.sb3
# Project: Increasing resolution to make text less blurry
# Start of textureText/edges1.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
desired height = 0.34
### Global Lists
x list = [-1,1,-1,1]
y list = [-1,-1,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (32)) color (#ffff00)) [clamp to edge v] [blurred v]
Simple3D | scale X:((desired height) * ((Simple3D | mesh [texture width v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh]))) Y:(desired height) Z:(1)
Simple3D | draw mesh [my mesh]
// What should you do if you don't want your text looking pixelated or blurry? The obvious answer is to increase the resolution
```
# End of textureText/edges1.sb3
# Project: Better solution for sharp text edges
# Start of textureText/edges2.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
### Global Variables
desired height = 3
### Global Lists
x list = [-1,1,-1,1]
y list = [-1,-1,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Sans Serif v] of size (128)) color (#ffff00)) [clamp to edge v] [blurred v] // Note that you need "blurred" here.\n\n"pixelated" wouldn't work.
Simple3D | scale X:((desired height) * ((Simple3D | mesh [texture width v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh]))) Y:(desired height) Z:(1)
Simple3D | draw mesh [my mesh]
Simple3D | set [my mesh] discord pixels less opaque than [0.5], for those that pass true
// What if that's still not enough? What if you want to look at your text REALLY upclose? Is there a solution? High resolutions take up a lot of memory (a lot of pixels to store) and can also be more laggy to render.\n\nYes, there is a solution! It is presented below. Figure out how to use it
```
# End of textureText/edges2.sb3
# Project: It's also useful for vegetation
# Start of textureText/edges3.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "leaves" - a bush, except it's just leaves and none of the wood parts. blurred, and has a lot of partial transparency on the edges
3. "leavesWood" - a bush, consisting of green leaves and brown wood. blurred, and has a lot of partial transparency on the edges
### Global Variables
zoom = 1
discard enabled = 0
### Global Lists
x list = [-1,1,-1,1]
y list = [-1,-1,1,1]
u list = [0,1,0,1]
v list = [1,1,0,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume leaves)) // There are 2 costumes for you to test [clamp to edge v] [blurred v]
wait until
forever
if <(discard enabled) = [1]> then
Simple3D | set [my mesh] discord pixels less opaque than [0.5], for those that pass true
else
Simple3D | set [my mesh] discord pixels less opaque than [-1], for those that pass false
end // Transparent pixel discard could also be useful for vegetation
Simple3D | clear (color and depth v)
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | scale X:((zoom) * ((Simple3D | mesh [texture width v] [my mesh]) / (Simple3D | mesh [texture height v] [my mesh]))) Y:(zoom) Z:(1)
Simple3D | draw mesh [my mesh]
end
```
# End of textureText/edges3.sb3
# Section: Animated textures
# Project: Changing texture directly (AVOID THIS!)
# Start of meshTextureAnimated/uploadEveryFrame.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
2. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
3. "box1" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
4. "box2" - lime-colored box
5. "box3" - blue box
6. "box4" - red box
### Global Variables
camX = 19.907037847304363
camY = 8.541936735341977
camZ = 5.4399309986059565
camRotX = 180
camRotY = 154
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
### Blocks
```scratchblocks
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | set [box] texture (Simple3D | texture from costume (join [box] ((([floor v] of (timer)) mod (4)) + (1)))) [clamp to edge v] [pixelated v] // DO NOT DO THIS!\n\nThis is slow. This has a few frames of delay. Doing it every frame like here might even cause TurboWarp to crash.
Simple3D | start with no transformation
Simple3D | wrapper {
Simple3D | move X:(-8) Y:(2.05) Z:(-16)
Simple3D | rotate around [Y v] by (35) degrees
Simple3D | scale X:(2) Y:(2) Z:(2)
Simple3D | draw mesh [box]
}
Simple3D | wrapper {
Simple3D | move X:(32) Y:(4.05) Z:(7)
Simple3D | rotate around [Y v] by (-10) degrees
Simple3D | scale X:(4) Y:(4) Z:(4)
Simple3D | draw mesh [box]
}
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
end
(costume box1)
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
```
# End of meshTextureAnimated/uploadEveryFrame.sb3
# Project: Pre-creating multiple meshes that all inherit from the same base mesh
# Start of meshTextureAnimated/inheritShapeCustomTexture.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
2. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
3. "box1" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
4. "box2" - lime-colored box
5. "box3" - blue box
6. "box4" - red box
### Global Variables
camX = 13.600298025340916
camY = 27.052185918445808
camZ = 20.947480341349316
camRotX = 180
camRotY = 171
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
### Blocks
```scratchblocks
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | start with no transformation
Simple3D | wrapper {
Simple3D | move X:(-8) Y:(2.05) Z:(-16)
Simple3D | rotate around [Y v] by (35) degrees
Simple3D | scale X:(2) Y:(2) Z:(2)
Simple3D | draw mesh (join [box] ((([floor v] of (timer)) mod (4)) + (1)))
}
Simple3D | wrapper {
Simple3D | move X:(32) Y:(4.05) Z:(7)
Simple3D | rotate around [Y v] by (-10) degrees
Simple3D | scale X:(4) Y:(4) Z:(4)
Simple3D | draw mesh (join [box] ((([floor v] of (timer)) mod (4)) + (1)))
}
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | create mesh [box1]
Simple3D | make [box1] inherit from meshes [box]
Simple3D | set [box1] texture (Simple3D | texture from costume (costume box1)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box2]
Simple3D | make [box2] inherit from meshes [box]
Simple3D | set [box2] texture (Simple3D | texture from costume (costume box2)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box3]
Simple3D | make [box3] inherit from meshes [box]
Simple3D | set [box3] texture (Simple3D | texture from costume (costume box3)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box4]
Simple3D | make [box4] inherit from meshes [box]
Simple3D | set [box4] texture (Simple3D | texture from costume (costume box4)) [clamp to edge v] [pixelated v]
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
end
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
```
# End of meshTextureAnimated/inheritShapeCustomTexture.sb3
# Project: Storing textures in meshes and using inheritance to switch between textures
# Start of meshTextureAnimated/inheritTexture.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
2. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
3. "box1" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
4. "box2" - lime-colored box
5. "box3" - blue box
6. "box4" - red box
### Global Variables
camX = 19.907037847304363
camY = 8.541936735341977
camZ = 5.4399309986059565
camRotX = 180
camRotY = 167
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
### Blocks
```scratchblocks
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | make [box] inherit from meshes (join (join [box] ((([floor v] of (timer)) mod (4)) + (1))) [texture])
Simple3D | start with no transformation
Simple3D | wrapper {
Simple3D | move X:(-8) Y:(2.05) Z:(-16)
Simple3D | rotate around [Y v] by (35) degrees
Simple3D | scale X:(2) Y:(2) Z:(2)
Simple3D | draw mesh [box]
}
Simple3D | wrapper {
Simple3D | move X:(32) Y:(4.05) Z:(7)
Simple3D | rotate around [Y v] by (-10) degrees
Simple3D | scale X:(4) Y:(4) Z:(4)
Simple3D | draw mesh [box]
}
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | create mesh [box1texture]
Simple3D | set [box1texture] texture (Simple3D | texture from costume (costume box1)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box2texture]
Simple3D | set [box2texture] texture (Simple3D | texture from costume (costume box2)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box3texture]
Simple3D | set [box3texture] texture (Simple3D | texture from costume (costume box3)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box4texture]
Simple3D | set [box4texture] texture (Simple3D | texture from costume (costume box4)) [clamp to edge v] [pixelated v]
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
end
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
```
# End of meshTextureAnimated/inheritTexture.sb3
# Project: Directly changing UV offset
# Start of meshTextureAnimated/directUVoffset.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
2. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
3. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
4. "multi" - 2x2 texture atlas of white, lime, blue and red boxes
### Global Variables
camX = 24.89976812720474
camY = 12.775294419755092
camZ = 20.97715960131236
camRotX = 180
camRotY = 162
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,0.5,0,0.5,0,0.5,0,0.5,0,0.5,0,0.5,0,0.5,0,0.5,0,0,0.5,0.5,0,0,0.5,0.5]
boxV = [0.5,0.5,0,0,0.5,0.5,0,0,0.5,0.5,0,0,0.5,0.5,0,0,0,0.5,0,0.5,0.5,0,0.5,0]
### Blocks
```scratchblocks
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | set [box] texture coordinate offset UV ((([floor v] of (timer)) mod (2)) * (0.5)) ((([floor v] of ((timer) / (2))) mod (2)) * (0.5))
Simple3D | start with no transformation
Simple3D | wrapper {
Simple3D | move X:(-8) Y:(2.05) Z:(-16)
Simple3D | rotate around [Y v] by (35) degrees
Simple3D | scale X:(2) Y:(2) Z:(2)
Simple3D | draw mesh [box]
}
Simple3D | wrapper {
Simple3D | move X:(32) Y:(4.05) Z:(7)
Simple3D | rotate around [Y v] by (-10) degrees
Simple3D | scale X:(4) Y:(4) Z:(4)
Simple3D | draw mesh [box]
}
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume multi)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
end
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
```
# End of meshTextureAnimated/directUVoffset.sb3
# Project: Inherited UV offset
# Start of meshTextureAnimated/inheritUVoffset.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
2. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
3. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
4. "multi" - 2x2 texture atlas of white, lime, blue and red boxes
### Global Variables
camX = 7.2561435160843715
camY = 27.052185918445808
camZ = 17.989152509164427
camRotX = 180
camRotY = 163
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,0.5,0,0.5,0,0.5,0,0.5,0,0.5,0,0.5,0,0.5,0,0.5,0,0,0.5,0.5,0,0,0.5,0.5]
boxV = [0.5,0.5,0,0,0.5,0.5,0,0,0.5,0.5,0,0,0.5,0.5,0,0,0,0.5,0,0.5,0.5,0,0.5,0]
### Blocks
```scratchblocks
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | start with no transformation
Simple3D | wrapper {
Simple3D | move X:(-8) Y:(2.05) Z:(-16)
Simple3D | rotate around [Y v] by (35) degrees
Simple3D | scale X:(2) Y:(2) Z:(2)
Simple3D | draw mesh (join [box] ((([floor v] of (timer)) mod (4)) + (1)))
}
Simple3D | wrapper {
Simple3D | move X:(32) Y:(4.05) Z:(7)
Simple3D | rotate around [Y v] by (-10) degrees
Simple3D | scale X:(4) Y:(4) Z:(4)
Simple3D | draw mesh (join [box] ((([floor v] of (timer)) mod (4)) + (1)))
}
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume multi)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | create mesh [box1]
Simple3D | make [box1] inherit from meshes [box]
Simple3D | create mesh [box2]
Simple3D | make [box2] inherit from meshes [box]
Simple3D | set [box2] texture coordinate offset UV (0.5) (0)
Simple3D | create mesh [box3]
Simple3D | make [box3] inherit from meshes [box]
Simple3D | set [box3] texture coordinate offset UV (0) (0.5)
Simple3D | create mesh [box4]
Simple3D | make [box4] inherit from meshes [box]
Simple3D | set [box4] texture coordinate offset UV (0.5) (0.5)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
end
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
```
# End of meshTextureAnimated/inheritUVoffset.sb3
# Section: Common mistakes while loading textures
# Project: Drawing before texture loads
# Start of meshTextureLoading/textureBeforeLoads.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "grid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient. Top left corner has label U:0 V:0, top right corner has label U:1 V:0, bottom left corner has label U:0 V:1, bottom right corner has label U:1 V:1.
### Global Lists
x list = [0,1,0]
y list = [0,0,1]
u list = [0,0,0.75]
v list = [0,1,0.5]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] positions XY [x list v] [y list v]
Simple3D | set [my mesh] texture coordinates UV [u list v] [v list v]
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume grid)) [clamp to edge v] [pixelated v]
Simple3D | draw mesh [my mesh]
wait until // The fix
// Why is it black? Where is the texture?\n\nThe issue is that while some texture sources load texture instantly, as soon as the block is executed (e.g empty, from text, from a list), others take some time for texture to finish loading (e.g. load from URL).\n\nContrary to what you may expect, load from costume belongs to the latter.\n\n[set [my mesh] texture (texture) [clamp to edge] [pixelated]] does not wait for loading to complete, so the [draw mesh []] runs before there is a texture.\n\nThe reason why it is drawn as black, rather than default test texture, is because the test texture is only drawn when the mesh has no texture. In this case however, the texture gets created and attached to mesh immediately, but it's content is what takes some time to load.
```
# End of meshTextureLoading/textureBeforeLoads.sb3
# Project: Blocked by CORS
# Start of meshTextureLoading/textureCORS.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "grid1" - UV grid texture with big blue '1' on it
3. "grid2" - UV grid texture with big blue '2' on it
4. "grid3" - UV grid texture with big blue '3' on it
### Global Variables
left is loading = false
left has failed = true
right is loading = false
right has failed = false
### Global Lists
x list 1 = [-1,-1,-0.02,-0.02]
y list = [1,-1,1,-1]
u list = [0,0,1,1]
v list = [0,1,0,1]
x list 2 = [0.02,0.02,1,1]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | create mesh [left]
Simple3D | set [left] positions XY [x list 1 v] [y list v]
Simple3D | set [left] texture coordinates UV [u list v] [v list v]
Simple3D | set [left] primitives (triangle strip v)
Simple3D | set [left] texture (Simple3D | texture from URL [https://u.cubeupload.com/Xeltalliv/Tdsgbv3Dthumbnail.png]) // CORS (Cross Origin Resource Sharing) policy is a set of rules that web browsers enforce, that determines whether some site can access content from some other site, or not. By default it is forbidden, unless the site from which the content is taken, explicitly sends some extra data to specify that it's allowed.\n\nMost sites don't do that, so you can't load textures from them.\n\nThere are however ways around it. For example, if you are writing a program that doesn't run in the browser, it isn't affected by this policy. E.g. in python using requests module.\n\nThat means it is possible to create a program that will serve as a middleman, where your scratch project asks it to get data from a specific URL, it get the data disregarding CORS, and gives it back to the project.\n\nAny program like that is typically called "CORS proxy", and there are already a lot of them to chose from: you can either find the downloadable one and run it yourself, or find and use the publicly hosted one (though they may spy on everything being sent).\n\nTry to fix this project by loading that image through a CORS proxy. [clamp to edge v] [pixelated v]
Simple3D | create mesh [right]
Simple3D | set [right] positions XY [x list 2 v] [y list v]
Simple3D | set [right] texture coordinates UV [u list v] [v list v]
Simple3D | set [right] primitives (triangle strip v)
Simple3D | set [right] texture (Simple3D | texture from URL [https://extensions.turbowarp.org/dango.png]) [clamp to edge v] [pixelated v]
forever
set [left is loading v] to (Simple3D | mesh [texture is loading v] [left])
set [right is loading v] to (Simple3D | mesh [texture is loading v] [right])
set [left has failed v] to (Simple3D | mesh [texture has failed to load v] [left])
set [right has failed v] to (Simple3D | mesh [texture has failed to load v] [right])
Simple3D | clear (color and depth v)
Simple3D | draw mesh [left]
Simple3D | draw mesh [right]
end
```
# End of meshTextureLoading/textureCORS.sb3
# Project: What is [texture data] anyways?
# Start of meshTextureLoading/texturePassing.sb3
## Sprite: "Stage"
### Costumes
1. "" - empty png
2. "grid1" - UV grid texture with big blue '1' on it
3. "grid2" - UV grid texture with big blue '2' on it
4. "grid3" - UV grid texture with big blue '3' on it
### Global Variables
texture 1 = "[texture data]"
texture 2 = "[texture data]"
texture 3 = "[texture data]"
it's all the same = true
### Global Lists
x list 1 = [-1,-1,-0.02,-0.02]
y list = [1,-1,1,-1]
u list = [0,0,1,1]
v list = [0,1,0,1]
x list 2 = [0.02,0.02,1,1]
### Blocks
```scratchblocks
when flag clicked
set [texture 1 v] to (Simple3D | texture from costume (costume grid1))
set [texture 2 v] to (Simple3D | texture from costume (costume grid2))
set [texture 3 v] to (Simple3D | texture from costume (costume grid3))
set [it's all the same v] to <<(texture 1) = (texture 2)> and <(texture 2) = (texture 3)>>
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | create mesh [left]
Simple3D | set [left] positions XY [x list 1 v] [y list v]
Simple3D | set [left] texture coordinates UV [u list v] [v list v]
Simple3D | set [left] primitives (triangle strip v)
Simple3D | set [left] texture (texture 1) [clamp to edge v] [pixelated v]
Simple3D | create mesh [right]
Simple3D | set [right] positions XY [x list 2 v] [y list v]
Simple3D | set [right] texture coordinates UV [u list v] [v list v]
Simple3D | set [right] primitives (triangle strip v)
Simple3D | set [right] texture (texture 2) [clamp to edge v] [pixelated v]
wait until < and >
Simple3D | draw mesh [left]
Simple3D | draw mesh [right]
// In this extension, there is an internal variable that is used for passing around the actual texture data. \n\nThe texture reporter blocks simply set that variable to the Promise that eventually resolves in a correct texture data. The reporter blocks themselves always simply return the string "[texture data]".\n\nThe blocks that take textures as inputs, check if the input string is "[texture data]", if so, read and save the latest Promise at that time, and start waiting for it to return texture data. (which may take a while if texture is loaded from URL over slow connection)
```
# End of meshTextureLoading/texturePassing.sb3
# Section: Instancing
# Project: No instancing
# Start of meshInstancing/instancingWithout.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = 7.14905100086089
camY = 28.562933656780633
camZ = 26.06407717639
camRotX = 180
camRotY = 161
i = 10000
frames = 10
fps = 15.180265654648956
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxesPosX = []
boxesPosY = []
boxesPosZ = []
boxesRotX = []
boxesRotY = []
boxesRotZ = []
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
Randomly scatter [10000] boxes :: custom
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
change [frames v] by (1)
if <(timer) > [1]> then
set [fps v] to ((frames) / (timer))
set [frames v] to [0]
reset timer
end
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
set [i v] to [0]
repeat (length of [boxesPosX v])
change [i v] by (1)
Simple3D | start with no transformation
Simple3D | move X:(item (i) of [boxesPosX v]) Y:(item (i) of [boxesPosY v]) Z:(item (i) of [boxesPosZ v])
Simple3D | rotate around [X v] by (item (i) of [boxesRotX v]) degrees
Simple3D | rotate around [Y v] by (item (i) of [boxesRotY v]) degrees
Simple3D | rotate around [Z v] by (item (i) of [boxesRotZ v]) degrees
Simple3D | draw mesh [box]
end
define Randomly scatter (n) boxes
delete all of [boxesPosX v]
delete all of [boxesPosY v]
delete all of [boxesPosZ v]
delete all of [boxesRotX v]
delete all of [boxesRotY v]
delete all of [boxesRotZ v]
repeat (n)
add (pick random (-100) to (100)) to [boxesPosX v]
add (pick random (0) to (100)) to [boxesPosY v]
add (pick random (-100) to (100)) to [boxesPosZ v]
add (pick random (-180) to (180)) to [boxesRotX v]
add (pick random (-180) to (180)) to [boxesRotY v]
add (pick random (-180) to (180)) to [boxesRotZ v]
end
// Sooner or later you will try to draw a lot of meshes per frame and come to the realization of just how slow it is. (Just like demonstrated in this project)\nEach time you use "draw mesh" block, that's 1 "draw call" (a term you may see used for 3D graphics in general, not just Simple3D). Draw calls are expensive and should generally be reduced.\n\nOne of the ways to reduce draw calls is to simply combine meshes into one. Though it does come with a disadvantage of consuming a lot of VRAM (video memory).\n\nAnother solution, if you need to draw a lot of the same mesh is called instancing. It lets you draw the same mesh many times with a single draw call, where some properties are specified per vertex and are the same on corresponding vertices across all the instances, while other properties are specified once per instance and are the same across all the vertices within one instance.\n\nNext we will look how to speed up this example project using instancing.\n\n
```
# End of meshInstancing/instancingWithout.sb3
# Project: Transforms instancing
# Start of meshInstancing/instancingTransforms1.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = 10.975074750273906
camY = 28.423314405282373
camZ = 33.61396207359942
camRotX = 180
camRotY = 151
i = 10000
frames = 24
fps = 30.303030303030305
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxesPosX = []
boxesPosY = []
boxesPosZ = []
boxesRotX = []
boxesRotY = []
boxesRotZ = []
boxesTransforms = []
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
Randomly scatter [10000] boxes :: custom
Generate and set instance transforms :: custom
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
change [frames v] by (1)
if <(timer) > [1]> then
set [fps v] to ((frames) / (timer))
set [frames v] to [0]
reset timer
end
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | start with no transformation // since we are using per instance transforms now, make sure that the normal "to world space from model space" doesn't contain the leftover data. For now we will just clear it.
Simple3D | draw mesh [box] // Yes, as simple as that
define Randomly scatter (n) boxes
delete all of [boxesPosX v]
delete all of [boxesPosY v]
delete all of [boxesPosZ v]
delete all of [boxesRotX v]
delete all of [boxesRotY v]
delete all of [boxesRotZ v]
repeat (n)
add (pick random (-100) to (100)) to [boxesPosX v]
add (pick random (0) to (100)) to [boxesPosY v]
add (pick random (-100) to (100)) to [boxesPosZ v]
add (pick random (-180) to (180)) to [boxesRotX v]
add (pick random (-180) to (180)) to [boxesRotY v]
add (pick random (-180) to (180)) to [boxesRotZ v]
end
define Generate and set instance transforms
Simple3D | configure [modelToWorld v] transformation
delete all of [boxesTransforms v]
set [i v] to [0]
repeat (length of [boxesPosX v])
change [i v] by (1)
Simple3D | start with no transformation
Simple3D | move X:(item (i) of [boxesPosX v]) Y:(item (i) of [boxesPosY v]) Z:(item (i) of [boxesPosZ v])
Simple3D | rotate around [X v] by (item (i) of [boxesRotX v]) degrees
Simple3D | rotate around [Y v] by (item (i) of [boxesRotY v]) degrees
Simple3D | rotate around [Z v] by (item (i) of [boxesRotZ v]) degrees
Simple3D | save into [boxesTransforms v] at ((length of [boxesTransforms v]) + (1)) // Appending new data to the end of the list
end
Simple3D | set [box] instance [transforms v] [boxesTransforms v]
// And here is what adding instancing did to performance.\n\nYou can try increasing amount of drawn boxes even more to test how powerful your GPU is.
```
# End of meshInstancing/instancingTransforms1.sb3
# Project: Transforms instancing with world transform
# Start of meshInstancing/instancingTransforms2.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = 20.10620233585619
camY = 24.826433251417285
camZ = 19.138353392379763
camRotX = 180
camRotY = 171
i = 10000
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxesPosX = []
boxesPosY = []
boxesPosZ = []
boxesRotX = []
boxesRotY = []
boxesRotZ = []
boxesTransforms = []
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
Randomly scatter [10000] boxes :: custom
Generate and set instance transforms :: custom
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | start with no transformation
Simple3D | move X:(0) Y:(([sin v] of ((timer) * (220))) * (0.5)) Z:(0)
Simple3D | rotate around [Y v] by ((timer) * (90)) degrees
Simple3D | draw mesh [box]
define Randomly scatter (n) boxes
delete all of [boxesPosX v]
delete all of [boxesPosY v]
delete all of [boxesPosZ v]
delete all of [boxesRotX v]
delete all of [boxesRotY v]
delete all of [boxesRotZ v]
repeat (n)
add (pick random (-100) to (100)) to [boxesPosX v]
add (pick random (0) to (100)) to [boxesPosY v]
add (pick random (-100) to (100)) to [boxesPosZ v]
add (pick random (-180) to (180)) // remove this to [boxesRotX v]
add (pick random (-180) to (180)) to [boxesRotY v]
add (pick random (-180) to (180)) // remove this to [boxesRotZ v]
end
define Generate and set instance transforms
Simple3D | configure [modelToWorld v] transformation
delete all of [boxesTransforms v]
set [i v] to [0]
repeat (length of [boxesPosX v])
change [i v] by (1)
Simple3D | start with no transformation
Simple3D | move X:(item (i) of [boxesPosX v]) Y:(item (i) of [boxesPosY v]) Z:(item (i) of [boxesPosZ v])
Simple3D | rotate around [X v] by (item (i) of [boxesRotX v]) degrees
Simple3D | rotate around [Y v] by (item (i) of [boxesRotY v]) degrees
Simple3D | rotate around [Z v] by (item (i) of [boxesRotZ v]) degrees
Simple3D | save into [boxesTransforms v] at ((length of [boxesTransforms v]) + (1))
end
Simple3D | set [box] instance [transforms v] [boxesTransforms v]
// "to world space from model space" transformation can still be used.\n\nBut note that: it is applied to each mesh individually, rather than to entire collection of instances - there is currently no transformation for that. Though you can still probably workaround it somehow using "to view space from world space".\n\nThe uses for "to world space from model space" transformation is for example spinning floating coins.
```
# End of meshInstancing/instancingTransforms2.sb3
# Project: Inheritance with instancing
# Start of meshInstancing/instancingTextures.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = 10.975074750273906
camY = 28.423314405282373
camZ = 33.61396207359942
camRotX = 180
camRotY = 167
i = 2000
frames = 29
fps = 37.51233958538993
red boxes visible = 1
blue boxes visible = 1
green boxes visible = 1
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxesPosX = []
boxesPosY = []
boxesPosZ = []
boxesRotX = []
boxesRotY = []
boxesRotZ = []
boxesTransforms = []
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
3. "red box" - blue box
4. "green box" - lime-colored box
5. "blue box" - red box
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | create mesh [red boxes]
Simple3D | make [red boxes] inherit from meshes [box]
Simple3D | set [red boxes] texture (Simple3D | texture from costume (costume red box)) [clamp to edge v] [pixelated v]
Randomly scatter [2000] boxes :: custom
Generate and set instance transforms [red boxes] :: custom
Simple3D | create mesh [green boxes]
Simple3D | make [green boxes] inherit from meshes [box]
Simple3D | set [green boxes] texture (Simple3D | texture from costume (costume green box)) [clamp to edge v] [pixelated v]
Randomly scatter [2000] boxes :: custom
Generate and set instance transforms [green boxes] :: custom
Simple3D | create mesh [blue boxes]
Simple3D | make [blue boxes] inherit from meshes [box]
Simple3D | set [blue boxes] texture (Simple3D | texture from costume (costume blue box)) [clamp to edge v] [pixelated v]
Randomly scatter [2000] boxes :: custom
Generate and set instance transforms [blue boxes] :: custom
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
change [frames v] by (1)
if <(timer) > [1]> then
set [fps v] to ((frames) / (timer))
set [frames v] to [0]
reset timer
end
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw boxes
Simple3D | start with no transformation
if <(red boxes visible) = [1]> then
Simple3D | draw mesh [red boxes]
end
if <(green boxes visible) = [1]> then
Simple3D | draw mesh [green boxes]
end
if <(blue boxes visible) = [1]> then
Simple3D | draw mesh [blue boxes]
end
define Randomly scatter (n) boxes
delete all of [boxesPosX v]
delete all of [boxesPosY v]
delete all of [boxesPosZ v]
delete all of [boxesRotX v]
delete all of [boxesRotY v]
delete all of [boxesRotZ v]
repeat (n)
add (pick random (-100) to (100)) to [boxesPosX v]
add (pick random (0) to (100)) to [boxesPosY v]
add (pick random (-100) to (100)) to [boxesPosZ v]
add (pick random (-180) to (180)) to [boxesRotX v]
add (pick random (-180) to (180)) to [boxesRotY v]
add (pick random (-180) to (180)) to [boxesRotZ v]
end
define Generate and set instance transforms (mesh name)
Simple3D | configure [modelToWorld v] transformation
delete all of [boxesTransforms v]
set [i v] to [0]
repeat (length of [boxesPosX v])
change [i v] by (1)
Simple3D | start with no transformation
Simple3D | move X:(item (i) of [boxesPosX v]) Y:(item (i) of [boxesPosY v]) Z:(item (i) of [boxesPosZ v])
Simple3D | rotate around [X v] by (item (i) of [boxesRotX v]) degrees
Simple3D | rotate around [Y v] by (item (i) of [boxesRotY v]) degrees
Simple3D | rotate around [Z v] by (item (i) of [boxesRotZ v]) degrees
Simple3D | save into [boxesTransforms v] at ((length of [boxesTransforms v]) + (1)) // Appending new data to the end of the list
end
Simple3D | set (mesh name) instance [transforms v] [boxesTransforms v]
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
// If you need multiple separate independently controllable groups of the same mesh (or almost the same mesh, like in this case shown with textures), you can create empty meshes that just have instance data, while inherit the rest from the base mesh.
```
# End of meshInstancing/instancingTextures.sb3
# Project: Chunk LOD system using instacing
# Start of meshInstancing/instancingChunks.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = -10.438870610795266
camY = 19.418690157441034
camZ = 36.16444322447011
camRotX = 180
camRotY = 159
i = 100
chunk X = 8
chunk Z = 8
chunk name = "chunk_7_7"
chunk real diff X = 385.4388706107953
chunk real diff Z = 338.8355567755299
distance = 513.198458213885
variant = 6
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxesPosX = []
boxesPosY = []
boxesPosZ = []
boxesRotX = []
boxesRotY = []
boxesRotZ = []
boxesTransforms = []
chunk lod = []
### Blocks
```scratchblocks
// Configuration for https://turbowarp.org/\nYou can move, resize, and minimize this comment, but don't edit it by hand. This comment can be deleted to remove the stored settings.\n{"hq":true} // _twconfig_
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
3. "red box" - blue box
4. "green box" - lime-colored box
5. "blue box" - red box
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | create mesh [box1]
Simple3D | make [box1] inherit from meshes [box]
Simple3D | set [box1] texture (Simple3D | texture from costume (costume red box)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box2]
Simple3D | make [box2] inherit from meshes [box]
Simple3D | set [box2] texture (Simple3D | texture from costume (costume green box)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box3]
Simple3D | make [box3] inherit from meshes [box]
Simple3D | set [box3] texture (Simple3D | texture from costume (costume blue box)) [clamp to edge v] [pixelated v]
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
generate chunks :: custom
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw chunks :: custom
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw chunks
Simple3D | start with no transformation
set [chunk Z v] to [-8]
repeat (16)
set [chunk X v] to [-8]
repeat (16)
set [chunk real diff X v] to ((((chunk X) + (0.5)) * (50)) - (camX))
set [chunk real diff Z v] to ((((chunk Z) + (0.5)) * (50)) - (camZ))
set [distance v] to ([sqrt v] of (((chunk real diff X) * (chunk real diff X)) + ((chunk real diff Z) * (chunk real diff Z))))
set [variant v] to ([ceiling v] of ((distance) / (100)))
if <(variant) < [4]> then
Simple3D | make (join (join [chunk_] (chunk X)) (join [_] (chunk Z))) inherit from meshes (join [box] (variant))
Simple3D | draw mesh (join (join [chunk_] (chunk X)) (join [_] (chunk Z)))
end
change [chunk X v] by (1)
end
change [chunk Z v] by (1)
end
define Randomly scatter (n) boxes (offset x) (offset z)
delete all of [boxesPosX v]
delete all of [boxesPosY v]
delete all of [boxesPosZ v]
delete all of [boxesRotX v]
delete all of [boxesRotY v]
delete all of [boxesRotZ v]
repeat (n)
add ((offset x) + (pick random (0) to (50))) to [boxesPosX v]
add (pick random (0) to (10)) to [boxesPosY v]
add ((offset z) + (pick random (0) to (50))) to [boxesPosZ v]
add (pick random (-180) to (180)) to [boxesRotX v]
add (pick random (-180) to (180)) to [boxesRotY v]
add (pick random (-180) to (180)) to [boxesRotZ v]
end
define Generate and set instance transforms (mesh name)
Simple3D | configure [modelToWorld v] transformation
delete all of [boxesTransforms v]
set [i v] to [0]
repeat (length of [boxesPosX v])
change [i v] by (1)
Simple3D | start with no transformation
Simple3D | move X:(item (i) of [boxesPosX v]) Y:(item (i) of [boxesPosY v]) Z:(item (i) of [boxesPosZ v])
Simple3D | rotate around [X v] by (item (i) of [boxesRotX v]) degrees
Simple3D | rotate around [Y v] by (item (i) of [boxesRotY v]) degrees
Simple3D | rotate around [Z v] by (item (i) of [boxesRotZ v]) degrees
Simple3D | save into [boxesTransforms v] at ((length of [boxesTransforms v]) + (1)) // Appending new data to the end of the list
end
Simple3D | set (mesh name) instance [transforms v] [boxesTransforms v]
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define generate chunks
set [chunk Z v] to [-8]
repeat (16)
set [chunk X v] to [-8]
repeat (16)
set [chunk name v] to (join (join [chunk_] (chunk X)) (join [_] (chunk Z)))
Simple3D | create mesh (chunk name)
Simple3D | make (chunk name) inherit from meshes [box]
Randomly scatter [100] boxes ((chunk X) * (50)) ((chunk Z) * (50)) :: custom
Generate and set instance transforms (chunk name) :: custom
change [chunk X v] by (1)
end
change [chunk Z v] by (1)
end
// If you need multiple separate independently controllable groups of the same mesh (or almost the same mesh, like in this case shown with textures), you can create empty meshes that just have instance data, while inherit the rest from the base mesh.\n\nExample use: You have a tree mesh. Each terrain chunk has a mostly empty mesh that just stores all the tree instance positions within that chunk. The tree shape is inherited from the base mesh.\n\nExample use 2: You have multiple meshes of different tree LOD levels. Each terrain chunk has a mostly empty mesh that just stores all the tree instance positions within that chunk. Each of those empty meshes also inherits from the correct LOD level base mesh. Inheritance can be switched very cheaply.
```
# End of meshInstancing/instancingChunks.sb3
# Project: Positions instancing
# Start of meshInstancing/instancingPos.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = 26.548468084306087
camY = 31.213771604442464
camZ = 52.901681639256914
camRotX = 180
camRotY = 165
i = 10000
frames = 16
fps = 30.303030303030305
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxesPosXYZ = []
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
Randomly scatter [10000] boxes :: custom
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
change [frames v] by (1)
if <(timer) > [1]> then
set [fps v] to ((frames) / (timer))
set [frames v] to [0]
reset timer
end
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | start with no transformation
Simple3D | draw mesh [box]
define Randomly scatter (n) boxes
delete all of [boxesPosXYZ v]
repeat (n)
add (pick random (-100) to (100)) to [boxesPosXYZ v]
add (pick random (0) to (100)) to [boxesPosXYZ v]
add (pick random (-100) to (100)) to [boxesPosXYZ v]
end
Simple3D | set [box] instance [XYZ positions v] [boxesPosXYZ v]
// And if you only need positions (or positions and sizes), there is an even simpler way.
```
# End of meshInstancing/instancingPos.sb3
# Project: Changing all instanced data every frame
# Start of meshInstancing/instancingMoveAll.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = -14.405563566759756
camY = 15.052038029831794
camZ = 1.5158077600987387
camRotX = 180
camRotY = 169
i = 30000
frames = 13
fps = 30.303030303030305
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxesPosXYZ = []
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
Randomly scatter [10000] boxes :: custom
forever
move boxes down :: custom
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
change [frames v] by (1)
if <(timer) > [1]> then
set [fps v] to ((frames) / (timer))
set [frames v] to [0]
reset timer
end
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | start with no transformation
Simple3D | draw mesh [box]
define Randomly scatter (n) boxes
delete all of [boxesPosXYZ v]
repeat (n)
add (pick random (-100) to (100)) to [boxesPosXYZ v]
add (pick random (0) to (100)) to [boxesPosXYZ v]
add (pick random (-100) to (100)) to [boxesPosXYZ v]
end
Simple3D | [box] optimize next uploaded list for being (frequently fully v) updated // Not required, but recommended. Whether this does anything or not depends on the GPU.
Simple3D | set [box] instance [XYZ positions v] [boxesPosXYZ v]
define move boxes down
set [i v] to [0]
repeat ((length of [boxesPosXYZ v]) / (3))
change [i v] by (3)
replace item ((i) - (1)) of [boxesPosXYZ v] with ((item ((i) - (1)) of [boxesPosXYZ v]) - (1))
if <(item ((i) - (1)) of [boxesPosXYZ v]) < [1]> then
replace item ((i) - (1)) of [boxesPosXYZ v] with [1]
end
end
Simple3D | set [box] instance [XYZ positions v] [boxesPosXYZ v]
// Updating instance properties every frame is quite fast.
```
# End of meshInstancing/instancingMoveAll.sb3
# Project: Changing some instanced data every frame
# Start of meshInstancing/instancingMoveOne.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = -133.4507807580492
camY = 99.59659612706753
camZ = -47.59436490181609
camRotX = 180
camRotY = 169
i = 30000
frames = 4
fps = 24.43792766373412
falling box id = 65009
falling box id x3 = 195027
fall vel y = -33.60000000000021
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxesPosXYZ = []
oneFallingBoxPosXYZ = ["","",""]
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
Randomly scatter [10000] boxes :: custom
forever
move boxes down :: custom
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
change [frames v] by (1)
if <(timer) > [1]> then
set [fps v] to ((frames) / (timer))
set [frames v] to [0]
reset timer
end
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | start with no transformation
Simple3D | draw mesh [box]
define Randomly scatter (n) boxes
delete all of [boxesPosXYZ v]
repeat (n)
add (pick random (-100) to (100)) to [boxesPosXYZ v]
add (pick random (90) to (100)) to [boxesPosXYZ v]
add (pick random (-100) to (100)) to [boxesPosXYZ v]
end
Simple3D | [box] optimize next uploaded list for being (frequently partially v) updated // Not required, but recommended. Whether this does anything or not depends on the GPU.
Simple3D | set [box] instance [XYZ positions v] [boxesPosXYZ v]
set [falling box id v] to (pick random (1) to ((length of [boxesPosXYZ v]) / (3)))
set [falling box id x3 v] to ((falling box id) * (3))
set [fall vel y v] to [0]
define move boxes down
change [fall vel y v] by (-0.1)
replace item ((falling box id x3) - (1)) of [boxesPosXYZ v] with ((item ((falling box id x3) - (1)) of [boxesPosXYZ v]) + (fall vel y))
if <(item ((falling box id x3) - (1)) of [boxesPosXYZ v]) < [1]> then
replace item ((falling box id x3) - (1)) of [boxesPosXYZ v] with [1]
end
replace item (1) of [oneFallingBoxPosXYZ v] with (item ((falling box id x3) - (2)) of [boxesPosXYZ v])
replace item (2) of [oneFallingBoxPosXYZ v] with (item ((falling box id x3) - (1)) of [boxesPosXYZ v])
replace item (3) of [oneFallingBoxPosXYZ v] with (item ((falling box id x3) - (0)) of [boxesPosXYZ v])
Simple3D | set [box] list update offset (falling box id)
Simple3D | set [box] instance [XYZ positions v] [oneFallingBoxPosXYZ v]
if <(item ((falling box id x3) - (1)) of [boxesPosXYZ v]) = [1]> then
set [falling box id v] to (pick random (1) to ((length of [boxesPosXYZ v]) / (3)))
set [falling box id x3 v] to ((falling box id) * (3))
set [fall vel y v] to [0]
end
// If updating everything is not fast enough and only a small amount of instances changes, you can use partial updates to update instances that change.
```
# End of meshInstancing/instancingMoveOne.sb3
# Project: Deleting and adding instances
# Start of meshInstancing/instancingDeleteOne.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = 18.30255992075574
camY = 131.25599654632364
camZ = -31.686377563578052
camRotX = 180
camRotY = 169
i = 98459
frames = 3
fps = 31.03782735208536
dx = -42
dz = -10
distance = 1864
minDistance = 205
minI = 77028
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxesPosXYZ = []
oneBoxPosXYZ = [-42,93,-10]
### Blocks
```scratchblocks
when stage clicked
Simple3D | transform X:(0) Y:(0) Z:(-5) from [view space v] to [world space v]
add (Simple3D | transformed [X v]) to [boxesPosXYZ v]
add (Simple3D | transformed [Y v]) to [boxesPosXYZ v]
add (Simple3D | transformed [Z v]) to [boxesPosXYZ v]
replace item (1) of [oneBoxPosXYZ v] with (item ((length of [boxesPosXYZ v]) - (2)) of [boxesPosXYZ v])
replace item (2) of [oneBoxPosXYZ v] with (item ((length of [boxesPosXYZ v]) - (1)) of [boxesPosXYZ v])
replace item (3) of [oneBoxPosXYZ v] with (item ((length of [boxesPosXYZ v]) - (0)) of [boxesPosXYZ v])
Simple3D | set [box] instance limit ((length of [boxesPosXYZ v]) / (3))
Simple3D | set [box] list update offset ((length of [boxesPosXYZ v]) / (3))
Simple3D | set [box] instance [XYZ positions v] [oneBoxPosXYZ v]
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
Randomly scatter [100000] boxes :: custom
forever
delete closest box :: custom
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
change [frames v] by (1)
if <(timer) > [1]> then
set [fps v] to ((frames) / (timer))
set [frames v] to [0]
reset timer
end
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | start with no transformation
Simple3D | draw mesh [box]
define Randomly scatter (n) boxes
delete all of [boxesPosXYZ v]
repeat (n)
add (pick random (-100) to (100)) to [boxesPosXYZ v]
add (pick random (90) to (100)) to [boxesPosXYZ v]
add (pick random (-100) to (100)) to [boxesPosXYZ v]
end
Simple3D | [box] optimize next uploaded list for being (frequently partially v) updated // Not required, but recommended. Whether this does anything or not depends on the GPU.
Simple3D | set [box] instance [XYZ positions v] [boxesPosXYZ v]
define delete instance (id)
replace item (((id) * (3)) - (2)) of [boxesPosXYZ v] with (item ((length of [boxesPosXYZ v]) - (2)) of [boxesPosXYZ v])
replace item (((id) * (3)) - (1)) of [boxesPosXYZ v] with (item ((length of [boxesPosXYZ v]) - (1)) of [boxesPosXYZ v])
replace item (((id) * (3)) - (0)) of [boxesPosXYZ v] with (item ((length of [boxesPosXYZ v]) - (0)) of [boxesPosXYZ v])
delete (last) of [boxesPosXYZ v]
delete (last) of [boxesPosXYZ v]
delete (last) of [boxesPosXYZ v]
replace item (1) of [oneFallingBoxPosXYZ v] with (item (((id) * (3)) - (2)) of [boxesPosXYZ v])
replace item (2) of [oneFallingBoxPosXYZ v] with (item (((id) * (3)) - (1)) of [boxesPosXYZ v])
replace item (3) of [oneFallingBoxPosXYZ v] with (item (((id) * (3)) - (0)) of [boxesPosXYZ v])
Simple3D | set [box] instance limit ((length of [boxesPosXYZ v]) / (3))
Simple3D | set [box] list update offset (id)
Simple3D | set [box] instance [XYZ positions v] [oneBoxPosXYZ v]
define delete closest box
if <(length of [boxesPosXYZ v]) = [0]> then
stop [this script v]
end
set [i v] to [0]
set [minI v] to [0]
set [minDistance v] to ((1) / (0))
repeat ((length of [boxesPosXYZ v]) / (3))
change [i v] by (1)
set [dx v] to (item (((i) * (3)) - (2)) of [boxesPosXYZ v])
set [dz v] to (item (((i) * (3)) - (0)) of [boxesPosXYZ v])
set [distance v] to (((dx) * (dx)) + ((dz) * (dz)))
if <(distance) < (minDistance)> then
set [minDistance v] to (distance)
set [minI v] to (i)
end
end
delete instance (minI) :: custom
// It is possible to "delete" an instance without reuploading all the instance data, by moving the data of the last instance in place of deleted instance and then hiding the original last instance by shrinking the instance draw limit.\n\nThis can only be useful if you have a lot of instances and they change rarely. Otherwise, just reupload the whole list - it will usually be fast enough and far easier to do.
```
# End of meshInstancing/instancingDeleteOne.sb3
# Project: Instanced boxes of different sizes with tiling textures
# Start of meshInstancing/instancingTiling2.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = -21.82789606517772
camY = 55.60012136415621
camZ = -57.082717817144115
camRotX = 180
camRotY = 157
i = 0
frames = 25
fps = 30.303030303030305
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [-1,-1,-1,-1,1,1,1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1,-1,1]
boxY = [-1,1,-1,1,-1,1,-1,1,-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1]
boxZ = [-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1]
boxIdx = [1,3,2,2,3,4,5,6,7,7,6,8,9,10,11,11,10,12,13,15,14,14,15,16,17,19,18,18,19,20,21,22,23,23,22,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1]
boxV = [0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,1,1]
boxesPosX = []
boxesPosY = []
boxesPosZ = []
boxesRotX = []
boxesRotY = []
boxesRotZ = []
boxesInstanceTransforms = []
boxesSizeX = []
boxesSizeY = []
boxesSizeZ = []
boxesInstanceUV-X = []
boxesInstanceUV-Y = []
boxesInstanceUV-Z = []
boxIdxSideX = [1,3,2,2,3,4,5,6,7,7,6,8]
boxIdxSideY = [9,10,11,11,10,12,13,15,14,14,15,16]
boxIdxSideZ = [17,19,18,18,19,20,21,22,23,23,22,24]
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [repeat v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | create mesh [boxSidesX]
Simple3D | make [boxSidesX] inherit from meshes [box]
Simple3D | set [boxSidesX] indices [boxIdxSideX v]
Simple3D | create mesh [boxSidesY]
Simple3D | make [boxSidesY] inherit from meshes [box]
Simple3D | set [boxSidesY] indices [boxIdxSideY v]
Simple3D | create mesh [boxSidesZ]
Simple3D | make [boxSidesZ] inherit from meshes [box]
Simple3D | set [boxSidesZ] indices [boxIdxSideZ v]
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
Randomly scatter [200] boxes :: custom
Generate and set instance transforms :: custom
forever
controls :: custom
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
change [frames v] by (1)
if <(timer) > [1]> then
set [fps v] to ((frames) / (timer))
set [frames v] to [0]
reset timer
end
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | when canvas resolution changes
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | start with no transformation
Simple3D | draw mesh [boxSidesX]
Simple3D | draw mesh [boxSidesY]
Simple3D | draw mesh [boxSidesZ]
define Randomly scatter (n) boxes
delete all of [boxesPosX v]
delete all of [boxesPosY v]
delete all of [boxesPosZ v]
delete all of [boxesRotX v]
delete all of [boxesRotY v]
delete all of [boxesRotZ v]
delete all of [boxesSizeX v]
delete all of [boxesSizeY v]
delete all of [boxesSizeZ v]
repeat (n)
add (pick random (-100) to (100)) to [boxesPosX v]
add (pick random (0) to (100)) to [boxesPosY v]
add (pick random (-100) to (100)) to [boxesPosZ v]
add (pick random (-10) to (10)) to [boxesRotX v]
add (pick random (-180) to (180)) to [boxesRotY v]
add (pick random (-10) to (10)) to [boxesRotZ v]
add (pick random (0.5) to (10.0)) to [boxesSizeX v]
add (pick random (0.5) to (10.0)) to [boxesSizeY v]
add (pick random (0.5) to (10.0)) to [boxesSizeZ v]
end
define Generate and set instance transforms
Simple3D | configure [modelToWorld v] transformation
delete all of [boxesInstanceTransforms v]
delete all of [boxesInstanceUV-X v]
delete all of [boxesInstanceUV-Y v]
delete all of [boxesInstanceUV-Z v]
set [i v] to [0]
repeat (length of [boxesPosX v])
change [i v] by (1)
Simple3D | start with no transformation
Simple3D | move X:(item (i) of [boxesPosX v]) Y:(item (i) of [boxesPosY v]) Z:(item (i) of [boxesPosZ v])
Simple3D | rotate around [X v] by (item (i) of [boxesRotX v]) degrees
Simple3D | rotate around [Y v] by (item (i) of [boxesRotY v]) degrees
Simple3D | rotate around [Z v] by (item (i) of [boxesRotZ v]) degrees
Simple3D | scale X:(item (i) of [boxesSizeX v]) Y:(item (i) of [boxesSizeY v]) Z:(item (i) of [boxesSizeZ v])
Simple3D | save into [boxesInstanceTransforms v] at ((length of [boxesInstanceTransforms v]) + (1))
add [0] to [boxesInstanceUV-X v]
add [0] to [boxesInstanceUV-X v]
add (item (i) of [boxesSizeY v]) to [boxesInstanceUV-X v]
add (item (i) of [boxesSizeZ v]) to [boxesInstanceUV-X v]
add [0] to [boxesInstanceUV-Y v]
add [0] to [boxesInstanceUV-Y v]
add (item (i) of [boxesSizeX v]) to [boxesInstanceUV-Y v]
add (item (i) of [boxesSizeZ v]) to [boxesInstanceUV-Y v]
add [0] to [boxesInstanceUV-Z v]
add [0] to [boxesInstanceUV-Z v]
add (item (i) of [boxesSizeX v]) to [boxesInstanceUV-Z v]
add (item (i) of [boxesSizeY v]) to [boxesInstanceUV-Z v]
end
Simple3D | set [box] instance [transforms v] [boxesInstanceTransforms v]
Simple3D | set [boxSidesX] instance [UV offsets and sizes v] [boxesInstanceUV-X v]
Simple3D | set [boxSidesY] instance [UV offsets and sizes v] [boxesInstanceUV-Y v]
Simple3D | set [boxSidesZ] instance [UV offsets and sizes v] [boxesInstanceUV-Z v]
```
# End of meshInstancing/instancingTiling2.sb3
# Project: Extra: Simple 2D instancing demo
# Start of meshInstancing/instancing2D.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
2. "dango cat" - default turbowarp sprite - dango cat
### Global Variables
i = 30000
### Global Lists
y = [-1,1,-1,1]
x = [-1,-1,1,1]
instance pos = []
u = [0,0,1,1]
v = [1,0,1,0]
instance vel = []
instance rgb = []
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | clear (color v)
create [10000] instances :: custom
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x v] [y v]
Simple3D | set [my mesh] texture coordinates UV [u v] [v v]
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume dango cat)) [clamp to edge v] [pixelated v]
Simple3D | set [my mesh] instance [XY positions v] [instance pos v]
Simple3D | set [my mesh] instance [RGB colors v] [instance rgb v]
Simple3D | [my mesh] optimize next uploaded list for being (frequently fully v) updated
Simple3D | set [my mesh] discord pixels less opaque than [0.5], for those that pass true
wait until
Simple3D | configure [worldToView v] transformation
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | scale X:((2) / (runtimeoptions | stage (height v))) Y:((2) / (runtimeoptions | stage (height v))) Z:(1)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | scale X:((Simple3D | mesh [texture width v] [my mesh]) * (0.05)) Y:((Simple3D | mesh [texture height v] [my mesh]) * (0.05)) Z:(1)
forever
step ((runtimeoptions | stage (width v)) / (2)) ((runtimeoptions | stage (height v)) / (2)) :: custom
Simple3D | set [my mesh] instance [XY positions v] [instance pos v]
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
define create (count) instances
delete all of [instance pos v]
delete all of [instance vel v]
delete all of [instance rgb v]
repeat (count)
add (pick random ((runtimeoptions | stage (width v)) / (-2)) to ((runtimeoptions | stage (width v)) / (2))) to [instance pos v]
add (pick random ((runtimeoptions | stage (height v)) / (-2)) to ((runtimeoptions | stage (height v)) / (2))) to [instance pos v]
add (pick random (-1.0) to (1.0)) to [instance vel v]
add (pick random (-1.0) to (1.0)) to [instance vel v]
add (pick random (0.5) to (1.0)) to [instance rgb v]
add (pick random (0.5) to (1.0)) to [instance rgb v]
add (pick random (0.5) to (1.0)) to [instance rgb v]
end
define step (halfWidth) (halfHeight)
set [i v] to [0]
repeat ((length of [instance pos v]) / (2))
replace item ((i) + (1)) of [instance pos v] with ((item ((i) + (1)) of [instance pos v]) + (item ((i) + (1)) of [instance vel v]))
replace item ((i) + (2)) of [instance pos v] with ((item ((i) + (2)) of [instance pos v]) + (item ((i) + (2)) of [instance vel v]))
if <([abs v] of (item ((i) + (1)) of [instance pos v])) > (halfWidth)> then
replace item ((i) + (1)) of [instance vel v] with ((0) - (item ((i) + (1)) of [instance vel v]))
end
if <([abs v] of (item ((i) + (2)) of [instance pos v])) > (halfHeight)> then
replace item ((i) + (2)) of [instance vel v] with ((0) - (item ((i) + (2)) of [instance vel v]))
end
change [i v] by (3)
end
// Configuration for https://turbowarp.org/\nYou can move, resize, and minimize this comment, but don't edit it by hand. This comment can be deleted to remove the stored settings.\n{"framerate":60,"hq":true} // _twconfig_
```
# End of meshInstancing/instancing2D.sb3
# Section: Modifying parts of the mesh lists
# Project: Updating vertex data
# Start of partialUpdate/vertex1.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
i = 73
mouse x = -3
mouse y = 9
paint red = 0
paint green = 255
paint blue = 0
### Global Lists
x = []
y = []
idx = []
r = []
g = []
b = []
update r = [0]
update g = [255]
update b = [0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color and depth v)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | scale X:((Simple3D | canvas height) / (Simple3D | canvas width)) Y:(1) Z:(1)
Simple3D | move X:(0.5) Y:(0) Z:(0)
Simple3D | scale X:(0.2) Y:(0.2) Z:(1)
Simple3D | move X:(-4) Y:(-4) Z:(0)
Generate lists :: custom
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x v] [y v]
Simple3D | set [my mesh] indices [idx v]
Simple3D | set [my mesh] colors RGB [r v] [g v] [b v]
forever
Simple3D | transform X:((mouse x) / ((runtimeoptions | stage (width v)) / (2))) Y:((mouse y) / ((runtimeoptions | stage (height v)) / (2))) Z:(0) from [view space v] to [world space v] // Manually converting from ranges (-240 240) (-180 180) to ranges (-1 1) (-1 1)
set [mouse x v] to (round (Simple3D | transformed [X v]))
set [mouse y v] to (round (Simple3D | transformed [Y v]))
if then
replace item (1) of [update r v] with (paint red)
replace item (1) of [update g v] with (paint green)
replace item (1) of [update b v] with (paint blue)
if < and > then
Simple3D | set [my mesh] list update offset (((1) + (mouse x :: variables)) + ((mouse y :: variables) * (9)))
Simple3D | set [my mesh] colors RGB [update r v] [update g v] [update b v]
end
end
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
define Generate lists
delete all of [r v]
delete all of [g v]
delete all of [b v]
delete all of [x v]
delete all of [y v]
delete all of [idx v]
set [i v] to [0]
repeat (9)
repeat (9)
add ((i) mod (9)) to [x v]
add ([floor v] of ((i) / (9))) to [y v]
add (pick random (1) to (255)) to [r v]
add (pick random (1) to (255)) to [g v]
add (pick random (1) to (255)) to [b v]
change [i v] by (1)
end
end
set [i v] to [1]
repeat (8)
repeat (9)
add (i) to [idx v]
add ((i) + (9)) to [idx v]
change [i v] by (1)
end
add [0] to [idx v]
end
```
# End of partialUpdate/vertex1.sb3
# Project: Updating vertex index data
# Start of partialUpdate/index1.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
i = 1
mouse x = -3
mouse y = 9
triangle to update = 4
### Global Lists
x = []
y = []
idx = []
r = []
g = []
b = []
update idx = []
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | depth test (everything v) write (false v)
Simple3D | clear (color v)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | scale X:((Simple3D | canvas height) / (Simple3D | canvas width)) Y:(1) Z:(1)
Simple3D | move X:(0.5) Y:(0) Z:(0)
Simple3D | scale X:(0.2) Y:(0.2) Z:(1)
Simple3D | move X:(-4) Y:(-4) Z:(0)
Generate lists :: custom
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] indices [idx v]
Simple3D | set [my mesh] positions XY [x v] [y v]
Simple3D | set [my mesh] colors RGB [r v] [g v] [b v]
Simple3D | create mesh [preview]
Simple3D | set [preview] primitives (line loop v)
Simple3D | set [preview] indices [update idx v]
Simple3D | set [preview] positions XY [x v] [y v]
Simple3D | [preview] optimize next uploaded list for being (frequently fully v) updated // Not required, but good to have
forever
Simple3D | transform X:((mouse x) / ((runtimeoptions | stage (width v)) / (2))) Y:((mouse y) / ((runtimeoptions | stage (height v)) / (2))) Z:(0) from [view space v] to [world space v] // Manually converting from ranges (-240 240) (-180 180) to ranges (-1 1) (-1 1)
set [mouse x v] to (round (Simple3D | transformed [X v]))
set [mouse y v] to (round (Simple3D | transformed [Y v]))
if < and > then
if then
add (((1) + (mouse x :: variables)) + ((mouse y :: variables) * (9))) to [update idx v]
if <(length of [update idx v]) = [3]> then
Simple3D | set [my mesh] list update offset ((-2) + ((triangle to update) * (3))) // This
Simple3D | set [my mesh] indices [update idx v] // And this
delete all of [update idx v]
end
wait until >
end
lmscomments | comment [don't mind this, it's just for visualization] {
add (((1) + (mouse x :: variables)) + ((mouse y :: variables) * (9))) to [update idx v]
Simple3D | set [preview] indices [update idx v]
delete (last) of [update idx v]
}
end
Simple3D | clear (color v)
Simple3D | draw mesh [my mesh]
Simple3D | draw mesh [preview]
end
define Generate lists
delete all of [r v]
delete all of [g v]
delete all of [b v]
delete all of [x v]
delete all of [y v]
delete all of [idx v]
set [i v] to [0]
repeat (9)
repeat (9)
add ((i) mod (9)) to [x v]
add ([floor v] of ((i) / (9))) to [y v]
add (pick random (1) to (255)) to [r v]
add (pick random (1) to (255)) to [g v]
add (pick random (1) to (255)) to [b v]
change [i v] by (1)
end
end
set [i v] to [1]
repeat (5)
repeat (3)
add (pick random (1) to (length of [x v])) to [idx v]
end
end
// Using partial updates to update indices of triangle vertices of a specific triangle.\n\nIn this case with just 5 triangles it doesn't make that big of a difference compared to updating everything, but if you have a mesh with a million triangles and you only want to edit handful of them, ability to directly do so without having to reupload every other triangle of the mesh that didn't change is useful.
```
# End of partialUpdate/index1.sb3
# Project: Updating instance data
# Start of partialUpdate/instance1.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
i = 6
### Global Lists
y = [-1,1,-1,1]
x = [-1,-1,1,1]
instance pos = []
instance pos update = [-0.9333333333333332,1]
### Blocks
```scratchblocks
when flag clicked
Simple3D | configure [worldToView v] transformation
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | scale X:(0.05) Y:(0.05) Z:(1)
Simple3D | depth test (everything v) write (false v)
Simple3D | set clear color R:(0.5) G:(0.5) B:(0.5) A:(1)
Simple3D | clear (color v)
fill lists :: custom
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x v] [y v]
Simple3D | set [my mesh] instance [XY positions v] [instance pos v]
Simple3D | [my mesh] optimize next uploaded list for being (frequently partially v) updated
forever
Simple3D | transform X:((mouse x) / ((runtimeoptions | stage (width v)) / (2))) Y:((mouse y) / ((runtimeoptions | stage (height v)) / (2))) Z:(0) from [view space v] to [world space v]
replace item (1) of [instance pos update v] with (Simple3D | transformed [X v])
replace item (2) of [instance pos update v] with (Simple3D | transformed [Y v])
change [i v] by (1)
if <(i) > ((length of [instance pos v]) / (2))> then
set [i v] to [1]
end
Simple3D | set [my mesh] list update offset (i) // This
Simple3D | set [my mesh] instance [XY positions v] [instance pos update v] // This
Simple3D | clear (color v)
Simple3D | draw mesh [my mesh]
end
define fill lists
delete all of [instance pos v]
repeat (9)
add [0] to [instance pos v]
add [0] to [instance pos v]
end // Now try 90000 to see how laggy it is (it isn't)
// Updating position of just 1 instance at the time
```
# End of partialUpdate/instance1.sb3
# Project: Inserting and removing triangles example
# Start of partialUpdate/index2.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
i = 1
mouse x = -3
mouse y = 9
triangle to delete (press D) = 1
triangle count = 3
### Global Lists
x = []
y = []
idx = []
r = []
g = []
b = []
update idx = []
delete idx = [23,66,48]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | depth test (everything v) write (false v)
Simple3D | clear (color v)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | scale X:((Simple3D | canvas height) / (Simple3D | canvas width)) Y:(1) Z:(1)
Simple3D | move X:(0.5) Y:(0) Z:(0)
Simple3D | scale X:(0.2) Y:(0.2) Z:(1)
Simple3D | move X:(-4) Y:(-4) Z:(0)
Generate lists :: custom
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] indices [idx v]
Simple3D | set [my mesh] positions XY [x v] [y v]
Simple3D | set [my mesh] colors RGB [r v] [g v] [b v]
Simple3D | set [my mesh] draw range from (1) to ((triangle count) * (3))
Simple3D | create mesh [preview]
Simple3D | set [preview] primitives (line loop v)
Simple3D | set [preview] indices [update idx v]
Simple3D | set [preview] positions XY [x v] [y v]
Simple3D | [preview] optimize next uploaded list for being (frequently fully v) updated // Not required, but good to have
forever
Simple3D | transform X:((mouse x) / ((runtimeoptions | stage (width v)) / (2))) Y:((mouse y) / ((runtimeoptions | stage (height v)) / (2))) Z:(0) from [view space v] to [world space v] // Manually converting from ranges (-240 240) (-180 180) to ranges (-1 1) (-1 1)
set [mouse x v] to (round (Simple3D | transformed [X v]))
set [mouse y v] to (round (Simple3D | transformed [Y v]))
if << and > and <(triangle count) < [10]>> then
if then
add (((1) + (mouse x :: variables)) + ((mouse y :: variables) * (9))) to [update idx v]
if <(length of [update idx v]) = [3]> then
change [triangle count v] by (1)
Simple3D | set [my mesh] list update offset ((-2) + ((triangle count) * (3)))
Simple3D | set [my mesh] indices [update idx v]
replace item ((-2) + ((triangle count) * (3))) of [idx v] with (item (1) of [update idx v])
replace item ((-1) + ((triangle count) * (3))) of [idx v] with (item (2) of [update idx v])
replace item ((0) + ((triangle count) * (3))) of [idx v] with (item (3) of [update idx v])
Simple3D | set [my mesh] draw range from (1) to ((triangle count) * (3))
delete all of [update idx v]
end
wait until >
end
lmscomments | comment [don't mind this, it's just for visualization] {
add (((1) + (mouse x :: variables)) + ((mouse y :: variables) * (9))) to [update idx v]
Simple3D | set [preview] indices [update idx v]
delete (last) of [update idx v]
}
end
Simple3D | clear (color v)
Simple3D | draw mesh [my mesh]
Simple3D | draw mesh [preview]
lmscomments | comment [don't mind this, it's just for visualization] {
if then
replace item (1) of [delete idx v] with (item ((-2) + ((triangle to delete (press D)) * (3))) of [idx v])
replace item (2) of [delete idx v] with (item ((-1) + ((triangle to delete (press D)) * (3))) of [idx v])
replace item (3) of [delete idx v] with (item ((0) + ((triangle to delete (press D)) * (3))) of [idx v])
Simple3D | set [preview] indices [delete idx v]
Simple3D | draw mesh [preview]
end
}
end
define Generate lists
delete all of [r v]
delete all of [g v]
delete all of [b v]
delete all of [x v]
delete all of [y v]
delete all of [idx v]
set [i v] to [0]
repeat (9)
repeat (9)
add ((i) mod (9)) to [x v]
add ([floor v] of ((i) / (9))) to [y v]
add (pick random (1) to (255)) to [r v]
add (pick random (1) to (255)) to [g v]
add (pick random (1) to (255)) to [b v]
change [i v] by (1)
end
end
set [i v] to [1]
set [triangle count v] to [3]
repeat (10)
repeat (3)
add (pick random (1) to (length of [x v])) to [idx v]
end
end
when [d v] key pressed
if then
delete all of [update idx v]
add (item ((-2) + ((triangle count) * (3))) of [idx v]) to [update idx v]
add (item ((-1) + ((triangle count) * (3))) of [idx v]) to [update idx v]
add (item ((0) + ((triangle count) * (3))) of [idx v]) to [update idx v]
Simple3D | set [my mesh] list update offset ((-2) + ((triangle to delete (press D)) * (3)))
Simple3D | set [my mesh] indices [update idx v]
replace item ((-2) + ((triangle to delete (press D)) * (3))) of [idx v] with (item ((-2) + ((triangle count) * (3))) of [idx v])
replace item ((-1) + ((triangle to delete (press D)) * (3))) of [idx v] with (item ((-1) + ((triangle count) * (3))) of [idx v])
replace item ((0) + ((triangle to delete (press D)) * (3))) of [idx v] with (item ((0) + ((triangle count) * (3))) of [idx v])
change [triangle count v] by (-1)
Simple3D | set [my mesh] draw range from (1) to ((triangle count) * (3))
delete all of [update idx v]
end
// This project demonstrates ability to add and remove individual triangles without having to re-upload every triangle of the mesh. It is achieved by pre-allocating space for some amount of triangles, but not actually drawing them. \n\nTo add new triangle, the data of the first unused triangle is updated with the data of the new triangle and the range of triangles that are drawn is expanded.\n\nWhen triangle is removed, we can't introduce holes in the continuous list of triangles, so to solve it, the last visible triangle is moved in place of removed one, and then the drawn range is reduced at the end, making is so that the original triangle of the one that got moved is no longer drawn.\n\nThis approach is not limited to working with 1 triangle at the time and can be used to add/remove groups of triangles in one go. (as long as groups are equally sized, or have sizes that are multiples of one another)
```
# End of partialUpdate/index2.sb3
# Section: Miscellaneous
# Project: Holding 3D item in hand and UI
# Start of misc/holdingAnItem.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = -9.94136680571213
camY = 1.8742766989765904
camZ = -16.92954378816409
camRotX = 180
camRotY = 179
held item angle = 0
held item target angle = 0
held item angle vel = 0
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
katana.obj = ["# Blender 3.6.0","# www.blender.org","o Katana","v -0.003551 -0.224113 0.023861","v -0.003551 -0.205217 0.023861","v 0.003551 -0.224113 0.023861","v 0.003551 -0.205217 0.023861","v 0.003551 -0.224113 -0.012050","v 0.003551 -0.205217 -0.012050","v -0.003551 -0.224113 -0.012050","v -0.003551 -0.205217 -0.012050","v -0.002791 -0.202106 0.023433","v 0.002791 -0.202106 0.023433","v 0.002791 -0.202106 -0.011622","v -0.002791 -0.202106 -0.011622","v -0.002029 -0.211428 0.021747","v -0.000200 0.524445 -0.026487","v 0.002029 -0.211428 0.021747","v 0.000200 0.524445 -0.026487","v 0.002027 -0.211428 -0.010392","v 0.000200 0.539517 -0.052756","v -0.002027 -0.211428 -0.010392","v -0.000200 0.539517 -0.052756","v -0.000200 0.155682 0.022483","v -0.002072 0.155682 -0.009657","v 0.002072 0.155682 -0.009657","v 0.000200 0.155682 0.022483","v -0.000200 0.347599 0.005836","v -0.002072 0.347599 -0.026304","v 0.002072 0.347599 -0.026304","v 0.000200 0.347599 0.005836","v -0.000200 -0.036236 0.024711","v -0.002072 -0.036236 -0.007429","v 0.002072 -0.036236 -0.007429","v 0.000200 -0.036236 0.024711","v 0.000200 -0.132195 0.024094","v -0.000200 -0.132195 0.024094","v -0.002072 -0.132195 -0.008046","v 0.002072 -0.132195 -0.008046","v -0.000200 0.059723 0.025327","v -0.002072 0.059723 -0.006813","v 0.002072 0.059723 -0.006813","v 0.000200 0.059723 0.025327","v -0.000200 0.251640 0.014448","v -0.002072 0.251640 -0.017692","v 0.002072 0.251640 -0.017692","v 0.000200 0.251640 0.014448","v -0.000200 0.443558 -0.005660","v -0.002072 0.443558 -0.037800","v 0.002072 0.443558 -0.037800","v 0.000200 0.443558 -0.005660","v -0.000200 0.534380 -0.036441","v 0.000200 0.534380 -0.036441","v 0.002072 0.443558 -0.021730","v 0.002072 0.347599 -0.010234","v 0.002072 0.251640 -0.001622","v 0.002072 0.155682 0.006413","v 0.002072 0.059723 0.009257","v 0.002072 -0.036236 0.008641","v 0.002072 -0.132195 0.008024","v 0.002027 -0.211428 0.005678","v -0.002027 -0.211428 0.005678","v -0.002072 -0.132195 0.008024","v -0.002072 -0.036236 0.008641","v -0.002072 0.059723 0.009257","v -0.002072 0.155682 0.006413","v -0.002072 0.251640 -0.001622","v -0.002072 0.347599 -0.010234","v -0.002072 0.443558 -0.021730","v -0.002027 -0.196145 -0.009940","v -0.002027 -0.196145 0.006130","v -0.002029 -0.196145 0.022200","v 0.002029 -0.196145 0.022200","v 0.002027 -0.196145 0.006130","v 0.002027 -0.196145 -0.009940","v -0.000200 0.511019 -0.018321","v -0.002072 0.507531 -0.031700","v -0.002072 0.507531 -0.047770","v 0.002072 0.507531 -0.047770","v 0.002072 0.507531 -0.031700","v 0.000200 0.511019 -0.018321","v -0.000200 -0.194485 0.022249","v -0.002072 -0.194485 0.006179","v -0.002072 -0.194485 -0.009891","v 0.002072 -0.194485 -0.009891","v 0.002072 -0.194485 0.006179","v 0.000200 -0.194485 0.022249","v 0.002072 -0.132195 0.005412","v 0.002072 -0.036236 0.006028","v 0.002072 0.059723 0.006645","v 0.002072 0.155682 0.003801","v 0.002072 0.251640 -0.004234","v 0.002072 0.347599 -0.012846","v 0.002072 0.443558 -0.024342","v 0.002072 0.507531 -0.034313","v 0.000200 0.535215 -0.039093","v -0.000200 0.535215 -0.039093","v -0.002072 0.507531 -0.034313","v -0.002072 0.443558 -0.024342","v -0.002072 0.347599 -0.012846","v -0.002072 0.251640 -0.004234","v -0.002072 0.155682 0.003801","v -0.002072 0.059723 0.006645","v -0.002072 -0.036236 0.006028","v -0.002072 -0.132195 0.005412","v -0.002072 -0.194485 0.003567","v -0.002027 -0.196145 0.003518","v -0.002027 -0.211428 0.003065","v 0.002027 -0.211428 0.003065","v 0.002027 -0.196145 0.003518","v 0.002072 -0.194485 0.003567","v 0.000000 -0.217898 0.005565","v 0.000000 -0.226299 0.005565","v 0.000000 -0.222291 0.052756","v 0.000000 -0.226299 0.052756","v -0.016561 -0.222291 0.049164","v -0.016561 -0.226299 0.049164","v -0.030600 -0.222291 0.038934","v -0.030600 -0.226299 0.038934","v -0.039981 -0.222291 0.023624","v -0.039981 -0.226299 0.023624","v -0.043275 -0.222291 0.005565","v -0.043275 -0.226299 0.005565","v -0.039981 -0.222291 -0.012494","v -0.039981 -0.226299 -0.012494","v -0.030600 -0.222291 -0.027804","v -0.030600 -0.226299 -0.027804","v -0.016561 -0.222291 -0.038033","v -0.016561 -0.226299 -0.038033","v 0.000000 -0.222291 -0.041625","v 0.000000 -0.226299 -0.041625","v 0.016561 -0.222291 -0.038033","v 0.016561 -0.226299 -0.038033","v 0.030600 -0.222291 -0.027804","v 0.030600 -0.226299 -0.027804","v 0.039981 -0.222291 -0.012494","v 0.039981 -0.226299 -0.012494","v 0.043275 -0.222291 0.005565","v 0.043275 -0.226299 0.005565","v 0.039981 -0.222291 0.023624","v 0.039981 -0.226299 0.023624","v 0.030600 -0.222291 0.038934","v 0.030600 -0.226299 0.038934","v 0.016561 -0.222291 0.049164","v 0.016561 -0.226299 0.049164","v -0.033317 -0.222291 -0.009484","v -0.025500 -0.222291 -0.022242","v -0.013801 -0.222291 -0.030767","v 0.000000 -0.222291 -0.033760","v 0.013801 -0.222291 -0.030767","v 0.025500 -0.222291 -0.022242","v 0.033317 -0.222291 -0.009484","v 0.036062 -0.222291 0.005565","v 0.033317 -0.222291 0.020614","v 0.025500 -0.222291 0.033372","v 0.013801 -0.222291 0.041897","v 0.000000 -0.222291 0.044891","v -0.013801 -0.222291 0.041897","v -0.025500 -0.222291 0.033372","v -0.033317 -0.222291 0.020614","v -0.036062 -0.222291 0.005565","v -0.036062 -0.226299 0.005565","v -0.033317 -0.226299 0.020614","v -0.025500 -0.226299 0.033372","v -0.013801 -0.226299 0.041897","v 0.000000 -0.226299 0.044891","v 0.013801 -0.226299 0.041897","v 0.025500 -0.226299 0.033372","v 0.033317 -0.226299 0.020614","v 0.036062 -0.226299 0.005565","v 0.033317 -0.226299 -0.009484","v 0.025500 -0.226299 -0.022242","v 0.013801 -0.226299 -0.030767","v 0.000000 -0.226299 -0.033760","v -0.013801 -0.226299 -0.030767","v -0.025500 -0.226299 -0.022242","v -0.033317 -0.226299 -0.009484","v -0.024042 -0.226299 0.005565","v -0.022212 -0.226299 0.015598","v -0.017000 -0.226299 0.024103","v -0.009200 -0.226299 0.029787","v 0.000000 -0.226299 0.031782","v 0.009200 -0.226299 0.029787","v 0.017000 -0.226299 0.024103","v 0.022212 -0.226299 0.015598","v 0.024042 -0.226299 0.005565","v 0.022212 -0.226299 -0.004468","v 0.017000 -0.226299 -0.012973","v 0.009200 -0.226299 -0.018656","v 0.000000 -0.226299 -0.020652","v -0.009200 -0.226299 -0.018656","v -0.017000 -0.226299 -0.012973","v -0.022212 -0.226299 -0.004468","v -0.022212 -0.222291 0.015598","v -0.017000 -0.222291 0.024103","v -0.009200 -0.222291 0.029787","v 0.000000 -0.222291 0.031782","v 0.009200 -0.222291 0.029787","v 0.017000 -0.222291 0.024103","v 0.022212 -0.222291 0.015598","v 0.024042 -0.222291 0.005565","v 0.022212 -0.222291 -0.004468","v 0.017000 -0.222291 -0.012973","v 0.009200 -0.222291 -0.018656","v 0.000000 -0.222291 -0.020652","v -0.009200 -0.222291 -0.018656","v -0.017000 -0.222291 -0.012973","v -0.022212 -0.222291 -0.004468","v -0.024042 -0.222291 0.005565","v 0.009200 -0.222291 0.029787","v -0.020946 -0.217898 0.015026","v -0.016031 -0.217898 0.023047","v -0.008676 -0.217898 0.028406","v 0.000000 -0.217898 0.030288","v 0.016031 -0.217898 0.023047","v 0.020946 -0.217898 0.015026","v 0.022671 -0.217898 0.005565","v 0.020946 -0.217898 -0.003896","v 0.016031 -0.217898 -0.011916","v 0.008676 -0.217898 -0.017275","v 0.000000 -0.217898 -0.019157","v -0.008676 -0.217898 -0.017275","v -0.016031 -0.217898 -0.011916","v -0.020946 -0.217898 -0.003896","v -0.022671 -0.217898 0.005565","v 0.008676 -0.217898 0.028406","v 0.004271 -0.224880 0.021618","v -0.000000 -0.539517 -0.012314","v 0.000000 -0.230161 0.023598","v -0.000000 -0.534004 0.005718","v -0.004632 -0.230161 0.022225","v -0.004632 -0.534004 0.004346","v -0.008559 -0.230161 0.018316","v -0.008559 -0.534004 0.000437","v -0.011183 -0.230161 0.012466","v -0.011183 -0.534004 -0.005414","v -0.012104 -0.230161 0.005565","v -0.012104 -0.534004 -0.012314","v -0.011183 -0.230161 -0.001336","v -0.011183 -0.534004 -0.019215","v -0.008559 -0.230161 -0.007186","v -0.008559 -0.534004 -0.025066","v -0.004632 -0.230161 -0.011095","v -0.004632 -0.534004 -0.028975","v 0.000000 -0.230161 -0.012468","v -0.000000 -0.534004 -0.030347","v 0.004632 -0.230161 -0.011095","v 0.004632 -0.534004 -0.028975","v 0.008559 -0.230161 -0.007186","v 0.008559 -0.534004 -0.025066","v 0.011183 -0.230161 -0.001336","v 0.011183 -0.534004 -0.019215","v 0.012104 -0.230161 0.005565","v 0.012104 -0.534004 -0.012314","v 0.011183 -0.230161 0.012466","v 0.011183 -0.534004 -0.005414","v 0.008559 -0.230161 0.018316","v 0.008559 -0.534004 0.000437","v 0.004632 -0.230161 0.022225","v 0.004632 -0.534004 0.004346","v -0.000000 -0.534004 0.004853","v -0.004195 -0.534004 0.003610","v -0.007865 -0.534004 -0.000043","v -0.010376 -0.534004 -0.005643","v -0.011267 -0.534004 -0.012314","v -0.010376 -0.534004 -0.018986","v -0.007865 -0.534004 -0.024586","v -0.004195 -0.534004 -0.028239","v -0.000000 -0.534004 -0.029482","v 0.004195 -0.534004 -0.028239","v 0.007865 -0.534004 -0.024586","v 0.010376 -0.534004 -0.018986","v 0.011267 -0.534004 -0.012314","v 0.010376 -0.534004 -0.005643","v 0.007865 -0.534004 -0.000043","v 0.004195 -0.534004 0.003610","v -0.000000 -0.539517 0.000647","v -0.003167 -0.539517 -0.000291","v -0.005938 -0.539517 -0.003049","v -0.007834 -0.539517 -0.007277","v -0.008507 -0.539517 -0.012314","v -0.007834 -0.539517 -0.017351","v -0.005938 -0.539517 -0.021579","v -0.003167 -0.539517 -0.024337","v -0.000000 -0.539517 -0.025276","v 0.003167 -0.539517 -0.024337","v 0.005938 -0.539517 -0.021579","v 0.007834 -0.539517 -0.017351","v 0.008507 -0.539517 -0.012314","v 0.007834 -0.539517 -0.007277","v 0.005938 -0.539517 -0.003049","v 0.003167 -0.539517 -0.000291","v 0.000000 -0.230161 0.022883","v -0.004271 -0.230161 0.021618","v -0.007985 -0.230161 0.017920","v -0.010517 -0.230161 0.012277","v -0.011413 -0.230161 0.005565","v -0.010517 -0.230161 -0.001146","v -0.007985 -0.230161 -0.006790","v -0.004271 -0.230161 -0.010487","v 0.000000 -0.230161 -0.011753","v 0.004271 -0.230161 -0.010487","v 0.007985 -0.230161 -0.006790","v 0.010517 -0.230161 -0.001146","v 0.011413 -0.230161 0.005565","v 0.010517 -0.230161 0.012277","v 0.007985 -0.230161 0.017920","v 0.004271 -0.230161 0.021618","v 0.000000 -0.224880 0.022883","v -0.004271 -0.224880 0.021618","v -0.007985 -0.224880 0.017920","v -0.010517 -0.224880 0.012277","v -0.011413 -0.224880 0.005565","v -0.010517 -0.224880 -0.001146","v -0.007985 -0.224880 -0.006790","v -0.004271 -0.224880 -0.010487","v 0.000000 -0.224880 -0.011753","v 0.004271 -0.224880 -0.010487","v 0.007985 -0.224880 -0.006790","v 0.010517 -0.224880 -0.001146","v 0.011413 -0.224880 0.005565","v 0.010517 -0.224880 0.012277","v 0.007985 -0.224880 0.017920","v -0.000000 -0.382083 -0.019966","v -0.004632 -0.382083 -0.018593","v -0.008559 -0.382083 -0.014684","v -0.011183 -0.382083 -0.008834","v -0.012104 -0.382083 -0.001933","v -0.011183 -0.382083 0.004968","v -0.008559 -0.382083 0.010818","v -0.004632 -0.382083 0.014728","v -0.000000 -0.382083 0.016100","v 0.004632 -0.382083 0.014728","v 0.008559 -0.382083 0.010818","v 0.011183 -0.382083 0.004968","v 0.012104 -0.382083 -0.001933","v 0.011183 -0.382083 -0.008834","v 0.008559 -0.382083 -0.014684","v 0.004632 -0.382083 -0.018593","v -0.004632 -0.306122 -0.014556","v -0.000000 -0.306122 -0.015928","v 0.004632 -0.306122 -0.014556","v 0.008559 -0.306122 -0.010647","v 0.011183 -0.306122 -0.004796","v 0.012104 -0.306122 0.002105","v 0.011183 -0.306122 0.009006","v 0.008559 -0.306122 0.014856","v 0.004632 -0.306122 0.018765","v -0.000000 -0.306122 0.020138","v -0.004632 -0.306122 0.018765","v -0.008559 -0.306122 0.014856","v -0.011183 -0.306122 0.009006","v -0.012104 -0.306122 0.002105","v -0.011183 -0.306122 -0.004796","v -0.008559 -0.306122 -0.010647","v -0.008559 -0.458043 -0.019298","v -0.004632 -0.458043 -0.023207","v -0.000000 -0.458043 -0.024580","v 0.004632 -0.458043 -0.023207","v 0.008559 -0.458043 -0.019298","v 0.011183 -0.458043 -0.013448","v 0.012104 -0.458043 -0.006547","v 0.011183 -0.458043 0.000354","v 0.008559 -0.458043 0.006204","v 0.004632 -0.458043 0.010113","v -0.000000 -0.458043 0.011486","v -0.004632 -0.458043 0.010113","v -0.008559 -0.458043 0.006204","v -0.011183 -0.458043 0.000354","v -0.012104 -0.458043 -0.006547","v -0.011183 -0.458043 -0.013448","vt 0.335080 0.952201","vt 0.345710 0.988647","vt 0.339813 0.987547","vt 0.317678 0.974468","vt 0.329271 0.952201","vt 0.068023 0.974468","vt 0.045888 0.987547","vt 0.056430 0.952201","vt 0.086181 0.956793","vt 0.797534 0.628137","vt 0.781743 0.628137","vt 0.781743 0.603260","vt 0.706539 0.587714","vt 0.626686 0.587714","vt 0.626686 0.562838","vt 0.797534 0.664392","vt 0.781743 0.664392","vt 0.781743 0.639515","vt 0.475165 0.582922","vt 0.395311 0.582922","vt 0.395311 0.558045","vt 0.760835 0.722484","vt 0.748422 0.722484","vt 0.748422 0.676335","vt 0.797534 0.723047","vt 0.781743 0.723047","vt 0.781743 0.675771","vt 0.746733 0.723047","vt 0.746733 0.675771","vt 0.762524 0.723047","vt 0.762524 0.675771","vt 0.760835 0.676335","vt 0.986323 0.994311","vt 0.985432 0.994311","vt 0.985432 0.976635","vt 0.240936 0.110000","vt 0.245039 0.027995","vt 0.250847 0.027995","vt 0.957984 0.994311","vt 0.957094 0.994311","vt 0.952932 0.952201","vt 0.245148 0.025810","vt 0.250957 0.025810","vt 0.817645 0.701569","vt 0.816754 0.701569","vt 0.816754 0.688465","vt 0.887544 0.579898","vt 0.878519 0.579898","vt 0.878524 0.558742","vt 0.147506 0.362660","vt 0.183241 0.362660","vt 0.176916 0.488990","vt 0.952932 0.362660","vt 0.962146 0.362660","vt 0.962146 0.488990","vt 0.208785 0.488990","vt 0.202461 0.362660","vt 0.238195 0.362660","vt 0.985432 0.382502","vt 0.986323 0.382502","vt 0.986323 0.508832","vt 0.123314 0.615320","vt 0.159049 0.615320","vt 0.139899 0.741650","vt 0.952932 0.615320","vt 0.962146 0.615320","vt 0.962146 0.741650","vt 0.245802 0.741650","vt 0.226652 0.615320","vt 0.262387 0.615320","vt 0.985432 0.635162","vt 0.986323 0.635162","vt 0.986323 0.761492","vt 0.144765 0.110000","vt 0.180499 0.110000","vt 0.181870 0.236330","vt 0.952932 0.110000","vt 0.962146 0.110000","vt 0.962146 0.236330","vt 0.203831 0.236330","vt 0.205202 0.110000","vt 0.985432 0.129842","vt 0.986323 0.129842","vt 0.986323 0.256172","vt 0.981366 0.025532","vt 0.990390 0.025532","vt 0.990390 0.045652","vt 0.139547 0.005690","vt 0.175281 0.005690","vt 0.176288 0.025810","vt 0.953031 0.005690","vt 0.962047 0.005690","vt 0.962047 0.025810","vt 0.209414 0.025810","vt 0.210420 0.005690","vt 0.246154 0.005690","vt 0.146136 0.236330","vt 0.952932 0.236330","vt 0.239566 0.236330","vt 0.985432 0.256172","vt 0.141182 0.488990","vt 0.952932 0.488990","vt 0.244519 0.488990","vt 0.985432 0.508832","vt 0.104165 0.741650","vt 0.114336 0.867980","vt 0.952932 0.741650","vt 0.962146 0.867980","vt 0.271365 0.867980","vt 0.281537 0.741650","vt 0.985432 0.761492","vt 0.986323 0.887823","vt 0.817645 0.723047","vt 0.816754 0.723047","vt 0.816754 0.705061","vt 0.365005 0.952201","vt 0.376091 0.994311","vt 0.317271 0.741650","vt 0.342834 0.867980","vt 0.312908 0.867980","vt 0.298121 0.615320","vt 0.287345 0.741650","vt 0.280254 0.488990","vt 0.268196 0.615320","vt 0.273929 0.362660","vt 0.250328 0.488990","vt 0.275300 0.236330","vt 0.244004 0.362660","vt 0.276671 0.110000","vt 0.245374 0.236330","vt 0.251963 0.005690","vt 0.281889 0.005690","vt 0.280882 0.025810","vt 0.878524 0.537586","vt 0.887539 0.537586","vt 0.887539 0.555303","vt 0.104819 0.025810","vt 0.103812 0.005690","vt 0.133738 0.005690","vt 0.110401 0.236330","vt 0.109031 0.110000","vt 0.138956 0.110000","vt 0.111772 0.362660","vt 0.140327 0.236330","vt 0.105447 0.488990","vt 0.141698 0.362660","vt 0.087580 0.615320","vt 0.135373 0.488990","vt 0.068430 0.741650","vt 0.117506 0.615320","vt 0.042868 0.867980","vt 0.098356 0.741650","vt 0.039991 0.988647","vt 0.009610 0.994311","vt 0.020696 0.952201","vt 0.104928 0.027995","vt 0.140663 0.027995","vt 0.985432 0.047837","vt 0.209304 0.027995","vt 0.280773 0.027995","vt 0.246745 0.110000","vt 0.952932 0.027995","vt 0.078602 0.867980","vt 0.072793 0.867980","vt 0.952932 0.867980","vt 0.962146 0.952201","vt 0.307099 0.867980","vt 0.985432 0.887823","vt 0.986323 0.976635","vt 0.838464 0.582922","vt 0.838459 0.561766","vt 0.842526 0.561701","vt 0.134744 0.025810","vt 0.953031 0.025810","vt 0.962146 0.027995","vt 0.981366 0.045652","vt 0.986323 0.047837","vt 0.817645 0.705061","vt 0.887539 0.558742","vt 0.878524 0.555303","vt 0.050621 0.952201","vt 0.140553 0.025810","vt 0.134854 0.027995","vt 0.657807 0.660430","vt 0.677100 0.657953","vt 0.677100 0.690500","vt 0.426530 0.502293","vt 0.463356 0.502293","vt 0.463356 0.507570","vt 0.702457 0.964072","vt 0.722916 0.932184","vt 0.722916 0.966699","vt 0.641452 0.667486","vt 0.395311 0.502293","vt 0.426530 0.507570","vt 0.685113 0.956590","vt 0.630523 0.678045","vt 0.677293 0.518949","vt 0.711336 0.518949","vt 0.711336 0.524226","vt 0.673524 0.945392","vt 0.626686 0.690500","vt 0.637135 0.518949","vt 0.677293 0.524226","vt 0.669455 0.932184","vt 0.630523 0.702955","vt 0.596978 0.518949","vt 0.637135 0.524226","vt 0.673524 0.918976","vt 0.641452 0.713515","vt 0.562934 0.518949","vt 0.596978 0.524226","vt 0.685113 0.907779","vt 0.657807 0.720570","vt 0.655491 0.502293","vt 0.686710 0.502293","vt 0.686710 0.507570","vt 0.702457 0.900297","vt 0.677100 0.723047","vt 0.618665 0.502293","vt 0.655491 0.507570","vt 0.722916 0.897670","vt 0.696392 0.720570","vt 0.581839 0.502293","vt 0.618665 0.507570","vt 0.743374 0.900297","vt 0.712747 0.713515","vt 0.550620 0.502293","vt 0.581839 0.507570","vt 0.760718 0.907779","vt 0.723676 0.702955","vt 0.509670 0.518949","vt 0.543714 0.518949","vt 0.543714 0.524226","vt 0.772307 0.918976","vt 0.727513 0.690500","vt 0.469512 0.518949","vt 0.509670 0.524226","vt 0.776377 0.932184","vt 0.723676 0.678045","vt 0.429355 0.518949","vt 0.469512 0.524226","vt 0.772307 0.945392","vt 0.712747 0.667486","vt 0.395311 0.518949","vt 0.429355 0.524226","vt 0.760718 0.956590","vt 0.696392 0.660430","vt 0.500181 0.502293","vt 0.531401 0.502293","vt 0.531401 0.507570","vt 0.743374 0.964072","vt 0.500181 0.507570","vt 0.654871 0.840483","vt 0.634011 0.820327","vt 0.648828 0.816365","vt 0.686090 0.853950","vt 0.666212 0.833161","vt 0.722916 0.858679","vt 0.692228 0.844384","vt 0.759741 0.853950","vt 0.722916 0.848325","vt 0.790960 0.840483","vt 0.753604 0.844384","vt 0.811820 0.820327","vt 0.779619 0.833161","vt 0.819145 0.796553","vt 0.797003 0.816365","vt 0.811820 0.772778","vt 0.803107 0.796553","vt 0.790960 0.752623","vt 0.797003 0.776740","vt 0.759741 0.739155","vt 0.779619 0.759944","vt 0.722916 0.734426","vt 0.753604 0.748722","vt 0.686090 0.739155","vt 0.722916 0.744781","vt 0.654871 0.752623","vt 0.692228 0.748722","vt 0.634011 0.772778","vt 0.666212 0.759944","vt 0.626686 0.796553","vt 0.648828 0.776740","vt 0.642724 0.796553","vt 0.634011 0.955959","vt 0.626686 0.932184","vt 0.642724 0.932184","vt 0.654871 0.976114","vt 0.648828 0.951997","vt 0.686090 0.989581","vt 0.666212 0.968792","vt 0.722916 0.994311","vt 0.692228 0.980015","vt 0.759741 0.989581","vt 0.722916 0.983956","vt 0.790960 0.976114","vt 0.753604 0.980015","vt 0.811820 0.955959","vt 0.779619 0.968792","vt 0.819145 0.932184","vt 0.797003 0.951997","vt 0.811820 0.908409","vt 0.803107 0.932184","vt 0.790960 0.888254","vt 0.797003 0.912372","vt 0.759741 0.874787","vt 0.779619 0.895576","vt 0.722916 0.870058","vt 0.753604 0.884353","vt 0.686090 0.874787","vt 0.722916 0.880412","vt 0.654871 0.888254","vt 0.692228 0.884353","vt 0.634011 0.908409","vt 0.666212 0.895576","vt 0.648828 0.912372","vt 0.673524 0.809761","vt 0.685113 0.820958","vt 0.743374 0.828440","vt 0.760718 0.820958","vt 0.772307 0.783344","vt 0.760718 0.772147","vt 0.702457 0.764665","vt 0.685113 0.772147","vt 0.835040 0.520929","vt 0.835040 0.526207","vt 0.804352 0.526207","vt 0.865728 0.520929","vt 0.865728 0.526207","vt 0.609146 0.535605","vt 0.609146 0.540883","vt 0.598917 0.540883","vt 0.629605 0.535605","vt 0.629604 0.540883","vt 0.650063 0.535605","vt 0.650063 0.540883","vt 0.569072 0.558045","vt 0.569072 0.563322","vt 0.557917 0.563322","vt 0.428776 0.485636","vt 0.428776 0.490914","vt 0.395311 0.490914","vt 0.462240 0.485636","vt 0.462240 0.490914","vt 0.513298 0.558045","vt 0.513298 0.563322","vt 0.502143 0.563322","vt 0.535607 0.558045","vt 0.535607 0.563322","vt 0.557917 0.558045","vt 0.628985 0.485636","vt 0.628985 0.490914","vt 0.598297 0.490914","vt 0.598297 0.485636","vt 0.567609 0.490914","vt 0.514321 0.535605","vt 0.514321 0.540883","vt 0.504092 0.540883","vt 0.534779 0.535605","vt 0.534779 0.540883","vt 0.555238 0.535605","vt 0.555238 0.540883","vt 0.565467 0.535605","vt 0.565467 0.540883","vt 0.548389 0.485636","vt 0.548389 0.490914","vt 0.514925 0.490914","vt 0.514925 0.485636","vt 0.481460 0.490914","vt 0.436534 0.535605","vt 0.436534 0.540883","vt 0.414224 0.540883","vt 0.458844 0.535605","vt 0.458844 0.540883","vt 0.414224 0.535605","vt 0.403070 0.540883","vt 0.469999 0.535605","vt 0.469999 0.540883","vt 0.660292 0.535605","vt 0.660292 0.540883","vt 0.629605 0.546666","vt 0.591802 0.540883","vt 0.610312 0.546666","vt 0.477757 0.540883","vt 0.475407 0.546666","vt 0.457572 0.546666","vt 0.436534 0.546666","vt 0.395311 0.540883","vt 0.415496 0.546666","vt 0.572582 0.540883","vt 0.570427 0.546666","vt 0.554072 0.546666","vt 0.534779 0.546666","vt 0.496977 0.540883","vt 0.515487 0.546666","vt 0.576830 0.563322","vt 0.574481 0.569106","vt 0.556645 0.569106","vt 0.535607 0.569106","vt 0.494384 0.563322","vt 0.514569 0.569106","vt 0.667407 0.540883","vt 0.665252 0.546666","vt 0.648897 0.546666","vt 0.797483 0.482285","vt 0.806980 0.482285","vt 0.806980 0.489238","vt 0.847097 0.694303","vt 0.857397 0.694303","vt 0.857397 0.794306","vt 0.737632 0.586479","vt 0.744675 0.570651","vt 0.744675 0.587714","vt 0.815240 0.482285","vt 0.815240 0.489238","vt 0.838365 0.694303","vt 0.847097 0.794306","vt 0.731471 0.582848","vt 0.804352 0.537586","vt 0.816902 0.537586","vt 0.816902 0.544539","vt 0.567524 0.694303","vt 0.580533 0.694303","vt 0.590793 0.794306","vt 0.727255 0.577282","vt 0.831826 0.537586","vt 0.831826 0.544539","vt 0.552178 0.694303","vt 0.577784 0.794306","vt 0.725759 0.570651","vt 0.846750 0.537586","vt 0.846750 0.544539","vt 0.536833 0.694303","vt 0.562439 0.794306","vt 0.727255 0.564019","vt 0.859299 0.537586","vt 0.859299 0.544539","vt 0.523824 0.694303","vt 0.547093 0.794306","vt 0.731471 0.558453","vt 0.648205 0.483961","vt 0.656464 0.483961","vt 0.656464 0.490914","vt 0.924981 0.694303","vt 0.933713 0.694303","vt 0.933713 0.794306","vt 0.737632 0.554822","vt 0.665962 0.483961","vt 0.665962 0.490914","vt 0.914681 0.694303","vt 0.924981 0.794306","vt 0.744675 0.553587","vt 0.675460 0.483961","vt 0.675460 0.490914","vt 0.904381 0.694303","vt 0.914681 0.794306","vt 0.751719 0.554822","vt 0.683719 0.483961","vt 0.683719 0.490914","vt 0.895649 0.694303","vt 0.904381 0.794306","vt 0.757879 0.558453","vt 0.779726 0.500617","vt 0.792275 0.500617","vt 0.792275 0.507570","vt 0.465944 0.694303","vt 0.478953 0.694303","vt 0.468693 0.794306","vt 0.762096 0.564019","vt 0.807199 0.500617","vt 0.807199 0.507570","vt 0.450599 0.694303","vt 0.455684 0.794306","vt 0.763591 0.570651","vt 0.822123 0.500617","vt 0.822123 0.507570","vt 0.435254 0.694303","vt 0.440339 0.794306","vt 0.762096 0.577282","vt 0.834673 0.500617","vt 0.834673 0.507570","vt 0.422244 0.694303","vt 0.424993 0.794306","vt 0.757879 0.582848","vt 0.779726 0.482285","vt 0.787985 0.482285","vt 0.787985 0.489238","vt 0.867697 0.694303","vt 0.876429 0.694303","vt 0.876429 0.794306","vt 0.751719 0.586479","vt 0.797482 0.489238","vt 0.867697 0.794306","vt 0.653601 0.646574","vt 0.643301 0.644767","vt 0.644272 0.643798","vt 0.634569 0.639621","vt 0.636113 0.638989","vt 0.628735 0.631919","vt 0.630527 0.631617","vt 0.626686 0.622834","vt 0.628547 0.622834","vt 0.628735 0.613749","vt 0.630527 0.614051","vt 0.634569 0.606047","vt 0.636113 0.606678","vt 0.643301 0.600900","vt 0.644272 0.601869","vt 0.653601 0.599093","vt 0.653601 0.600232","vt 0.663901 0.600900","vt 0.662930 0.601869","vt 0.672633 0.606047","vt 0.671090 0.606678","vt 0.678468 0.613749","vt 0.676675 0.614051","vt 0.680516 0.622834","vt 0.678655 0.622834","vt 0.678468 0.631919","vt 0.676675 0.631617","vt 0.672633 0.639621","vt 0.671090 0.638989","vt 0.663901 0.644767","vt 0.662930 0.643798","vt 0.653601 0.645435","vt 0.801657 0.582922","vt 0.792328 0.582922","vt 0.794613 0.575664","vt 0.784168 0.582922","vt 0.788453 0.575664","vt 0.785132 0.526207","vt 0.772680 0.526207","vt 0.769045 0.518949","vt 0.757844 0.526207","vt 0.757844 0.518949","vt 0.743009 0.526207","vt 0.746644 0.518949","vt 0.730556 0.526207","vt 0.737242 0.518949","vt 0.819145 0.564285","vt 0.810986 0.564285","vt 0.808700 0.557027","vt 0.801657 0.564285","vt 0.801657 0.557027","vt 0.792328 0.564285","vt 0.794613 0.557027","vt 0.784168 0.564285","vt 0.788453 0.557027","vt 0.760506 0.507570","vt 0.748053 0.507570","vt 0.744418 0.500312","vt 0.733218 0.507570","vt 0.733218 0.500312","vt 0.718382 0.507570","vt 0.722017 0.500312","vt 0.705929 0.507570","vt 0.712615 0.500312","vt 0.819145 0.582922","vt 0.810986 0.582922","vt 0.808700 0.575664","vt 0.801657 0.575664","vt 0.716351 0.600900","vt 0.726651 0.599093","vt 0.726651 0.600034","vt 0.707619 0.606047","vt 0.717153 0.601701","vt 0.701785 0.613749","vt 0.708894 0.606568","vt 0.699736 0.622834","vt 0.703266 0.613998","vt 0.701785 0.631919","vt 0.701273 0.622834","vt 0.707619 0.639621","vt 0.703266 0.631669","vt 0.716351 0.644767","vt 0.708894 0.639099","vt 0.726651 0.646574","vt 0.717153 0.643967","vt 0.736951 0.644767","vt 0.726651 0.645633","vt 0.745683 0.639621","vt 0.736149 0.643967","vt 0.751518 0.631919","vt 0.744408 0.639099","vt 0.753567 0.622834","vt 0.750037 0.631669","vt 0.751518 0.613749","vt 0.752029 0.622834","vt 0.745683 0.606047","vt 0.750037 0.613998","vt 0.736951 0.600900","vt 0.744408 0.606568","vt 0.736149 0.601701","vt 0.924981 0.994311","vt 0.914681 0.994311","vt 0.914681 0.894308","vt 0.933713 0.994311","vt 0.924981 0.894308","vt 0.563766 0.994311","vt 0.550757 0.994311","vt 0.543062 0.894308","vt 0.579112 0.994311","vt 0.556071 0.894308","vt 0.594457 0.994311","vt 0.571416 0.894308","vt 0.607466 0.994311","vt 0.586762 0.894308","vt 0.847097 0.994311","vt 0.838365 0.994311","vt 0.838365 0.894308","vt 0.857397 0.994311","vt 0.847097 0.894308","vt 0.867697 0.994311","vt 0.857397 0.894308","vt 0.876429 0.994311","vt 0.867697 0.894308","vt 0.408320 0.994311","vt 0.395311 0.994311","vt 0.403006 0.894308","vt 0.423666 0.994311","vt 0.416015 0.894308","vt 0.439011 0.994311","vt 0.431361 0.894308","vt 0.452020 0.994311","vt 0.446706 0.894308","vt 0.904381 0.994311","vt 0.895649 0.994311","vt 0.895649 0.894308","vt 0.904381 0.894308","vt 0.895649 0.794306","vt 0.459715 0.894308","vt 0.411984 0.794306","vt 0.876429 0.894308","vt 0.838365 0.794306","vt 0.599771 0.894308","vt 0.534084 0.794306","vt 0.933713 0.894308","vt 0.924981 0.594301","vt 0.933713 0.594301","vt 0.914681 0.594301","vt 0.904381 0.594301","vt 0.895649 0.594301","vt 0.478770 0.594301","vt 0.491779 0.594301","vt 0.463424 0.594301","vt 0.448079 0.594301","vt 0.435070 0.594301","vt 0.867697 0.594301","vt 0.876429 0.594301","vt 0.857397 0.594301","vt 0.847097 0.594301","vt 0.838365 0.594301","vt 0.554698 0.594301","vt 0.567708 0.594301","vt 0.539353 0.594301","vt 0.524008 0.594301","vt 0.510998 0.594301","vt 0.299520 0.956793","vt 0.797534 0.603260","vt 0.706539 0.562838","vt 0.797534 0.639515","vt 0.475165 0.558045","vt 0.797534 0.675771","vt 0.817645 0.688465","vt 0.176397 0.027995","vt 0.838365 0.582857","vt 0.395311 0.507570","vt 0.562934 0.524226","vt 0.550620 0.507570","vt 0.395311 0.524226","vt 0.702457 0.828440","vt 0.772307 0.809761","vt 0.743374 0.764665","vt 0.673524 0.783344","vt 0.804352 0.520929","vt 0.598917 0.535605","vt 0.395311 0.485636","vt 0.502143 0.558045","vt 0.567609 0.485636","vt 0.504092 0.535605","vt 0.481460 0.485636","vt 0.403070 0.535605","vt 0.593957 0.546666","vt 0.397661 0.546666","vt 0.499132 0.546666","vt 0.496734 0.569106","vt 0.804352 0.544539","vt 0.648205 0.490914","vt 0.779726 0.507570","vt 0.779726 0.489238","vt 0.778447 0.518949","vt 0.814861 0.557027","vt 0.753820 0.500312","vt 0.814861 0.575664","s 1","f 92/1 93/2 50/3","f 50/3 16/4 77/5","f 14/6 49/7 74/8","f 14/6 74/8 73/9","f 4/10 2/11 1/12","f 6/13 4/14 3/15","f 8/16 6/17 5/18","f 2/19 8/20 7/21","f 11/22 12/23 9/24","f 3/25 1/26 7/27","f 8/28 2/29 9/24","f 6/30 8/28 12/23","f 4/31 6/30 11/22","f 2/29 4/31 10/32","f 16/33 14/34 73/35","f 57/36 83/37 108/38","f 20/39 18/40 76/41","f 83/37 71/42 107/43","f 50/44 49/45 14/46","f 15/47 13/48 59/49","f 62/50 37/51 21/52","f 39/53 38/54 22/55","f 24/56 40/57 55/58","f 37/59 40/60 24/61","f 64/62 41/63 25/64","f 43/65 42/66 26/67","f 28/68 44/69 53/70","f 41/71 44/72 28/73","f 60/74 34/75 29/76","f 36/77 35/78 30/79","f 32/80 33/81 57/36","f 34/82 33/83 32/84","f 13/85 15/86 70/87","f 59/88 13/89 69/90","f 17/91 19/92 67/93","f 70/94 15/95 58/96","f 61/97 29/76 37/51","f 31/98 30/79 38/54","f 40/57 32/80 56/99","f 29/100 32/84 40/60","f 63/101 21/52 41/63","f 23/102 22/55 42/66","f 44/69 24/56 54/103","f 21/104 24/61 44/72","f 65/105 25/64 45/106","f 27/107 26/67 46/108","f 48/109 28/68 52/110","f 25/111 28/73 48/112","f 18/113 20/114 94/115","f 76/116 18/117 93/2","f 27/118 47/119 91/120","f 43/121 27/118 90/122","f 23/123 43/121 89/124","f 39/125 23/123 88/126","f 31/127 39/125 87/128","f 36/129 31/127 86/130","f 106/131 17/132 72/133","f 19/134 17/135 106/136","f 67/137 19/138 105/139","f 30/140 35/141 102/142","f 38/143 30/140 101/144","f 22/145 38/143 100/146","f 42/147 22/145 99/148","f 26/149 42/147 98/150","f 46/151 26/149 97/152","f 94/153 20/154 75/155","f 102/142 35/141 81/156","f 34/75 60/74 80/157","f 33/83 34/82 79/158","f 57/36 33/81 84/159","f 82/160 36/129 85/161","f 35/78 36/77 82/162","f 66/163 45/106 73/9","f 75/155 46/151 96/164","f 47/165 46/108 75/166","f 91/120 47/119 76/116","f 48/109 51/167 77/5","f 45/168 48/112 78/169","f 68/170 69/171 79/172","f 81/156 67/137 104/173","f 72/174 67/93 81/175","f 107/43 72/133 82/160","f 70/94 71/42 83/37","f 69/176 70/87 84/177","f 56/99 57/36 85/161","f 55/58 56/99 86/130","f 54/103 55/58 87/128","f 53/70 54/103 88/126","f 52/110 53/70 89/124","f 51/167 52/110 90/122","f 77/5 51/167 91/120","f 71/42 58/96 106/131","f 49/45 50/44 93/178","f 58/179 59/49 105/180","f 66/163 74/8 95/181","f 65/105 66/163 96/164","f 64/62 65/105 97/152","f 63/101 64/62 98/150","f 62/50 63/101 99/148","f 61/97 62/50 100/146","f 60/74 61/97 101/144","f 80/157 60/74 102/142","f 68/182 80/157 103/183","f 59/88 68/182 104/173","f 210/184 211/185 109/186","f 114/187 112/188 111/189","f 178/190 110/191 179/192","f 209/193 210/184 109/186","f 116/194 114/187 113/195","f 177/196 110/191 178/190","f 208/197 209/193 109/186","f 118/198 116/199 115/200","f 176/201 110/191 177/196","f 222/202 208/197 109/186","f 120/203 118/198 117/204","f 175/205 110/191 176/201","f 221/206 222/202 109/186","f 122/207 120/203 119/208","f 190/209 110/191 175/205","f 220/210 221/206 109/186","f 124/211 122/207 121/212","f 189/213 110/191 190/209","f 219/214 220/210 109/186","f 126/215 124/216 123/217","f 188/218 110/191 189/213","f 218/219 219/214 109/186","f 128/220 126/215 125/221","f 187/222 110/191 188/218","f 217/223 218/219 109/186","f 130/224 128/220 127/225","f 186/226 110/191 187/222","f 216/227 217/223 109/186","f 132/228 130/224 129/229","f 185/230 110/191 186/226","f 215/231 216/227 109/186","f 134/232 132/233 131/234","f 184/235 110/191 185/230","f 214/236 215/231 109/186","f 136/237 134/232 133/238","f 183/239 110/191 184/235","f 213/240 214/236 109/186","f 138/241 136/237 135/242","f 182/243 110/191 183/239","f 212/244 213/240 109/186","f 140/245 138/241 137/246","f 181/247 110/191 182/243","f 223/248 212/244 109/186","f 142/249 140/250 139/251","f 180/252 110/191 181/247","f 211/185 223/248 109/186","f 112/188 142/249 141/253","f 179/192 110/191 180/252","f 123/254 121/255 143/256","f 125/257 123/254 144/258","f 127/259 125/257 145/260","f 129/261 127/259 146/262","f 131/263 129/261 147/264","f 133/265 131/263 148/266","f 135/267 133/265 149/268","f 137/269 135/267 150/270","f 139/271 137/269 151/272","f 141/273 139/271 152/274","f 111/275 141/273 153/276","f 113/277 111/275 154/278","f 115/279 113/277 155/280","f 117/281 115/279 156/282","f 119/283 117/281 157/284","f 121/255 119/283 158/285","f 118/286 120/287 159/288","f 116/289 118/286 160/290","f 114/291 116/289 161/292","f 112/293 114/291 162/294","f 142/295 112/293 163/296","f 140/297 142/295 164/298","f 138/299 140/297 165/300","f 136/301 138/299 166/302","f 134/303 136/301 167/304","f 132/305 134/303 168/306","f 130/307 132/305 169/308","f 128/309 130/307 170/310","f 126/311 128/309 171/312","f 124/313 126/311 172/314","f 122/315 124/313 173/316","f 120/287 122/315 174/317","f 144/258 143/256 205/318","f 161/292 160/290 176/201","f 162/294 161/292 177/196","f 145/260 144/258 204/319","f 148/266 147/264 201/320","f 165/300 164/298 180/252","f 166/302 165/300 181/247","f 149/268 148/266 200/321","f 152/274 151/272 197/322","f 169/308 168/306 184/235","f 170/310 169/308 185/230","f 153/276 152/274 196/323","f 156/282 155/280 193/324","f 173/316 172/314 188/218","f 174/317 173/316 189/213","f 157/284 156/282 192/325","f 163/326 154/327 153/328","f 162/329 155/330 154/327","f 178/331 193/332 155/333","f 179/334 194/335 193/332","f 180/336 207/337 194/335","f 168/338 149/339 199/340","f 167/341 150/342 149/343","f 166/344 151/345 150/342","f 182/346 197/347 151/348","f 183/349 198/350 197/347","f 184/351 199/340 198/350","f 170/352 147/353 146/354","f 171/355 146/354 145/356","f 186/357 201/358 147/359","f 187/360 202/361 201/358","f 188/362 203/363 202/361","f 172/364 145/365 203/363","f 174/366 143/367 158/368","f 159/369 158/368 157/370","f 175/371 206/372 205/373","f 176/374 191/375 206/372","f 190/376 205/373 143/377","f 160/378 157/379 191/375","f 164/380 153/381 207/337","f 193/332 194/335 211/382","f 192/383 193/332 210/384","f 191/375 192/385 209/386","f 206/372 191/375 208/387","f 205/373 206/372 222/388","f 204/389 205/373 221/390","f 203/363 204/391 220/392","f 202/361 203/363 219/393","f 201/358 202/361 218/394","f 200/395 201/358 217/396","f 199/340 200/397 216/398","f 198/350 199/340 215/399","f 197/347 198/350 214/400","f 196/401 197/347 213/402","f 207/337 196/403 212/404","f 194/335 207/337 223/405","f 290/406 305/407 224/408","f 364/409 363/410 329/411","f 275/412 225/413 274/414","f 305/407 304/415 320/416","f 365/417 364/409 328/418","f 276/419 225/413 275/412","f 304/420 303/421 319/422","f 366/423 365/424 327/425","f 277/426 225/413 276/419","f 303/421 302/427 318/428","f 367/429 366/423 326/430","f 278/431 225/413 277/426","f 302/427 301/432 317/433","f 368/434 367/429 325/435","f 279/436 225/413 278/431","f 301/432 300/437 316/438","f 353/439 368/434 324/440","f 280/441 225/413 279/436","f 300/442 299/443 315/444","f 354/445 353/446 323/447","f 281/448 225/413 280/441","f 299/443 298/449 314/450","f 355/451 354/445 322/452","f 282/453 225/413 281/448","f 298/449 297/454 313/455","f 356/456 355/451 321/457","f 283/458 225/413 282/453","f 297/454 296/459 312/460","f 357/461 356/456 336/462","f 284/463 225/413 283/458","f 296/464 295/465 311/466","f 358/467 357/468 335/469","f 285/470 225/413 284/463","f 295/465 294/471 310/472","f 359/473 358/467 334/474","f 286/475 225/413 285/470","f 294/471 293/476 309/477","f 360/478 359/473 333/479","f 287/480 225/413 286/475","f 293/476 292/481 308/482","f 361/483 360/478 332/484","f 288/485 225/413 287/480","f 292/486 291/487 307/488","f 362/489 361/490 331/491","f 289/492 225/413 288/485","f 291/487 290/406 306/493","f 363/410 362/489 330/494","f 274/414 225/413 289/492","f 227/495 229/496 259/497","f 229/496 231/498 260/499","f 231/498 233/500 261/501","f 233/500 235/502 262/503","f 235/502 237/504 263/505","f 237/504 239/506 264/507","f 239/506 241/508 265/509","f 241/508 243/510 266/511","f 243/510 245/512 267/513","f 245/512 247/514 268/515","f 247/514 249/516 269/517","f 249/516 251/518 270/519","f 251/518 253/520 271/521","f 253/520 255/522 272/523","f 255/522 257/524 273/525","f 257/524 227/495 258/526","f 258/527 259/528 275/529","f 259/528 260/530 276/531","f 260/532 261/533 277/534","f 261/533 262/535 278/536","f 262/535 263/537 279/538","f 263/537 264/539 280/540","f 264/541 265/542 281/543","f 265/542 266/544 282/545","f 266/544 267/546 283/547","f 267/546 268/548 284/549","f 268/550 269/551 285/552","f 269/551 270/553 286/554","f 270/553 271/555 287/556","f 271/555 272/557 288/558","f 272/559 273/560 289/561","f 273/560 258/527 274/562","f 228/563 226/564 290/565","f 230/566 228/563 291/567","f 232/568 230/566 292/569","f 234/570 232/568 293/571","f 236/572 234/570 294/573","f 238/574 236/572 295/575","f 240/576 238/574 296/577","f 242/578 240/576 297/579","f 244/580 242/578 298/581","f 246/582 244/580 299/583","f 248/584 246/582 300/585","f 250/586 248/584 301/587","f 252/588 250/586 302/589","f 254/590 252/588 303/591","f 256/592 254/590 304/593","f 226/564 256/592 305/594","f 240/595 242/596 338/597","f 238/598 240/595 337/599","f 236/600 238/601 352/602","f 234/603 236/600 351/604","f 232/605 234/603 350/606","f 230/607 232/605 349/608","f 228/609 230/610 348/611","f 226/612 228/609 347/613","f 256/614 226/612 346/615","f 254/616 256/614 345/617","f 252/618 254/619 344/620","f 250/621 252/618 343/622","f 248/623 250/621 342/624","f 246/625 248/623 341/626","f 244/627 246/628 340/629","f 242/596 244/627 339/630","f 321/457 322/452 337/599","f 336/462 321/457 338/597","f 335/631 336/462 339/630","f 334/474 335/469 340/632","f 333/479 334/474 341/626","f 332/484 333/479 342/624","f 331/633 332/484 343/622","f 330/494 331/491 344/634","f 329/411 330/494 345/617","f 328/418 329/411 346/615","f 327/635 328/418 347/613","f 326/430 327/425 348/636","f 325/435 326/430 349/608","f 324/440 325/435 350/606","f 323/637 324/440 351/604","f 322/452 323/447 352/638","f 241/639 239/640 353/446","f 243/641 241/639 354/445","f 245/642 243/641 355/451","f 247/643 245/642 356/456","f 249/644 247/645 357/468","f 251/646 249/644 358/467","f 253/647 251/646 359/473","f 255/648 253/647 360/478","f 257/649 255/650 361/490","f 227/651 257/649 362/489","f 229/652 227/651 363/410","f 231/653 229/652 364/409","f 233/654 231/655 365/424","f 235/656 233/654 366/423","f 237/657 235/656 367/429","f 239/658 237/657 368/434","f 16/4 78/659 77/5","f 94/153 95/181 74/8","f 77/5 92/1 50/3","f 3/660 4/10 1/12","f 5/661 6/13 3/15","f 7/662 8/16 5/18","f 1/663 2/19 7/21","f 10/32 11/22 9/24","f 5/664 3/25 7/27","f 12/23 8/28 9/24","f 11/22 6/30 12/23","f 10/32 4/31 11/22","f 9/24 2/29 10/32","f 78/169 16/33 73/35","f 85/161 57/36 108/38","f 75/166 20/39 76/41","f 108/38 83/37 107/43","f 16/665 50/44 14/46","f 58/179 15/47 59/49","f 63/101 62/50 21/52","f 23/102 39/53 22/55","f 54/103 24/56 55/58","f 21/104 37/59 24/61","f 65/105 64/62 25/64","f 27/107 43/65 26/67","f 52/110 28/68 53/70","f 25/111 41/71 28/73","f 61/97 60/74 29/76","f 31/98 36/77 30/79","f 56/99 32/80 57/36","f 29/100 34/82 32/84","f 69/176 13/85 70/87","f 68/182 59/88 69/90","f 72/174 17/91 67/93","f 71/42 70/94 58/96","f 62/50 61/97 37/51","f 39/53 31/98 38/54","f 55/58 40/57 56/99","f 37/59 29/100 40/60","f 64/62 63/101 41/63","f 43/65 23/102 42/66","f 53/70 44/69 54/103","f 41/71 21/104 44/72","f 66/163 65/105 45/106","f 47/165 27/107 46/108","f 51/167 48/109 52/110","f 45/168 25/111 48/112","f 93/178 18/113 94/115","f 92/1 76/116 93/2","f 90/122 27/118 91/120","f 89/124 43/121 90/122","f 88/126 23/123 89/124","f 87/128 39/125 88/126","f 86/130 31/127 87/128","f 85/161 36/129 86/130","f 107/43 106/131 72/133","f 105/180 19/134 106/136","f 104/173 67/137 105/139","f 101/144 30/140 102/142","f 100/146 38/143 101/144","f 99/148 22/145 100/146","f 98/150 42/147 99/148","f 97/152 26/149 98/150","f 96/164 46/151 97/152","f 95/181 94/153 75/155","f 103/183 102/142 81/156","f 79/666 34/75 80/157","f 84/177 33/83 79/158","f 83/37 57/36 84/159","f 108/38 82/160 85/161","f 81/175 35/78 82/162","f 74/8 66/163 73/9","f 95/181 75/155 96/164","f 76/41 47/165 75/166","f 92/1 91/120 76/116","f 78/659 48/109 77/5","f 73/35 45/168 78/169","f 80/667 68/170 79/172","f 103/183 81/156 104/173","f 82/162 72/174 81/175","f 108/38 107/43 82/160","f 84/159 70/94 83/37","f 79/158 69/176 84/177","f 86/130 56/99 85/161","f 87/128 55/58 86/130","f 88/126 54/103 87/128","f 89/124 53/70 88/126","f 90/122 52/110 89/124","f 91/120 51/167 90/122","f 92/1 77/5 91/120","f 107/43 71/42 106/131","f 94/115 49/45 93/178","f 106/136 58/179 105/180","f 96/164 66/163 95/181","f 97/152 65/105 96/164","f 98/150 64/62 97/152","f 99/148 63/101 98/150","f 100/146 62/50 99/148","f 101/144 61/97 100/146","f 102/142 60/74 101/144","f 103/183 80/157 102/142","f 104/173 68/182 103/183","f 105/139 59/88 104/173","f 113/195 114/187 111/189","f 115/668 116/194 113/195","f 117/204 118/198 115/200","f 119/208 120/203 117/204","f 121/212 122/207 119/208","f 123/669 124/211 121/212","f 125/221 126/215 123/217","f 127/225 128/220 125/221","f 129/229 130/224 127/225","f 131/670 132/228 129/229","f 133/238 134/232 131/234","f 135/242 136/237 133/238","f 137/246 138/241 135/242","f 139/671 140/245 137/246","f 141/253 142/249 139/251","f 111/189 112/188 141/253","f 144/258 123/254 143/256","f 145/260 125/257 144/258","f 146/262 127/259 145/260","f 147/264 129/261 146/262","f 148/266 131/263 147/264","f 149/268 133/265 148/266","f 150/270 135/267 149/268","f 151/272 137/269 150/270","f 152/274 139/271 151/272","f 153/276 141/273 152/274","f 154/278 111/275 153/276","f 155/280 113/277 154/278","f 156/282 115/279 155/280","f 157/284 117/281 156/282","f 158/285 119/283 157/284","f 143/256 121/255 158/285","f 160/290 118/286 159/288","f 161/292 116/289 160/290","f 162/294 114/291 161/292","f 163/296 112/293 162/294","f 164/298 142/295 163/296","f 165/300 140/297 164/298","f 166/302 138/299 165/300","f 167/304 136/301 166/302","f 168/306 134/303 167/304","f 169/308 132/305 168/306","f 170/310 130/307 169/308","f 171/312 128/309 170/310","f 172/314 126/311 171/312","f 173/316 124/313 172/314","f 174/317 122/315 173/316","f 159/288 120/287 174/317","f 204/319 144/258 205/318","f 177/196 161/292 176/201","f 178/190 162/294 177/196","f 203/672 145/260 204/319","f 200/321 148/266 201/320","f 181/247 165/300 180/252","f 182/243 166/302 181/247","f 199/673 149/268 200/321","f 196/323 152/274 197/322","f 185/230 169/308 184/235","f 186/226 170/310 185/230","f 207/674 153/276 196/323","f 192/325 156/282 193/324","f 189/213 173/316 188/218","f 190/209 174/317 189/213","f 191/675 157/284 192/325","f 164/676 163/326 153/328","f 163/326 162/329 154/327","f 162/677 178/331 155/333","f 178/331 179/334 193/332","f 179/334 180/336 194/335","f 184/351 168/338 199/340","f 168/678 167/341 149/343","f 167/341 166/344 150/342","f 166/679 182/346 151/348","f 182/346 183/349 197/347","f 183/349 184/351 198/350","f 171/355 170/352 146/354","f 172/680 171/355 145/356","f 170/681 186/357 147/359","f 186/357 187/360 201/358","f 187/360 188/362 202/361","f 188/362 172/364 203/363","f 159/369 174/366 158/368","f 160/682 159/369 157/370","f 190/376 175/371 205/373","f 175/371 176/374 206/372","f 174/683 190/376 143/377","f 176/374 160/378 191/375","f 180/336 164/380 207/337","f 210/384 193/332 211/382","f 209/684 192/383 210/384","f 208/387 191/375 209/386","f 222/388 206/372 208/387","f 221/390 205/373 222/388","f 220/685 204/389 221/390","f 219/393 203/363 220/392","f 218/394 202/361 219/393","f 217/396 201/358 218/394","f 216/686 200/395 217/396","f 215/399 199/340 216/398","f 214/400 198/350 215/399","f 213/402 197/347 214/400","f 212/687 196/401 213/402","f 223/405 207/337 212/404","f 211/382 194/335 223/405","f 306/493 290/406 224/408","f 328/418 364/409 329/411","f 224/408 305/407 320/416","f 327/635 365/417 328/418","f 320/688 304/420 319/422","f 326/430 366/423 327/425","f 319/422 303/421 318/428","f 325/435 367/429 326/430","f 318/428 302/427 317/433","f 324/440 368/434 325/435","f 317/433 301/432 316/438","f 323/637 353/439 324/440","f 316/689 300/442 315/444","f 322/452 354/445 323/447","f 315/444 299/443 314/450","f 321/457 355/451 322/452","f 314/450 298/449 313/455","f 336/462 356/456 321/457","f 313/455 297/454 312/460","f 335/631 357/461 336/462","f 312/690 296/464 311/466","f 334/474 358/467 335/469","f 311/466 295/465 310/472","f 333/479 359/473 334/474","f 310/472 294/471 309/477","f 332/484 360/478 333/479","f 309/477 293/476 308/482","f 331/633 361/483 332/484","f 308/691 292/486 307/488","f 330/494 362/489 331/491","f 307/488 291/487 306/493","f 329/411 363/410 330/494","f 258/526 227/495 259/497","f 259/497 229/496 260/499","f 260/499 231/498 261/501","f 261/501 233/500 262/503","f 262/503 235/502 263/505","f 263/505 237/504 264/507","f 264/507 239/506 265/509","f 265/509 241/508 266/511","f 266/511 243/510 267/513","f 267/513 245/512 268/515","f 268/515 247/514 269/517","f 269/517 249/516 270/519","f 270/519 251/518 271/521","f 271/521 253/520 272/523","f 272/523 255/522 273/525","f 273/525 257/524 258/526","f 274/562 258/527 275/529","f 275/529 259/528 276/531","f 276/692 260/532 277/534","f 277/534 261/533 278/536","f 278/536 262/535 279/538","f 279/538 263/537 280/540","f 280/693 264/541 281/543","f 281/543 265/542 282/545","f 282/545 266/544 283/547","f 283/547 267/546 284/549","f 284/694 268/550 285/552","f 285/552 269/551 286/554","f 286/554 270/553 287/556","f 287/556 271/555 288/558","f 288/695 272/559 289/561","f 289/561 273/560 274/562","f 291/567 228/563 290/565","f 292/569 230/566 291/567","f 293/571 232/568 292/569","f 294/573 234/570 293/571","f 295/575 236/572 294/573","f 296/577 238/574 295/575","f 297/579 240/576 296/577","f 298/581 242/578 297/579","f 299/583 244/580 298/581","f 300/585 246/582 299/583","f 301/587 248/584 300/585","f 302/589 250/586 301/587","f 303/591 252/588 302/589","f 304/593 254/590 303/591","f 305/594 256/592 304/593","f 290/565 226/564 305/594","f 337/599 240/595 338/597","f 352/638 238/598 337/599","f 351/604 236/600 352/602","f 350/606 234/603 351/604","f 349/608 232/605 350/606","f 348/636 230/607 349/608","f 347/613 228/609 348/611","f 346/615 226/612 347/613","f 345/617 256/614 346/615","f 344/634 254/616 345/617","f 343/622 252/618 344/620","f 342/624 250/621 343/622","f 341/626 248/623 342/624","f 340/632 246/625 341/626","f 339/630 244/627 340/629","f 338/597 242/596 339/630","f 338/597 321/457 337/599","f 339/630 336/462 338/597","f 340/629 335/631 339/630","f 341/626 334/474 340/632","f 342/624 333/479 341/626","f 343/622 332/484 342/624","f 344/620 331/633 343/622","f 345/617 330/494 344/634","f 346/615 329/411 345/617","f 347/613 328/418 346/615","f 348/611 327/635 347/613","f 349/608 326/430 348/636","f 350/606 325/435 349/608","f 351/604 324/440 350/606","f 352/602 323/637 351/604","f 337/599 322/452 352/638","f 354/445 241/639 353/446","f 355/451 243/641 354/445","f 356/456 245/642 355/451","f 357/461 247/643 356/456","f 358/467 249/644 357/468","f 359/473 251/646 358/467","f 360/478 253/647 359/473","f 361/483 255/648 360/478","f 362/489 257/649 361/490","f 363/410 227/651 362/489","f 364/409 229/652 363/410","f 365/417 231/653 364/409","f 366/423 233/654 365/424","f 367/429 235/656 366/423","f 368/434 237/657 367/429","f 353/439 239/658 368/434","f 49/7 94/153 74/8",""]
crosshairX = [-1,-1,1,1]
crosshairY = [-1,1,-1,1]
crosshairU = [0,0,1,1]
crosshairV = [0,1,0,1]
### Blocks
```scratchblocks
when stage clicked
set [held item target angle v] to [-60]
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
3. "uv grid" - a 256x256 png of horizontal left-to-right 0-to-255 red gradient, vertical top-to-bottom 0-to-255 green gradient, and a 4x4 grid on top of the gradient. Top left corner has label U:0 V:0, top right corner has label U:1 V:0, bottom left corner has label U:0 V:1, bottom right corner has label U:1 V:1.
4. "Katana_Base_Color" - base color texture atlas of katana 3D model
5. "crosshair" - plus shaped crosshair
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | create mesh [katana]
Simple3D | set [katana] from [obj mtl v] [katana.obj v]
Simple3D | set [katana] texture (Simple3D | texture from costume (costume Katana_Base_Color)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [crosshair]
Simple3D | set [crosshair] primitives (triangle strip v)
Simple3D | set [crosshair] positions XY [crosshairX v] [crosshairY v]
Simple3D | set [crosshair] texture coordinates UV [crosshairU v] [crosshairV v]
Simple3D | set [crosshair] texture (Simple3D | texture from costume (costume crosshair)) [repeat v] [pixelated v]
Simple3D | set [crosshair] blending (invert v)
forever
controls :: custom
Simple3D | clear (color and depth v)
setup main 3d camera :: custom
draw plane :: custom
draw boxes :: custom
Simple3D | clear (depth v)
setup viewspace 3d camera :: custom
draw katana :: custom
Simple3D | clear (depth v)
setup gui 2d camera :: custom
draw crosshair :: custom
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
define draw plane
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define draw boxes
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by (timer) degrees
Simple3D | wrapper {
Simple3D | move X:(-8) Y:(2.05) Z:(-16)
Simple3D | rotate around [Y v] by (35) degrees
Simple3D | scale X:(2) Y:(2) Z:(2)
Simple3D | draw mesh [box]
}
Simple3D | wrapper {
Simple3D | move X:(32) Y:(4.05) Z:(7)
Simple3D | rotate around [Y v] by (-10) degrees
Simple3D | scale X:(4) Y:(4) Z:(4)
Simple3D | draw mesh [box]
}
define draw katana
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | move X:(0.5) Y:(0) Z:(-0.5) // Camera is facing negative Z. Moving mesh in front of the camera and right
Simple3D | move X:(0) Y:(-0.5) Z:(0) // 3.Undoing the offset
Simple3D | rotate around [X v] by (held item angle) degrees // 2.Rotating around 0,0,0 (handle)
Simple3D | move X:(0) Y:(0.5) Z:(0) // 1.Moving mesh up, so that XYZ 0,0,0 ends up at the handle
Simple3D | scale X:(1) Y:(1) Z:(-1)
Simple3D | draw mesh [katana]
change [held item angle v] by (held item angle vel)
change [held item angle vel v] by (((held item target angle) - (held item angle)) / (20))
if <(held item angle) < [-59]> then
set [held item target angle v] to [0]
end
if <(held item angle) > [0]> then
set [held item target angle v] to [0]
set [held item angle vel v] to [0]
set [held item angle v] to [0]
end
define setup main 3d camera
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.1) far: (1000)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
define setup viewspace 3d camera
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.1) far: (1000)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
define setup gui 2d camera
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
define draw crosshair
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | scale X:(0.1) Y:(0.1) Z:(0)
Simple3D | draw mesh [crosshair]
// Katana model:\nhttps://opengameart.org/content/katana-3\nhttps://3dmodelscc0.com/model/katana\nLicense: CC0
```
# End of misc/holdingAnItem.sb3
# Project: Portals via oblique projection
# Start of misc/obliqueProjection.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Variables
camX = 15.055665501572374
camY = 10.509682751616191
camZ = 15.780029105025768
camRotX = 180
camRotY = 166
X = 18.425982446122394
Y = 10.509682751616193
Z = -11.668999663462428
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxPos1 = []
boxPos2 = []
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Local Variables
_A = 0.24192189559966773
_B = 1.1882695554102554e-16
_C = -0.9702957262759965
_D = -15.780029105025768
_q.x = 1.3333333333333333
_q.y = 1.0000000000000002
_q.z = -1
_q.w = 0.0010000000000002813
_scale = 1.5660747802415842
### Local Lists
_matrix = [0.75,0,0.3788677794868771,0,0,0.9999999999999999,1.8609189828568807e-16,0,0,0,-0.5195556662970295,-1,0,0,-24.712705612859033,0]
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [sky]
Simple3D | set [sky] positions XY [planeX v] [planeY v]
Simple3D | create mesh [plane]
Simple3D | set [plane] positions XY [planeX v] [planeY v]
Simple3D | set [plane] texture coordinates UV [planeU v] [planeV v]
Simple3D | set [plane] texture (Simple3D | texture from costume (costume grid)) [repeat v] [pixelated v]
Simple3D | set [plane] texture mipmapping [smooth transitions v]
Simple3D | set [plane] texture anisotropic filtering (16 v)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] texture (Simple3D | texture from costume (costume box)) [clamp to edge v] [pixelated v]
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
init :: custom
Simple3D | depth test (closer or same v) write (true v)
forever
controls :: custom
Simple3D | transform X:(0) Y:(0) Z:(0) from [world space v] to [view space v]
set [X v] to (Simple3D | transformed [X v])
set [Y v] to (Simple3D | transformed [Y v])
set [Z v] to (Simple3D | transformed [Z v])
Simple3D | transform direction X:(0) Y:(0) Z:(1) from [world space v] to [view space v]
Simple3D | configure [viewToProjected v] transformation
start with oblique perspective FOV: [90] near: [0.1] far: [1000] plane: (Simple3D | transformed [X v]) (Simple3D | transformed [Y v]) (Simple3D | transformed [Z v]) ((0) - ((((X) * (Simple3D | transformed [X v])) + ((Y) * (Simple3D | transformed [Y v]))) + ((Z) * (Simple3D | transformed [Z v])))) :: custom // Oblique perspective projection is used to cut off meshes that too close (closer than the portal from the red world)
Simple3D | clear (color and depth v)
Simple3D | configure [modelToWorld v] transformation
draw sky [0.1] [0] [0] :: custom
Simple3D | set global color [multiplier v] R:(1) G:(0.6) B:(0.6) A:(1)
draw plane :: custom
Simple3D | start with no transformation
Simple3D | draw mesh [boxes1]
Simple3D | clear (depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.1) far: (1000)
Simple3D | configure [modelToWorld v] transformation
Simple3D | set global color [multiplier v] R:(0) G:(0) B:(0) A:(0)
draw portal :: custom
draw sky [0] [0] [0.1] :: custom
Simple3D | set global color [multiplier v] R:(0.6) G:(0.6) B:(1) A:(1)
draw plane :: custom
Simple3D | start with no transformation
Simple3D | draw mesh [boxes2]
end
define controls
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:(0) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
Simple3D | draw mesh [plane]
define controls (6 directions)
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:( - ) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
define draw portal
Simple3D | start with no transformation
Simple3D | scale X:(20) Y:(10) Z:(0)
Simple3D | move X:(0) Y:(1) Z:(0)
Simple3D | draw mesh [plane]
define init
delete all of [boxPos1 v]
delete all of [boxPos2 v]
repeat (30)
add (pick random (-100) to (100)) to [boxPos1 v]
add (pick random (0.5) to (5)) to [boxPos1 v]
add (pick random (-100) to (100)) to [boxPos1 v]
add (item ((length of [boxPos1 v]) - (1)) of [boxPos1 v]) to [boxPos1 v]
add (pick random (-100) to (100)) to [boxPos2 v]
add (pick random (0.5) to (5)) to [boxPos2 v]
add (pick random (-100) to (100)) to [boxPos2 v]
add (item ((length of [boxPos2 v]) - (1)) of [boxPos2 v]) to [boxPos2 v]
end
Simple3D | create mesh [boxes1]
Simple3D | make [boxes1] inherit from meshes [box]
Simple3D | set [boxes1] instance [XYZ positions and sizes v] [boxPos1 v]
Simple3D | create mesh [boxes2]
Simple3D | make [boxes2] inherit from meshes [box]
Simple3D | set [boxes2] instance [XYZ positions and sizes v] [boxPos2 v]
define draw sky (r) (g) (b)
Simple3D | wrapper {
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with no transformation
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | move X:(0) Y:(0) Z:(1)
Simple3D | set global color [multiplier v] R:(r) G:(g) B:(b) A:(1)
Simple3D | draw mesh [sky]
}
define start with oblique perspective FOV: (FOV) near: (NEAR) far: (FAR) plane: (A) (B) (C) (D)
Simple3D | start with perspective FOV: (FOV) near: (NEAR) far: (FAR)
Simple3D | save into [_matrix v] at (1)
if <(D) > [0]> then
set [_A v] to ((0) - (A))
set [_B v] to ((0) - (B))
set [_C v] to ((0) - (C))
set [_D v] to ((0) - (D))
else
set [_A v] to (A)
set [_B v] to (B)
set [_C v] to (C)
set [_D v] to (D)
end
set [_q.x v] to ((((_A) / ([abs v] of (_A))) + (item (9) of [_matrix v])) / (item (1) of [_matrix v]))
set [_q.y v] to ((((_B) / ([abs v] of (_B))) + (item (10) of [_matrix v])) / (item (6) of [_matrix v]))
set [_q.z v] to [-1]
set [_q.w v] to (((1) + (item (11) of [_matrix v])) / (item (15) of [_matrix v]))
set [_scale v] to ((2) / ((((_A) * (_q.x)) + ((_B) * (_q.y))) + (((_C) * (_q.z)) + ((_D) * (_q.w)))))
replace item (3) of [_matrix v] with (((_A) * (_scale)) - (item (4) of [_matrix v]))
replace item (7) of [_matrix v] with (((_B) * (_scale)) - (item (8) of [_matrix v]))
replace item (11) of [_matrix v] with (((_C) * (_scale)) - (item (12) of [_matrix v]))
replace item (15) of [_matrix v] with (((_D) * (_scale)) - (item (16) of [_matrix v]))
Simple3D | start with saved in [_matrix v] at (1)
```
# End of misc/obliqueProjection.sb3
# Section: Overdraw
# Project: With overdraw
# Start of overdraw/overdrawWith.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
2. "dango cat" - default turbowarp sprite - dango cat
### Global Variables
i = 300000
### Global Lists
y = [-1,1,-1,1]
x = [-1,-1,1,1]
instance pos = []
u = [0,0,1,1]
v = [1,0,1,0]
instance vel = []
instance rgb = []
### Blocks
```scratchblocks
when flag clicked
Simple3D | depth test (everything v) write (true v) // Note that here depth test is set to allow everything.\n\nThis demo draws an instanced dango cat, then draws another instance of dango cat on top of it, blending them together, draws the third dango cat on top, while blending it with what is already drawn, ... , and so on 9997 more times.\n\nThis causes every pixel of every dango cat instance to be to be computed, but vast majority of them get overwritten with another fully opaque pixel later, making computations go to waste.\n\nThe result of this is that if multiple instances overlap on the same location, you will see the LAST drawn of them.\n\nNow compare it to the other example.
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | clear (color v)
create [100000] instances :: custom
Simple3D | create mesh [my mesh] // By default blending is set to "default", which blends the already drawn color with the new color based on alpha (transparency).\n\nIt takes a bit of extra video memory bandwidth. To move that data around.
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x v] [y v]
Simple3D | set [my mesh] texture coordinates UV [u v] [v v]
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume dango cat)) [clamp to edge v] [pixelated v]
Simple3D | set [my mesh] instance [XY positions v] [instance pos v]
Simple3D | set [my mesh] instance [RGB colors v] [instance rgb v]
Simple3D | [my mesh] optimize next uploaded list for being (frequently fully v) updated
wait until
Simple3D | configure [worldToView v] transformation
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | scale X:((2) / (runtimeoptions | stage (height v))) Y:((2) / (runtimeoptions | stage (height v))) Z:(1)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | scale X:((Simple3D | mesh [texture width v] [my mesh]) * (0.1)) Y:((Simple3D | mesh [texture height v] [my mesh]) * (0.1)) Z:(1)
forever
step ((runtimeoptions | stage (width v)) / (2)) ((runtimeoptions | stage (height v)) / (2)) :: custom
Simple3D | set [my mesh] instance [XY positions v] [instance pos v]
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
define create (count) instances
delete all of [instance pos v]
delete all of [instance vel v]
delete all of [instance rgb v]
repeat (count)
add (pick random ((runtimeoptions | stage (width v)) / (-2)) to ((runtimeoptions | stage (width v)) / (2))) to [instance pos v]
add (pick random ((runtimeoptions | stage (height v)) / (-2)) to ((runtimeoptions | stage (height v)) / (2))) to [instance pos v]
add (pick random (-1.0) to (1.0)) to [instance vel v]
add (pick random (-1.0) to (1.0)) to [instance vel v]
add (pick random (0.5) to (1.0)) to [instance rgb v]
add (pick random (0.5) to (1.0)) to [instance rgb v]
add (pick random (0.5) to (1.0)) to [instance rgb v]
end
define step (halfWidth) (halfHeight)
set [i v] to [0]
repeat ((length of [instance pos v]) / (2))
replace item ((i) + (1)) of [instance pos v] with ((item ((i) + (1)) of [instance pos v]) + (item ((i) + (1)) of [instance vel v]))
replace item ((i) + (2)) of [instance pos v] with ((item ((i) + (2)) of [instance pos v]) + (item ((i) + (2)) of [instance vel v]))
if <([abs v] of (item ((i) + (1)) of [instance pos v])) > (halfWidth)> then
replace item ((i) + (1)) of [instance vel v] with ((0) - (item ((i) + (1)) of [instance vel v]))
end
if <([abs v] of (item ((i) + (2)) of [instance pos v])) > (halfHeight)> then
replace item ((i) + (2)) of [instance vel v] with ((0) - (item ((i) + (2)) of [instance vel v]))
end
change [i v] by (3)
end
// Configuration for https://turbowarp.org/\nYou can move, resize, and minimize this comment, but don't edit it by hand. This comment can be deleted to remove the stored settings.\n{"framerate":60,"hq":true} // _twconfig_
```
# End of overdraw/overdrawWith.sb3
# Project: Without overdraw
# Start of overdraw/overdrawWithout.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
2. "dango cat" - default turbowarp sprite - dango cat
### Global Variables
i = 300000
### Global Lists
y = [-1,1,-1,1]
x = [-1,-1,1,1]
instance pos = []
u = [0,0,1,1]
v = [1,0,1,0]
instance vel = []
instance rgb = []
### Blocks
```scratchblocks
when flag clicked
Simple3D | depth test (closer v) write (true v) // This block is redundant, because those values are default.\n\nHere, new pixels only get computed and drawn if they are CLOSER than the already drawn pixels at those locations.\n\nSince this is 2D and everything has the same depth, nothing is ever closer, so whichever dango cat was drawn first, ends up occupying those pixels until the end. This way, a lot of pixels fail depth test early, their colors don't get computed and computations don't go to waste.\n\nThe result of this is that if multiple instances overlap on the same location, you will see the FIRST drawn of them.
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | clear (color v)
create [100000] instances :: custom
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] primitives (triangle strip v)
Simple3D | set [my mesh] positions XY [x v] [y v]
Simple3D | set [my mesh] texture coordinates UV [u v] [v v]
Simple3D | set [my mesh] texture (Simple3D | texture from costume (costume dango cat)) [clamp to edge v] [pixelated v]
Simple3D | set [my mesh] instance [XY positions v] [instance pos v]
Simple3D | set [my mesh] instance [RGB colors v] [instance rgb v]
Simple3D | [my mesh] optimize next uploaded list for being (frequently fully v) updated
Simple3D | set [my mesh] discord pixels less opaque than [0.5], for those that pass true // Making all pixels either fully opaque or discarding them before they get to a blending stage.
Simple3D | set [my mesh] blending (overwrite color (fastest for opaque) v) // Since we are dealing with only fully opaque pixels, we don't need blending.\n\nInstead of spending extra time reading the old data from memory to perform blending - it's faster to just overwrite it there right away.\n\nOverall, blending doesn't consume that much speed, but you can get a bit of extra performance by turning it off.
wait until
Simple3D | configure [worldToView v] transformation
Simple3D | start with orthographic near:(-1) far:(1)
Simple3D | scale X:((2) / (runtimeoptions | stage (height v))) Y:((2) / (runtimeoptions | stage (height v))) Z:(1)
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | scale X:((Simple3D | mesh [texture width v] [my mesh]) * (0.1)) Y:((Simple3D | mesh [texture height v] [my mesh]) * (0.1)) Z:(1)
forever
step ((runtimeoptions | stage (width v)) / (2)) ((runtimeoptions | stage (height v)) / (2)) :: custom
Simple3D | set [my mesh] instance [XY positions v] [instance pos v]
Simple3D | clear (color and depth v)
Simple3D | draw mesh [my mesh]
end
define create (count) instances
delete all of [instance pos v]
delete all of [instance vel v]
delete all of [instance rgb v]
repeat (count)
add (pick random ((runtimeoptions | stage (width v)) / (-2)) to ((runtimeoptions | stage (width v)) / (2))) to [instance pos v]
add (pick random ((runtimeoptions | stage (height v)) / (-2)) to ((runtimeoptions | stage (height v)) / (2))) to [instance pos v]
add (pick random (-1.0) to (1.0)) to [instance vel v]
add (pick random (-1.0) to (1.0)) to [instance vel v]
add (pick random (0.5) to (1.0)) to [instance rgb v]
add (pick random (0.5) to (1.0)) to [instance rgb v]
add (pick random (0.5) to (1.0)) to [instance rgb v]
end
define step (halfWidth) (halfHeight)
set [i v] to [0]
repeat ((length of [instance pos v]) / (2))
replace item ((i) + (1)) of [instance pos v] with ((item ((i) + (1)) of [instance pos v]) + (item ((i) + (1)) of [instance vel v]))
replace item ((i) + (2)) of [instance pos v] with ((item ((i) + (2)) of [instance pos v]) + (item ((i) + (2)) of [instance vel v]))
if <([abs v] of (item ((i) + (1)) of [instance pos v])) > (halfWidth)> then
replace item ((i) + (1)) of [instance vel v] with ((0) - (item ((i) + (1)) of [instance vel v]))
end
if <([abs v] of (item ((i) + (2)) of [instance pos v])) > (halfHeight)> then
replace item ((i) + (2)) of [instance vel v] with ((0) - (item ((i) + (2)) of [instance vel v]))
end
change [i v] by (3)
end
// Configuration for https://turbowarp.org/\nYou can move, resize, and minimize this comment, but don't edit it by hand. This comment can be deleted to remove the stored settings.\n{"framerate":60,"hq":true} // _twconfig_
```
# End of overdraw/overdrawWithout.sb3
# Section: Simple3D + Skins extension
# Project: Simple text skins
# Start of extSkins/textSimple.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "costume1" - empty svg
### Blocks
```scratchblocks
when flag clicked
Simple3D | create mesh [my mesh]
Simple3D | set [my mesh] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Handwriting v] of size [128]) color (#00ff15) border (4) (#000000)) [clamp to edge v] [pixelated v]
Simple3D | render to texture of [my mesh]
lmsSkins | load skin from URL (Simple3D | render target [image as data URI v]) as [my skin]
lmsSkins | set skin of [_myself_ f] to [my skin]
```
# End of extSkins/textSimple.sb3
# Project: Textured text skins with gradient
# Start of extSkins/textTextured.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - 480x360 of #0c0a87
### Global Variables
repeat = 32
### Global Lists
fill x = [-1,-1,1,1]
fill y = [-1,1,-1,1]
fill u scaled = [0,0,28.21875,28.21875]
full v scaled = [0,6.25,0,6.25]
fill u = [0,0,1,1]
fill v = [0,1,0,1]
brightness = [255,64,255,64]
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "box1" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
set [repeat v] to [32]
hide
lmscomments | comment [creating base mesh that just covers the entire screen] {
Simple3D | create mesh [cover]
Simple3D | set [cover] primitives (triangle strip v)
Simple3D | set [cover] positions XY [fill x v] [fill y v]
Simple3D | set [cover] texture coordinates UV [fill u v] [fill v v]
}
lmscomments | comment [creating mesh that covers the entire screen and has text] {
Simple3D | create mesh [text]
Simple3D | make [text] inherit from meshes [cover]
Simple3D | set [text] texture (Simple3D | texture from text [Hello World!] font (Simple3D | font [Scratch v] of size [200]) color (#ffffff)) [clamp to edge v] [pixelated v]
Simple3D | set [text] blending (mask v)
}
lmscomments | comment [creating a mesh that covers the entire screen and fills it with repeating texture] {
replace item (3) of [fill u scaled v] with ((Simple3D | mesh [texture width v] [text]) / (repeat))
replace item (4) of [fill u scaled v] with ((Simple3D | mesh [texture width v] [text]) / (repeat))
replace item (2) of [full v scaled v] with ((Simple3D | mesh [texture height v] [text]) / (repeat))
replace item (4) of [full v scaled v] with ((Simple3D | mesh [texture height v] [text]) / (repeat))
Simple3D | create mesh [tex filler]
Simple3D | make [tex filler] inherit from meshes [cover]
Simple3D | set [tex filler] texture (Simple3D | texture from costume (costume box1)) [repeat v] [pixelated v]
Simple3D | set [tex filler] texture coordinates UV [fill u scaled v] [full v scaled v]
Simple3D | set [tex filler] colors RGB [brightness v] [brightness v] [brightness v]
wait until
}
lmscomments | comment [creating resulting image] {
Simple3D | create mesh [result]
Simple3D | set [result] texture (Simple3D | texture of size (Simple3D | mesh [texture width v] [text]) (Simple3D | mesh [texture height v] [text])) [clamp to edge v] [pixelated v]
}
lmscomments | comment [generating result] {
Simple3D | render to texture of [result]
Simple3D | draw mesh [tex filler]
Simple3D | draw mesh [text]
}
lmsSkins | load skin from URL (Simple3D | render target [image as data URI v]) as [my skin]
lmsSkins | set skin of [_myself_ f] to [my skin]
wait until
show
```
# End of extSkins/textTextured.sb3
# Project: Turning 2D costumes into pre-rendered 3D block skins
# Start of extSkins/blocks.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - empty svg
### Global Lists
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
boxBrightness = [114,114,114,114,114,114,114,114,255,255,255,255,255,255,255,255,167,167,167,167,167,167,167,167]
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
3. "box1" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
4. "box2" - lime-colored box
5. "box3" - blue box
6. "box4" - red box
### Local Variables
i = 36
### Blocks
```scratchblocks
when flag clicked
Simple3D | set clear color R:(0) G:(0) B:(0) A:(1)
Simple3D | create mesh [box]
Simple3D | set [box] indices [boxIdx v]
Simple3D | set [box] positions XYZ [boxX v] [boxY v] [boxZ v]
Simple3D | set [box] texture coordinates UV [boxU v] [boxV v]
Simple3D | set [box] colors RGB [boxBrightness v] [boxBrightness v] [boxBrightness v]
Simple3D | set [box] primitives (triangle strip v)
Simple3D | set [box] discord pixels less opaque than [0.1], for those that pass true
Simple3D | create mesh [box1]
Simple3D | make [box1] inherit from meshes [box]
Simple3D | set [box1] texture (Simple3D | texture from costume (costume box1)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box2]
Simple3D | make [box2] inherit from meshes [box]
Simple3D | set [box2] texture (Simple3D | texture from costume (costume box2)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box3]
Simple3D | make [box3] inherit from meshes [box]
Simple3D | set [box3] texture (Simple3D | texture from costume (costume box3)) [clamp to edge v] [pixelated v]
Simple3D | create mesh [box4]
Simple3D | make [box4] inherit from meshes [box]
Simple3D | set [box4] texture (Simple3D | texture from costume (costume box4)) [clamp to edge v] [pixelated v]
wait until
wait until
wait until
wait until
Draw inventory of blocks :: custom
when I start as a clone
Set block skin from costume (join [box] (pick random (1) to (4))) :: custom
set drag mode [draggable v]
define Draw inventory of blocks
set [i v] to [0]
go to x: (-128) y: (48)
repeat (4)
set x to (-128)
repeat (9)
change [i v] by (1)
create clone of (_myself_ v)
change x by (32)
end
change y by (-32)
end
define Set block skin from costume (costume)
Simple3D | create mesh [block image]
Simple3D | set [block image] texture (Simple3D | texture of size (64) (64)) [clamp to edge v] [pixelated v]
Simple3D | render to texture of [block image]
Simple3D | depth test (closer v) write (true v)
Simple3D | set clear color R:(0) G:(0) B:(0) A:(0)
Simple3D | clear (color and depth v)
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with orthographic near:(-2) far:(2)
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | scale X:(0.6) Y:(-0.6) Z:(0.6)
Simple3D | rotate around [X v] by (35) degrees
Simple3D | rotate around [Y v] by (45) degrees
Simple3D | configure [modelToWorld v] transformation
Simple3D | start with no transformation
Simple3D | draw mesh (costume)
lmsSkins | load skin from URL (Simple3D | render target [image as data URI v]) as (join [my skin ] (i))
lmsSkins | set skin of [_myself_ f] to (join [my skin ] (i))
wait until
show
```
# End of extSkins/blocks.sb3
# Section: Simple3D + Pen+ extension
# Project: Using transformation blocks with Pen+ v7 shaders
# Start of extPenPlus/v7.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - 480x360 of #000000
### Global Variables
camX = -2.8843808746558484
camY = 9.157581539729435
camZ = 9.955021352813885
camRotX = 180
camRotY = 162
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,10,0,0,10,10]
planeV = [0,0,10,10,0,10]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
tmp = [6.94580322777171,41.893192318953936,11.77451233442409,0,0,-0.7272878507996765,37.34054022216893,18.731309886860647,1,1,-0.7272878507996765,43.37821686395111,13.482837654936588,1,0]
tmp2 = []
matrix = [3.9967747781213823,0,-0.1605969270340346,0,0,4,0,0,0.1605969270340346,0,3.9967747781213823,0,32.75667147088694,4.05,0.021774948481779965,1]
v7 positions = []
v7 uvs = []
v7 box = ["{\"a_position\":[1,-1,-1,1,-1,-1,-1,1,1,1,-1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,1,1,1,0,0]}","{\"a_position\":[-1,-1,-1,1,1,1,-1,1,-1,1,-1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[1,1,0,0,1,0]}","{\"a_position\":[-1,-1,1,1,1,-1,1,1,-1,1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,1,1,1,0,0]}","{\"a_position\":[1,-1,1,1,-1,1,1,1,1,1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[1,1,0,0,1,0]}","{\"a_position\":[-1,-1,-1,1,1,-1,-1,1,-1,-1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,1,1,1,0,0]}","{\"a_position\":[1,-1,-1,1,-1,-1,1,1,1,-1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[1,1,0,0,1,0]}","{\"a_position\":[1,1,-1,1,-1,1,-1,1,1,1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,1,1,1,0,0]}","{\"a_position\":[-1,1,-1,1,1,1,1,1,-1,1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[1,1,0,0,1,0]}","{\"a_position\":[-1,1,-1,1,-1,-1,-1,1,-1,1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,0,0,1,1,0]}","{\"a_position\":[-1,-1,-1,1,-1,1,1,1,-1,-1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,1,1,0,1,1]}","{\"a_position\":[1,-1,-1,1,1,1,-1,1,1,-1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,1,0,0,1,1]}","{\"a_position\":[1,1,-1,1,1,-1,1,1,1,1,1,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,0,1,1,1,0]}"]
v7 color = []
v7 plane = ["{\"a_position\":[-1,-1,0,1,1,-1,0,1,-1,1,0,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,0,100,0,0,100]}","{\"a_position\":[-1,1,0,1,1,-1,0,1,1,1,0,1],\"a_color\":[1,1,1,1,1,1,1,1,1,1,1,1],\"a_texCoord\":[0,100,100,0,100,100]}"]
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Init Pen+ :: custom
Update perspective projection :: custom
forever
controls (6 directions) :: custom
erase all
Simple3D | configure [modelToWorld v] transformation
draw plane :: custom
draw boxes :: custom
end
Simple3D | when canvas resolution changes
Update perspective projection :: custom
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
v7 plane renderer :: custom
define draw boxes
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by (timer) degrees
Simple3D | wrapper {
Simple3D | move X:(-8) Y:(2.05) Z:(-16)
Simple3D | rotate around [Y v] by (35) degrees
Simple3D | scale X:(2) Y:(2) Z:(2)
v7 cube renderer :: custom
}
Simple3D | wrapper {
Simple3D | move X:(32) Y:(4.05) Z:(7)
Simple3D | rotate around [Y v] by (-10) degrees
Simple3D | scale X:(4) Y:(4) Z:(4)
v7 cube renderer :: custom
}
define controls (6 directions)
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:( - ) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
Simple3D | save into [matrix v] at (1)
penP | set matrix [u_view] in [simple v] to [matrix v] :: pen
define v7 cube renderer
Simple3D | save into [matrix v] at (1)
penP | set matrix [u_model] in [simple v] to [matrix v] :: pen
penP | set texture [u_texture] in [simple v] to [box v] :: pen
penP | draw shader triangles from list [v7 box v] using [simple v] :: pen
define v7 plane renderer
Simple3D | save into [matrix v] at (1)
penP | set matrix [u_model] in [simple v] to [matrix v] :: pen
penP | set texture [u_texture] in [simple v] to [grid v] :: pen
penP | draw shader triangles from list [v7 plane v] using [simple v] :: pen
when I start as a clone
set [GHOST v] effect to (100)
wait (0) seconds
delete this clone
define Init Pen+
show
switch costume to (costume grid)
create clone of (_myself_ v)
switch costume to (costume box)
create clone of (_myself_ v)
hide
define Update perspective projection
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000)
Simple3D | save into [matrix v] at (1)
penP | set matrix [u_projection] in [simple v] to [matrix v] :: pen
```
# End of extPenPlus/v7.sb3
# Project: Using transformation blocks with Pen+ v6 textured triangle blocks
# Start of extPenPlus/v6.sb3
## Sprite: "Stage"
### Costumes
1. "backdrop1" - 480x360 of #000000
### Global Variables
camX = 29.21093914470537
camY = 8.157581539729435
camZ = -9.482151287138171
camRotX = 180
camRotY = 170
i = 30
j = 3
k = "24"
### Global Lists
planeX = [-1,1,-1,-1,1,1]
planeY = [-1,-1,1,1,-1,1]
planeU = [0,100,0,0,100,100]
planeV = [0,0,100,100,0,100]
boxX = [1,-1,1,-1,-1,1,-1,1,-1,1,-1,1,1,-1,1,-1,-1,-1,-1,-1,1,1,1,1]
boxY = [-1,-1,1,1,-1,-1,1,1,-1,-1,-1,-1,1,1,1,1,1,-1,1,-1,-1,1,-1,1]
boxZ = [-1,-1,-1,-1,1,1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1,-1,-1,1,1]
boxIdx = [1,2,3,4,0,5,6,7,8,0,9,10,11,12,0,13,14,15,16,0,17,18,19,20,0,21,22,23,24]
boxU = [0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,0,0,1,1]
boxV = [1,1,0,0,1,1,0,0,1,1,0,0,1,1,0,0,0,1,0,1,1,0,1,0]
tmp = []
### Blocks
```scratchblocks
```
## Sprite: "Sprite1"
### Costumes
1. "grid" - a 16x16 png containing a 2x2 white/grey checkerboard pattern
2. "box" - a 16x16 png of stereotypical box, with border around the edge and X-shape in the middle
### Blocks
```scratchblocks
when flag clicked
Init Pen+ :: custom
Update perspective projection :: custom
forever
controls (6 directions) :: custom
Simple3D | configure [modelToWorld v] transformation
erase all
draw plane :: custom
draw boxes :: custom
end
Simple3D | when canvas resolution changes
Update perspective projection :: custom
define draw plane
Simple3D | start with no transformation
Simple3D | rotate around [X v] by (90) degrees
Simple3D | scale X:(100) Y:(100) Z:(100)
v6 plane renderer :: custom
define draw boxes
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by (timer) degrees
Simple3D | wrapper {
Simple3D | move X:(-8) Y:(2.05) Z:(-16)
Simple3D | rotate around [Y v] by (35) degrees
Simple3D | scale X:(2) Y:(2) Z:(2)
v6 cube render :: custom
}
Simple3D | wrapper {
Simple3D | move X:(32) Y:(4.05) Z:(7)
Simple3D | rotate around [Y v] by (-10) degrees
Simple3D | scale X:(4) Y:(4) Z:(4)
v6 cube render :: custom
}
define controls (6 directions)
set [camRotX v] to (mouse y)
set [camRotY v] to ((0) - (mouse x))
Simple3D | configure [worldToView v] transformation
Simple3D | start with no transformation
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | transform direction X:( - ) Y:( - ) Z:( - ) from [view space v] to [world space v]
change [camX v] by (Simple3D | transformed [X v])
change [camY v] by (Simple3D | transformed [Y v])
change [camZ v] by (Simple3D | transformed [Z v])
Simple3D | start with no transformation
Simple3D | rotate around [X v] by ((0) - (camRotX)) degrees
Simple3D | rotate around [Y v] by ((0) - (camRotY)) degrees
Simple3D | move X:((0) - (camX)) Y:((0) - (camY)) Z:((0) - (camZ))
define v6 cube render
set [i v] to [0]
repeat (6)
repeat (2)
delete all of [tmp v]
set [j v] to [0]
repeat (3)
change [i v] by (1)
change [j v] by (1)
set [k v] to (item (i) of [boxIdx v])
Simple3D | transform X:(item (k) of [boxX v]) Y:(item (k) of [boxY v]) Z:(item (k) of [boxZ v]) from [model space v] to [projected (scratch units) v]
add (Simple3D | transformed [X v]) to [tmp v]
add (Simple3D | transformed [Y v]) to [tmp v]
add (Simple3D | transformed [Z v]) to [tmp v]
add (item (k) of [boxU v]) to [tmp v]
add (item (k) of [boxV v]) to [tmp v]
end
draw triangle with texture [box] :: custom
change [i v] by (-2)
end
change [i v] by (3)
end
define v6 plane renderer
set [i v] to [0]
repeat (2)
delete all of [tmp v]
repeat (3)
change [i v] by (1)
Simple3D | transform X:(item (i) of [planeX v]) Y:(item (i) of [planeY v]) Z:(0) from [model space v] to [projected (scratch units) v]
add (Simple3D | transformed [X v]) to [tmp v]
add (Simple3D | transformed [Y v]) to [tmp v]
add (Simple3D | transformed [Z v]) to [tmp v]
add (item (i) of [planeU v]) to [tmp v]
add (item (i) of [planeV v]) to [tmp v]
end
draw triangle with texture [grid] :: custom
end
when I start as a clone
set [GHOST v] effect to (100)
wait (0) seconds
delete this clone
define Update perspective projection
Simple3D | configure [viewToProjected v] transformation
Simple3D | start with perspective FOV: (90) near: (0.01) far: (1000) // This block implicitly takes aspect ratio of the currently selected render target.
define Init Pen+
penP | turn advanced setting [wValueUnderFlow v] [on v] :: pen
show
switch costume to (costume grid)
create clone of (_myself_ v)
switch costume to (costume box)
create clone of (_myself_ v)
hide
[grid v]
define draw triangle with texture (texture)
penP | set triangle point [1 v]'s [5 v] to (item (3) of [tmp v]) :: pen
penP | set triangle point [1 v]'s [6 v] to (item (3) of [tmp v]) :: pen
penP | set triangle point [1 v]'s [0 v] to (item (4) of [tmp v]) :: pen
penP | set triangle point [1 v]'s [1 v] to (item (5) of [tmp v]) :: pen
penP | set triangle point [2 v]'s [5 v] to (item (8) of [tmp v]) :: pen
penP | set triangle point [2 v]'s [6 v] to (item (8) of [tmp v]) :: pen
penP | set triangle point [2 v]'s [0 v] to (item (9) of [tmp v]) :: pen
penP | set triangle point [2 v]'s [1 v] to (item (10) of [tmp v]) :: pen
penP | set triangle point [3 v]'s [5 v] to (item (13) of [tmp v]) :: pen
penP | set triangle point [3 v]'s [6 v] to (item (13) of [tmp v]) :: pen
penP | set triangle point [3 v]'s [0 v] to (item (14) of [tmp v]) :: pen
penP | set triangle point [3 v]'s [1 v] to (item (15) of [tmp v]) :: pen
penP | draw textured triangle between (item (1) of [tmp v]) (item (2) of [tmp v]), (item (6) of [tmp v]) (item (7) of [tmp v]) and (item (11) of [tmp v]) (item (12) of [tmp v]) with the texture (texture) :: pen
```
# End of extPenPlus/v6.sb3
# Section: Simple3D + Augmented Reality extension
No examples in this section