Module igeCore.apputil.graphicsHelper
graphicsHelper.py
Functions to help build graphics data
Expand source code
"""
graphicsHelper.py
Functions to help build graphics data
"""
import igeCore as core
import igeVmath as vmath
import math
_uvs = (0.0, 1.0, 1.0, 1.0, 0.0, 0.0, 1.0, 0.0)
_tris = (0, 2, 1, 1, 2, 3)
_pivotoffset = (1,-1, 0,-1, -1,-1, 1,0, 0,0, -1,0, 1,1, 0,1, -1,1)
def textFigure(word, fontpath, fontsize,color=(1.0, 1.0, 1.0, 1.0), pivot=4, scale = 1.0):
'''
Create Visible text
Parameters
----------
word : string
text
fontpath : string
font data file path
fontsize : string
font size
color : (float,float,float,float)
text color
pivot : int
center point of polygon
0 1 2
+-------+-------+
| | |
3| 4| 5|
+-------+-------+
| | |
6| 7| 8|
+-------+-------+
'''
w,h = core.calcFontPixelSize(word, fontpath, fontsize)
tex = core.texture(core.unique("text"),w,h, format=core.GL_RED)
tex.setText(word, fontpath,fontsize)
gen = core.shaderGenerator()
gen.setColorTexture(True)
gen.setBoneCondition(1, 1)
gen.discardColorMapRGB()
hw = w/2 * scale
hh = h/2 * scale
px = _pivotoffset[pivot*2+0] * hw;
py = _pivotoffset[pivot*2+1] * hh;
points = ((-hw+px,hh+py,0.0), (hw+px,hh+py,0.0), (-hw+px,-hh+py,0.0), (hw+px,-hh+py,0.0))
efig = createMesh(points, _tris, None, _uvs, gen)
efig.setMaterialParam("mate", "DiffuseColor", color);
efig.setMaterialParamTexture("mate", "ColorSampler", tex,
wrap_s=core.SAMPLERSTATE_BORDER,wrap_t=core.SAMPLERSTATE_BORDER,
minfilter=core.SAMPLERSTATE_NEAREST, magfilter=core.SAMPLERSTATE_LINEAR)
efig.setMaterialRenderState("mate", "blend_enable", True)
return efig
def createSprite(width:float=100, height:float=100, texture=None, uv_left_top:tuple=(0,0), uv_right_bottom:tuple=(1,1), normal=None, pivot=4, shader=None):
"""
Create Visible Rectangle
Parameters
----------
width : float (optional)
sprite width
height: float (optional)
sprite height
texture: string (optional)
texture file name
uv_left_top: tuple (optional)
texture uv value of left top cornar
uv_right_bottom: tuple (optional)
texture uv value of right bottom cornar
normal: pyvmath.vec3 (optional)
specify rectangle's nomal vector
pivot : int
center point of polygon
shader : igeCore.shader
shader object
Returns
-------
editableFigure
"""
hw = width/2
hh = height/2
px = _pivotoffset[pivot*2+0] * hw;
py = _pivotoffset[pivot*2+1] * hh;
points = ((-hw+px,hh+py,0.0), (hw+px,hh+py,0.0), (-hw+px,-hh+py,0.0), (hw+px,-hh+py,0.0))
if normal is not None:
newpoints = []
nom0 = (0, 0, 1)
mat = vmath.mat33(vmath.quat_rotation(nom0, normal))
for p in points:
newpoints.append(mat * p)
points = newpoints
# uvs = (uv_left_top[0], uv_right_bottom[1],
# uv_right_bottom[0], uv_right_bottom[1],
# uv_left_top[0], uv_left_top[1],
# uv_right_bottom[1], uv_left_top[1])
uvs = ( uv_left_top[0], uv_right_bottom[1],
uv_right_bottom[0], uv_right_bottom[1],
uv_left_top[0], uv_left_top[1],
uv_right_bottom[0], uv_left_top[1])
return createMesh(points, _tris, texture, uvs, shader)
def createMesh(points, tris, texture=None, uvs = None, shader = None, normals = None):
"""
Create a polygon mesh by specifying vertex coordinates and triangle index
Parameters
----------
points: tuple or list
list or tuple of points
tris: tuple or list
list or tuple of triangle indices
texture: string (optional)
file path of texture
uvs: list or tuple (optional)
shader : igeCore.shader
shader object
normals : list or tuple (optional)
list or tuple of vertex normal
Returns
-------
editableFigure
"""
if shader is None:
shader = core.shaderGenerator()
if texture != None:
shader.setColorTexture(True)
shader.setBoneCondition(1, 1)
efig = core.editableFigure("sprite", True)
efig.addMaterial("mate", shader)
efig.addMesh("mesh", "mate");
efig.setVertexElements("mesh", core.ATTRIBUTE_ID_POSITION, points)
if uvs:
efig.setVertexElements("mesh", core.ATTRIBUTE_ID_UV0,uvs)
if normals:
efig.setVertexElements("mesh", core.ATTRIBUTE_ID_NORMAL,normals)
efig.setTriangles("mesh", tris);
efig.addJoint("joint");
efig.setMaterialParam("mate", "DiffuseColor", (1.0, 1.0, 1.0, 1.0));
#efig.setMaterialRenderState("mate", "cull_face_enable", False)
if texture != None:
efig.setMaterialParamTexture("mate", "ColorSampler", texture,
wrap_s=core.SAMPLERSTATE_BORDER,wrap_t=core.SAMPLERSTATE_BORDER,
minfilter=core.SAMPLERSTATE_LINEAR, magfilter=core.SAMPLERSTATE_LINEAR)
efig.setMaterialRenderState("mate", "blend_enable", True)
return efig
def __tranform(normal, poss, noms):
nom0 = (0, 0, 1)
newpoints = []
mat = vmath.mat33(vmath.quat_rotation(nom0, normal))
for p in poss:
newpoints.append(mat * p)
poss = newpoints
newnoms = []
for n in noms:
newnoms.append(mat * n)
noms = newnoms
return poss, noms
###################################################################################################
plane_triangles=(0, 2, 1, 1, 2, 3)
def makePlane(width:float, height:float, uv_left_top:tuple=(0,0), uv_right_bottom:tuple=(1,1), normal=None, jointIndex=0):
w = width / 2
h = height / 2
poss = (vmath.vec3(-w, h, 0.0), vmath.vec3(w, h, 0.0), vmath.vec3(-w, -h, 0.0), vmath.vec3(w, -h, 0.0))
uvs = (vmath.vec2(uv_left_top[0], uv_right_bottom[1]),
vmath.vec2(uv_right_bottom[0], uv_right_bottom[1]),
vmath.vec2(uv_left_top[0], uv_left_top[1]),
vmath.vec2(uv_right_bottom[1], uv_left_top[1]))
nom = vmath.vec3(0,0,1)
noms = (nom,)*4
if normal is not None:
poss, noms = __tranform(normal, poss, noms)
idxs = ((jointIndex,0,0,0),)*len(poss)
return poss, noms, uvs, idxs, plane_triangles
###################################################################################################
cubeN = ((-1.0, 0.0, 0.0), (0.0, 1.0, 0.0), (1.0, 0.0, 0.0),
(0.0, -1.0, 0.0), (0.0, 0.0, 1.0), (0.0, 0.0, -1.0))
cubeF = ((0, 1, 5, 4), (4, 5, 6, 7), (7, 6, 2, 3),
( 1, 0, 3, 2 ), ( 1, 2, 6, 5 ), ( 0, 4, 7, 3 ))
cubeV = ((-.5, -.5, -.5), (-.5, -.5, .5), ( .5, -.5, .5), ( .5, -.5, -.5), # Lower tier (lower in y)
(-.5, .5, -.5), (-.5, .5, .5), ( .5, .5, .5), ( .5, .5, -.5)) # Upper tier
cubeT = ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0))
def makeBox(width:float, height:float, depth:float, jointIndex=0):
poss = []
noms = []
uvs = []
tris = []
nvrt = 0
for i in range(6):
for j in range(4):
poss.append(vmath.vec3(cubeV[cubeF[i][j]][0] * width, cubeV[cubeF[i][j]][1] * height, cubeV[cubeF[i][j]][2] * depth))
noms.append(vmath.vec3(cubeN[i][0], cubeN[i][1], cubeN[i][2]))
uvs.append(vmath.vec2(cubeT[j][0], cubeT[j][1]))
tris.append(nvrt)
tris.append(nvrt + 1)
tris.append(nvrt + 2)
tris.append(nvrt + 2)
tris.append(nvrt + 3)
tris.append(nvrt)
nvrt += 4
idxs = ((jointIndex,0,0,0),)*len(poss)
return poss, noms, uvs, idxs, tris
###################################################################################################
def makeBoxFromAABB(min , max, jointIndex=0):
cubeV2 = ((min.x, min.y, min.z), (min.x, min.y, max.z), (max.x, min.y, max.z), (max.x, min.y, min.z),
(min.x, max.y, min.z), (min.x, max.y, max.z), (max.x, max.y, max.z), (max.x, max.y, min.z))
poss = []
noms = []
uvs = []
tris = []
nvrt = 0
for i in range(6):
for j in range(4):
poss.append((cubeV2[cubeF[i][j]][0], cubeV2[cubeF[i][j]][1], cubeV2[cubeF[i][j]][2]))
noms.append((cubeN[i][0], cubeN[i][1], cubeN[i][2]))
uvs.append((cubeT[j][0], cubeT[j][1]))
tris.append(nvrt)
tris.append(nvrt + 1)
tris.append(nvrt + 2)
tris.append(nvrt + 2)
tris.append(nvrt + 3)
tris.append(nvrt)
nvrt += 4
idxs = ((jointIndex,0,0,0),)*len(poss)
return poss, noms, uvs, idxs, tris
###################################################################################################
def makeCylinder(radius1:float, radius2:float, length:float, slices:int, stacks:int, normal=None, jointIndex=0):
# Sin/Cos caches
sinI = []
cosI = []
for i in range(slices):
angle = 2.0 * math.pi * i / slices
sinI.append(math.sin(angle))
cosI.append(math.cos(angle))
# Compute side normal angle
deltaRadius = radius2 - radius1
sideLength = math.sqrt( deltaRadius * deltaRadius + length * length )
normalXY = 1.0
if sideLength > 0.00001:
normalXY = length / sideLength
normalZ = 0.0
if sideLength > 0.00001:
normalZ = deltaRadius / sideLength
# Base cap (uSlices + 1)
fZ = length * -0.5
radius = radius1
poss = []
noms = []
uvs = []
tris = []
poss.append((0.0, 0.0, fZ))
noms.append((0.0, 0.0, -1.0))
uvs.append((0.0, 0.0))
for i in range(slices):
poss.append((radius * sinI[i], radius * cosI[i], fZ))
noms.append((0.0, 0.0, -1.0))
uvs.append((0.0, 0.0))
# Stacks ((uStacks + 1)*uSlices)
for j in range(stacks+1):
f = j / stacks
fZ = length * ( f - 0.5 )
radius = radius1 + f * deltaRadius
for i in range(slices):
poss.append((radius * sinI[i], radius * cosI[i], fZ))
noms.append((normalXY * sinI[i], normalXY * cosI[i], normalZ))
uvs.append((0.0, 0.0))
# Top cap (uSlices + 1)
fZ = length * 0.5
radius = radius2
for i in range(slices):
poss.append((radius * sinI[i], radius * cosI[i], fZ))
noms.append((0.0, 0.0, 1.0))
uvs.append((0.0, 0.0))
poss.append((0.0, 0.0, fZ))
noms.append((0.0, 0.0, 1.0))
uvs.append((0.0, 0.0))
if normal is not None:
poss, noms = __tranform(normal, poss, noms)
# Generate indices
# Z+ pole (uSlices)
rowA = 0
rowB = 1
for i in range(slices - 1):
tris.append( rowA )
tris.append( rowB + i )
tris.append( rowB + i + 1 )
tris.append( rowA )
tris.append( rowB + slices - 1 )
tris.append( rowB )
# Interior stacks (uStacks * uSlices * 2)
for j in range(stacks):
rowA = 1 + ( j + 1 ) * slices
rowB = rowA + slices
for i in range(slices - 1):
tris.append( rowA + i )
tris.append( rowB + i )
tris.append( rowA + i + 1 )
tris.append( rowA + i + 1 )
tris.append( rowB + i )
tris.append( rowB + i + 1 )
tris.append( rowA + slices - 1 )
tris.append( rowB + slices - 1 )
tris.append( rowA )
tris.append( rowA )
tris.append( rowB + slices - 1 )
tris.append( rowB )
# Z- pole (uSlices)
rowA = 1 + ( stacks + 2 ) * slices
rowB = rowA + slices
for i in range(slices - 1):
tris.append( rowA + i )
tris.append( rowB )
tris.append( rowA + i + 1 )
tris.append( rowA + slices - 1 )
tris.append( rowB )
tris.append( rowA )
idxs = ((jointIndex,0,0,0),) * len(poss)
return poss, noms, uvs, idxs, tris
###################################################################################################
def makeSphere(radius:float, slices:int, stacks:int, jointIndex=0 ):
# Sin/Cos caches
sinI = []
cosI = []
sinJ = []
cosJ = []
for i in range(slices):
angle = 2.0 * math.pi * i / slices
sinI.append(math.sin(angle))
cosI.append(math.cos(angle))
for j in range(stacks):
angle = math.pi * j / stacks
sinJ.append(math.sin(angle))
cosJ.append(math.cos(angle))
poss = []
noms = []
uvs = []
tris = []
# +Z pole
poss.append(vmath.vec3(0.0, 0.0, radius))
noms.append(vmath.vec3(0.0, 0.0, 1.0))
uvs.append(vmath.vec2(0.0, 0.0))
# Stacks
for j in range(stacks):
for i in range(slices):
norm = vmath.vec3(sinI[i] * sinJ[j], cosI[i] * sinJ[j], cosJ[j])
poss.append(vmath.vec3(norm.x * radius, norm.y * radius, norm.z * radius))
noms.append(norm)
uvs.append(vmath.vec2(0.0, 0.0))
# Z- pole
poss.append(vmath.vec3(0.0, 0.0, -radius))
noms.append(vmath.vec3(0.0, 0.0, -1.0))
uvs.append(vmath.vec2(0.0, 0.0))
# Generate indices
# Z+ pole
rowA = 0
rowB = 1
# for i in range(slices-1):
# tris.append( rowA )
# tris.append( rowB + i + 1 )
# tris.append( rowB + i )
# tris.append( rowA )
# tris.append( rowB )
# tris.append( rowB + slices-1 )
# Interior stacks
for j in range(1,stacks):
rowA = 1 + (j - 1) * slices
rowB = rowA + slices
for i in range(slices - 1):
tris.append(rowA + i)
tris.append(rowA + i + 1)
tris.append(rowB + i)
tris.append(rowA + i + 1)
tris.append(rowB + i + 1)
tris.append(rowB + i)
tris.append(rowA + slices - 1)
tris.append(rowA)
tris.append(rowB + slices - 1)
tris.append(rowA)
tris.append(rowB)
tris.append(rowB + slices - 1)
#Z- pole
rowA = 1 + (stacks - 1) * slices
rowB = rowA + slices
for i in range(slices - 1):
tris.append(rowA + i)
tris.append(rowA + i + 1)
tris.append(rowB)
tris.append(rowA + slices - 1)
tris.append(rowA)
tris.append(rowB)
idxs = ((jointIndex,0,0,0),) * len(poss)
return poss, noms, uvs, idxs, tris
###################################################################################################
def makeTorus(innerRadius:float, outerRadius:float, sides:int, rings:int, normal=None, jointIndex=0):
poss = []
noms = []
uvs = []
tris = []
# Compute the vertices
for i in range(rings):
theta = i * 2.0 * math.pi / rings
st = math.sin(theta)
ct = math.cos(theta)
for j in range(sides):
phi = j * 2.0 * math.pi / sides
sp = math.sin(phi)
cp = math.cos(phi)
poss.append((ct * ( outerRadius + innerRadius * cp ), -st * ( outerRadius + innerRadius * cp ), sp * innerRadius))
noms.append((ct * cp, -st * cp, sp))
uvs.append((0.0, 0.0))
if normal is not None:
poss, noms = __tranform(normal, poss, noms)
for i in range(rings - 1):
for j in range(sides - 1):
# Tri 1 (Top-Left tri, CCW)
tris.append( i * sides + j )
tris.append( i * sides + j + 1 )
tris.append( ( i + 1 ) * sides + j )
# Tri 2 (Bottom-Right tri, CCW)
tris.append( ( i + 1 ) * sides + j )
tris.append( i * sides + j + 1 )
tris.append( ( i + 1 ) * sides + j + 1 )
j = sides - 1
# Tri 1 (Top-Left tri, CCW)
tris.append( i * sides + j )
tris.append( i * sides )
tris.append( ( i + 1 ) * sides + j )
# Tri 2 (Bottom-Right tri, CCW)
tris.append( ( i + 1 ) * sides + j )
tris.append( i * sides + 0 )
tris.append( ( i + 1 ) * sides + 0 )
i = rings-1
#join the two ends of the tube
for j in range(sides - 1):
# Tri 1 (Top-Left tri, CCW)
tris.append( i * sides + j )
tris.append( i * sides + j + 1 )
tris.append( j )
# Tri 2 (Bottom-Right tri, CCW)
tris.append( j )
tris.append( i * sides + j + 1 )
tris.append( j + 1 )
j = sides-1
# Tri 1 (Top-Left tri, CCW)
tris.append( i * sides + j )
tris.append( i * sides )
tris.append( j )
# Tri 2 (Bottom-Right tri, CCW)
tris.append( j )
tris.append( i * sides )
tris.append( 0 )
idxs = ((jointIndex,0,0,0),) * len(poss)
return poss, noms, uvs, idxs, tris
Functions
def createMesh(points, tris, texture=None, uvs=None, shader=None, normals=None)-
Create a polygon mesh by specifying vertex coordinates and triangle index
Parameters ---------- points: tuple or list list or tuple of points tris: tuple or list list or tuple of triangle indices texture: string (optional) file path of texture uvs: list or tuple (optional) shader : igeCore.shader shader object normals : list or tuple (optional) list or tuple of vertex normal Returns ------- editableFigureExpand source code
def createMesh(points, tris, texture=None, uvs = None, shader = None, normals = None): """ Create a polygon mesh by specifying vertex coordinates and triangle index Parameters ---------- points: tuple or list list or tuple of points tris: tuple or list list or tuple of triangle indices texture: string (optional) file path of texture uvs: list or tuple (optional) shader : igeCore.shader shader object normals : list or tuple (optional) list or tuple of vertex normal Returns ------- editableFigure """ if shader is None: shader = core.shaderGenerator() if texture != None: shader.setColorTexture(True) shader.setBoneCondition(1, 1) efig = core.editableFigure("sprite", True) efig.addMaterial("mate", shader) efig.addMesh("mesh", "mate"); efig.setVertexElements("mesh", core.ATTRIBUTE_ID_POSITION, points) if uvs: efig.setVertexElements("mesh", core.ATTRIBUTE_ID_UV0,uvs) if normals: efig.setVertexElements("mesh", core.ATTRIBUTE_ID_NORMAL,normals) efig.setTriangles("mesh", tris); efig.addJoint("joint"); efig.setMaterialParam("mate", "DiffuseColor", (1.0, 1.0, 1.0, 1.0)); #efig.setMaterialRenderState("mate", "cull_face_enable", False) if texture != None: efig.setMaterialParamTexture("mate", "ColorSampler", texture, wrap_s=core.SAMPLERSTATE_BORDER,wrap_t=core.SAMPLERSTATE_BORDER, minfilter=core.SAMPLERSTATE_LINEAR, magfilter=core.SAMPLERSTATE_LINEAR) efig.setMaterialRenderState("mate", "blend_enable", True) return efig def createSprite(width: float = 100, height: float = 100, texture=None, uv_left_top: tuple = (0, 0), uv_right_bottom: tuple = (1, 1), normal=None, pivot=4, shader=None)-
Create Visible Rectangle
Parameters ---------- width : float (optional) sprite width height: float (optional) sprite height texture: string (optional) texture file name uv_left_top: tuple (optional) texture uv value of left top cornar uv_right_bottom: tuple (optional) texture uv value of right bottom cornar normal: pyvmath.vec3 (optional) specify rectangle's nomal vector pivot : int center point of polygon shader : igeCore.shader shader object Returns ------- editableFigureExpand source code
def createSprite(width:float=100, height:float=100, texture=None, uv_left_top:tuple=(0,0), uv_right_bottom:tuple=(1,1), normal=None, pivot=4, shader=None): """ Create Visible Rectangle Parameters ---------- width : float (optional) sprite width height: float (optional) sprite height texture: string (optional) texture file name uv_left_top: tuple (optional) texture uv value of left top cornar uv_right_bottom: tuple (optional) texture uv value of right bottom cornar normal: pyvmath.vec3 (optional) specify rectangle's nomal vector pivot : int center point of polygon shader : igeCore.shader shader object Returns ------- editableFigure """ hw = width/2 hh = height/2 px = _pivotoffset[pivot*2+0] * hw; py = _pivotoffset[pivot*2+1] * hh; points = ((-hw+px,hh+py,0.0), (hw+px,hh+py,0.0), (-hw+px,-hh+py,0.0), (hw+px,-hh+py,0.0)) if normal is not None: newpoints = [] nom0 = (0, 0, 1) mat = vmath.mat33(vmath.quat_rotation(nom0, normal)) for p in points: newpoints.append(mat * p) points = newpoints # uvs = (uv_left_top[0], uv_right_bottom[1], # uv_right_bottom[0], uv_right_bottom[1], # uv_left_top[0], uv_left_top[1], # uv_right_bottom[1], uv_left_top[1]) uvs = ( uv_left_top[0], uv_right_bottom[1], uv_right_bottom[0], uv_right_bottom[1], uv_left_top[0], uv_left_top[1], uv_right_bottom[0], uv_left_top[1]) return createMesh(points, _tris, texture, uvs, shader) def makeBox(width: float, height: float, depth: float, jointIndex=0)-
Expand source code
def makeBox(width:float, height:float, depth:float, jointIndex=0): poss = [] noms = [] uvs = [] tris = [] nvrt = 0 for i in range(6): for j in range(4): poss.append(vmath.vec3(cubeV[cubeF[i][j]][0] * width, cubeV[cubeF[i][j]][1] * height, cubeV[cubeF[i][j]][2] * depth)) noms.append(vmath.vec3(cubeN[i][0], cubeN[i][1], cubeN[i][2])) uvs.append(vmath.vec2(cubeT[j][0], cubeT[j][1])) tris.append(nvrt) tris.append(nvrt + 1) tris.append(nvrt + 2) tris.append(nvrt + 2) tris.append(nvrt + 3) tris.append(nvrt) nvrt += 4 idxs = ((jointIndex,0,0,0),)*len(poss) return poss, noms, uvs, idxs, tris def makeBoxFromAABB(min, max, jointIndex=0)-
Expand source code
def makeBoxFromAABB(min , max, jointIndex=0): cubeV2 = ((min.x, min.y, min.z), (min.x, min.y, max.z), (max.x, min.y, max.z), (max.x, min.y, min.z), (min.x, max.y, min.z), (min.x, max.y, max.z), (max.x, max.y, max.z), (max.x, max.y, min.z)) poss = [] noms = [] uvs = [] tris = [] nvrt = 0 for i in range(6): for j in range(4): poss.append((cubeV2[cubeF[i][j]][0], cubeV2[cubeF[i][j]][1], cubeV2[cubeF[i][j]][2])) noms.append((cubeN[i][0], cubeN[i][1], cubeN[i][2])) uvs.append((cubeT[j][0], cubeT[j][1])) tris.append(nvrt) tris.append(nvrt + 1) tris.append(nvrt + 2) tris.append(nvrt + 2) tris.append(nvrt + 3) tris.append(nvrt) nvrt += 4 idxs = ((jointIndex,0,0,0),)*len(poss) return poss, noms, uvs, idxs, tris def makeCylinder(radius1: float, radius2: float, length: float, slices: int, stacks: int, normal=None, jointIndex=0)-
Expand source code
def makeCylinder(radius1:float, radius2:float, length:float, slices:int, stacks:int, normal=None, jointIndex=0): # Sin/Cos caches sinI = [] cosI = [] for i in range(slices): angle = 2.0 * math.pi * i / slices sinI.append(math.sin(angle)) cosI.append(math.cos(angle)) # Compute side normal angle deltaRadius = radius2 - radius1 sideLength = math.sqrt( deltaRadius * deltaRadius + length * length ) normalXY = 1.0 if sideLength > 0.00001: normalXY = length / sideLength normalZ = 0.0 if sideLength > 0.00001: normalZ = deltaRadius / sideLength # Base cap (uSlices + 1) fZ = length * -0.5 radius = radius1 poss = [] noms = [] uvs = [] tris = [] poss.append((0.0, 0.0, fZ)) noms.append((0.0, 0.0, -1.0)) uvs.append((0.0, 0.0)) for i in range(slices): poss.append((radius * sinI[i], radius * cosI[i], fZ)) noms.append((0.0, 0.0, -1.0)) uvs.append((0.0, 0.0)) # Stacks ((uStacks + 1)*uSlices) for j in range(stacks+1): f = j / stacks fZ = length * ( f - 0.5 ) radius = radius1 + f * deltaRadius for i in range(slices): poss.append((radius * sinI[i], radius * cosI[i], fZ)) noms.append((normalXY * sinI[i], normalXY * cosI[i], normalZ)) uvs.append((0.0, 0.0)) # Top cap (uSlices + 1) fZ = length * 0.5 radius = radius2 for i in range(slices): poss.append((radius * sinI[i], radius * cosI[i], fZ)) noms.append((0.0, 0.0, 1.0)) uvs.append((0.0, 0.0)) poss.append((0.0, 0.0, fZ)) noms.append((0.0, 0.0, 1.0)) uvs.append((0.0, 0.0)) if normal is not None: poss, noms = __tranform(normal, poss, noms) # Generate indices # Z+ pole (uSlices) rowA = 0 rowB = 1 for i in range(slices - 1): tris.append( rowA ) tris.append( rowB + i ) tris.append( rowB + i + 1 ) tris.append( rowA ) tris.append( rowB + slices - 1 ) tris.append( rowB ) # Interior stacks (uStacks * uSlices * 2) for j in range(stacks): rowA = 1 + ( j + 1 ) * slices rowB = rowA + slices for i in range(slices - 1): tris.append( rowA + i ) tris.append( rowB + i ) tris.append( rowA + i + 1 ) tris.append( rowA + i + 1 ) tris.append( rowB + i ) tris.append( rowB + i + 1 ) tris.append( rowA + slices - 1 ) tris.append( rowB + slices - 1 ) tris.append( rowA ) tris.append( rowA ) tris.append( rowB + slices - 1 ) tris.append( rowB ) # Z- pole (uSlices) rowA = 1 + ( stacks + 2 ) * slices rowB = rowA + slices for i in range(slices - 1): tris.append( rowA + i ) tris.append( rowB ) tris.append( rowA + i + 1 ) tris.append( rowA + slices - 1 ) tris.append( rowB ) tris.append( rowA ) idxs = ((jointIndex,0,0,0),) * len(poss) return poss, noms, uvs, idxs, tris def makePlane(width: float, height: float, uv_left_top: tuple = (0, 0), uv_right_bottom: tuple = (1, 1), normal=None, jointIndex=0)-
Expand source code
def makePlane(width:float, height:float, uv_left_top:tuple=(0,0), uv_right_bottom:tuple=(1,1), normal=None, jointIndex=0): w = width / 2 h = height / 2 poss = (vmath.vec3(-w, h, 0.0), vmath.vec3(w, h, 0.0), vmath.vec3(-w, -h, 0.0), vmath.vec3(w, -h, 0.0)) uvs = (vmath.vec2(uv_left_top[0], uv_right_bottom[1]), vmath.vec2(uv_right_bottom[0], uv_right_bottom[1]), vmath.vec2(uv_left_top[0], uv_left_top[1]), vmath.vec2(uv_right_bottom[1], uv_left_top[1])) nom = vmath.vec3(0,0,1) noms = (nom,)*4 if normal is not None: poss, noms = __tranform(normal, poss, noms) idxs = ((jointIndex,0,0,0),)*len(poss) return poss, noms, uvs, idxs, plane_triangles def makeSphere(radius: float, slices: int, stacks: int, jointIndex=0)-
Expand source code
def makeSphere(radius:float, slices:int, stacks:int, jointIndex=0 ): # Sin/Cos caches sinI = [] cosI = [] sinJ = [] cosJ = [] for i in range(slices): angle = 2.0 * math.pi * i / slices sinI.append(math.sin(angle)) cosI.append(math.cos(angle)) for j in range(stacks): angle = math.pi * j / stacks sinJ.append(math.sin(angle)) cosJ.append(math.cos(angle)) poss = [] noms = [] uvs = [] tris = [] # +Z pole poss.append(vmath.vec3(0.0, 0.0, radius)) noms.append(vmath.vec3(0.0, 0.0, 1.0)) uvs.append(vmath.vec2(0.0, 0.0)) # Stacks for j in range(stacks): for i in range(slices): norm = vmath.vec3(sinI[i] * sinJ[j], cosI[i] * sinJ[j], cosJ[j]) poss.append(vmath.vec3(norm.x * radius, norm.y * radius, norm.z * radius)) noms.append(norm) uvs.append(vmath.vec2(0.0, 0.0)) # Z- pole poss.append(vmath.vec3(0.0, 0.0, -radius)) noms.append(vmath.vec3(0.0, 0.0, -1.0)) uvs.append(vmath.vec2(0.0, 0.0)) # Generate indices # Z+ pole rowA = 0 rowB = 1 # for i in range(slices-1): # tris.append( rowA ) # tris.append( rowB + i + 1 ) # tris.append( rowB + i ) # tris.append( rowA ) # tris.append( rowB ) # tris.append( rowB + slices-1 ) # Interior stacks for j in range(1,stacks): rowA = 1 + (j - 1) * slices rowB = rowA + slices for i in range(slices - 1): tris.append(rowA + i) tris.append(rowA + i + 1) tris.append(rowB + i) tris.append(rowA + i + 1) tris.append(rowB + i + 1) tris.append(rowB + i) tris.append(rowA + slices - 1) tris.append(rowA) tris.append(rowB + slices - 1) tris.append(rowA) tris.append(rowB) tris.append(rowB + slices - 1) #Z- pole rowA = 1 + (stacks - 1) * slices rowB = rowA + slices for i in range(slices - 1): tris.append(rowA + i) tris.append(rowA + i + 1) tris.append(rowB) tris.append(rowA + slices - 1) tris.append(rowA) tris.append(rowB) idxs = ((jointIndex,0,0,0),) * len(poss) return poss, noms, uvs, idxs, tris def makeTorus(innerRadius: float, outerRadius: float, sides: int, rings: int, normal=None, jointIndex=0)-
Expand source code
def makeTorus(innerRadius:float, outerRadius:float, sides:int, rings:int, normal=None, jointIndex=0): poss = [] noms = [] uvs = [] tris = [] # Compute the vertices for i in range(rings): theta = i * 2.0 * math.pi / rings st = math.sin(theta) ct = math.cos(theta) for j in range(sides): phi = j * 2.0 * math.pi / sides sp = math.sin(phi) cp = math.cos(phi) poss.append((ct * ( outerRadius + innerRadius * cp ), -st * ( outerRadius + innerRadius * cp ), sp * innerRadius)) noms.append((ct * cp, -st * cp, sp)) uvs.append((0.0, 0.0)) if normal is not None: poss, noms = __tranform(normal, poss, noms) for i in range(rings - 1): for j in range(sides - 1): # Tri 1 (Top-Left tri, CCW) tris.append( i * sides + j ) tris.append( i * sides + j + 1 ) tris.append( ( i + 1 ) * sides + j ) # Tri 2 (Bottom-Right tri, CCW) tris.append( ( i + 1 ) * sides + j ) tris.append( i * sides + j + 1 ) tris.append( ( i + 1 ) * sides + j + 1 ) j = sides - 1 # Tri 1 (Top-Left tri, CCW) tris.append( i * sides + j ) tris.append( i * sides ) tris.append( ( i + 1 ) * sides + j ) # Tri 2 (Bottom-Right tri, CCW) tris.append( ( i + 1 ) * sides + j ) tris.append( i * sides + 0 ) tris.append( ( i + 1 ) * sides + 0 ) i = rings-1 #join the two ends of the tube for j in range(sides - 1): # Tri 1 (Top-Left tri, CCW) tris.append( i * sides + j ) tris.append( i * sides + j + 1 ) tris.append( j ) # Tri 2 (Bottom-Right tri, CCW) tris.append( j ) tris.append( i * sides + j + 1 ) tris.append( j + 1 ) j = sides-1 # Tri 1 (Top-Left tri, CCW) tris.append( i * sides + j ) tris.append( i * sides ) tris.append( j ) # Tri 2 (Bottom-Right tri, CCW) tris.append( j ) tris.append( i * sides ) tris.append( 0 ) idxs = ((jointIndex,0,0,0),) * len(poss) return poss, noms, uvs, idxs, tris def textFigure(word, fontpath, fontsize, color=(1.0, 1.0, 1.0, 1.0), pivot=4, scale=1.0)-
Create Visible text
Parameters
word : string text fontpath : string font data file path fontsize : string font size color : (float,float,float,float) text color pivot : int center point of polygon 0 1 2 +-------+-------+ | | | 3| 4| 5| +-------+-------+ | | | 6| 7| 8| +-------+-------+Expand source code
def textFigure(word, fontpath, fontsize,color=(1.0, 1.0, 1.0, 1.0), pivot=4, scale = 1.0): ''' Create Visible text Parameters ---------- word : string text fontpath : string font data file path fontsize : string font size color : (float,float,float,float) text color pivot : int center point of polygon 0 1 2 +-------+-------+ | | | 3| 4| 5| +-------+-------+ | | | 6| 7| 8| +-------+-------+ ''' w,h = core.calcFontPixelSize(word, fontpath, fontsize) tex = core.texture(core.unique("text"),w,h, format=core.GL_RED) tex.setText(word, fontpath,fontsize) gen = core.shaderGenerator() gen.setColorTexture(True) gen.setBoneCondition(1, 1) gen.discardColorMapRGB() hw = w/2 * scale hh = h/2 * scale px = _pivotoffset[pivot*2+0] * hw; py = _pivotoffset[pivot*2+1] * hh; points = ((-hw+px,hh+py,0.0), (hw+px,hh+py,0.0), (-hw+px,-hh+py,0.0), (hw+px,-hh+py,0.0)) efig = createMesh(points, _tris, None, _uvs, gen) efig.setMaterialParam("mate", "DiffuseColor", color); efig.setMaterialParamTexture("mate", "ColorSampler", tex, wrap_s=core.SAMPLERSTATE_BORDER,wrap_t=core.SAMPLERSTATE_BORDER, minfilter=core.SAMPLERSTATE_NEAREST, magfilter=core.SAMPLERSTATE_LINEAR) efig.setMaterialRenderState("mate", "blend_enable", True) return efig