[BD3] RigidBodyDynamics (Physik Library für Spiele) - P2

Übersicht BlitzBasic Codearchiv

Neue Antwort erstellen

darth

Betreff: [BD3] RigidBodyDynamics (Physik Library für Spiele) - P2

BeitragFr, Nov 06, 2009 21:28
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

hier folgt wie versprochen der zweite Teil.
Der Funktionsumfang ist diesmal einiges grösser, da es auch die 'endgültige' Library Version darstellen soll. Wie sich herausstellt scheint die Verletimplementation doch schneller zu sein, da man weniger rechnen muss für die Kollisionsantwort, dennoch bleibt der Vorteil der erhöhten Stabilität.

Einschränkungen der Library:
Die Funktionen unterstützen nur eine maximale Anzahl von 32 Vertice pro Körper, das sollte genügen, da man (momentan) noch keine konkaven Körper verwenden kann.
Nach eigenen kleineren Leistungstest kommt man auf etwa 100 Objekte, wenn sie nahe zusammen sind. Es wird eine Abstandskontrolle ausgeführt die nur Kollisionen testet, wenn sich die Körper auch treffen können.
Wie auch beim vorherigen Code sollte man den GarbageCollector mitlaufen lassen, weil sich sonst Fehler einschleichen können, durch Speicherüberflutung.

Einsatzmöglichkeiten der Library:
Nachdem man seinen Körper initialisiert hat, muss man ihn dem System bekannt geben ( addBody() ), dort wird der Körper mit Hilfe des etwas modifizierten Subtracting Ears Method von Noobody direkt in Meshes verwandelt. Nach dem Initialisieren der Kamera ( initGameCam() ) werden diese dann auch dargestellt, hierbei wird es so gehandhabt, dass die Kamera sich wie das 2D Koordinatensystem verhält (Origin in der Mitte des Bildschirms!)
Natürlich hat der Nutzer die Möglichkeit, sich auf die 2D Ebene zu beschränken, indem er die erstellten Meshes löscht ( DestroyMeshes() ) und die 2D Rendermethode ( GameRender() ) benutzt.
Die Geschwindigkeit der Simulation lässt sich mit dem Parameter dt# in der Funktion GameUpdate(dt#) steuern, getestet wurde stets mit 0.125, höhere Werte führen zu schnelleren Bewegungen, aber vorsicht, es kann vorkommen, dass die Simulation zu schnell wird und aus dem Ruder läuft!
Selbstverständlich können auch beide Rendermethoden parallel benutzt werden, man beachte allerdings den erhöhten Aufwand.bj
Der Code ist eigentlich dazu gedacht, dass man gewisse physikalische Objekte in sein Spiel integrieren kann. Zur strikten 2D Benutzung sollte er wohl noch etwas umgeschrieben werden (hauptsächlich die Zeile zur Meshgenerierung auskommentieren), da ich aber von 3D Meshbenutzung ausgehe, setze ich diese Version hierin.

Hier der Code der Library, es hat noch einige Kommentare drin, die getrost ignoriert werden können. Viele dienen zur Gliederung des Codes, einige zur Beschreibung der Funktionen und andere sind unseriöse Bemerkungen meinerseits.
BlitzBasic: [AUSKLAPPEN]
;<STUFF
Global NaN#=1./Floor(0.1)

Function Clampf#(x#,min#,max#)
If x<min
Return min
ElseIf x>max
Return max
EndIf

Return x
End Function

Function Wrapf#(x#,min#,max#)
If x<min
Return x-min+max
ElseIf x>max
Return x-max+min
EndIf

Return x
End Function

