Hi,
Something like this ?? its not a good example but the method works.. I needs a better mapped model to work with so that each triangle has a unique texture position.
Global LM_red=0,LM_grn=0,LM_blu=0
Global DEBUG=True
Graphics3D 640,480,0,2
SetBuffer BackBuffer()
cam=CreateCamera()
PositionEntity cam,0,3,-10
;l=CreateLight()
Addlight -6,0,0 ,6 ,255,0,0
Addlight 0,10,6 ,6 ,0,255,0
Addlight 6,0,0 ,6 ,0,0,255
tex2=LoadTexture("nskinwh.jpg")
mesh=LoadMesh("ninja.b3d")
tex=VMapp(mesh,tex2)
EntityTexture mesh,tex2
While Not KeyDown(1)
TurnEntity mesh,0,1,0
If KeyHit(32) Then Debug=1-debug
RenderWorld
If DEBUG
CopyRect 0,0,TextureWidth(tex2),TextureHeight(tex2),0,0,TextureBuffer(tex2),BackBuffer()
EndIf
Flip
Wend
Function Max3Vect(a#,b#,c#)
If a<0 Then a=-a
If b<0 Then b=-b
If c<0 Then c=-c
If a>b And a>c Then Return 1
If b>a And b>c Then Return 2
If c>a And c>b Then Return 3
If a=b Then a=a+0.00001
If b=c Then b=b+0.00002
If c=a Then c=c+0.00003
Return 0
End Function
Function VMapp(ent, Tex)
; TexFinal# = this to match the scale of the texture on the entity
this_tex=tex
texfinal#=TextureWidth(tex)
buff=GraphicsBuffer()
SetBuffer TextureBuffer(this_tex)
LockBuffer TextureBuffer(this_tex)
Local vx#[2],vy#[2],vz#[2],vu#[2],vv#[2]
Local x#,y#,z#,nx#,ny#,nz#,nd#
surf=GetSurface(ent,1)
For t=0 To CountTriangles(surf)-1
minu#=9999:maxu#=-9999
minv#=9999:maxv#=-9999
;Convert to World Scale
For b=0 To 2
x=VertexX(surf,TriangleVertex(surf,t,b))
y=VertexY(surf,TriangleVertex(surf,t,b))
z=VertexZ(surf,TriangleVertex(surf,t,b))
TFormPoint x,y,z,ent,0
vx[b]=x:vy[b]=y:vz[b]=z
vu[b]=VertexU(surf,TriangleVertex(surf,t,b))
vv[b]=VertexV(surf,TriangleVertex(surf,t,b))
If vu[b]<minu Then minu=vu[b]
If vu[b]>maxu Then maxu=vu[b]
If vv[b]<minv Then minv=vv[b]
If vv[b]>maxv Then maxv=vv[b]
Next
uvwid#=maxu-minu
uvhgt#=maxv-minv
tex_x#=TexFinal*uvwid
tex_y#=TexFinal*uvhgt
tx#=minu#*TexFinal
ty#=minv#*TexFinal
;Calc the normal
x1#=vx[1]-vx[2]
y1#=vy[1]-vy[2]
z1#=vz[1]-vz[2]
x2#=vx[1]-vx[0]
y2#=vy[1]-vy[0]
z2#=vz[1]-vz[0]
nx=(y1*z2)-(z1*y2)
ny=(z1*x2)-(x1*z2)
nz=(x1*y2)-(y1*x2)
nd=-((nx*vx[0])+(ny*vy[0])+(nz*vz[0]))
Select Max3Vect(nx,ny,nz)
Case 1; YZ Plane
PX#=-((nz*MinU)+(ny*MinV)+nd)/nx
VectorX#=PX:VectorY#=MinV:VectorZ#=MinU
PX#=-((nz*MaxU)+(ny*MinV)+nd)/nx
Vect1X#=PX : Vect1Y#=MinV : Vect1Z#=MaxU
PX#=-((nz*MinU)+(ny*MaxV)+nd)/nx
Vect2X#=PX : Vect2y#=MaxV : Vect2Z#=MinU
Case 2; XZ Plane
PY#=-((nx*MinU)+(nz*MinV)+nd)/ny
VectorX#=MinU:VectorY#=PY:VectorZ#=MinV
PY#=-((nx*MaxU)+(nz*MinV)+nd)/ny
Vect1X#=MaxU : Vect1Y#=PY : Vect1Z#=MinV
PY#=-((nx*MinU)+(nz*MaxV)+nd)/ny
Vect2X#=MinU : Vect2Y#=PY : Vect2Z#=MaxV
Case 3; XY Plane
PZ#=-((nx*MinU)+(ny*MinV)+nd)/nz
VectorX#=MinU:VectorY#=MinV:VectorZ#=PZ
PZ#=-((nx*MaxU)+(ny*MinV)+nd)/nz
Vect1X#=MaxU : Vect1Y#=MinV : Vect1Z#=PZ
PZ#=-((nx*MinU)+(ny*MaxV)+nd)/nz
Vect2X#=MinU : Vect2Y#=MaxV : Vect2Z#=PZ
End Select
e1X# =Vect1X-VectorX
e1Y# =Vect1Y-VectorY
e1Z# =Vect1Z-VectorZ
e2X# =Vect2X-VectorX
e2Y# =Vect2Y-VectorY
e2Z# =Vect2Z-VectorZ
For iX# = 0 To Int(tex_x)-1
For iY# = 0 To Int(tex_y)-1
ufactor#= Float(ix)/Float(tex_x)
vfactor#= Float(iy)/Float(tex_y)
ne1X#= e1X*ufactor
ne1Y#= e1Y*ufactor
ne1Z#= e1Z*ufactor
ne2X#= e2X*vfactor
ne2Y#= e2Y*vfactor
ne2Z#= e2Z*vfactor
lx#=VectorX+ne2X+ne1X
ly#=VectorY+ne2Y+ne1Y
lz#=VectorZ+ne2Z+ne1Z
;check if point is in triangle
If InsideTriangle(ix+tx,iy+ty,vu[0]*texfinal,vv[0]*texfinal,vu[1]*texfinal,vv[1]*texfinal,vu[2]*texfinal,vv[2]*texfinal)
col=ReadPixelFast(tx+ix,ty+iy,TextureBuffer(this_tex)) And $ffffff
fcr#=(col And $ff0000) Shr 16
fcg#=(col And $ff00) Shr 8
fcb#=col And $ff
LM_Red=0
LM_grn=0
LM_blu=0
;point is in triangle
;so check it against all the lights in the scene
For l.Light=Each light
dx#=lx-l\x
dy#=ly-l\y
dz#=lz-l\z
trange#=Sqr(dx*dx+dy*dy+dz*dz)
lvx#=dx/trange
lvy#=dy/trange
lvz#=dz/trange
lightatpoint l\r,l\g,l\b,lvx,lvy,lvz,l\range,trange,nx,ny,nz
Next
lm_red=(lm_red+fcr)/2
lm_grn=(lm_grn+fcg)/2
lm_blu=(lm_blu+fcb)/2
col=(LM_red Shl 16) Or (LM_grn Shl 8) Or (LM_blu)
WritePixelFast tx+ix,ty+iy,col,TextureBuffer(this_tex)
EndIf
Next
Next
For b=0 To 2
VertexTexCoords surf,TriangleVertex(surf,t,b),vu[b],vv[b],0,1
Next
If DEBUG
Color 255,255,255
Line vu[0]*texfinal,vv[0]*texfinal,vu[1]*texfinal,vv[1]*texfinal
Line vu[1]*texfinal,vv[1]*texfinal,vu[2]*texfinal,vv[2]*texfinal
Line vu[2]*texfinal,vv[2]*texfinal,vu[0]*texfinal,vv[0]*texfinal
EndIf
Next
UnlockBuffer TextureBuffer(this_tex)
SetBuffer buff
End Function
Function CapVal_float#(val#,min#,max#)
If val>min And val<max Then Return val
If val<min Then Return min
If val>max Then Return max
Return val
End Function
Function dot(x0#,y0#,x1#,y1#,x2#,y2#)
Return (x1#-x0#)*(y2#-y1#)-(x2#-x1#)*(y1#-y0#)
End Function
Function InsideTriangle(px#,py#,x0#,y0#,x1#,y1#,x2#,y2#)
If dot(x0,y0,x1,y1,px,py)>=0
If dot(x1,y1,x2,y2,px,py)>=0
If dot(x2,y2,x0,y0,px,py)>=0
Return True
EndIf
EndIf
EndIf
End Function
Type light
Field r#,g#,b#
Field x#,y#,z#
Field range#
End Type
;Light
Function LightatPoint(lr#,lg#,lb#,lvx#,lvy#,lvz#,lrange#,range#,nx#,ny#,nz#)
CosAng#=((lvx*nx)+(lvy*ny)+(lvz*nz))
att0#=.63
att1#=.025
att2#=.055
If cosang<0 Then Return False
Att# = 1 / (Att0 + (Att1 * range) + (Att2 * range * range))
Intensity# = (lrange*.75 ) *att * cosAng
LM_Red=capval_Float((lr * intensity) + LM_Red,0,255)
LM_Grn=capval_Float((lg * intensity) + LM_Grn,0,255)
LM_Blu=capval_Float((lb * intensity) + LM_Blu,0,255)
Return True
End Function
Function AddLight.light(x#,y#,z#,rng#,r#=255,g#=255,b#=255)
l.Light=New Light
l\x=x
l\y=y
l\z=z
l\r=r
l\g=g
l\b=b
l\range=rng
Return l
End Function
|