Advertisement
Guest User

Untitled

a guest
Jul 26th, 2016
58
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 29.27 KB | None | 0 0
  1.  
  2. --# Notes
  3. --[[
  4. ** What is a mesh? **
  5.  
  6. A mesh is a quick way of drawing a shape. It is a set of points which create an outline (or wirefame) of an object
  7. It is made up of triangles (groups of three points)
  8. Triangles are used because a triangle has the smallest number of points that encloses an area
  9. Each triangle corner is known as a VERTEX, and has a position and a colour
  10. The colours of all the points inside the triangle are interpolated from the colours of the three corners
  11.  
  12. This means you can draw quite complex shapes without having to say what colour every pixel is going to be - your program will figure that out itself, just from the colours at the corners of each triangle.
  13.  
  14. ** Should I learn meshes? **
  15.  
  16. When you are starting out with Codea, you don't need to worry about "meshes", because for simple 2D projects,
  17. sprites are usually the simplest option.
  18.  
  19. But as you develop your skills, you should learn about meshes, because
  20. * they are used to draw everything (sprites are meshes),
  21. * you can deform or twist meshes more easily than sprites, because you can move any of the vertices
  22. * if you have hundreds of sprites to draw, a single mesh may draw much faster than sprites, because there
  23. is some setting up before each sprite (which is a mesh) is drawn
  24. * meshes are the only way to draw in 3D
  25.  
  26. So the best approach may be to use sprites until you are very comfortable with 2D graphics, and then
  27. learn about meshes.
  28.  
  29. This set of demos shows you the basics of meshes for 2D graphics. For 3D meshes, see the 3D demo app.
  30. --]]
  31. --# Triangle
  32. --Triangle
  33.  
  34. --in this demo, we'll draw just one triangle, with a different colour at each corner
  35. --so you can see the interpolation
  36.  
  37. function setup()
  38. m=mesh() --always start by creating an empty mesh
  39. --create a table of three vec2(x,y) positions to make a triangle
  40. --vertices must always be in groups of three, making triangles
  41. m.vertices={vec2(300,400),vec2(500,400),vec2(400,560)}
  42. --we'll make each vertex colour different so you can see the interpolation
  43. m.colors={color(255,0,0),color(255,255,0),color(0,255,0)}
  44. --if you wanted ALL the colours to be the same, you can just write this
  45. --m:setColors(color(255,255,0))
  46. end
  47.  
  48. function draw()
  49. background(180)
  50. m:draw() --draws the mesh with the positions and fills it with the colour we defined
  51. end
  52.  
  53. function PrintExplanation()
  54. output.clear()
  55. print("All meshes are made up of triangles.\n\nThis demo creates a mesh of just one triangle in a fixed place")
  56. print("Look at the code for details")
  57. print("When you understand it, choose the next step with the slider at the top, and press the Run button.")
  58. end
  59.  
  60. --# Square
  61. --Square
  62.  
  63. function setup()
  64. m=mesh()
  65. --a square is made up of two triangles next to each other
  66. --a square has 4 corners, and 2 triangles have 6 corners, so two of the vertices get used twice
  67. --the vertices start to get messy, so it's easiest to first define the corners of the square
  68. --I'm doing it in the order - bottom left, bottom right, top left, top right
  69. local bL, bR, tR, tL = vec2(300,400), vec2(500,400), vec2(500,600), vec2(300,600) --positions of corners
  70. --now we create two sets of three vertices to make two triangles
  71. --it is best to list vertices anticlockwise
  72. m.vertices={bL,bR,tR, tR,tL,bL} --can you see how each set of three forms a triangle?
  73. --we'll colour each triangle a different colour
  74. c1, c2 = color(255,0,0), color(255,255,0)
  75. --assign the colours to the six vertices in order, three red then three yellow
  76. m.colors={c1,c1,c1, c2,c2,c2}
  77. end
  78.  
  79. function draw()
  80. background(180)
  81. m:draw()
  82. end
  83.  
  84. function PrintExplanation()
  85. output.clear()
  86. print("Now we create a square made up of two triangles next to each other.")
  87. print("The two triangles are given different colours so you can see them clearly")
  88. end
  89.  
  90. --# AddRect
  91. --Using addRect for rectangles
  92.  
  93. --[[
  94. To make it easier to add rectangles, which are used for many shapes, Codea has some special functions
  95.  
  96. addRect adds a rectangle to a mesh, and there are other functions to make it easy to change the vertex
  97. positions, and even rotate them
  98.  
  99. This demo uses addRect to make a shape from several rectangles to show how easy it is.
  100. --]]
  101. function setup()
  102. m=mesh()
  103. --addRect adds a rectangle
  104. --first two parameters are the centre point, next two are width, height
  105. --we'll build a stick person
  106. m:addRect(400,350,100,200) --body
  107. m:addRect(365,200,30,150)--leg
  108. m:addRect(435,200,30,150) --leg
  109. m:addRect(400,435,350,30) --arms
  110. m:addRect(400,480,50,60) --head
  111. --our mesh now has 5 rectangles, each with 2 triangles of 3 vertices, so it has 5x2x3=30 vertices in total
  112. --Codea creates all these vertices for us
  113. print("Number of vertices = "..m.size) --we'll check this
  114.  
  115. --we'll set all the vertex colours to yellow, we can do this with one command
  116. m:setColors(color(255,255,0))
  117. end
  118.  
  119. function draw()
  120. background(180)
  121. m:draw()
  122. end
  123.  
  124. function PrintExplanation()
  125. output.clear()
  126. print("It's messy working with vertices, so addRect makes it easy to create rectangles")
  127. print("If you made this shape using triangles, you would need to define 10 triangles and 30 vertices, instead of just 5 lines of code!")
  128. end
  129.  
  130. --# Texture
  131. --Adding an image, known as a TEXTURE
  132.  
  133. --[[
  134. We can add a picture to our mesh, rather than a colour.
  135.  
  136. You need to tell Codea which part of the texture image is at each vertex in the mesh, as a fraction 0-1
  137. An image texture is a rectangle, and the positions of its corners are
  138. bottom left = (0,0)
  139. bottom right = (1,0) ie all the way to the right, on the bottom
  140. top left = (0,1) ie on the left, all the way to the top
  141. top right = (1,1) ie all the way to the right and all the way up
  142.  
  143. So if a picture is 100x200 pixels, and a vertex is at (50,150) on the picture, then the texture position
  144. is (0.5,0.75) ie (50/100,150/200)
  145.  
  146. You must set these positions for each vertex, but if you create your rectangles with addRect, and if your rectangle
  147. uses the whole picture, Codea will do all the work for you.
  148. --]]
  149.  
  150. function setup()
  151. m=mesh()
  152. --choose a picture to draw (change it if you like)
  153. img=readImage("Planet Cute:Character Princess Girl")
  154. m:addRect(400,400,img.width,img.height) --same size as image
  155. --let's add a second one, twice the size
  156. --Codea will scale the image to the size of the rectangle
  157. m:addRect(250,250,img.width*2,img.height*2)
  158. m.texture=img --it's this easy to use an image
  159. --it will be used for all the rectangles on this mesh
  160. --there's no need to set the texture positions if we use addRect, because Codea will do it for us
  161. --the only time you need to do it yourself is if you don't want to use the whole image
  162. --we'll look at that option later
  163. end
  164.  
  165. function draw()
  166. background(180)
  167. m:draw()
  168. end
  169.  
  170. function PrintExplanation()
  171. output.clear()
  172. print("We can use a texture (ie picture) instead of colours on our rectangles")
  173. end
  174.  
  175. --# Tiling
  176. --Using the same image repeatedly to "tile" an area
  177.  
  178. --[[
  179. If you add rectangles with addRect and a texture image, you can create a tiled effect, repeating the image
  180. across an area. That's because Codea will use the texture image for EACH rectangle in the mesh.
  181.  
  182. The demo below creates a castle like this.
  183.  
  184. But there is one problem. We want to create a floor, a castle, and soldiers, each with different texture images.
  185. However, a mesh can only have one texture image attached.
  186.  
  187. One solution is to create a separate mesh for each image, and that's what we'll do here.
  188. In the next demo, we'll show a different solution.
  189. --]]
  190.  
  191.  
  192. function setup()
  193. x,y=100,100 --start drawing here
  194. size=70 --size of tiles
  195. SetupMeshes()
  196. end
  197.  
  198. function SetupMeshes()
  199. --create one mesh for the bottom layer, a grassy surface
  200. local imgFloor=readImage("Platformer Art:Block Grass")
  201. floor=mesh()
  202. for i=1,8 do --calculate positions and add rectangles
  203. local xx=x+(i-0.5)*size --mid point of rectangle
  204. floor:addRect(xx,y+size/2,imgFloor.width,size)
  205. end
  206. floor.texture=imgFloor
  207.  
  208. --another mesh for the brick castle
  209. local imgBlock=readImage("Platformer Art:Block Brick")
  210. --problem - image has round edges that leave gaps when we stack them, so trim the edges off
  211. imgBlock=imgBlock:copy(3,3,imgBlock.width-6,imgBlock.height-6)
  212.  
  213. castle=mesh()
  214. castle.texture=imgBlock
  215. --we'll build a castle, 6 blocks wide by 7 high, with some gaps for windows and the castle top
  216. --here is a map of the castle in a table
  217. map={}
  218. map[1]="bs b" --mark each block position with a "b", and each soldier with "s", gaps with " "
  219. map[2]="bbbbbb" --you can change these if you like
  220. map[3]="bbbbsb"
  221. map[4]="bbbbbb"
  222. map[5]="bsbbbb"
  223. map[6]="bbbbbb"
  224. map[7]="bbssbb"
  225.  
  226. --create a separate mesh for soldiers
  227. imgSoldier=readImage("Planet Cute:Character Boy")
  228. soldiers=mesh()
  229. soldiers.texture=imgSoldier
  230.  
  231. --read the map and add soldiers and blocks to their meshes
  232. for i=1,#map do
  233. local yy = y+size*(#map-i+3/2) --y position of this block
  234. for j=1,map[i]:len() do
  235. local xx = x+(j+0.5)*size --x position of this block
  236. local a=map[i]:sub(j,j) --get map character (b, s or blank)
  237. if a~=" " then
  238. if a=="b" then castle:addRect(xx,yy,size,size)
  239. elseif a=="s" then soldiers:addRect(xx,yy,imgSoldier.width,imgSoldier.height)
  240. end
  241. end
  242. end
  243. end
  244. end
  245.  
  246. function draw()
  247. background(170, 194, 211, 255)
  248. floor:draw()
  249. soldiers:draw()
  250. castle:draw()
  251. end
  252.  
  253. function PrintExplanation()
  254. output.clear()
  255. print("We can 'tile' images using a mesh")
  256. end
  257.  
  258. --# Tilemap
  259. --Using several images on one texture
  260.  
  261. --[[
  262. A problem with meshes is that each can only have ONE texture image attached
  263. In the previous demo, we made a separate mesh for each texture image.
  264. But there is another way that is used by most game developers.
  265.  
  266. We put all the pictures into a single image, put all our rectangles into one mesh using that image,
  267. and then tell Codea which part of the image to use for each rectangle.
  268.  
  269. A combined image of this kind is often called a spritesheet
  270. Normally, you'll create the spritesheet beforehand, but we'll do it as part of this demo
  271.  
  272. Then we'll add some rectangles, and tell Codea which part of the image to use for each of them
  273. if we used addRect, Codea provides a function setRectTex to add texture positions for each rectangle
  274. We give it the x,y value of the bottom left corner, and the width and height
  275. All these values need to be a fraction of width and height, ie between 0 and 1
  276.  
  277. Note - is it better to use a spritesheet or separate meshes? A single mesh draws faster than many separate meshes,
  278. although the difference is so small that you probably won't notice until you have hundreds of rectangles.
  279. Most of the time, it doesn't matter, and you can choose whichever suits you best.
  280. --]]
  281.  
  282. function setup()
  283. --combine three pictures into one image
  284. img,imgPos=MakeSpriteSheet() --returns the image, and the positions of the three pictures on that image
  285. --now our mesh
  286. m=mesh()
  287. --add three rectangles
  288. m:addRect(200,350,101,171)
  289. m:addRect(300,450,101,171)
  290. m:addRect(400,550,101,171)
  291. m.texture=img --set the texture image
  292. --now we need to use setRectTex to tell Codea which part of the image to use for each rectangle
  293. --the values have to be fractions of width and height, so let's get the width and height of the total image
  294. local w,h=img.width,img.height
  295. --loop through all the rectangles and add texture positions to them
  296. for i=1,3 do
  297. --get the texture positions for this rectangle (give it a short name to make the code below easier to read)
  298. local p=imgPos[i]
  299. --because there are three rectangles created with addRect, we need to tell Codea which one we want
  300. --Codea numbers them 1,2,3... in the order they are created
  301. --we'll use the pictures in the same order as the rectangles, ie the left hand picture will be used
  302. --for the first rectangle, so we can simply use our looping counter i as the rectangle number
  303. --that's why the first item in brackets below is i, it tells Codea which rectangle we want
  304. --the other items are the x,y position of the bottom left corner, and width and height
  305. --all of these must be fractions 0-1, which is why I divide by w and h
  306. m:setRectTex(i, p.pos.x/w, p.pos.y/h, p.w/w, p.h/h)
  307. end
  308. end
  309.  
  310. function draw()
  311. background(180)
  312. fill(0)
  313. text("These three rectangles\nare on a single mesh",200,500)
  314. m:draw()
  315.  
  316. --draw the spritesheet as well
  317. text("..using this texture image which has three pictures on it",250,200)
  318. sprite(img,50,50)
  319. end
  320.  
  321. --the MakeSpriteSheet function creates the image and gives us a table of positions (imgPos) for each picture
  322. --There are three items in imgPos, which we need for setting texture positions in the mesh
  323. --pos (x,y position of bottom left corner),
  324. --w (width) in pixels, and
  325. --h (height) in pixels
  326. function MakeSpriteSheet()
  327. --make a list of the pics we want
  328. pics={"Planet Cute:Character Boy","Planet Cute:Character Pink Girl","Planet Cute:Character Princess Girl"}
  329. --they are all 101 x 171 pixels, and we'll draw them in a row from left to right
  330. --we'll leave a few pixels in between, drawing them 105 pixels apart, so we need an image 315 x171 pixels
  331. local img=image(315,171)
  332. setContext(img) --tell Codea to draw on this image instead of the screen
  333. local imgPos={} --make a table to tell us how to find these images later
  334. --we'll store the bottom left x and y, width, height
  335. --naming the table items makes the code easier to use later
  336. imgPos[1]={pos=vec2(0,0), w=101,h=171}
  337. imgPos[2]={pos=vec2(105,0),w=101,h=171}
  338. imgPos[3]={pos=vec2(210,0),w=101,h=171}
  339. --sprite command usually needs the mid point position of each image, but we only have the bottom left corner
  340. --so we can tell sprite to use that instead
  341. spriteMode(CORNER)
  342. for i=1,3 do
  343. sprite(pics[i],imgPos[i].pos.x,imgPos[i].pos.y)
  344. end
  345. setContext() --stop drawing on the image
  346. return img,imgPos --return the image and the positions of the pictures
  347. end
  348.  
  349. function PrintExplanation()
  350. output.clear()
  351. print("We can use several different pictures in a mesh, by first combining them into one image")
  352. end
  353.  
  354. --# Moving_1
  355. --Moving our rectangles
  356.  
  357. --[[
  358. We have several rectangles in a mesh
  359. Now how do we move them and rotate them, especially if they are all moving differently?
  360.  
  361. There is a special setRect command for this, if we've added the rectangles with addRect
  362.  
  363. We'll use the previous example of three images and a spritesheet, in this demo, and move and rotate them
  364. --]]
  365.  
  366. function setup()
  367. img,imgPos=MakeSpriteSheet() ---same as previous demo
  368. SetupMesh() --put all the mesh code in its own function to keep it tidy
  369. end
  370.  
  371. function SetupMesh()
  372. --you can do this first part any way you like
  373. rects={} --a table to hold position and movement details for all our rectangles
  374. --note the items are named, to make the code easier to follow when we draw
  375. --pos=current position,
  376. --vel=velocity (is added to pos each time we draw)
  377. --angle=rotation angle,
  378. --rot=change in rotation, ie we add rot to angle when we draw
  379. rects[1] = {pos=vec2(200,350), vel=vec2(0.1,0.2), angle=0, rot=0.1}
  380. rects[2] = {pos=vec2(300,450), vel=vec2(0.1,-0.1), angle=0, rot=-0.3}
  381. rects[3] = {pos=vec2(400,550), vel=vec2(-0.1,-0.2), angle=0, rot=0.2}
  382.  
  383. --now the mesh
  384. m=mesh()
  385. --add our three rectangles
  386. --we can position them all at 0,0 because we will be changing their positions every frame
  387. --When we change the positions, we will need to tell Codea which rectangle to change
  388. --It is a good idea to store the rectangle number while we are creating it, because in more complex
  389. --projects, we may be working with hundreds of rectangles
  390. --Codea helps us by returning the rectangle number when you use addRect, so we'll store that to use later
  391. for i=1,3 do
  392. rects[i].id = m:addRect(0,0,101,171)
  393. end
  394. m.texture = img --and the texture image
  395. --this next part is the same as the last demo, we set the texture positions for each rectangle
  396. local w,h = img.width,img.height
  397. for i=1,3 do
  398. local p = imgPos[i]
  399. m:setRectTex(rects[i].id, p.pos.x/w, p.pos.y/h, p.w/w, p.h/h)
  400. end
  401. end
  402.  
  403. function draw()
  404. background(180)
  405. --reposition and rotate all our rectangles using setRect
  406. for i=1,#rects do
  407. local r=rects[i] --put the position details for this rect into r to make the code below easier to read
  408. --setRect parameters are rectangle number, x,y position, width, height, rotation angle in radians
  409. m:setRect(i, r.pos.x, r.pos.y, 101, 171, math.rad(r.angle)) --pretty easy, huh?
  410. --update position and rotation for this rectangle
  411. r.pos = r.pos+r.vel
  412. r.angle = r.angle+r.rot
  413. end
  414. m:draw()
  415. end
  416.  
  417. function MakeSpriteSheet() --same as the last demo
  418. --make a list of the pics we want
  419. pics={"Planet Cute:Character Boy","Planet Cute:Character Pink Girl","Planet Cute:Character Princess Girl"}
  420. --they are all 101 x 171 pixels, and we'll draw them in a row from left to right
  421. --we'll leave a few pixels in between, drawing them 105 pixels apart, so we need an image 315 x171 pixels
  422. local img=image(315,171)
  423. setContext(img) --tell Codea to draw on this image instead of the screen
  424. local imgPos={} --make a table to tell us how to find these images later
  425. --we'll store the start x, start y, width, height
  426. --naming the table items makes the code easier to use later
  427. imgPos[1]={pos=vec2(0,0), w=101,h=171}
  428. imgPos[2]={pos=vec2(105,0),w=101,h=171}
  429. imgPos[3]={pos=vec2(210,0),w=101,h=171}
  430. --sprite command usually needs the mid point position of each image, but we only have the bottom left corner
  431. --so we can tell sprite to use that instead
  432. spriteMode(CORNER)
  433. for i=1,3 do
  434. sprite(pics[i],imgPos[i].pos.x,imgPos[i].pos.y)
  435. end
  436. setContext() --stop drawing on the image
  437. return img,imgPos --return the image and the positions of the pictures
  438. end
  439.  
  440.  
  441. function PrintExplanation()
  442. output.clear()
  443. print("We can easily move and rotate our rectangle images")
  444. end
  445.  
  446. --# Moving_2
  447. --Moving and rotating a whole mesh
  448.  
  449. --[[
  450. If you want to move and rotate a whole mesh, maybe with several objects, this is the way to do it
  451.  
  452. 1. When you create your mesh, centre it on (0,0). Your mesh will rotate around a point, usually the centre of the
  453. mesh - make this (0,0). You don't need to make a vertex for it, but all your other points must be positioned
  454. relative to it.
  455. For example, if you have a 100 x 50 rectangle, then if its centre is at (0,0), the four corners will be at
  456. (-50,-25), (50,-25), (50,25), (-50,25)
  457.  
  458. 2. Before drawing, "translate" to the position you want. This redefines the point (0,0) as that position, and if
  459. you now draw your mesh [which is centred on (0,0) ] it will actually draw at the translated position. If it
  460. sounds confusing, imagine you are drawing on a sheet of paper, and the position (0,0) is under your hand,
  461. where it is easiest to draw. You want to draw something in the top left corner, which means stretching and
  462. not drawing as well. So instead, you pull the paper toward you, so the top left corner is under your hand. You
  463. have just "translated" [your drawing position] to the top left corner.
  464.  
  465. If we couldn't translate like this, we would have to adjust the position of EVERY vertex before drawing - and
  466. when you have meshes with thousands of vertices, that is a lot of work! And if the mesh is rotating...!!
  467.  
  468. 3. After translating, rotate, and then draw. Imagine our piece of paper again. We've pulled it toward us so the
  469. place we want to draw is under our hand. But we want to draw something at an angle of 30 degrees. So we turn
  470. the paper around that point by 30 degrees, so now we can draw the image the right way up.
  471.  
  472. 4. When we're done, reverse the rotation and translation. Codea does this using two oddly named functions
  473. pushMatrix() --stores the current screen settings
  474. popMatrix --puts back the screen settings you stored with pushMatrix
  475. The names push and pop are chosen because the settings are stored in a "stack", and the usual names for
  476. adding to a stack and getting items from it, are "push" and "pop"
  477.  
  478. This demo shows how to do this using the stick figure from an earlier demo
  479. --]]
  480.  
  481. function setup()
  482. --create the stick figure from the addRect demo, centred on (0,0)
  483. --the previous stick figure is not centred on (0,0), so how did I know where the middle was?
  484. --I cheated by getting the previous demo to add up all the vertices, and took the average, which was (400,333)
  485. --I subtracted this from all the vertex positions, to centre the figure on (0,0)
  486. m=mesh()
  487. m:addRect(0,17,100,200) --body
  488. m:addRect(-35,-133,30,150)--leg
  489. m:addRect(35,-133,30,150) --leg
  490. m:addRect(0,102,350,30) --arms
  491. m:addRect(0,147,50,60) --head
  492. m:setColors(color(255,255,0))
  493.  
  494. --we'll make it move slowly across the screen, and rotate
  495. pos = vec2(150,150) --starting position
  496. posChange = vec2(0.3,0.2) --how far it moves each time we draw
  497. angle = 0 --rotation angle
  498. angleChange=0.1 --change in angle each time we draw
  499. end
  500.  
  501. function draw()
  502. background(200)
  503. pushMatrix() --store screen settings
  504. translate(pos.x,pos.y)
  505. rotate(angle)
  506. m:draw()
  507. popMatrix() --restore screen settings
  508. --update position and angle
  509. pos=pos+posChange
  510. angle=angle+angleChange
  511. end
  512.  
  513. function PrintExplanation()
  514. output.clear()
  515. print("Moving and rotating a whole mesh is a little different")
  516. end
  517. --# Curves
  518. --Curves (when addRect is not enough - creating your own mesh, vertex by vertex)
  519.  
  520. --[[
  521. Because meshes use triangles with straight edges, rectangular objects are the easiest to make in 3D (which is why
  522. Minecraft looks the way it does), and addRect is very useful. But what if you need to draw other shapes, like
  523. curves?
  524.  
  525. VERTICES
  526.  
  527. You will have to set all the vertices yourself, grouped into triangles, and if you want a smooth curve, you may
  528. need a lot of them.
  529.  
  530. There is a special triangulate command in Codea that may help. If you give it a table of points which make a shape (the points must be in clockwise or anticlockwise order), it will return a set of triangles that can be used in a mesh.
  531.  
  532. TEXTURE IMAGE
  533.  
  534. Then, if you want to attach an image to the mesh, you have to define all the texture positions for each vertex.
  535.  
  536. Generally, in 2D, it's easiest to use rectangles with curved texture images, to create smooth curves (eg to create a circle, make a picture of a circle and add it as a texture on a mesh rectangle).
  537.  
  538. THIS DEMO
  539.  
  540. We'll create a circular set of points - you choose how many points using the parameter slider - and use the
  541. triangulate command to make mesh triangles from these points. Each triangle will be a different colour so you can see how they were created.
  542.  
  543. You can turn on the Texture option to see an image put onto this circular mesh, instead of colours. This requires
  544. us to set texture positions for each point in our mesh.
  545. --]]
  546.  
  547. function setup()
  548. parameter.integer("Points",5,100,5,MakePizza)
  549. parameter.boolean("ShowTriangle",false,MakePizza)
  550. parameter.boolean("UseTexture",false,MakePizza)
  551. end
  552.  
  553. --makes a circular mesh
  554. function MakePizza()
  555. --r is radius, n is number of points
  556. r,n=300,Points
  557. pizza=mesh()
  558. v={}
  559. for i=1,n do
  560. --calculate x,y position of point
  561. local a=2*math.pi*i/n --angle in radians
  562. --yes, time for high school math again!
  563. v[i]=vec2(r*math.sin(a), r*math.cos(a))
  564. end
  565. pizza.vertices=triangulate(v)
  566.  
  567. --if UseTexture is set, define texture positions for each point in the mesh
  568. if UseTexture then
  569. local img=readImage("Cargo Bot:Starry Background") --pick a square image to put on the circle
  570. --imagine laying the image on top of the circle and resizing it, so the circle just fits inside it
  571. --the middle of the circle - which is the point (0,0) - will be at the middle of the image
  572. --the width of the image will equal the radius of the circle
  573. --the texture positions are fractions (0-1) of the width of the image
  574. --to turn our screen positions into texture positions, this is the adjustment
  575. --texture position of point(x,y) = (0.5,0.5) + (x,y) * 0.5/r
  576. --we start at (0.5,0.5) because this is the texture equivalent of the circle centre of (0,0)
  577. --then we divide by r, and divide by 2 because our radius r is half the width (or height)
  578. --perhaps you can start to see how meshes can get tricky!
  579. t={}
  580. for i=1,pizza.size do --m.size tells us how many vertices there are (same as #pizza.vertices)
  581. --when you store vertices in a mesh, it is done as a vec3, we need a vec2, ie just the x,y part
  582. local p=vec2(pizza.vertices[i].x,pizza.vertices[i].y) --get the vertex position as a vec2
  583. t[i]=vec2(0.5,0.5) + p*0.5/r
  584. end
  585. pizza.texCoords=t
  586. pizza.texture=img
  587. pizza:setColors(color(255)) --remove individual triangle colours
  588. elseif ShowTriangle then --colour each slice(ie each triangle of three vertices) a different colour
  589. colors={}
  590. for i=1,pizza.size,3 do --m.size tells us how many vertices there are (same as #pizza.vertices)
  591. local c=color(math.random(0,255),math.random(0,255),math.random(0,255))
  592. colors[i],colors[i+1],colors[i+2]=c,c,c
  593. end
  594. pizza.colors=colors
  595. pizza.texCoords,pizza.texture=nil,nil --remove texture if we were using one
  596. else --just use once colour for the whole shape
  597. pizza:setColors(color(186, 88, 181, 255))
  598. end
  599. end
  600.  
  601. function draw()
  602. background(200)
  603. translate(WIDTH/2,HEIGHT/2)
  604. pizza:draw()
  605. end
  606.  
  607. function PrintExplanation()
  608. output.clear()
  609. print("This demo draws a circle - you can adjust the number of points")
  610. print("The triangulate function is used to make triangles from a set of points")
  611. print("The ShowTriangle parameter gives each triangle a different colour")
  612. print("The UseTexture parameter attaches an image texture")
  613. end
  614. --# 3D
  615. --[[
  616. Some 3D objects have thousands of vertices, which is why most people create them using a
  617. program like Blender, which does the hard work for you.
  618.  
  619. one of the hardest in 3D is a sphere,
  620. especially if you want to wrap an image around it.
  621.  
  622. The very basic 3D demo below draws a 3D block. Even with a simple block, you can see how much work it is!
  623. To learn more, look at the 3D demo app.
  624. --]]
  625.  
  626. function setup()
  627. img=readImage("Platformer Art:Block Brick")
  628. --make it square by trimming off the bottom
  629. img=img:copy(3,3,img.width-6,img.height-6)
  630. b=MakeBlock(30,20,10,img)
  631. r,dr=vec3(0,0,0),vec3(0.2,-0.33,0.27)
  632. end
  633.  
  634. function draw()
  635. background(150)
  636. perspective() --turn on 3D
  637. camera(-10,10,100,0,0,0)
  638. rotate(r.x,1,0,0)
  639. rotate(r.y,0,1,0)
  640. rotate(r.z,0,0,1)
  641. b:draw()
  642. r=r+dr
  643. end
  644.  
  645. function MakeBlock(w,h,d) --width,height,depth
  646. local m=mesh()
  647. --define the 8 corners of the block ,centred on (0,0,0)
  648. local fbl=vec3(-w/2,-h/2,d/2) --front bottom left
  649. local fbr=vec3(w/2,-h/2,d/2) --front bottom right
  650. local ftr=vec3(w/2,h/2,d/2) --front top right
  651. local ftl=vec3(-w/2,h/2,d/2) --front top left
  652. local bbl=vec3(-w/2,-h/2,-d/2) --back bottom left (as viewed from the front)
  653. local bbr=vec3(w/2,-h/2,-d/2) --back bottom right
  654. local btr=vec3(w/2,h/2,-d/2) --back top right
  655. local btl=vec3(-w/2,h/2,-d/2) --back top left
  656. --now create the 6 faces of the block, each is two triangles with 3 vertices (arranged anticlockwise)
  657. --so that is 36 vertices
  658. --for each face, I'm going to start at bottom left, then bottom right, then top right, and for the second
  659. --triangle, top right, top left, then bottom left
  660. m.vertices={
  661. fbl,fbr,ftr, ftr,ftl,fbl, --front face
  662. bbl,fbl,ftl, ftl,btl,bbl, --left face
  663. fbr,bbr,btr, btr,ftr,fbr, --right face
  664. ftl,ftr,btr, btr,btl,ftl, --top face
  665. bbl,bbr,fbr, fbr,fbl,bbl, --bottom face
  666. bbr,bbl,btl, btl,btr,bbr --back face
  667. }
  668. --add texture positions, we will use the same image for each face so we only need 4bcorner positions
  669. local bl,br,tr,tl=vec2(0,0),vec2(1,0),vec2(1,1),vec2(0,1)
  670. local t={}
  671. for i=1,6 do --use a loop to add texture positions for each face, as they are the same for each face
  672. t[#t+1]=bl
  673. t[#t+1]=br
  674. t[#t+1]=tr
  675. t[#t+1]=tr
  676. t[#t+1]=tl
  677. t[#t+1]=bl
  678. end
  679. m.texCoords=t
  680. m.texture=img
  681. m:setColors(color(200))
  682. return m
  683. end
  684.  
  685. function PrintExplanation()
  686. output.clear()
  687. print("A simple 3D block mesh")
  688. end
  689.  
  690. --# Main
  691. -- MultiStep
  692.  
  693. function setup()
  694. steps = listProjectTabs()
  695. if steps[1]=="Notes" then table.remove(steps,1) end --remove first tab if named Notes
  696. table.remove(steps) --remove the last tab
  697. startStep()
  698. global = "select a step"
  699. end
  700.  
  701. function showList()
  702. output.clear()
  703. for i=1,#steps do print(i,steps[i]) end
  704. end
  705.  
  706. function startStep()
  707. if cleanup then cleanup() end
  708. lastStep=Step or readProjectData("lastStep") or 1
  709. lastStep=math.min(lastStep,#steps)
  710. saveProjectData("lastStep",lastStep)
  711. parameter.clear()
  712. parameter.integer("Step", 1, #steps, lastStep,showList)
  713. parameter.action("Run", startStep)
  714. loadstring(readProjectTab(steps[Step]))()
  715. if PrintExplanation then PrintExplanation() end
  716. setup()
  717. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement