Difference between revisions of "Libs3D Mesh"

From GiderosMobile
 
(3 intermediate revisions by the same user not shown)
Line 3: Line 3:
 
__TOC__
 
__TOC__
  
=== I am 3D ===
+
== I am 3D ==
 
First and foremost, for 3D, we set our application as such. There are many ways to tell our application be 3D:
 
First and foremost, for 3D, we set our application as such. There are many ways to tell our application be 3D:
* application configureFrustum
+
* application ''configureFrustum''
* Matrix orthographicProjection
+
* Matrix ''orthographicProjection''
* Matrix perspectiveProjection
+
* Matrix ''perspectiveProjection''
* Viewport setProjection
+
* Viewport ''setProjection''
  
 
Let's see some of those making our first steps in Gideros 3D.
 
Let's see some of those making our first steps in Gideros 3D.
  
 +
== Flat 3D ==
 
=== A Triangle ===
 
=== A Triangle ===
As seen above, first we set our application 3D.
+
As seen above, first we set our application 3D: ''configureFrustum''.
  
Then, the '''Mesh''' class is used to create and display custom constructed set of triangles (triangle meshes).
+
The '''Mesh''' class is used to create and display custom constructed triangles (triangle meshes).
  
 
A triangle is:
 
A triangle is:
* an array of 3 vertices with an x and y position: '''setVertexArray'''
+
* an array of 3 vertices with an x and y position: ''setVertexArray''
* those 3 vertices connect to make a face (ClockWise): '''setIndexArray'''
+
* those 3 vertices connect to make a face (ClockWise): ''setIndexArray''
* optionally coloring each vertex (color and alpha): '''setColorArray'''
+
* optionally coloring each vertex (color and alpha): ''setColorArray''
  
 
'''The code''':
 
'''The code''':
Line 30: Line 31:
  
 
local mesh = Mesh.new()
 
local mesh = Mesh.new()
stage:addChild(mesh)
 
  
 
mesh:setVertexArray(
 
mesh:setVertexArray(
Line 46: Line 46:
 
)
 
)
  
 +
-- ok
 
mesh:setPosition(12*16, 8*16, -1*16)
 
mesh:setPosition(12*16, 8*16, -1*16)
 +
stage:addChild(mesh)
 +
 
mesh:addEventListener(Event.ENTER_FRAME, function(e)
 
mesh:addEventListener(Event.ENTER_FRAME, function(e)
 
mesh:setRotationX(mesh:getRotationX()+1)
 
mesh:setRotationX(mesh:getRotationX()+1)
Line 55: Line 58:
  
 
[[File:3d_triangle.png|414px]]
 
[[File:3d_triangle.png|414px]]
 
3D is all about triangles. You combine triangles to build other 3D shapes like cubes, spheres, cones, ...
 
  
 
=== A Rectangle ===
 
=== A Rectangle ===
Line 67: Line 68:
  
 
local mesh = Mesh.new()
 
local mesh = Mesh.new()
stage:addChild(mesh)
 
  
 
mesh:setVertexArray(
 
mesh:setVertexArray(
Line 86: Line 86:
 
)
 
)
  
 +
-- ok
 
mesh:setPosition(12*16, 8*16, -1*16)
 
mesh:setPosition(12*16, 8*16, -1*16)
 +
stage:addChild(mesh)
 +
 
mesh:addEventListener(Event.ENTER_FRAME, function(e)
 
mesh:addEventListener(Event.ENTER_FRAME, function(e)
 
mesh:setRotationX(mesh:getRotationX()+1)
 
mesh:setRotationX(mesh:getRotationX()+1)
Line 94: Line 97:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== WIP ===
+
=== A Cube ===
 +
In Gideros, a simple Sprite can be cube:
 +
* '''we set the application 3D'''
 +
* we create a local function to make the faces for our cube using Shape
 +
* we add six faces (with appropriate rotation) to a parent Sprite
 +
* and we are cube ;-)
 +
<syntaxhighlight lang="lua">
 +
application:setBackgroundColor(0x323232)
 +
 
 +
-- configure the field of view for 3D projection
 +
application:configureFrustum(45) -- (fov, farplane)
 +
 
 +
-- create faces for a cube
 +
local function face(color, rx, ry)
 +
local s = Shape.new()
 +
s:setFillStyle(Shape.SOLID, color, 0.7) -- translucent color
 +
s:beginPath()
 +
s:moveTo(-1,-1)
 +
s:lineTo(-1,1)
 +
s:lineTo(1,1)
 +
s:lineTo(1,-1)
 +
s:lineTo(-1,-1)
 +
s:endPath()
 +
-- orientation
 +
s:setRotationX(rx)
 +
s:setRotationY(ry)
 +
-- offset position -1 along its local Z axis
 +
s:setPosition(s:getMatrix():transformPoint(0, 0, -1))
 +
 
 +
return s
 +
end
 +
 
 +
-- a cube with 6 faces
 +
cube = Sprite.new()
 +
cube:addChild(face(0xFF8080, 0,0)) -- color, rx, ry
 +
cube:addChild(face(0xFFFF00, 90,0)) -- color, rx, ry
 +
cube:addChild(face(0xFF00FF, -90,0)) -- color, rx, ry
 +
cube:addChild(face(0x80FF80, 180,0)) -- color, rx, ry
 +
cube:addChild(face(0x00FFFF, 0,90)) -- color, rx, ry
 +
cube:addChild(face(0x8080FF, 0,-90)) -- color, rx, ry
 +
 
 +
-- enable depth sorting for translucency
 +
cube:setAutoSort(true)
 +
cube:setScale(2*16, 2*16, 2*16)
 +
cube:setPosition(12*16, 8*16, 1*16)
 +
 
 +
stage:addChild(cube)
 +
 
 +
-- Rotate our cube
 +
cube:addEventListener(Event.ENTER_FRAME,function(e)
 +
cube:setRotationX(cube:getRotationX()+1)
 +
cube:setRotation(cube:getRotation()+1.3)
 +
end)
 +
</syntaxhighlight>
 +
 
 +
== Let's get real ==
 +
=== A 3D Plane ===
 +
So far we managed to be 3D using only the x and y axes. Let's get real and add the z axis:
 +
* Mesh.new(''true'')
 +
 
 +
Initializing a '''Mesh''' with ''true'' makes the mesh expect a Z coordinate in its vertex array. Now this is real 3D 😉.
 +
 
 +
The principles are the same as flat 3D but with an extra axis to deal with. Let's introduce Texturing as well.
 +
 
 +
The raw:
 +
<syntaxhighlight lang="lua">
 +
application:setBackgroundColor(0x323232)
 +
 
 +
-- configure the field of view for 3D projection
 +
application:configureFrustum(45) -- (fov, farplane)
 +
 
 +
local plane3d = Mesh.new(true) -- true = this mesh expects a Z coordinate in its vertex array
 +
local w, h, d = 5*8, 1*8, 10*8 -- 3d plane dimensions
 +
 
 +
local va = { -- vertex array
 +
-w,h,-d, -- 1. vertex position
 +
w,h,-d, -- 2. vertex position
 +
w,h,d, -- 3. vertex position
 +
-w,h,d, -- 4. vertex position
 +
-- -w,h-30,d, -- 4. vertex position, test another position
 +
}
 +
local ia = { -- index array
 +
1,2,3, -- 1. triangle from 1, 2 and 3 vertex
 +
1,3,4, -- 2. triangle from 1, 3 and 4 vertex
 +
}
 +
plane3d:setVertexArray(va)
 +
plane3d:setIndexArray(ia)
 +
 
 +
-- texture it
 +
local tex = Texture.new("gfx/Aurichalcite Deposit.jpg", false, { wrap=Texture.REPEAT, } )
 +
local tw,th = tex:getWidth()*0.5, tex:getHeight()*1 -- 0.5 and 1 are the texture scale (uv)
 +
plane3d:setTextureCoordinateArray {
 +
0,0, -- 1. vertex texture coordinate
 +
tw,0, -- 2. vertex texture coordinate
 +
tw,th, -- 3. vertex texture coordinate
 +
0,th, -- 4. vertex texture coordinate
 +
}
 +
plane3d:setTexture(tex)
 +
 
 +
-- why no color
 +
plane3d:setColor(1, 0xffffff, 1)
 +
plane3d:setColor(2, 0x5500ff, 1)
 +
plane3d:setColor(3, 0x000000, 1)
 +
plane3d:setColor(4, 0xaaff00, 1)
 +
 
 +
-- ok
 +
plane3d:setPosition(12*16, 10*16, -1*16)
 +
stage:addChild(plane3d)
 +
 
 +
-- rotate it
 +
plane3d:addEventListener(Event.ENTER_FRAME,function(e)
 +
plane3d:setRotationX(plane3d:getRotationX()+1)
 +
plane3d:setRotation(plane3d:getRotation()+1.3)
 +
end)
 +
</syntaxhighlight>
  
 
----
 
----
 
'''[[Libs3D]]'''
 
'''[[Libs3D]]'''
 
{{GIDEROS IMPORTANT LINKS}}
 
{{GIDEROS IMPORTANT LINKS}}

Latest revision as of 05:17, 24 January 2026

Supported platforms: Platform android.pngPlatform ios.pngPlatform mac.pngPlatform pc.pngPlatform html5.pngPlatform winrt.pngPlatform win32.pngPlatform linux.png

I am 3D

First and foremost, for 3D, we set our application as such. There are many ways to tell our application be 3D:

  • application configureFrustum
  • Matrix orthographicProjection
  • Matrix perspectiveProjection
  • Viewport setProjection

Let's see some of those making our first steps in Gideros 3D.

Flat 3D

A Triangle

As seen above, first we set our application 3D: configureFrustum.

The Mesh class is used to create and display custom constructed triangles (triangle meshes).

A triangle is:

  • an array of 3 vertices with an x and y position: setVertexArray
  • those 3 vertices connect to make a face (ClockWise): setIndexArray
  • optionally coloring each vertex (color and alpha): setColorArray

The code:

application:setBackgroundColor(0x323232)

-- Configures the field of view (fov) and far clipping plane for 3D projection
application:configureFrustum(45, -100) -- (fov, farplane)

local mesh = Mesh.new()

mesh:setVertexArray(
	50, 0, -- 1. vertex position
	100, 100, -- 2. vertex position
	0, 100 -- 3. vertex position
)
mesh:setIndexArray(
	1,2,3 -- 1. triangle from 1, 2 and 3 vertex
)
mesh:setColorArray(
	0xff0000,0.5, -- 1. vertex color and alpha
	0x00ff00,0.7, -- 2. vertex color and alpha
	0x0000ff,1.0 -- 3. vertex color and alpha
)

-- ok
mesh:setPosition(12*16, 8*16, -1*16)
stage:addChild(mesh)

mesh:addEventListener(Event.ENTER_FRAME, function(e)
	mesh:setRotationX(mesh:getRotationX()+1)
	mesh:setRotationY(mesh:getRotationY()+1)
	mesh:setRotation(mesh:getRotation()+1)
end)

3d triangle.png

A Rectangle

Take the triangle code above, add one vertex and you have two triangles that make a rectangle.

application:setBackgroundColor(0x323232)

-- Configures the field of view (fov) and far clipping plane for 3D projection
application:configureFrustum(45, -100) -- (fov, farplane)

local mesh = Mesh.new()

mesh:setVertexArray(
	0, 0, -- 1. vertex position
	100, 0, -- 2. vertex position
	100, 150, -- 3. vertex position
	0, 150 -- -- 4. vertex position
)
mesh:setIndexArray(
	1,2,3, -- 1. triangle from 1, 2 and 3 vertex
	1,3,4 -- 2. triangle from 1, 3 and 4 vertex
)
mesh:setColorArray(
	0xff0000,0.5, -- 1. vertex color and alpha
	0x00ff00,0.7, -- 2. vertex color and alpha
	0x0000ff,1.0, -- 3. vertex color and alpha
	0xffff00,0 -- 4. vertex color and alpha
)

-- ok
mesh:setPosition(12*16, 8*16, -1*16)
stage:addChild(mesh)

mesh:addEventListener(Event.ENTER_FRAME, function(e)
	mesh:setRotationX(mesh:getRotationX()+1)
	mesh:setRotationY(mesh:getRotationY()+1)
	mesh:setRotation(mesh:getRotation()+1)
end)

A Cube

In Gideros, a simple Sprite can be cube:

  • we set the application 3D
  • we create a local function to make the faces for our cube using Shape
  • we add six faces (with appropriate rotation) to a parent Sprite
  • and we are cube ;-)
application:setBackgroundColor(0x323232)

-- configure the field of view for 3D projection
application:configureFrustum(45) -- (fov, farplane)

-- create faces for a cube
local function face(color, rx, ry)
	local s = Shape.new()
	s:setFillStyle(Shape.SOLID, color, 0.7) -- translucent color
	s:beginPath()
	s:moveTo(-1,-1)
	s:lineTo(-1,1)
	s:lineTo(1,1)
	s:lineTo(1,-1)
	s:lineTo(-1,-1)
	s:endPath()
	-- orientation
	s:setRotationX(rx)
	s:setRotationY(ry)
	-- offset position -1 along its local Z axis
	s:setPosition(s:getMatrix():transformPoint(0, 0, -1))

	return s
end

-- a cube with 6 faces
cube = Sprite.new()
cube:addChild(face(0xFF8080, 0,0)) -- color, rx, ry
cube:addChild(face(0xFFFF00, 90,0)) -- color, rx, ry
cube:addChild(face(0xFF00FF, -90,0)) -- color, rx, ry
cube:addChild(face(0x80FF80, 180,0)) -- color, rx, ry
cube:addChild(face(0x00FFFF, 0,90)) -- color, rx, ry
cube:addChild(face(0x8080FF, 0,-90)) -- color, rx, ry

-- enable depth sorting for translucency
cube:setAutoSort(true)
cube:setScale(2*16, 2*16, 2*16)
cube:setPosition(12*16, 8*16, 1*16)

stage:addChild(cube)

-- Rotate our cube
cube:addEventListener(Event.ENTER_FRAME,function(e)
	cube:setRotationX(cube:getRotationX()+1)
	cube:setRotation(cube:getRotation()+1.3)
end)

Let's get real

A 3D Plane

So far we managed to be 3D using only the x and y axes. Let's get real and add the z axis:

  • Mesh.new(true)

Initializing a Mesh with true makes the mesh expect a Z coordinate in its vertex array. Now this is real 3D 😉.

The principles are the same as flat 3D but with an extra axis to deal with. Let's introduce Texturing as well.

The raw:

application:setBackgroundColor(0x323232)

-- configure the field of view for 3D projection
application:configureFrustum(45) -- (fov, farplane)

local plane3d = Mesh.new(true) -- true = this mesh expects a Z coordinate in its vertex array 
local w, h, d = 5*8, 1*8, 10*8 -- 3d plane dimensions

local va = { -- vertex array
	-w,h,-d, -- 1. vertex position
	w,h,-d, -- 2. vertex position
	w,h,d, -- 3. vertex position
	-w,h,d, -- 4. vertex position
--	-w,h-30,d, -- 4. vertex position, test another position
}
local ia = { -- index array
	1,2,3, -- 1. triangle from 1, 2 and 3 vertex
	1,3,4, -- 2. triangle from 1, 3 and 4 vertex
}
plane3d:setVertexArray(va)
plane3d:setIndexArray(ia)

-- texture it
local tex = Texture.new("gfx/Aurichalcite Deposit.jpg", false, { wrap=Texture.REPEAT, } )
local tw,th = tex:getWidth()*0.5, tex:getHeight()*1 -- 0.5 and 1 are the texture scale (uv)
plane3d:setTextureCoordinateArray {
	0,0, -- 1. vertex texture coordinate
	tw,0, -- 2. vertex texture coordinate
	tw,th, -- 3. vertex texture coordinate
	0,th, -- 4. vertex texture coordinate
}
plane3d:setTexture(tex)

-- why no color
plane3d:setColor(1, 0xffffff, 1)
plane3d:setColor(2, 0x5500ff, 1)
plane3d:setColor(3, 0x000000, 1)
plane3d:setColor(4, 0xaaff00, 1)

-- ok
plane3d:setPosition(12*16, 10*16, -1*16)
stage:addChild(plane3d)

-- rotate it
plane3d:addEventListener(Event.ENTER_FRAME,function(e)
	plane3d:setRotationX(plane3d:getRotationX()+1)
	plane3d:setRotation(plane3d:getRotation()+1.3)
end)

Libs3D