Const RtD#=180./Pi
Const DtR#=Pi/180.
Function RadiansToDegrees(rad#)
Return rad*RtD
End Function

Function DegreesToRadians(deg#)
Return deg*DtR
End Function
;STUFF>

;<VECTOR
Type Vector
Field X#
Field Y#

Field used
End Type

Function cVector.Vector(ix#,iy#)
v.Vector=New Vector

v\x=ix
v\y=iy

Return v
End Function

Function opVector_Div(v.Vector,Scalar#)
v\X=v\X/Scalar
v\Y=v\Y/Scalar
End Function

Function opVector_Mult(v.Vector,Scalar#)
v\X=v\X*Scalar
v\Y=v\Y*Scalar
End Function

Function opVector_Add(v.Vector,other.Vector)
v\X=v\X+other\X
v\Y=v\Y+other\Y
End Function

Function opVector_Sub(v.Vector,other.Vector)
v\X=v\X-other\X
v\Y=v\Y-other\Y
End Function

Function opVector_CP#(v.Vector,other.Vector) ;^
Return v\X*other\Y-v\Y*other\X
End Function

Function opVector_DP#(v.Vector,other.Vector)
Return v\X*other\X+v\Y*other\Y
End Function

Function opVectorN_Mult.Vector(v.Vector,Scalar#)
vn.vector=New Vector

vn\x=v\X*Scalar
vn\y=v\Y*Scalar

Return vn
End Function

Function opVectorN_Div.Vector(v.Vector,Scalar#)
vn.vector=New Vector

vn\X=v\X/Scalar
vn\Y=v\Y/Scalar

Return vn
End Function

Function opVectorN_Add.Vector(v.Vector,other.Vector)
vn.vector=New Vector

vn\x=v\X+other\X
vn\y=v\Y+other\Y

Return vn
End Function

Function opVectorN_Sub.Vector(v.Vector,other.Vector)
vn.vector=New Vector

vn\x=v\X-other\X
vn\y=v\Y-other\Y

Return vn
End Function

Function Normalise#(v.Vector)
fLength#=Sqr(v\X*v\X+v\Y*v\Y)

If fLength<=0
Return 0
EndIf

v\X=v\X/fLength
v\Y=v\Y/fLength

Return fLength
End Function

Function Direction.Vector(v.Vector)
temp.vector=New Vector

temp\x=v\X
temp\y=v\Y

Normalise(temp)

Return temp
End Function

Function RotateV(v.Vector,fAngle#)
Local tx#=v\X

v\X=v\X*Cos(fAngle)-v\Y*Sin(fAngle)
v\Y=tx*Sin(fAngle)+v\Y*Cos(fAngle)
End Function

Function RotateVC(v.Vector,xCentre.Vector,fAngle#)
Local D.Vector=opVectorN_Sub(v,xCentre)
RotateV(D,fAngle)

v\X=xCentre\X+D\X
v\Y=xCentre\Y+D\Y
End Function

Function ClampV(v.Vector,min.Vector,max.Vector)
If v\X<min\X
v\X=min\X
ElseIf v\X>max\X
v\X=max\X
EndIf

If v\Y<min\Y
v\Y=min\Y
ElseIf v\Y>max\Y
v\Y=max\Y
EndIf
End Function

Function Randomise(v.Vector,xMin.Vector,xMax.Vector)
v\X=Rnd(xMin\X,xMax\X)
v\Y=Rnd(xMin\Y,xMax\Y)
End Function

Function Length#(v.Vector)
Return Sqr(v\X*v\X+v\Y*v\Y)
End Function
;VECTOR>

;<MATRIX
Type Matrix
Field e11#
Field e12#
Field e21#
Field e22#
End Type

Function cMatrix.Matrix(e11#,e12#,e21#,e22#)
m.matrix=New Matrix

m\e11=e11 : m\e12=e12
m\e21=e21 : m\e22=e22

Return m
End Function

Function cMatrix_Identity.Matrix()
Return cMatrix(1,0,0,1)
End Function

Function cMatrix_Rot.Matrix(fAngle#)
m.matrix=New Matrix

Local c#=Cos(fAngle)
Local s#=Sin(fAngle)

m\e11=c : m\e12=s
m\e21=-s : m\e22=c

Return m
End Function

Function MatrixEntry#(m.Matrix,i,j)
If i=1
If j=1
Return m\e11
ElseIf j=2
Return m\e12
EndIf
ElseIf i=2
If j=1
Return m\e21
ElseIf j=2
Return m\e22
EndIf
EndIf

Return 0
End Function

Function opMatrixN_MMult.Matrix(m.Matrix,other.Matrix)
mn.matrix=New Matrix

mn\e11=m\e11*other\e11+m\e12*other\e21
mn\e21=m\e21*other\e11+m\e22*other\e21
mn\e12=m\e11*other\e12+m\e12*other\e22
mn\e22=m\e21*other\e12+m\e22*other\e22

Return mn
End Function

Function opMatrixN_MPow.Matrix(m.Matrix,other.Matrix)
mn.matrix=New Matrix

mn\e11=m\e11*other\e11+m\e12*other\e12
mn\e21=m\e21*other\e11+m\e22*other\e12
mn\e12=m\e11*other\e21+m\e12*other\e22
mn\e22=m\e21*other\e21+m\e22*other\e22

Return mn
End Function

Function opMatrixN_Mult(m.Matrix,Scalar#)
mn.matrix=New Matrix

mn\e11=m\e11*Scalar
mn\e12=m\e12*Scalar
mn\e21=m\e21*Scalar
mn\e22=m\e22*Scalar
End Function

Function opVectorNs_Mult.Vector(v.Vector,m.Matrix)
vn.Vector=New Vector

vn\x=v\X*m\e11+v\Y*m\e12
vn\y=v\X*m\e21+v\Y*m\e22

Return vn
End Function

Function opVectorNs_Pow.Vector(v.Vector,m.Matrix)
vn.Vector=New Vector

vn\x=v\X*m\e11+v\Y*m\e21
vn\y=v\X*m\e12+v\Y*m\e22

Return vn
End Function

Function opVectors_Mult(v.Vector,m.Matrix)
Local tx#=v\X
Local ty#=v\Y

v\X=tx*m\e11+ty*m\e12
v\Y=tx*m\e21+ty*m\e22
End Function

Function opVectors_Pow(v.Vector,m.Matrix)
Local tx#=v\X
Local ty#=v\Y

v\X=tx*m\e11+ty*m\e21
v\Y=tx*m\e12+ty*m\e22
End Function
;MATRIX>

;<POLYGON

;CHANGES:
; axVertices.Vector[32]
Function BuildBox(axVertices.Vector[32],width#,height#)
axVertices[0]=cVector(-width/2,-height/2)
axVertices[1]=cVector(width/2,-height/2)
axVertices[2]=cVector(width/2,height/2)
axVertices[3]=cVector(-width/2,height/2)

Return
End Function

;CHANGES:
; axVertices.Vector[32]
Function BuildBlob(axVertices.Vector[32],iVerticeCount,radiusx#,radiusy#)
If iVerticeCount=1
axVertices[0]=cVector(0,0)

Return
EndIf

Local a_#=RadiansToDegrees(Pi/iVerticeCount)
Local da_#=RadiansToDegrees(2*Pi/iVerticeCount)

For i=0 To iVerticeCount-1
a_=a_+da_

axVertices[i]=cVector(Cos(a_)*radiusx,Sin(a_)*radiusy)
Next

Return
End Function

Function RenderP(xOffset.Vector,xOrient.Matrix,axVertices.Vector[32],iVerticeCount)
j=iVerticeCount-1
For i=0 To iVerticeCount-1
P1.Vector=opVectorN_Add(xOffset,opVectorNs_Mult(axVertices[i],xOrient))
P2.Vector=opVectorN_Add(xOffset,opVectorNs_Mult(axVertices[j],xOrient))

Line P1\x,P1\y,P2\x,P2\y

j=i
Next
End Function

;CHANGES:
; N.Vector
; t#
Global Coll_t#
Function CollideP(A.Vector[32],Anum,PA.Vector,VA.Vector,OA.Matrix,B.Vector[32],Bnum,PB.Vector,VB.Vector,OB.Matrix,N.Vector,t#)
Coll_t=t

xOrient.Matrix=opMatrixN_MPow(OA,OB)
xOffset.Vector=opVectorNs_Pow(opVectorN_Sub(PA,PB),OB)
xVel.Vector=opVectorNs_Pow(opVectorN_Sub(VA,VB),OB)

Local xAxis.Vector[64]
Local taxis#[64]
iNumAxes=0

If fVel2>0.000001
If Not IntervalIntersect(A,Anum,B,Bnum,xAxis[iNumAxes],xOffset,xVel,xOrient,taxis[iNumAxes],Coll_t)
Return False
EndIf
taxis[iNumAxes]=IntInt_taxis
iNumAxes=iNumAxes+1
EndIf

j=Anum-1
For i=0 To Anum-1
E0.Vector=A[j]
E1.Vector=A[i]
E.Vector=opVectorN_Sub(E1,E0)
xAxis[iNumAxes]=opVectorNs_Mult(cVector(-E\y,E\x),xOrient)

If Not IntervalIntersect(A,Anum,B,Bnum,xAxis[iNumAxes],xOffset,xVel,xOrient,taxis[iNumAxes],Coll_t)
Return False
EndIf
taxis[iNumAxes]=IntInt_taxis
iNumAxes=iNumAxes+1

j=i
Next

j=Bnum-1
For i=0 To Bnum-1
E0.Vector=B[j]
E1.Vector=B[i]
E.Vector=opVectorN_Sub(E1,E0)
xAxis[iNumAxes]=cVector(-E\y,E\x)

If Not IntervalIntersect(A,Anum,B,Bnum,xAxis[iNumAxes],xOffset,xVel,xOrient,taxis[iNumAxes],Coll_t)
Return False
EndIf
taxis[iNumAxes]=IntInt_taxis
iNumAxes=iNumAxes+1

j=i
Next

If Bnum=2
E.Vector=opVectorN_Sub(B[1],B[0])
xAxis[iNumAxes]=E

If Not IntervalIntersect(A,Anum,B,Bnum,xAxis[iNumAxes],xOffset,xVel,xOrient,taxis[iNumAxes],Coll_t)
Return False
EndIf
taxis[iNumAxes]=IntInt_taxis
iNumAxes=iNumAxes+1
EndIf

If Anum=2
E.Vector=opVectorN_Sub(A[1],A[0])
xAxis[iNumAxes]=opVectorNs_Mult(E,xOrient)

If Not IntervalIntersect(A,Anum,B,Bnum,xAxis[iNumAxes],xOffset,xVel,xOrient,taxis[iNumAxes],Coll_t)
Return False
EndIf
taxis[iNumAxes]=IntInt_taxis
iNumAxes=iNumAxes+1
EndIf

If Not FindMTD(xAxis,taxis,iNumAxes,N)
Return False
EndIf
Coll_t=fMTD_t

If opVector_DP(N,xOffset)<0
opVector_Mult(N,-1)
EndIf
opVectors_Mult(N,OB)

Return True
End Function

;CHANGES:
; min#
; max#
Global GetI_min#, GetI_max#
Function GetInterval(axVertices.Vector[32],iVerticeCount,xAxis.Vector)
GetI_min=opVector_DP(axVertices[0],xAxis)
GetI_max=GetI_min

For i=1 To iVerticeCount-1
d#=opVector_DP(axVertices[i],xAxis)

If d<GetI_min
GetI_min=d
ElseIf d>GetI_max
GetI_max=d
EndIf
Next
End Function

;CHANGES:
; taxis#
Global IntInt_taxis#
Function IntervalIntersect(A.Vector[32],Anum,B.Vector[32],Bnum,xAxis.Vector,xOffset.Vector,xVel.Vector,xOrient.Matrix,taxis#,tmax#)
IntInt_taxis=taxis

GetInterval(A,Anum,opVectorNs_Pow(xAxis,xOrient))
min0#=GetI_min
max0#=GetI_max

GetInterval(B,Bnum,xAxis)
min1#=GetI_min
max1#=GetI_max

h#=opVector_DP(xOffset,xAxis)
min0=min0+h
max0=max0+h

d0#=min0-max1
d1#=min1-max0

If d0>0 Or d1>0
v#=opVector_DP(xVel,xAxis)

t0#=-d0/v
t1#=d1/v

If t0>t1
temp#=t0
t0=t1
t1=temp
EndIf

If t0>0
IntInt_taxis=t0
Else
IntInt_taxis=t1
EndIf

If IntInt_taxis<0 Or IntInt_taxis>tmax
Return False
EndIf

Return True
Else
If d0>d1
IntInt_taxis=d0
Else
IntInt_taxis=d1
EndIf

Return True
EndIf
End Function

;CHANGES:
; N.Vector
; t#
Global fMTD_t#
Function FindMTD(xAxis.Vector[64],taxis#[64],iNumAxes,N.Vector)
mini=-1
t#=0 : fMTD_t=0

N\X=0
N\Y=0

For i=0 To iNumAxes-1
If taxis[i]>0
If taxis[i]>t
mini=i
t=taxis[i]
N\X=xAxis[i]\X : N\Y=xAxis[i]\Y
Normalise(N)
EndIf
EndIf
Next

If mini<>-1
fMTD_t=t
Return True
EndIf

mini=-1
For i=0 To iNumAxes-1
n_#=Normalise(xAxis[i])
taxis[i]=taxis[i]/n_

If taxis[i]>t Or mini=-1
mini=i
t=taxis[i]
N\X=xAxis[i]\X : N\Y=xAxis[i]\Y
EndIf
Next

fMTD_t=t
If mini<>-1
Return True
Else
Return False
EndIf
End Function

;CHANGES
; W.Vector
; t#
Global PPOS_t#
Function ProjectPointOnSegment(V.Vector,A.Vector,B.Vector,W.Vector)
AV.Vector=opVectorN_Sub(V,A)
AB.Vector=opVectorN_Sub(B,A)
t#=opVector_DP(AV,AB)/opVector_DP(AB,AB)

If t<0
t=0
ElseIf t>1
t=1
EndIf

PPOS_t=t

W\X=A\X+t*AB\X
W\Y=A\Y+t*AB\y

Return True
End Function

Function Transform.Vector(Vertex.Vector,P.Vector,V.Vector,xOrient.Matrix,t_#)
T.Vector=opVectorN_Add(P,opVectorNs_Mult(Vertex,xOrient))

If t_>0
opVector_Add(T,opVectorN_Mult(V,t_))
EndIf

Return T
End Function

;CHANGES:
; S.Vector[4]
Function FindSupportPoints(N.Vector,t#,A.Vector[32],Anum,PA.Vector,VA.Vector,OA.Matrix,S.Vector[4])
Norm.Vector=opVectorNs_Pow(N,OA)

Local d#[32]
dmin#=opVector_DP(A[0],Norm)
d[0]=dmin

For i=1 To Anum-1
d[i]=opVector_DP(A[i],Norm)

If d[i]<dmin
dmin=d[i]
EndIf
Next

Snum=0
threshold#=0.0001
Local s_#[2]
sign_=False

Perp.Vector=cVector(-Norm\y,Norm\x)

For i=0 To Anum-1
If d[i]<dmin+threshold
Contact.Vector=Transform(A[i],PA,VA,OA,t)

c#=opVector_DP(Contact,Perp)

If Snum<2
s_[Snum]=c
S[Snum]=Contact
Snum=Snum+1

If Snum>1
If s_[1]>s_[0]
sign_=True
Else
sign_=False
EndIf
EndIf
Else
If sign_
min#=s_[0]
max#=s_[1]

xMin.Vector=S[0]
xMax.Vector=S[1]
Else
min#=s_[1]
max#=s_[0]

xMin.Vector=S[1]
xMax.Vector=S[0]
EndIf

If c<min
min=c
xMin=Contact
ElseIf c>max
max=c
xMax=Contact
EndIf
EndIf
EndIf
Next

Return Snum
End Function

;CHANGES:
; S0.Vector[4]
; S1.Vector[4]
; C0.Vector[4]
; C1.Vector[4]
; Cnum
Global CSPTC_Cnum
Function ConvertSupportPointsToContacts(N.Vector,S0.Vector[4],S0num,S1.Vector[4],S1num,C0.Vector[4],C1.Vector[4]) ;int& Cnum
CSPTC_Cnum=0 : Cnum=0

If S0num=0 Or S1num=0
Return False
EndIf

If S0num=1 And S1num=1
C0[Cnum]=S0[0]
C1[Cnum]=S1[0]
Cnum=Cnum+1

CSPTC_Cnum=Cnum
Return True
EndIf

xPerp.Vector=cVector(-N\Y,N\X)

min0#=opVector_DP(S0[0],xPerp)
max0#=min0
min1#=opVector_DP(S1[0],xPerp)
max1#=min1

If S0num=2
max0=opVector_DP(S0[1],xPerp)

If max0<min0
temp#=min0
min0=max0
max0=temp

T.Vector=S0[0]
S0[0]=S0[1]
S0[1]=T
EndIf
EndIf

If S1num=2
max1=opVector_DP(S1[1],xPerp)

If max1<min1
temp#=min1
min1=max1
max1=temp

T.Vector=S1[0]
S1[0]=S1[1]
S1[0]=T
EndIf
EndIf

If min0>max1 Or min1>max0
CSPTC_Cnum=Cnum
Return False
EndIf

If min0>min1
Pseg.Vector=cVector(0,0)
If ProjectPointOnSegment(S0[0],S1[0],S1[1],Pseg)
C0[Cnum]=S0[0]
C1[Cnum]=Pseg
Cnum=Cnum+1
EndIf
Else
Pseg.Vector=cVector(0,0)
If ProjectPointOnSegment(S1[0],S0[0],S0[1],Pseg)
C0[Cnum]=Pseg
C1[Cnum]=S1[0]
Cnum=Cnum+1
EndIf
EndIf

If Abs(max0-min0)>0.0001 And Abs(max1-min1)>0.0001
If max0<max1
Pseg.Vector=cVector(0,0)
If ProjectPointOnSegment(S0[1],S1[0],S1[1],Pseg)
C0[Cnum]=S0[1]
C1[Cnum]=Pseg
Cnum=Cnum+1
EndIf
Else
Pseg.Vector=cVector(0,0)
If ProjectPointOnSegment(S1[1],S0[0],S0[1],Pseg)
C0[Cnum]=Pseg
S1[Cnum]=S1[1]
Cnum=Cnum+1
EndIf
EndIf
EndIf

CSPTC_Cnum=Cnum
Return True
End Function

;CHANGES:
; Cnum
Global FC_Cnum
Function FindContacts(A.Vector[32],Anum,PA.Vector,VA.Vector,OA.Matrix,B.Vector[32],Bnum,PB.Vector,VB.Vector,OB.Matrix,N.Vector,t#,CA.Vector[4],CB.Vector[4],Cnum)
FC_Cnum=Cnum

Local S0.Vector[4]
Local S1.Vector[4]

S0num=FindSupportPoints(N,t,A,Anum,PA,VA,OA,S0)
S1num=FindSupportPoints(opVectorN_Mult(N,-1),t,B,Bnum,PB,VB,OB,S1)

If Not ConvertSupportPointsToContacts(N,S0,S0num,S1,S1num,CA,CB)
FC_Cnum=CSPTC_Cnum
Return False
EndIf

FC_Cnum=CSPTC_Cnum
Return True
End Function

Function CalculateMass#(A.Vector[32],Anum,density#)
If Anum<2
Return 5*density
EndIf

mass#=0

j=Anum-1
For i=0 To Anum-1
P0.Vector=A[j]
P1.Vector=A[i]

mass=mass+Abs(opVector_CP(P0,P1))

j=i
Next

If Anum<=2
mass=10
EndIf

mass=mass*density*0.5

Return mass
End Function

Function CalculateInertia#(A.Vector[32],Anum,mass#)
If Anum=1
Return 0
EndIf

denom#=0
numer#=0

inertia#=0

j=Anum-1
For i=0 To Anum-1
P0.Vector=A[j]
P1.Vector=A[i]

a_#=Abs(opVector_CP(P0,P1))
b_#=opVector_DP(P1,P1)+opVector_DP(P1,P0)+opVector_DP(P0,P0)

denom=denom+(a_*b_)
numer=numer+a_

j=i
Next

inertia#=(mass/6.)*(denom/numer)

Return inertia
End Function
;POLYGON>

;<BODY
Type Body
Field axVertices.Vector[32]
Field iVerticeCount

Field xVelocity.Vector
Field xPosition.Vector

Field fDensity#
Field fMass#
Field fInvMass#
Field fInertia#
Field fInvInertia#

Field fOrientation#
Field fAngVelocity#
Field xOrientation.Matrix

Field xNetForce.Vector
Field fNetTorque#

;<optimize
Field fMaxRadius#
Field fMaxRadiusSqare#
;optimize>

;<filler
Field vx#
Field vy#
Field px#
Field py#
Field vertx#[32]
Field verty#[32]
;filler>
End Type

Function cBody_Empty.Body()
b.Body=New Body

Return b
End Function

Function cBody_Box.Body(xPosition.Vector,fDensity#,width#,height#)
b.Body=New Body

iVerticeCount=4
Local axVertices.Vector[32]
BuildBox(axVertices,width,height)

InitialiseB(b,xPosition,fDensity,axVertices,iVerticeCount)

Return b
End Function

Function cBody_Blob.Body(xPosition.Vector,fDensity#,radiusx#,radiusy#)
b.Body=New Body

iVerticeCount=Rand(3,10)
Local axVertices.Vector[32]
BuildBlob(axVertices,iVerticeCount,radiusx,radiusy)

InitialiseB(b,xPosition,fDensity,axVertices,iVerticeCount)

Return b
End Function

Function InitialiseB(B.Body,xPosition.Vector,fDensity#,axVertices.Vector[32],iVerticeCount)
B\xVelocity=cVector(0,0)
B\fAngVelocity=0
B\xOrientation=cMatrix_Identity()
B\xNetForce=cVector(0,0)
B\fNetTorque=0
B\xPosition=xPosition

B\fDensity=fDensity

B\fMass=CalculateMass(axVertices,iVerticeCount,fDensity)
B\fInertia=CalculateInertia(axVertices,iVerticeCount,B\fMass)

If B\fMass=NaN
B\fMass=0
EndIf
If B\fInertia=NaN
B\fInertia=0
EndIf

If B\fMass>0.0001
B\fInvMass=1/B\fMass
Else
B\fInvMass=0
EndIf

If B\fInertia>0.0001
B\fInvInertia=1/B\fInertia
Else
B\fInvInertia=0
EndIf

maxRad#=0
For i=0 To iVerticeCount-1
B\axVertices[i]=axVertices[i]

actRad#=(B\xPosition\X-B\axVertices[i]\X)^2+(B\xPosition\Y-B\axVertices[i]\Y)^2
If actRad>maxRad
maxRad=actRad
EndIf
Next
B\iVerticeCount=iVerticeCount

B\fMaxRadiusSqare=maxRad
B\fMaxRadius=Sqr(maxRad)
End Function

Function IsUnmovable(B.Body)
If B\fMass<0.0001
Return True
Else
Return False
EndIf
End Function

Function AddForce1(B.Body,F.Vector)
If IsUnmovable(B)
Return
EndIf

opVector_Add(B\xNetForce,F)
End Function

Function AddForce2(B.Body,F.Vector,P.Vector)
If IsUnmovable(B)
Return
EndIf

opVector_Add(B\xNetForce,F)
B\fNetTorque=B\fNetTorque+opVector_CP(opVectorN_Sub(P,B\xPosition),F)
End Function

Function UpdateB(B.Body,dt#)
If IsUnmovable(B)
B\xVelocity\X=0
B\xVelocity\Y=0

B\fAngVelocity=0

Return
EndIf

opVector_Add(B\xPosition,opVectorN_Mult(B\xVelocity,dt))
B\fOrientation=B\fOrientation+B\fAngVelocity*dt
B\fOrientation=Wrapf(B\fOrientation,-2*Pi,2*Pi)
B\xOrientation=cMatrix_Rot(RadiansToDegrees(B\fOrientation))

opVector_Add(B\xVelocity,opVectorN_Mult(B\xNetForce,B\fInvMass*dt))
B\fAngVelocity=B\fAngVelocity+B\fNetTorque*(B\fInvInertia*dt)

B\xNetForce\X=0 : B\xNetForce\Y=0
B\fNetTorque=0
End Function

Function RenderB(B.Body)
If IsUnmovable(B)
Color 125,125,125
Else
Color 255,255,255
EndIf

RenderP(B\xPosition,B\xOrientation,B\axVertices,B\iVerticeCount)
End Function

Function CollideB(A.Body,B.Body,dt#)
If IsUnmovable(A) And IsUnmovable(B)
Return False
EndIf

t#=dt
N.Vector=cVector(0,0)

If CollideP(A\axVertices,A\iVerticeCount,A\xPosition,A\xVelocity,A\xOrientation,B\axVertices,B\iVerticeCount,B\xPosition,B\xVelocity,B\xOrientation,N,t)
t#=Coll_t

Local CA.Vector[4]
Local CB.Vector[4]
Local Cnum

FindContacts(A\axVertices,A\iVerticeCount,A\xPosition,A\xVelocity,A\xOrientation,B\axVertices,B\iVerticeCount,B\xPosition,B\xVelocity,B\xOrientation,N,t,CA,CB,Cnum)
Cnum=FC_Cnum

xContact.Contact=cContact(CA,CB,Cnum,N,t,A,B)
Solve(xContact)

Return True
EndIf

Return False
End Function
;BODY>

;<CONTACT
Const eMaxContacts=2

Type Contact
Field axBodies.Body[2]
Field xContacts.Vector[eMaxContacts*2]
Field xNormal.Vector
Field t#
Field iNumContacts
End Type

Function cContact.Contact(CA.Vector[4],CB.Vector[4],Cnum,N.Vector,t#,pxBodyA.Body,pxBodyB.Body)
C.Contact=New Contact

C\iNumContacts=0
C\axBodies[0]=pxBodyA
C\axBodies[1]=pxBodyB
C\xNormal=N
C\t=t

For i=0 To Cnum-1
AddContactPair(C,CA[i],CB[i])
Next

Return c
End Function

Function AddContactPair(C.Contact,CA.Vector,CB.Vector)
If C\iNumContacts>=eMaxContacts
Return
EndIf

C\xContacts[C\iNumContacts+0*eMaxContacts]=CA
C\xContacts[C\iNumContacts+1*eMaxContacts]=CB
C\iNumContacts=C\iNumContacts+1
End Function

Function Solve(C.Contact)
If C\t<0
ResolveOverlapG(C)
EndIf

ResolveCollisionG(C)
End Function

Function ResolveOverlapG(C.Contact)
If C\axBodies[0]=Null Or C\axBodies[1]=Null
Return
EndIf

For i=0 To C\iNumContacts-1
ResolveOverlap(C,C\xContacts[i+0*eMaxContacts],C\xContacts[i+1*eMaxContacts])
Next
End Function

Function ResolveOverlap(C.Contact,C0.Vector,C1.Vector)
m0#=C\axBodies[0]\fInvMass
m1#=C\axBodies[1]\fInvMass
m#=m0+m1

If C0=Null Or C1=Null
Return
EndIf

D.Vector=opVectorN_Sub(C1,C0)
fRelaxation#=s_fSep

opVector_Mult(D,fRelaxation)

D0.Vector=Null
D1.Vector=Null

If m0>0
D0=opVectorN_Mult(D,m0/m)
opVector_Add(C\axBodies[0]\xPosition,D0)
EndIf
If m1>0
D1=opVectorN_Mult(D,-m1/m)
opVector_Add(C\axBodies[1]\xPosition,D1)
EndIf
End Function

Function ResolveCollisionG(C.Contact)
If C\axBodies[0]=Null Or C\axBodies[1]=Null
Return
EndIf

For i=0 To C\iNumContacts-1
ResolveCollision(C,C\xContacts[i+0*eMaxContacts],C\xContacts[i+1*eMaxContacts])
Next
End Function

Function ResolveCollision(C.Contact,C0.Vector,C1.Vector)
If C0=Null Or C1=Null
Return
EndIf

m0#=C\axBodies[0]\fInvMass
m1#=C\axBodies[1]\fInvMass
i0#=C\axBodies[0]\fInvInertia
i1#=C\axBodies[1]\fInvInertia

P0.Vector=C\axBodies[0]\xPosition
P1.Vector=C\axBodies[1]\xPosition
V0.Vector=C\axBodies[0]\xVelocity
V1.Vector=C\axBodies[1]\xVelocity
w0#=C\axBodies[0]\fAngVelocity
w1#=C\axBodies[1]\fAngVelocity

fCoR#=s_fCoR
fCoF#=s_fCoF

ResolveCollisionB(opVectorN_Mult(C\xNormal,-1),C\t,fCoF,fCoR,C1,P1,V1,w1,m1,i1,C0,P0,V0,w0,m0,i0)
C\axBodies[0]\fAngVelocity=RC_w1
C\axBodies[1]\fAngVelocity=RC_w0
End Function

;CHANGES:
; V0.Vector
; V1.Vector
; w0#
; w1#
Global RC_w0#, RC_w1#
Function ResolveCollisionB(Ncoll.Vector,t#,fCoF#,fCoR#,C0.Vector,P0.Vector,V0.Vector,w0#,m0#,i0#,C1.Vector,P1.Vector,V1.Vector,w1#,m1#,i1#) ;float& w0, float& w1
RC_w0=w0
RC_w1=w1

If t>0
tcoll#=t
Else
tcoll#=0
EndIf

Q0.Vector=opVectorN_Add(P0,opVectorN_Mult(V0,tcoll))
Q1.Vector=opVectorN_Add(P1,opVectorN_Mult(V1,tcoll))
R0.Vector=opVectorN_Sub(C0,Q0)
R1.Vector=opVectorN_Sub(C1,Q1)
T0.Vector=cVector(-R0\y,R0\x)
T1.Vector=cVector(-R1\y,R1\x)
VP0.Vector=opVectorN_Sub(V0,opVectorN_Mult(T0,w0))
VP1.Vector=opVectorN_Sub(V1,opVectorN_Mult(T1,w1))

Vcoll.Vector=opVectorN_Sub(VP0,VP1)
vn_#=opVector_DP(Vcoll,Ncoll)
VN.Vector=opVectorN_Mult(Ncoll,vn_)
VT.Vector=opVectorN_Sub(Vcoll,VN)

If vn_>0
Return
EndIf

vt_#=Normalise(VT)

J.Vector=Null
JT.Vector=cVector(0,0)
JN.Vector=cVector(0,0)

t0_#=opVector_CP(R0,Ncoll)*opVector_CP(R0,Ncoll)*i0
t1_#=opVector_CP(R1,Ncoll)*opVector_CP(R1,Ncoll)*i1
m#=m0+m1

denom#=m+t0_+t1_

jn_#=vn_/denom

JN=opVectorN_Mult(Ncoll,-(1+fCoR)*jn_)

If dbg_useFriction
JT=opVectorN_Mult(Direction(VT),fCoF*jn_)
EndIf

J=opVectorN_Add(JN,JT)

dV0.Vector=opVectorN_Mult(J,m0)
dV1.Vector=opVectorN_Mult(J,-m1)

dw0#=-opVector_CP(R0,J)*i0
dw1#=opVector_CP(R1,J)*i1

If m0>0
opVector_Add(V0,dV0)
w0=w0+dw0
EndIf
If m1>0
opVector_Add(V1,dV1)
w1=w1+dw1
EndIf

If vn_<0 And fCoF>0
cone#=-vt_/vn_

If cone#<fCoF
Nfriction.Vector=opVectorN_Mult(Direction(VT),-1)
fCoS#=s_fCoS

ResolveCollisionB(Nfriction,0,0,fCoS,C0,P0,V0,w0,m0,i0,C1,P1,V1,w1,m1,i1)
w0=RC_w0
w1=RC_w1
EndIf
EndIf

RC_w0=w0
RC_w1=w1
End Function
;CONTACT>

;<GAME CODE
Const s_fCoF#=0.2
Const s_fCoR#=0.3
Const s_fCoS#=0.4
Const s_fSep#=0.5
Global s_xGravity.Vector=cVector(0,0.5)

Global dbg_useFriction=True
Global dbg_useGravity=True

Const s_MAX_BODIES=100
Global s_axBody.Body[s_MAX_BODIES]
Global s_pxPlayer.Body
Global s_iBodyCount=15

Function GameUpdate(dt#)
For i=0 To s_iBodyCount-1
If s_axBody[i]<>Null
If dbg_useGravity
AddForce1(s_axBody[i],opVectorN_Mult(s_xGravity,s_axBody[i]\fMass)) ;cVector(0,0.5*s_axBody[i]\fMass))
EndIf
EndIf
Next

For i=0 To s_iBodyCount-1
If s_axBody[i]<>Null
For j=i+1 To s_iBodyCount-1
If s_axBody[j]<>Null
If IsUnmovable(s_axBody[i])=0 Or IsUnmovable(s_axBody[j])=0
;ich wunder mich:
; Body[i]\MaxRadius^2+Body[j]\MaxRadius^2<(Body[i]\MaxRadius+Body[j]\MaxRadius)^2 und doch funktionierts

BodyDist#=(s_axBody[i]\xPosition\X-s_axBody[j]\xPosition\X)*(s_axBody[i]\xPosition\X-s_axBody[j]\xPosition\X)+(s_axBody[i]\xPosition\Y-s_axBody[j]\xPosition\Y)*(s_axBody[i]\xPosition\Y-s_axBody[j]\xPosition\Y)
;MaxDist#=(s_axBody[i]\fMaxRadius+s_axBody[j]\fMaxRadius)*(s_axBody[i]\fMaxRadius+s_axBody[j]\fMaxRadius)
MaxDist#=s_axBody[i]\fMaxRadiusSqare+s_axBody[j]\fMaxRadiusSqare
If BodyDist<MaxDist
CollideB(s_axBody[i],s_axBody[j],dt)
EndIf
EndIf
EndIf
Next
EndIf
Next

For i=0 To s_iBodyCount-1
If s_axBody[i]<>Null
If Not IsUnmovable(s_axBody[i])
UpdateB(s_axBody[i],dt)
EndIf
EndIf
Next
End Function

Function GameRender()
LockBuffer BackBuffer()

For b.body=Each Body
RenderB(b)
Next

UnlockBuffer BackBuffer()
End Function

Function GC()
Local B.Body
For B.Body=Each Body
B\vx=B\xVelocity\X
B\vy=B\xVelocity\Y

B\px=B\xPosition\X
B\py=B\xPosition\Y

For i=0 To B\iVerticeCount-1
B\vertx[i]=B\axVertices[i]\X
B\verty[i]=B\axVertices[i]\Y
Next
Next

gx#=s_xGravity\X : gy#=s_xGravity\Y
Delete Each Vector
Delete Each Matrix
Delete Each Contact
s_xGravity=cVector(gx,gy)

For B.Body=Each Body
B\xVelocity=cVector(B\vx,B\vy)
B\xPosition=cVector(B\px,B\py)
B\xOrientation=cMatrix_Rot(RadiansToDegrees(B\fOrientation))
B\xNetForce=cVector(0,0)

For i=0 To B\iVerticeCount-1
B\axVertices[i]=cVector(B\vertx[i],B\verty[i])
Next
Next
End Function
;GAME CODE>

;<3D STUFF
Function addBody(B.Body)
s_axBody[s_iBodyCount]=B
s_Mesh[s_iBodyCount]=GenerateMesh(B)

s_iBodyCount=s_iBodyCount+1
End Function

Function addVertice(B.Body,V.Vector)
B\axVertices[B\iVerticeCount]=V
B\iVerticeCount=B\iVerticeCount+1
End Function

Global s_Mesh[s_MAX_BODIES]
Global s_GameCam

Function initGameCam()
s_GameCam=CreateCamera()

PositionEntity s_GameCam,0,0,GraphicsWidth()/2
RotateEntity s_GameCam,0,180,180
End Function

Type TmpTrig
Field V1.Vector
Field V2.Vector
Field V3.Vector
End Type

Function GenerateMesh(B.Body)
SubtractingEars(B,B\axVertices[0])

Mesh=CreateMesh()
EntityFX Mesh,16
Surf=CreateSurface(Mesh)

For t.TmpTrig=Each TmpTrig
v1=AddVertex(Surf,t\v1\x,t\v1\y,0)
v2=AddVertex(surf,t\v2\x,t\v2\y,0)
v3=AddVertex(Surf,t\v3\x,t\v3\y,0)

AddTriangle(surf,v1,v2,v3)
Next

Delete Each TmpTrig

Return Mesh
End Function

Function SubtractingEars(B.Body,Vertex.Vector)
For i=0 To B\iVerticeCount-1
If Vertex=B\axVertices[i]
vIndex=i
Exit
EndIf
Next

Pred.Vector=PredVertex(B,vIndex)
Succ.Vector=SuccVertex(B,vIndex)

If LineInPoly(B,Pred,Succ,Vertex) Or VertexCount(B)=3
Triangle.TmpTrig=New TmpTrig
Triangle\V1=Vertex
Triangle\V2=Pred
Triangle\V3=Succ

Vertex\used=True
EndIf

If VertexCount(B)>=3
SubtractingEars(B,Succ)
EndIf
End Function

Function PredVertex.Vector(B.Body,vIndex)
While True
vIndex=vIndex-1
If vIndex<0
vIndex=B\iVerticeCount-1
EndIf

If Not B\axVertices[vIndex]\used
Return B\axVertices[vIndex]
EndIf
Wend
End Function

Function SuccVertex.Vector(B.Body,vIndex)
While True
vIndex=vIndex+1
If vIndex>B\iVerticeCount-1
vIndex=0
EndIf

If Not B\axVertices[vIndex]\used
Return B\axVertices[vIndex]
EndIf
Wend
End Function

Function VertexCount(B.Body)
count=0

For i=0 To B\iVerticeCount-1
If Not B\axVertices[i]\used
count=count+1
EndIf
Next

Return count
End Function

Function LineInPoly(B.Body,V1.Vector,V2.Vector,MidVertex.Vector)
angle#=(360+ATan2(V1\Y-MidVertex\Y,V1\X-MidVertex\X)-ATan2(V2\Y-MidVertex\Y,V2\X-MidVertex\X)) Mod 360

If angle>180
Return False
EndIf

For i=0 To B\iVerticeCount-1
Succ.Vector=SuccVertex(B,i)

If B\axVertices[i]<>V1 And B\axVertices[i]<>V2 And Succ<>V1 And Succ<>V2
If LineCollision(V1\X,V1\Y,V2\X-V1\X,V2\Y-V1\Y,B\axVertices[i]\X,B\axVertices[i]\Y,succ\x-B\axVertices[i]\X,succ\y-B\axVertices[i]\Y)
Return False
EndIf
EndIf
Next

vx#=V1\Y-V2\Y
vy#=V2\X-V1\X

c#=-V1\X*vx-V1\Y*vy

sign=0
For i=0 To B\iVerticeCount-1
If B\axVertices[i]<>V1 And B\axVertices[i]<>V2
If sign
If sign<>Sgn(B\axVertices[i]\X*vx+B\axVertices[i]\Y*vy+c)
Exit
EndIf
Else
sign=Sgn(B\axVertices[i]\X*vx+B\axVertices[i]\Y*vy+c)
EndIf
EndIf
Next

Return True
End Function

Function LineCollision(X1#,Y1#,VX1#,VY1#,X2#,Y2#,VX2#,VY2#)
If VX1=0 Then VX1=0.001
If VY1=0 Then VY1=0.001
If VX2=0 Then VX2=0.001
If VY2=0 Then VY2=0.001

IntersectionX#=-(X1*VX2*VY1-(X2*VY2+(Y1-Y2)*VX2)*VX1)/(VX1*VY2-VX2*VY1)
IntersectionT#=(IntersectionX-X1)/VX1

If IntersectionT>=0 And IntersectionT<=1
IntersectionT=(IntersectionX-X2)/VX2

If IntersectionT>=0 And IntersectionT<=1
Return True
EndIf
EndIf
End Function

Function DestroyMeshes()
For i=0 To s_iBodyCount-1
If s_Mesh[i]<>0
FreeEntity s_Mesh[i]
s_Mesh[i]=0
EndIf
Next

If s_GameCam<>0
FreeEntity s_GameCam
s_GameCam=0
EndIf
End Function

Function UpdateMeshes()
For i=0 To s_iBodyCount-1
PositionEntity s_Mesh[i],s_axBody[i]\xPosition\X,s_axBody[i]\xPosition\Y,0
RotateEntity s_Mesh[i],0,0,RadiansToDegrees(-s_axBody[i]\fOrientation)
Next
End Function
;3D STUFF>

(ich hoffe die Codebox macht meine Teilungskommentare nicht wieder kaputt)

Und erneut eine kleine Sandbox zum Test:
WARNUNG: Benötigt den Library Code von oben. Hineinkopieren oder speichern als "RigidPhysicsLib.bb"
BlitzBasic: [AUSKLAPPEN]
Include "RigidPhysicsLib.bb"

Function GameInit()
xBottom.Vector=cVector(0,240)
xTop.Vector=cVector(0,-240)
xLeft.Vector=cVector(-320,0)
xRight.Vector=cVector(320,0)
xCentre.Vector=cVector(0,0)

s_axBody[0]=cBody_Box(xBottom,0,640,5)
s_axBody[1]=cBody_Box(xTop,0,640,5)
s_axBody[2]=cBody_Box(xLeft,0,5,480)
s_axBody[3]=cBody_Box(xRight,0,5,480)
s_axBody[4]=cBody_Box(xCentre,0,30,30)

For i=5 To s_iBodyCount-1
s_axBody[i]=cBody_Blob(cVector(Rnd(-300,300),Rnd(-200,-100)),0.075,Rnd(10,25),Rnd(10,25))
s_axBody[i]\fAngVelocity=Rnd(0.1,0.5)
s_axBody[i]\fOrientation=Rnd(0,Pi)
s_axBody[i]\xOrientation=cMatrix_Rot(RadiansToDegrees(s_axBody[i]\fOrientation))
Next

For i=0 To s_iBodyCount-1
s_Mesh[i]=GenerateMesh(s_axBody[i])
Next
End Function

Global screenWidth#=640
Global screenHeight#=480
Global timer=CreateTimer(60)
Graphics3D screenWidth,screenHeight,0,2
SetBuffer BackBuffer()

initGameCam()

Origin 320,240

GameInit()

While Not KeyHit(1)
RenderWorld

If MouseHit(1)
If s_iBodyCount<s_MAX_BODIES-1
tmpBody.Body=cBody_Blob(cVector(MouseX()-GraphicsWidth()/2,MouseY()-GraphicsHeight()/2),0.1,Rnd(10,25),Rnd(10,25))
addBody(tmpBody)
EndIf
EndIf

GameUpdate(0.125)
;GameRender()
UpdateMeshes()

Color 255,255,255
fps=fps+1
If MilliSecs()-fpsTime>999
fpsCur=fps
fpsTime=MilliSecs()
fps=0
EndIf
Text 300,220,fpsCur

Text -310,-230,(s_iBodyCount-4)

Flip 0
Cls
WaitTimer(timer)

GC()
Wend


Der Code ist ausgiebig getestet, aber dennoch gilt das Prinzip [i]errare humanum est, solltet ihr also Fehler oder Verbesserungsvorschläge haben, bin ich immer offen dafür.
Ich möchte eigentlich versuchen, den Code nach C++ zu portieren, um eine DLL daraus zu machen, um noch etwas mehr Geschwindigkeit herauszuholen, aber dazu muss ich mir noch die Kommunikation zwischen C++ und BlitzBasic genauer betrachten.

Bis dahin:
GG, HF, GL

MfG,
Darth

Danksagung
Chris Hecker, Tutorial
Noobody, Triangulierungsmethode
  • Zuletzt bearbeitet von darth am Sa, Nov 07, 2009 14:13, insgesamt einmal bearbeitet

Triton

BeitragSa, Nov 07, 2009 2:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Dies ist also das gleiche wie die andere, nur besser?

Dann kann ich die alte doch Trashen?!


edit--
Na fein.
Coding: silizium-net.de | Portfolio: Triton.ch.vu
  • Zuletzt bearbeitet von Triton am Sa, Nov 07, 2009 14:37, insgesamt einmal bearbeitet

darth

BeitragSa, Nov 07, 2009 2:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Triton,

es ist nicht direkt das gleiche. Der Einsatzbereich ist ein anderer (meiner Meinung nach). Der erste Teil ist eher für Kollisionsphysik für Spiele gedacht, wenn man nicht will, dass sich die Figuren stets hinundher drehen. Dieser Teil hier ist für realistischere Physikeinbindungen gedacht.
Natürlich kann man einfach sämtliche Winkelgeschwindigkeiten nachträglich wieder auf 0 setzen, dann hat man im Prinzip wieder Teil 1, aber für diesen Einsatzbereich würde halt zuviel unnötiges gerechnet.

Wenn du immernoch denkst es sei sich zu gleich, dann kannst du den anderen Thread natürlich löschen.

MfG,
Darth
Diese Signatur ist leer.

ToeB

BeitragSa, Nov 07, 2009 12:40
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich krige hier einen fehler mit Blitzarray (in der Lib):

Code: [AUSKLAPPEN]
Function BuildBlob(axVertices.Vector[32],iVerticeCount,radiusx#,radiusy#)
If iVerticeCount=1
axVertices[0]=cVector(0,0)

Return
EndIf

Local a_#=RadiansToDegrees(Pi/iVerticeCount)
Local da_#=RadiansToDegrees(2*Pi/iVerticeCount)

For i=0 To iVerticeCount-1
a_=a_+da_

axVertices=cVector(Cos(a_)*radiusx,Sin(a_)*radiusy) ;HIER <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Next

Return
End Function

Function RenderP(xOffset.Vector,xOrient.Matrix,axVertices.Vector[32],iVerticeCount)
j=iVerticeCount-1
For i=0 To iVerticeCount-1
P1.Vector=opVectorN_Add(xOffset,opVectorNs_Mult(axVertices[i],xOrient))
P2.Vector=opVectorN_Add(xOffset,opVectorNs_Mult(axVertices[j],xOrient))

Line P1\x,P1\y,P2\x,P2\y

j=i
Next
End Function


??
Religiöse Kriege sind Streitigkeiten erwachsener Männer darum, wer den besten imaginären Freund hat.
Race-Project - Das Rennspiel der etwas anderen Art
SimpleUDP3.0 - Neuste Version der Netzwerk-Bibliothek
Vielen Dank an dieser Stelle nochmal an Pummelie, welcher mir einen Teil seines VServers für das Betreiben meines Masterservers zur verfügung stellt!

darth

BeitragSa, Nov 07, 2009 14:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo ToeB,

danke für den Hinweis. Da sollte (und es tut) ein [ i ] dahinter stehen, scheinbar wird das vom BB-Syntax-Hilight-Algorithmus als italic interpretiert, und rausgenommen.
Ich habe nun auf normal Code umgestellt, damit alles richtig dargestellt wird.

user posted image

[Edit]
Dank unermüdlichem Einsatz seitens der Administration ist der kleine Fehler korrigiert. Die Codes sind nun wieder bunt und sollten alle Zeichen beinhalten. Ich habe vorhin alles kopiert um zu testen, ob noch irgendwo etwas kaputt gegangen sein könnte, und es hat funktioniert. Der Code sollte also einsetzbar sein.
Danke liebe Administration für eure Arbeit Smile .

MfG,
Darth
Diese Signatur ist leer.

Neue Antwort erstellen


Übersicht BlitzBasic Codearchiv

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group