Kujira no Hara
Re: Kujira no Hara
Ça le fait.
- Roi of the Suisse
- Messages : 2107
- Enregistré le : 28 avr. 2019, 23:38
- Contact :
Re: Kujira no Hara
WIP de script qui affiche des conneries en 3D
Code : Tout sélectionner
class Tetra_Sprite < Sprite
def initialize(viewport = nil)
super
self.bitmap = Bitmap.new(640, 480)
self.x, self.y, self.z = 0, 0, 4
refresh
end
def dispose
self.bitmap.dispose
super
end
def update
refresh
end
def refresh
self.bitmap.clear
require "matrix"
# sommets
s1 = Vector[-1, 1, 1].normalize
s2 = Vector[ 1, -1, 1].normalize
s3 = Vector[-1, -1, -1].normalize
s4 = Vector[ 1, 1, -1].normalize
# centres de faces
c1 = (s2+s3+s4).normalize
c2 = (s3+s4+s1).normalize
c3 = (s4+s1+s2).normalize
c4 = (s1+s2+s3).normalize
# troncature sur l'arête entre sommet et centre de face
l = 0.366
s1c2 = (s1*l+c2*(1-l)).normalize
s1c3 = (s1*l+c3*(1-l)).normalize
s1c4 = (s1*l+c4*(1-l)).normalize
s2c3 = (s2*l+c3*(1-l)).normalize
s2c4 = (s2*l+c4*(1-l)).normalize
s2c1 = (s2*l+c1*(1-l)).normalize
s3c4 = (s3*l+c4*(1-l)).normalize
s3c1 = (s3*l+c1*(1-l)).normalize
s3c2 = (s3*l+c2*(1-l)).normalize
s4c1 = (s4*l+c1*(1-l)).normalize
s4c2 = (s4*l+c2*(1-l)).normalize
s4c3 = (s4*l+c3*(1-l)).normalize
# troncature sur l'arête entre deux sommets
k = 0.611
s1s2 = (s1*k+s2*(1-k)).normalize
s2s1 = (s2*k+s1*(1-k)).normalize
s2s3 = (s2*k+s3*(1-k)).normalize
s3s2 = (s3*k+s2*(1-k)).normalize
s4s3 = (s4*k+s3*(1-k)).normalize
s3s4 = (s3*k+s4*(1-k)).normalize
s4s1 = (s4*k+s1*(1-k)).normalize
s1s4 = (s1*k+s4*(1-k)).normalize
s4s2 = (s4*k+s2*(1-k)).normalize
s2s4 = (s2*k+s4*(1-k)).normalize
s1s3 = (s1*k+s3*(1-k)).normalize
s3s1 = (s3*k+s1*(1-k)).normalize
# faces hexagonales
h1 = [s1s4, s1c2, s1s3, s1c4, s1s2, s1c3]
h2 = [s2s1, s2c3, s2s4, s2c1, s2s3, s2c4]
h3 = [s3s1, s3c4, s3s2, s3c1, s3s4, s3c2]
h4 = [s4s1, s4c3, s4s2, s4c1, s4s3, s4c2]
# faces pentagonales
p14 = [s2c1, c1, s3c1, s3s2, s2s3]
p12 = [s3c1, c1, s4c1, s4s3, s3s4]
p13 = [s4c1, c1, s2c1, s2s4, s4s2]
p24 = [s1c2, c2, s3c2, s3s1, s1s3]
p21 = [s3c2, c2, s4c2, s4s3, s3s4]
p23 = [s4c2, c2, s1c2, s1s4, s4s1]
p34 = [s2c3, c3, s1c3, s1s2, s2s1]
p32 = [s1c3, c3, s4c3, s4s1, s1s4]
p31 = [s4c3, c3, s2c3, s2s4, s4s2]
p43 = [s2c4, c4, s1c4, s1s2, s2s1]
p42 = [s1c4, c4, s3c4, s3s1, s1s3]
p41 = [s3c4, c4, s2c4, s2s3, s3s2]
# filtrer les faces avec un dot product négatif
touteslesfaces = [h1,h2,h3,h4, p14,p12,p13, p21,p23,p24, p31,p32,p34, p41,p42,p43]
rotation = Time.now.to_f * 1000.0 % (2*Math.PI)
for face in touteslesfaces
directionface = directionface(face)
dotprod = dotproduct(directionface, rotation)
if dotprod < 0
touteslesfaces.delete(face)
end
end
# classer les faces de la plus derrière à la plus devant
touteslesfaces.sort! { |f1, f2| dotproduct(f1, rotation) <=> dotproduct(f2, rotation) }
# dessiner les faces
for face in touteslesfaces
# couleur en fonction de l'orientation de la face
dot = dotproduct(directionface(face), rotation)
if dot < 0
dot = 0
end
facecolor = Color.new(dot, dot, dot, 255) # gris
# on decompose la face en triangles
sommet1 = face[0]
for i in 1..face.size-1
sommet2 = face[i]
sommet3 = face[i+1]
triangles = Array.new
t = Triangle.new(
# Projection de x et y de chaque sommet selon l'angle de rotation
x1: dotproduct(sommet1, rotation),
y1: sommet1[2],
x2: dotproduct(sommet2, rotation),
y2: sommet2[2],
x3: dotproduct(sommet3, rotation),
y3: sommet3[2],
color: 'red',
z: 100
)
triangles.push(t)
end
for t in triangles
draw_triangle(t)
end
end
end
# normale d'une face (vecteur)
def directionface(face)
directionface = Vector[0, 0, 0]
for sommet in face
directionface += sommet
end
return directionface
end
# produit scalaire entre un vecteur et un angle
def dotproduct(vecteur, angle)
return vecteur[0] * Math.cos(rotation) + vecteur[1] * Math.sin(rotation)
end
def draw_triangle(t, color)
# at first sort the three vertices by y-coordinate ascending so v1 is the topmost vertice
vertices = [[t.x1, t.y1], [t.x2, t.y2], [t.x3, t.y3]]
vertices.sort! { |vertex1, vertex2| vertex1[1] <=> vertex2[1] }
v1 = vertices[0]
v2 = vertices[1]
v3 = vertices[2]
# here we know that v1.y <= v2.y <= v3.y
# check for trivial case of bottom-flat triangle
if v2[1] == v3[1]
fillBottomFlatTriangle(v1, v2, v3, color)
# check for trivial case of top-flat triangle
elsif v1[1] == v2[1]
fillTopFlatTriangle(v1, v2, v3, color)
else
# general case: split the triangle in a topflat and bottom-flat one
v4 = [(v1[0] + ((v2[1] - v1[1]).to_f / (v3[1] - v1[1]).to_f) * (v3[0] - v1[0])).to_i, v2[1]]
fillBottomFlatTriangle(v1, v2, v4, color)
fillTopFlatTriangle(v2, v4, v3, color)
end
end
# remplir le demi-triangle dont le bas est plat
def fillBottomFlatTriangle(v1, v2, v3, color)
invslope1 = (v2[0] - v1[0]).to_f / (v2[1] - v1[1]).to_f
invslope2 = (v3[0] - v1[0]).to_f / (v3[1] - v1[1]).to_f
curx1 = v1[0]
curx2 = v1[0]
for scanlineY in v1[1]..v2[1]
# drawLine(curx1, scanlineY, curx2, scanlineY)
width = curx2 - curx1
height = 1
# fill_rect(x, y, width, height, color)
self.bitmap.fill_rect(curx1, scanlineY, width, height, color)
curx1 += invslope1
curx2 += invslope2
end
end
# remplir le demi-triangle dont le haut est plat
def fillTopFlatTriangle(v1, v2, v3, color)
invslope1 = (v3[0] - v1[0]).to_f / (v3[1] - v1[1]).to_f
invslope2 = (v3[0] - v2[0]).to_f / (v3[1] - v2[1]).to_f
curx1 = v3[0]
curx2 = v3[0]
# il y aura pê un problème ici, car la ligne est pê à l'envers
for scanlineY in v1[1]..v3[1]
# drawLine(curx1, scanlineY, curx2, scanlineY)
width = curx2 - curx1
height = 1
# fill_rect(x, y, width, height, color)
self.bitmap.fill_rect(curx1, scanlineY, width, height, color)
curx1 -= invslope1;
curx2 -= invslope2;
end
end
end
- Roi of the Suisse
- Messages : 2107
- Enregistré le : 28 avr. 2019, 23:38
- Contact :
Re: Kujira no Hara
Voilà ce que ça donne :
- Roi of the Suisse
- Messages : 2107
- Enregistré le : 28 avr. 2019, 23:38
- Contact :
Re: Kujira no Hara
Tonsillolithe ?
- Roi of the Suisse
- Messages : 2107
- Enregistré le : 28 avr. 2019, 23:38
- Contact :
Re: Kujira no Hara
Berk nan.
C’est juste un triakitétraèdre tronqué parce que j’aime bien les triakitétraèdres tronqués.
C’est juste un triakitétraèdre tronqué parce que j’aime bien les triakitétraèdres tronqués.
Re: Kujira no Hara
(un ballon de foot quoi )
Woh. T'as écrit le script toi-même ? Ça marche comment, le moteur colore des surfaces de l'écran en fonction de certains paramètres ?
Le saviez-tu ? La triforce dans l'intro de ALttP est en vraie 3D, de même pour les cristaux qui tournent quand on délivre les descendantes des sept sages.
Woh. T'as écrit le script toi-même ? Ça marche comment, le moteur colore des surfaces de l'écran en fonction de certains paramètres ?
Le saviez-tu ? La triforce dans l'intro de ALttP est en vraie 3D, de même pour les cristaux qui tournent quand on délivre les descendantes des sept sages.
- Roi of the Suisse
- Messages : 2107
- Enregistré le : 28 avr. 2019, 23:38
- Contact :
Re: Kujira no Hara
Non un ballon de foot c’est un icosaèdre tronqué, pas un triakitétraèdre tronqué. Tu ne connais rien au foot ma parole !
Bah euh le script est simple : je note les coordonnées x y z de chaque sommet de l’objet, puis je découpe les faces en triangles, je projette les triangles sur l’écran avec un produit scalaire et voilà.
Pour la couleur de chaque face, c’est encore un produit scalaire, cette fois-ci entre la perpendiculaire de chaque face et le vecteur "lumière" (qui indique la direction de la lumière).
C’est rare qu’on utilise un produit scalaire ou un produit vectoriel dans la vie de tous les jours, mais là c’est le cas.
Oué bah pour Zelda je pense qu’ils ont exactement écrit le même script.
Bah euh le script est simple : je note les coordonnées x y z de chaque sommet de l’objet, puis je découpe les faces en triangles, je projette les triangles sur l’écran avec un produit scalaire et voilà.
Pour la couleur de chaque face, c’est encore un produit scalaire, cette fois-ci entre la perpendiculaire de chaque face et le vecteur "lumière" (qui indique la direction de la lumière).
C’est rare qu’on utilise un produit scalaire ou un produit vectoriel dans la vie de tous les jours, mais là c’est le cas.
Oué bah pour Zelda je pense qu’ils ont exactement écrit le même script.
- Roi of the Suisse
- Messages : 2107
- Enregistré le : 28 avr. 2019, 23:38
- Contact :
Re: Kujira no Hara
Je peux aussi faire des objets simples :
Erf il y a un petit bug sur une face qui s'affiche quand il ne faut pas et qui ne s'affiche pas quand il faudrait
Erf il y a un petit bug sur une face qui s'affiche quand il ne faut pas et qui ne s'affiche pas quand il faudrait
- Roi of the Suisse
- Messages : 2107
- Enregistré le : 28 avr. 2019, 23:38
- Contact :
Re: Kujira no Hara
Spoiler de la fin du jeu
Spoiler
Afficher