'**********************************************************************************************
' FzxNGN written by justsomeguy
' Physics code ported from RandyGaul's Impulse Engine
' https://github.com/RandyGaul/ImpulseEngine
' http://RandyGaul.net
'**********************************************************************************************
'/*
' Copyright (c) 2013 Randy Gaul http://RandyGaul.net
' This software is provided 'as-is', without any express or implied
' warranty. In no event will the authors be held liable for any damages
' arising from the use of this software.
' Permission is granted to anyone to use this software for any purpose,
' including commercial applications, and to alter it and redistribute it
' freely, subject to the following restrictions:
' 1. The origin of this software must not be misrepresented; you must not
' claim that you wrote the original software. If you use this software
' in a product, an acknowledgment in the product documentation would be
' appreciated but is not required.
' 2. Altered source versions must be plainly marked as such, and must not be
' misrepresented as being the original software.
' 3. This notice may not be removed or altered from any source distribution.
'
' Port to QB64 by justsomeguy
'*/
'
'**********************************************************************************************
' Setup Types and Variables
'**********************************************************************************************
Type tTRIANGLE
' Not used
ty
As Integer ' cSHAPE_CIRCLE = 1, cSHAPE_POLYGON = 2 radius
As _Float ' Only necessary for circle shapes u
As tMATRIX2d
' Only neceassary for polygons flipTexture
As Integer 'flag for flipping texture depending on direction
Type tPOLY
'list of vertices for all objects in simulation
Type tPOLYATTRIB
'keep track of polys in monlithic list of vertices start
As Integer ' starting vertex of the polygon count
As Integer ' number of vertices in polygon
localAnchor1
As tVECTOR2d
localAnchor2
As tVECTOR2d
Const cMAXNUMOFTRIANGLES
= 100 Const cMAXNUMBEROFOBJECTS
= 1000 ' Max number of objects at one time Const cMAXNUMBEROFPOLYGONS
= 10000 ' Max number of total vertices included in all objects Const cMAXNUMBEROFJOINTS
= 100 Const cMAXNUMBEROFHITS
= 1000 Const cEPSILON_SQ
= cEPSILON
* cEPSILON
Const cBIAS_RELATIVE
= 0.95 Const cBIAS_ABSOLUTE
= 0.01 Const cPENETRATION_ALLOWANCE
= 0.05 Const cPENETRATION_CORRECTION
= 0.4 ' misspelled in original code Const cPARAMETER_POSITION
= 1 Const cPARAMETER_VELOCITY
= 2 Const cPARAMETER_FORCE
= 3 Const cPARAMETER_ANGULARVELOCITY
= 4 Const cPARAMETER_TORQUE
= 5 Const cPARAMETER_ORIENT
= 6 Const cPARAMETER_STATICFRICTION
= 7 Const cPARAMETER_DYNAMICFRICTION
= 8 Const cPARAMETER_COLOR
= 9 Const cPARAMETER_VISIBLE
= 10 Const cPARAMETER_STATIC
= 11 Const cPARAMETER_TEXTURE
= 12 Const cPARAMETER_FLIPTEXTURE
= 13 Const cRENDER_COLLISIONS
= 0 Const cPLAYER_FORCE
= 1000000
Dim Shared sRESTING
As _Float:
Dim o
As tVECTOR2d:
Call vectorMultiplyScalarND
(o
, sGRAVITY
, cDT
): sRESTING
= vectorLengthSq
(o
) + cEPSILON
Dim Shared sNUMBEROFBODIES
As Integer: sNUMBEROFBODIES
= 50 ' 0 is included - Don't go under 25 for the current scene Dim Shared sNUMBEROFJOINTS
As Integer: sNUMBEROFJOINTS
= 12 ' if zero then no joints at all
Dim poly
(cMAXNUMBEROFPOLYGONS
) As tPOLY
Dim polyattributes
(cMAXNUMBEROFPOLYGONS
) As tPOLYATTRIB
Dim body
(cMAXNUMBEROFOBJECTS
) As tBODY
Dim joints
(cMAXNUMBEROFJOINTS
) As tJOINT
Dim hits
(cMAXNUMBEROFHITS
) As tHIT
Const cSCENE_SPINNEROFDEATH
= 2 Const cSCENE_RIGHTRAMP
= 3 Const cSCENE_LEFTRAMP
= 4 Const cSCENE_DOZEROFDOOM
= 5 Const cSCENE_ELEVATOROFTERROR
= 6 Const cSCENE_RIGHTWALL
= 7 Const cSCENE_ELEVATORKICKER
= 8 Const cSCENE_PENDULUM
= 10
'**********************************************************************************************
_Title "FzxNGN" ' vowels are obsolete
Call buildSimpleScene
(poly
(), polyattributes
(), body
(), joints
()) '**********************************************************************************************
Call impulseStep
(poly
(), polyattributes
(), body
(), joints
(), cDT
, cITERATIONS
, hits
()) Call renderBodies
(poly
(), polyattributes
(), body
(), joints
(), hits
()) Call animateScene
(body
(), hits
()) '**********************************************************************************************
' End of Main loop
'**********************************************************************************************
'**********************************************************************************************
' Scene Creation and Handling Ahead
'**********************************************************************************************
Sub animateScene
(body
() As tBODY
, hits
() As tHIT
)
Call setBody
(body
(), cPARAMETER_ORIENT
, cSCENE_USER
, 0, 0) If isBodyTouching
(hits
(), cSCENE_USER
) Then Call vectorSet
(body
(cSCENE_USER
).force
, 0, -cPLAYER_FORCE
)
Call vectorSet
(body
(cSCENE_USER
).force
, -cPLAYER_FORCE
/ 10, 0)
Call vectorSet
(body
(cSCENE_USER
).force
, cPLAYER_FORCE
/ 10, 0)
body(cSCENE_USER).velocity.x = impulseClamp(-100, 100, body(cSCENE_USER).velocity.x)
body(cSCENE_USER).velocity.y = impulseClamp(-100, 100, body(cSCENE_USER).velocity.y)
Call setBody
(body
(), cPARAMETER_ORIENT
, cSCENE_SPINNEROFDEATH
, body
(cSCENE_SPINNEROFDEATH
).orient
+ (cPI
/ 90), 0) If body
(cSCENE_SPINNEROFDEATH
).orient
> 2 * cPI
Then body
(cSCENE_SPINNEROFDEATH
).orient
= 0
Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_DOZEROFDOOM
, body
(cSCENE_DOZEROFDOOM
).position.x
- 1, _Height - 75) If body
(cSCENE_DOZEROFDOOM
).position.x
< 120 Then body
(cSCENE_DOZEROFDOOM
).position.x
= _Width
Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_ELEVATOROFTERROR
, 55, body
(cSCENE_ELEVATOROFTERROR
).position.y
- 1) If body
(cSCENE_ELEVATOROFTERROR
).position.y
< 50 Then body
(cSCENE_ELEVATOROFTERROR
).position.y
= _Height - 25
Sub buildSimpleScene
(p
() As tPOLY
, pa
() As tPOLYATTRIB
, body
() As tBODY
, j
() As tJOINT
) Call generateBitmap
(bm
()) ' auto generated bitmaps can be substituted for whatever images you have
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_USER
, 20, 20) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_USER
, (20), (20)) Call setBody
(body
(), cPARAMETER_VELOCITY
, cSCENE_USER
, 0, 0) Call setBody
(body
(), cPARAMETER_TEXTURE
, cSCENE_USER
, bm
(2), 0) Call setBody
(body
(), cPARAMETER_FLIPTEXTURE
, cSCENE_USER
, 1, 0)
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_FLOOR
, 1000, 5) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_FLOOR
, (_Width / 2), (_Height - 20)) Call setBody
(body
(), cPARAMETER_STATIC
, cSCENE_FLOOR
, 0, 0)
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_SPINNEROFDEATH
, 75, 5) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_SPINNEROFDEATH
, (_Width / 2), (_Height - 100)) Call setBody
(body
(), cPARAMETER_STATIC
, cSCENE_SPINNEROFDEATH
, 0, 0)
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_RIGHTRAMP
, 350, 5) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_RIGHTRAMP
, (_Width * .75) + 35, (_Height / 2) + 105) Call setBody
(body
(), cPARAMETER_ORIENT
, cSCENE_RIGHTRAMP
, (cPI
* .75), 0) Call setBody
(body
(), cPARAMETER_STATIC
, cSCENE_RIGHTRAMP
, 0, 0)
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_LEFTRAMP
, 225, 5) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_LEFTRAMP
, (_Width * .25) + 55, (_Height / 2)) Call setBody
(body
(), cPARAMETER_ORIENT
, cSCENE_LEFTRAMP
, (cPI
* .1), 0) Call setBody
(body
(), cPARAMETER_STATIC
, cSCENE_LEFTRAMP
, 0, 0)
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_DOZEROFDOOM
, 5, 50) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_DOZEROFDOOM
, 0, _Height - 75) Call setBody
(body
(), cPARAMETER_STATIC
, cSCENE_DOZEROFDOOM
, 0, 0)
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_ELEVATOROFTERROR
, 50, 5) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_ELEVATOROFTERROR
, 55, _Height - 25) Call setBody
(body
(), cPARAMETER_ORIENT
, cSCENE_ELEVATOROFTERROR
, (cPI
* .98), 0) Call setBody
(body
(), cPARAMETER_STATIC
, cSCENE_ELEVATOROFTERROR
, 0, 0)
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_RIGHTWALL
, 5, 375) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_RIGHTWALL
, 5, _Height / 2 - 20) Call setBody
(body
(), cPARAMETER_STATIC
, cSCENE_RIGHTWALL
, 0, 0)
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_ELEVATORKICKER
, 100, 5) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_ELEVATORKICKER
, 55, 120) Call setBody
(body
(), cPARAMETER_ORIENT
, cSCENE_ELEVATORKICKER
, (cPI
* .70), 0) Call setBody
(body
(), cPARAMETER_STATIC
, cSCENE_ELEVATORKICKER
, 0, 0) '********************************************************
' Make the Chain
'********************************************************
Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_PIVOT
, 20, 20) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_PIVOT
, _Width / 2, 50) Call setBody
(body
(), cPARAMETER_ORIENT
, cSCENE_PIVOT
, (cPI
* 1.5), 0) Call setBody
(body
(), cPARAMETER_STATIC
, cSCENE_PIVOT
, 0, 0)
For i
= 0 To sNUMBEROFJOINTS
- 1 Call createBoxBodies
(p
(), pa
(), body
(), cSCENE_PENDULUM
+ i
, 12, 8) ' Call createCircleBody(pa(), body(), cSCENE_PENDULUM + i, 10)
Call setBody
(body
(), cPARAMETER_ORIENT
, cSCENE_PENDULUM
+ i
, (cPI
* 1.5), 0) Call setBody
(body
(), cPARAMETER_POSITION
, cSCENE_PENDULUM
+ i
, _Width / 2, 90 + (i
* 30)) Call jointSet
(j
(i
+ 1), body
(), cSCENE_PENDULUM
+ i
- 1, cSCENE_PENDULUM
+ i
, body
(cSCENE_PENDULUM
+ i
- 1).position.x
, body
(cSCENE_PENDULUM
+ i
- 1).position.y
)
'********************************************************
' Make Random objects
'********************************************************
For i
= cSCENE_PENDULUM
+ sNUMBEROFJOINTS
To sNUMBEROFBODIES
If Rnd > .35 Then ' Circles are much faster than polygons ty = cSHAPE_CIRCLE
ty = cSHAPE_POLYGON
Call createBodies
(p
(), pa
(), body
(), i
, ty
) Call setBody
(body
(), cPARAMETER_VELOCITY
, i
, Rnd * 100 - 50, Rnd * 100 - 50)
'********************************************************
' Texture Bodies
'********************************************************
For i
= cSCENE_ELEVATORKICKER
+ 1 To sNUMBEROFBODIES
If body
(i
).shape.ty
= cSHAPE_CIRCLE
Then Call setBody
(body
(), cPARAMETER_TEXTURE
, i
, bm
(0), 0) If body
(i
).shape.ty
= cSHAPE_POLYGON
Then Call setBody
(body
(), cPARAMETER_TEXTURE
, i
, bm
(1), 0)
'**********************************************************************************************
' Collision Helper Tools
'**********************************************************************************************
isBodyTouchingBody = 0
Do While hits
(hitcount
).A
<> hits
(hitcount
).B
If hits
(hitcount
).A
= A
And hits
(hitcount
).B
= B
Then isBodyTouchingBody = hitcount
isBodyTouchingStatic = 0
Do While hits
(hitcount
).A
<> hits
(hitcount
).B
If body
(hits
(hitcount
).B
).mass
= 0 Then isBodyTouchingStatic = hitcount
isBodyTouching = 0
Do While hits
(hitcount
).A
<> hits
(hitcount
).B
isBodyTouching = hitcount
'**********************************************************************************************
' Scene Creation Tools ahead
'**********************************************************************************************
Case cPARAMETER_POSITION:
Call vectorSet
(body
(Index
).position
, arg1
, arg2
) Case cPARAMETER_VELOCITY:
Call vectorSet
(body
(Index
).velocity
, arg1
, arg2
) Call vectorSet
(body
(Index
).force
, arg1
, arg2
) Case cPARAMETER_ANGULARVELOCITY:
body(Index).angularVelocity = arg1
body(Index).torque = arg1
body(Index).orient = arg1
Call matrixSetRadians
(body
(Index
).shape.u
, body
(Index
).orient
) Case cPARAMETER_STATICFRICTION:
body(Index).staticFriction = arg1
Case cPARAMETER_DYNAMICFRICTION:
body(Index).dynamicFriction = arg1
body(Index).c = arg1
body(Index).visible = arg1
Call bodySetStatic
(body
(Index
)) body(Index).shape.texture = arg1
Case cPARAMETER_FLIPTEXTURE:
body(Index).shape.flipTexture = arg1
Call shapeCreate
(shape
, cSHAPE_CIRCLE
, radius
) Call bodyCreate
(body
(), index
, shape
) Call circleInitialize
(body
(), index
) ' Even though circles do not have Polygons, they still must be included in the Vertices
pa(index).start = 0
pa(index).start = pa(index - 1).start + pa(index - 1).count + 1
pa(index).count = 1
body
(index
).c
= _RGB32(255, 255, 255)
Call shapeCreate
(shape
, cSHAPE_POLYGON
, 0) Call bodyCreate
(body
(), index
, shape
) Call boxCreate
(p
(), pa
(), index
, xs
, ys
) Call polygonInitialize
(body
(), p
(), pa
(), index
) body
(index
).c
= _RGB32(255, 255, 255)
Call createCircleBody
(pa
(), body
(), index
, 10 + Rnd * 20) Call createBoxBodies
(p
(), pa
(), body
(), index
, 10 + Rnd * 10, 10 + Rnd * 10)
'**********************************************************************************************
' Physics and Collision Stuff Ahead
'**********************************************************************************************
dts = dt * .5
Call vectorAddVectorScalar
(b.velocity
, b.force
, b.invMass
* dts
) Call vectorAddVectorScalar
(b.velocity
, sGRAVITY
, dts
) b.angularVelocity = b.angularVelocity + (b.torque * b.invInertia * dts)
Call vectorAddVectorScalar
(body.position
, body.velocity
, dt
) body.orient = body.orient + (body.angularVelocity * dt)
Call matrixSetRadians
(body.shape.u
, body.orient
) Call impulseIntegrateForces
(body
, dt
)
Dim c
(cMAXNUMBEROFOBJECTS
) As tVECTOR2d
Dim manifolds
(sNUMBEROFBODIES
* sNUMBEROFBODIES
) As tMANIFOLD
Dim collisions
(sNUMBEROFBODIES
* sNUMBEROFBODIES
, cMAXNUMBEROFOBJECTS
) As tVECTOR2d
' // Generate new collision info
' // erase hitlist
hits(hitCount) = dHit
hitCount = hitCount + 1
Loop Until hits
(hitCount
).A
= hits
(hitCount
).B
hitCount = 0
' TODO: Implement hidden object logic
For i
= 0 To sNUMBEROFBODIES
' number of bodies A = body(i)
For j
= i
+ 1 To sNUMBEROFBODIES
B = body(j)
'Mainfold solve - handle collisions
If A.shape.ty
= cSHAPE_CIRCLE
And B.shape.ty
= cSHAPE_CIRCLE
Then Call collisionCCHandle
(m
, c
(), A
, B
) If A.shape.ty
= cSHAPE_POLYGON
And B.shape.ty
= cSHAPE_POLYGON
Then Call collisionPPHandle
(p
(), pa
(), body
(), m
, c
(), i
, j
) If A.shape.ty
= cSHAPE_CIRCLE
And B.shape.ty
= cSHAPE_POLYGON
Then Call collisionCPHandle
(p
(), pa
(), body
(), m
, c
(), i
, j
) If B.shape.ty
= cSHAPE_CIRCLE
And A.shape.ty
= cSHAPE_POLYGON
Then Call collisionPCHandle
(p
(), pa
(), body
(), m
, c
(), i
, j
) m.A = i 'identify the index of objects
m.B = j
manifolds(manifoldCount) = m
For k
= 0 To m.contactCount
hits(hitCount).A = i
hits(hitCount).B = j
hits(hitCount).position = c(k)
collisions(manifoldCount, k) = c(k)
hitCount = hitCount + 1
manifoldCount = manifoldCount + 1
' // Integrate forces
For i
= 0 To sNUMBEROFBODIES
Call impulseIntegrateForces
(body
(i
), dt
) ' // Initialize collision
For i
= 0 To manifoldCount
- 1 ' this is the stupidest thing ever since QB will not let you split arrays
For k
= 0 To manifolds
(i
).contactCount
- 1 c(k) = collisions(i, k)
Call manifoldInit
(manifolds
(i
), body
(), c
()) ' joint pre Steps
For i
= 1 To sNUMBEROFJOINTS
Call jointPrestep
(j
(i
), body
(), dt
)
'// Solve collisions
For j
= 0 To iterations
- 1
For i
= 0 To manifoldCount
- 1 For k
= 0 To manifolds
(i
).contactCount
- 1 c(k) = collisions(i, k)
Call manifoldApplyImpulse
(manifolds
(i
), body
(), c
()) For i
= 1 To sNUMBEROFJOINTS
Call jointApplyImpulse
(j
(i
), body
())
'// Integrate velocities
For i
= 0 To sNUMBEROFBODIES
Call impulseIntegrateVelocity
(body
(i
), dt
) '// Correct positions
For i
= 0 To manifoldCount
- 1 Call manifoldPositionalCorrection
(manifolds
(i
), body
()) '// Clear all forces
For i
= 0 To sNUMBEROFBODIES
Call vectorSet
(body
(i
).force
, 0, 0) body(i).torque = 0
Sub bodyApplyImpulse
(body
As tBODY
, impulse
As tVECTOR2d
, contactVector
As tVECTOR2d
) Call vectorAddVectorScalar
(body.velocity
, impulse
, body.invMass
) body.angularVelocity = body.angularVelocity + body.invInertia * vectorCross(contactVector, impulse)
Sub bodySetStatic
(body
As tBODY
) body.inertia = 0.0
body.invInertia = 0.0
body.mass = 0.0
body.invMass = 0.0
Sub manifoldInit
(m
As tMANIFOLD
, body
() As tBODY
, contacts
() As tVECTOR2d
) m.e = scalarMin(body(m.A).restitution, body(m.B).restitution)
m.sf
= Sqr(body
(m.A
).staticFriction
* body
(m.A
).staticFriction
) m.df
= Sqr(body
(m.A
).dynamicFriction
* body
(m.A
).dynamicFriction
) For i
= 0 To m.contactCount
- 1 Call vectorSubVectorND
(contacts
(i
), body
(m.A
).position
, ra
) Call vectorSubVectorND
(contacts
(i
), body
(m.B
).position
, rb
)
Call vectorCrossScalar
(tv1
, rb
, body
(m.B
).angularVelocity
) Call vectorCrossScalar
(tv2
, ra
, body
(m.A
).angularVelocity
) Call vectorAddVector
(tv1
, body
(m.B
).velocity
) Call vectorSubVectorND
(tv2
, body
(m.A
).velocity
, tv2
) Call vectorSubVectorND
(rv
, tv1
, tv2
)
If vectorLengthSq
(rv
) < sRESTING
Then m.e = 0.0
Sub manifoldApplyImpulse
(m
As tMANIFOLD
, body
() As tBODY
, contacts
() As tVECTOR2d
)
Dim tangentImpulse
As tVECTOR2d
If impulseEqual
(body
(m.A
).invMass
+ body
(m.B
).invMass
, 0.0) Then Call manifoldInfiniteMassCorrection
(body
(m.A
), body
(m.B
))
For i
= 0 To m.contactCount
- 1 '// Calculate radii from COM to contact
'// Vec2 ra = contacts[i] - A->position;
'// Vec2 rb = contacts[i] - B->position;
Call vectorSubVectorND
(ra
, contacts
(i
), body
(m.A
).position
) Call vectorSubVectorND
(rb
, contacts
(i
), body
(m.B
).position
)
'// Relative velocity
'// Vec2 rv = B->velocity + Cross( B->angularVelocity, rb ) - A->velocity - Cross( A->angularVelocity, ra );
Call vectorCrossScalar
(tv1
, rb
, body
(m.B
).angularVelocity
) Call vectorCrossScalar
(tv2
, ra
, body
(m.A
).angularVelocity
) Call vectorAddVectorND
(rv
, tv1
, body
(m.B
).velocity
) Call vectorSubVector
(rv
, body
(m.A
).velocity
) Call vectorSubVector
(rv
, tv2
)
'// Relative velocity along the normal
'// real contactVel = Dot( rv, normal );
contactVel = vectorDot(rv, m.normal)
'// Do not resolve if velocities are separating
'// real raCrossN = Cross( ra, normal );
'// real rbCrossN = Cross( rb, normal );
'// real invMassSum = A->im + B->im + Sqr( raCrossN ) * A->iI + Sqr( rbCrossN ) * B->iI;
raCrossN = vectorCross(ra, m.normal)
rbCrossN = vectorCross(rb, m.normal)
invMassSum = body(m.A).invMass + body(m.B).invMass + (raCrossN * raCrossN) * body(m.A).invInertia + (rbCrossN * rbCrossN) * body(m.B).invInertia
'// Calculate impulse scalar
j = -(1.0 + m.e) * contactVel
j = j / invMassSum
j = j / m.contactCount
'// Apply impulse
Call vectorMultiplyScalarND
(impulse
, m.normal
, j
)
Call vectorNegND
(tv1
, impulse
) Call bodyApplyImpulse
(body
(m.A
), tv1
, ra
) Call bodyApplyImpulse
(body
(m.B
), impulse
, rb
)
'// Friction impulse
'// rv = B->velocity + Cross( B->angularVelocity, rb ) - A->velocity - Cross( A->angularVelocity, ra );
Call vectorCrossScalar
(tv1
, rb
, body
(m.B
).angularVelocity
) Call vectorCrossScalar
(tv2
, ra
, body
(m.A
).angularVelocity
) Call vectorAddVectorND
(rv
, tv1
, body
(m.B
).velocity
) Call vectorSubVector
(rv
, body
(m.A
).velocity
) Call vectorSubVector
(rv
, tv2
)
'// Vec2 t = rv - (normal * Dot( rv, normal ));
'// t.Normalize( );
Call vectorMultiplyScalarND
(t
, m.normal
, vectorDot
(rv
, m.normal
)) Call vectorSubVectorND
(t
, rv
, t
)
'// j tangent magnitude
jt = -vectorDot(rv, t)
jt = jt / invMassSum
jt = jt / m.contactCount
'// Don't apply tiny friction impulses
'// Coulumb's law
Call vectorMultiplyScalarND
(tangentImpulse
, t
, jt
) Call vectorMultiplyScalarND
(tangentImpulse
, t
, -j
* m.df
)
'// Apply friction impulse
'// A->ApplyImpulse( -tangentImpulse, ra );
'// B->ApplyImpulse( tangentImpulse, rb );
Call vectorNegND
(tv1
, tangentImpulse
) Call bodyApplyImpulse
(body
(m.A
), tv1
, ra
) Call bodyApplyImpulse
(body
(m.B
), tangentImpulse
, rb
)
Sub manifoldPositionalCorrection
(m
As tMANIFOLD
, body
() As tBODY
) correction = scalarMax(m.penetration - cPENETRATION_ALLOWANCE, 0.0) / (body(m.A).invMass + body(m.B).invMass) * cPENETRATION_CORRECTION
Call vectorAddVectorScalar
(body
(m.A
).position
, m.normal
, -body
(m.A
).invMass
* correction
) Call vectorAddVectorScalar
(body
(m.B
).position
, m.normal
, body
(m.B
).invMass
* correction
)
Sub manifoldInfiniteMassCorrection
(A
As tBODY
, B
As tBODY
) Call vectorSet
(A.velocity
, 0, 0) Call vectorSet
(B.velocity
, 0, 0)
'**********************************************************************************************
' Collision Stuff Ahead
'**********************************************************************************************
Sub collisionCCHandle
(m
As tMANIFOLD
, contacts
() As tVECTOR2d
, A
As tBODY
, B
As tBODY
)
Call vectorSubVectorND
(normal
, B.position
, A.position
) dist_sqr = vectorLengthSq(normal)
radius = A.shape.radius + B.shape.radius
If (dist_sqr
>= radius
* radius
) Then m.contactCount = 0
m.contactCount = 1
m.penetration = A.shape.radius
Call vectorSet
(m.normal
, 1.0, 0.0) Call vectorSetVector
(contacts
(0), A.position
) m.penetration = radius - distance
Call vectorDivideScalarND
(m.normal
, normal
, distance
)
Call vectorMultiplyScalarND
(contacts
(0), m.normal
, A.shape.radius
) Call vectorAddVector
(contacts
(0), A.position
)
Call collisionCPHandle
(p
(), pa
(), body
(), m
, contacts
(), B
, A
)
'A is the Circle
'B is the POLY
m.contactCount = 0
Call vectorSubVectorND
(center
, body
(A
).position
, body
(B
).position
) Call matrixTranspose
(body
(B
).shape.u
, tm
) Call matrixMultiplyVector
(tm
, center
, center
)
Call vectorSubVectorND
(tv
, center
, p
(pa
(B
).start
+ i
).vert
) s = vectorDot(p(pa(B).start + i).norm, tv)
separation = s
faceNormal = i
v1 = p(pa(B).start + faceNormal).vert
i2 = pa(B).start + arrayNextIndex(faceNormal, pa(B).count)
v2 = p(i2).vert
m.contactCount = 1
Call matrixMultiplyVector
(body
(B
).shape.u
, p
(pa
(B
).start
+ faceNormal
).norm
, m.normal
) Call vectorMultiplyScalarND
(contacts
(0), m.normal
, ARadius
) Call vectorAddVector
(contacts
(0), body
(A
).position
) m.penetration = ARadius
Call vectorSubVectorND
(tv1
, center
, v1
) Call vectorSubVectorND
(tv2
, v2
, v1
) dot1 = vectorDot(tv1, tv2)
Call vectorSubVectorND
(tv1
, center
, v2
) Call vectorSubVectorND
(tv2
, v1
, v2
) dot2 = vectorDot(tv1, tv2)
m.penetration = ARadius - separation
m.contactCount = 1
Call vectorSubVectorND
(n
, v1
, center
) Call matrixMultiplyVector
(body
(B
).shape.u
, n
, n
) m.normal = n
Call matrixMultiplyVector
(body
(B
).shape.u
, v1
, v1
) Call vectorAddVectorND
(v1
, v1
, body
(B
).position
) contacts(0) = v1
m.contactCount = 1
Call vectorSubVectorND
(n
, v2
, center
) Call matrixMultiplyVector
(body
(B
).shape.u
, v2
, v2
) Call vectorAddVectorND
(v2
, v2
, body
(B
).position
) contacts(0) = v2
Call matrixMultiplyVector
(body
(B
).shape.u
, n
, n
) m.normal = n
n = p(pa(B).start + faceNormal).norm
Call vectorSubVectorND
(tv1
, center
, v1
) m.contactCount = 1
Call matrixMultiplyVector
(body
(B
).shape.u
, n
, n
) m.normal = n
Call vectorMultiplyScalarND
(contacts
(0), m.normal
, ARadius
) Call vectorAddVector
(contacts
(0), body
(A
).position
)
Dim o
(cMAXNUMBEROFPOLYGONS
) As tVECTOR2d
o(0) = face(0)
o(1) = face(1)
o(sp) = face(0)
sp = sp + 1
o(sp) = face(1)
sp = sp + 1
'out[sp] = face[0] + alpha * (face[1] - face[0]);
Call vectorSubVectorND
(tempv
, face
(1), face
(0)) Call vectorMultiplyScalar
(tempv
, alpha
) Call vectorAddVectorND
(o
(sp
), tempv
, face
(0)) sp = sp + 1
face(0) = o(0)
face(1) = o(1)
collisionPPClip = sp
Dim referenceNormal
As tVECTOR2d
Dim uRef
As tMATRIX2d: uRef
= b
(RefPoly
).shape.u
Dim uInc
As tMATRIX2d: uInc
= b
(IncPoly
).shape.u
referenceNormal = p(pa(RefPoly).start + referenceIndex).norm
' // Calculate normal in incident's frame of reference
' // referenceNormal = RefPoly->u * referenceNormal; // To world space
Call matrixMultiplyVector
(uRef
, referenceNormal
, referenceNormal
) ' // referenceNormal = IncPoly->u.Transpose( ) * referenceNormal; // To incident's model space
Call matrixTranspose
(uInc
, uTemp
) Call matrixMultiplyVector
(uTemp
, referenceNormal
, referenceNormal
)
For i
= 0 To pa
(IncPoly
).count
dot = vectorDot(referenceNormal, p(pa(IncPoly).start + i).norm)
minDot = dot
incidentFace = i
'// Assign face vertices for incidentFace
'// v[0] = IncPoly->u * IncPoly->m_vertices[incidentFace] + IncPoly->body->position;
Call matrixMultiplyVector
(uInc
, p
(pa
(IncPoly
).start
+ incidentFace
).vert
, v
(0)) Call vectorAddVector
(v
(0), b
(IncPoly
).position
)
'// incidentFace = incidentFace + 1 >= (int32)IncPoly->m_vertexCount ? 0 : incidentFace + 1;
incidentFace = arrayNextIndex(incidentFace, pa(IncPoly).count)
'// v[1] = IncPoly->u * IncPoly->m_vertices[incidentFace] + IncPoly->body->position;
Call matrixMultiplyVector
(uInc
, p
(pa
(IncPoly
).start
+ incidentFace
).vert
, v
(1)) Call vectorAddVector
(v
(1), b
(IncPoly
).position
)
m.contactCount = 0
penetrationA = collisionPPFindAxisLeastPenetration(p(), pa(), body(), faceA(), A, B)
penetrationB = collisionPPFindAxisLeastPenetration(p(), pa(), body(), faceB(), B, A)
If impulseGT
(penetrationA
, penetrationB
) Then RefPoly = A
IncPoly = B
referenceIndex = faceA(0)
flip = 0
RefPoly = B
IncPoly = A
referenceIndex = faceB(0)
flip = 1
Dim incidentFace
(2) As tVECTOR2d
Call collisionPPFindIncidentFace
(p
(), pa
(), body
(), incidentFace
(), RefPoly
, IncPoly
, referenceIndex
)
v1 = p(pa(RefPoly).start + referenceIndex).vert
referenceIndex = arrayNextIndex(referenceIndex, pa(RefPoly).count)
v2 = p(pa(RefPoly).start + referenceIndex).vert
'// Transform vertices to world space
'// v1 = RefPoly->u * v1 + RefPoly->body->position;
'// v2 = RefPoly->u * v2 + RefPoly->body->position;
Call matrixMultiplyVector
(body
(RefPoly
).shape.u
, v1
, v1t
) Call vectorAddVectorND
(v1
, v1t
, body
(RefPoly
).position
) Call matrixMultiplyVector
(body
(RefPoly
).shape.u
, v2
, v2t
) Call vectorAddVectorND
(v2
, v2t
, body
(RefPoly
).position
)
'// Calculate reference face side normal in world space
'// Vec2 sidePlaneNormal = (v2 - v1);
'// sidePlaneNormal.Normalize( );
Dim sidePlaneNormal
As tVECTOR2d
Call vectorSubVectorND
(sidePlaneNormal
, v2
, v1
) Call vectorNormalize
(sidePlaneNormal
)
'// Orthogonalize
'// Vec2 refFaceNormal( sidePlaneNormal.y, -sidePlaneNormal.x );
Dim refFaceNormal
As tVECTOR2d
Call vectorSet
(refFaceNormal
, sidePlaneNormal.y
, -sidePlaneNormal.x
)
'// ax + by = c
'// c is distance from origin
'// real refC = Dot( refFaceNormal, v1 );
'// real negSide = -Dot( sidePlaneNormal, v1 );
'// real posSide = Dot( sidePlaneNormal, v2 );
Dim refC
As _Float: refC
= vectorDot
(refFaceNormal
, v1
) Dim negSide
As _Float: negSide
= -vectorDot
(sidePlaneNormal
, v1
) Dim posSide
As _Float: posSide
= vectorDot
(sidePlaneNormal
, v2
)
'// Clip incident face to reference face side planes
'// if(Clip( -sidePlaneNormal, negSide, incidentFace ) < 2)
Dim negSidePlaneNormal
As tVECTOR2d
Call vectorNegND
(negSidePlaneNormal
, sidePlaneNormal
)
If collisionPPClip
(negSidePlaneNormal
, negSide
, incidentFace
()) < 2 Then Exit Sub If collisionPPClip
(sidePlaneNormal
, posSide
, incidentFace
()) < 2 Then Exit Sub
Call vectorSet
(m.normal
, refFaceNormal.x
, refFaceNormal.y
)
'// Keep points behind reference face
Dim cp
As Integer: cp
= 0 '// clipped points behind reference face separation = vectorDot(refFaceNormal, incidentFace(0)) - refC
contacts(cp) = incidentFace(0)
m.penetration = -separation
cp = cp + 1
m.penetration = 0
separation = vectorDot(refFaceNormal, incidentFace(1)) - refC
contacts(cp) = incidentFace(1)
m.penetration = m.penetration + -separation
cp = cp + 1
m.penetration = m.penetration / cp
m.contactCount = cp
k = pa(A).start + i
'// Retrieve a face normal from A
'// Vec2 n = A->m_normals[i];
'// Vec2 nw = A->u * n;
n = p(k).norm
Call matrixMultiplyVector
(body
(A
).shape.u
, n
, nw
)
'// Transform face normal into B's model space
'// Mat2 buT = B->u.Transpose( );
'// n = buT * nw;
Call matrixTranspose
(body
(B
).shape.u
, buT
) Call matrixMultiplyVector
(buT
, nw
, n
)
'// Retrieve support point from B along -n
'// Vec2 s = B->GetSupport( -n );
Call vectorGetSupport
(p
(), pa
(), B
, nn
, s
)
'// Retrieve vertex on face from A, transform into
'// B's model space
'// Vec2 v = A->m_vertices[i];
'// v = A->u * v + A->body->position;
'// v -= B->body->position;
'// v = buT * v;
v = p(k).vert
Call matrixMultiplyVector
(body
(A
).shape.u
, v
, tv
) Call vectorAddVectorND
(v
, tv
, body
(A
).position
)
Call vectorSubVector
(v
, body
(B
).position
) Call matrixMultiplyVector
(buT
, v
, tv
)
Call vectorSubVector
(s
, tv
) d = vectorDot(n, s)
bestDistance = d
bestIndex = i
faceIndex(0) = bestIndex
collisionPPFindAxisLeastPenetration = bestDistance
'**********************************************************************************************
' Shape Creation Ahead
'**********************************************************************************************
Call matrixSetScalar
(u
, 1, 0, 0, 1) sh.ty = ty
sh.radius = radius
sh.u = u
Call vectorSet
(body
(index
).position
, 0, 0) Call vectorSet
(body
(index
).velocity
, 0, 0) body(index).angularVelocity = 0.0
body(index).torque = 0.0
body(index).orient = 0.0 ' impulseRandom_float(-cPI, cPI)
Call vectorSet
(body
(index
).force
, 0, 0) body(index).staticFriction = 0.5
body(index).dynamicFriction = 0.3
body(index).restitution = 0.2
body(index).shape = shape
Dim verts
(vertlength
) As tVECTOR2d
Call vectorSet
(verts
(0), -sizex
, -sizey
) Call vectorSet
(verts
(1), sizex
, -sizey
) Call vectorSet
(verts
(2), sizex
, sizey
) Call vectorSet
(verts
(3), -sizex
, sizey
)
Call vertexSet
(p
(), pa
(), index
, verts
(), vertlength
)
Dim verts
(vertlength
) As tVECTOR2d
Call vectorSet
(verts
(0), -sizex
, -sizey
) Call vectorSet
(verts
(1), sizex
, -sizey
) Call vectorSet
(verts
(2), sizex
, sizey
) Call vectorSet
(verts
(3), -sizex
, sizey
) Call vectorSet
(verts
(4), -sizex
, sizey
/ 2) Call vectorSet
(verts
(5), sizex
/ 2, sizey
/ 2) Call vectorSet
(verts
(6), sizex
/ 2, -sizey
/ 2) Call vectorSet
(verts
(7), -sizex
, sizey
/ 2)
Call vertexSet
(p
(), pa
(), index
, verts
(), vertlength
)
Dim highestXCoord
As _Float: highestXCoord
= verts
(0).x
x = verts(i).x
highestXCoord = x
rightMost = i
If verts
(i
).y
< verts
(rightMost
).y
Then rightMost = i
hull(outCount) = indexHull
nextHullIndex = 0
If nextHullIndex
= indexHull
Then nextHullIndex = i
Call vectorSubVectorND
(e1
, verts
(nextHullIndex
), verts
(hull
(outCount
))) Call vectorSubVectorND
(e2
, verts
(i
), verts
(hull
(outCount
))) c = vectorCross(e1, e2)
If c
< 0.0 Then nextHullIndex
= i
If c
= 0.0 And (vectorLengthSq
(e2
) > vectorLengthSq
(e1
)) Then nextHullIndex = i
outCount = outCount + 1
indexHull = nextHullIndex
If nextHullIndex
= rightMost
Then pa(index).count = outCount - 1
pa(index).start = 0
pa(index).start = pa(index - 1).start + pa(index - 1).count + 1
p(pa(index).start + i).vert = verts(hull(i))
Call vectorSubVectorND
(face
, p
(pa
(index
).start
+ arrayNextIndex
(i
, pa
(index
).count
)).vert
, p
(pa
(index
).start
+ i
).vert
) Call vectorSet
(p
(pa
(index
).start
+ i
).norm
, face.y
, -face.x
) Call vectorNormalize
(p
(pa
(index
).start
+ i
).norm
)
arrayNextIndex
= ((i
+ 1) Mod (count
+ 1))
'**********************************************************************************************
' Rendering Stuff Ahead
'**********************************************************************************************
fpsLast = fps
fps = 0
Sub renderBodies
(p
() As tPOLY
, pa
() As tPOLYATTRIB
, body
() As tBODY
, j
() As tJOINT
, hits
() As tHIT
)
For i
= 0 To sNUMBEROFBODIES
'TODO: Put hidden object logic
If body
(i
).shape.ty
= cSHAPE_CIRCLE
Then If body
(i
).shape.texture
= 0 Then Call renderWireframeCircle
(body
(), i
) Call renderTexturedCircle
(body
(), i
) If body
(i
).shape.texture
= 0 Then Call renderWireframePoly
(p
(), pa
(), body
(), i
) Call renderTexturedBox
(p
(), pa
(), body
(), i
) ' If b(index).position.y < 0 Then b(index).position.y = _Height
For i
= 1 To sNUMBEROFJOINTS
Call renderJoints
(j
(i
), body
()) hitcount = 0
Do While hits
(hitcount
).A
<> hits
(hitcount
).B
Circle (hits
(hitcount
).position.x
, hits
(hitcount
).position.y
), 5, _RGB(255, 6, 11) hitcount = hitcount + 1
Sub renderJoints
(j
As tJOINT
, b
() As tBODY
) Dim b1
As tBODY: b1
= b
(j.body1
) Dim b2
As tBODY: b2
= b
(j.body2
) Dim R1
As tMATRIX2d: R1
= b1.shape.u
'Call matrixSetRadians(R1, b1.orient) Dim R2
As tMATRIX2d: R2
= b2.shape.u
' Call matrixSetRadians(R2, b2.orient)
Dim x1
As tVECTOR2d: x1
= b1.position
Dim p1
As tVECTOR2d:
Call matrixMultiplyVector
(R1
, j.localAnchor1
, p1
)
Call vectorAddVectorND
(p1
, p1
, x1
)
Dim x2
As tVECTOR2d: x2
= b2.position
Dim p2
As tVECTOR2d:
Call matrixMultiplyVector
(R2
, j.localAnchor2
, p2
)
Call vectorAddVectorND
(p2
, p2
, x2
)
'Line (x1.x, x1.y)-(p1.x, p1.y), _RGB(127, 127, 244) 'blue
Line (p1.x
, p1.y
)-(x2.x
, x2.y
), _RGB(255, 255, 127) 'yellow ' Line (x2.x, x2.y)-(p2.x, p2.y), _RGB32(127, 255, 127) 'green
' Line (p2.x, p2.y)-(x1.x, x1.y), _RGB(127, 6, 127) 'purple
Sub renderWireframePoly
(p
() As tPOLY
, pa
() As tPOLYATTRIB
, b
() As tBODY
, index
As Integer) Dim a
As tVECTOR2d
' dummy vertices
For i
= 0 To pa
(index
).count
element = pa(index).start + i
element_next = pa(index).start + arrayNextIndex(i, pa(index).count) ' wrap around back to first element
a = p(element).vert
b = p(element_next).vert
Call matrixMultiplyVector
(b
(index
).shape.u
, a
, a
) Call matrixMultiplyVector
(b
(index
).shape.u
, b
, b
) Call vectorAddVector
(a
, b
(index
).position
) Call vectorAddVector
(b
, b
(index
).position
)
Line (a.x
, a.y
)-(b.x
, b.y
), b
(index
).c
bm = b(index).shape.texture
vert(i) = p(pa(index).start + i).vert
Call matrixMultiplyVector
(b
(index
).shape.u
, vert
(i
), vert
(i
)) Call vectorAddVector
(vert
(i
), b
(index
).position
) If b
(index
).velocity.x
> 1 Or b
(index
).shape.flipTexture
= 0 Then _MapTriangle (0, 0)-(W
- 1, 0)-(W
- 1, H
- 1), bm
To(vert
(3).x
, vert
(3).y
)-(vert
(0).x
, vert
(0).y
)-(vert
(1).x
, vert
(1).y
) _MapTriangle (0, 0)-(0, H
- 1)-(W
- 1, H
- 1), bm
To(vert
(3).x
, vert
(3).y
)-(vert
(2).x
, vert
(2).y
)-(vert
(1).x
, vert
(1).y
) _MapTriangle (0, 0)-(W
- 1, 0)-(W
- 1, H
- 1), bm
To(vert
(0).x
, vert
(0).y
)-(vert
(3).x
, vert
(3).y
)-(vert
(2).x
, vert
(2).y
) _MapTriangle (0, 0)-(0, H
- 1)-(W
- 1, H
- 1), bm
To(vert
(0).x
, vert
(0).y
)-(vert
(1).x
, vert
(1).y
)-(vert
(2).x
, vert
(2).y
)
Circle (b
(index
).position.x
, b
(index
).position.y
), b
(index
).shape.radius
, b
(index
).c
Line (b
(index
).position.x
, b
(index
).position.y
)-(b
(index
).position.x
+ Cos(b
(index
).orient
) * b
(index
).shape.radius
, b
(index
).position.y
+ Sin(b
(index
).orient
) * b
(index
).shape.radius
), b
(index
).c
bm = b(index).shape.texture
Call vectorSet
(vert
(0), -b
(index
).shape.radius
, -b
(index
).shape.radius
) Call vectorSet
(vert
(1), -b
(index
).shape.radius
, b
(index
).shape.radius
) Call vectorSet
(vert
(2), b
(index
).shape.radius
, b
(index
).shape.radius
) Call vectorSet
(vert
(3), b
(index
).shape.radius
, -b
(index
).shape.radius
) Call matrixMultiplyVector
(b
(index
).shape.u
, vert
(i
), vert
(i
)) Call vectorAddVector
(vert
(i
), b
(index
).position
) _MapTriangle (0, 0)-(0, H
- 1)-(W
- 1, H
- 1), bm
To(vert
(0).x
, vert
(0).y
)-(vert
(1).x
, vert
(1).y
)-(vert
(2).x
, vert
(2).y
) _MapTriangle (0, 0)-(W
- 1, 0)-(W
- 1, H
- 1), bm
To(vert
(0).x
, vert
(0).y
)-(vert
(3).x
, vert
(3).y
)-(vert
(2).x
, vert
(2).y
)
Call matrixSetRadians
(b.shape.u
, radians
)
'**********************************************************************************************
' Object initialization Ahead
'**********************************************************************************************
Call circleComputeMass
(b
(), index
, 1.0)
b(index).mass = cPI * b(index).shape.radius * b(index).shape.radius * density
b(index).invMass = 1.0 / b(index).mass
b(index).invMass = 0.0
b(index).inertia = b(index).mass * b(index).shape.radius * b(index).shape.radius
b(index).invInertia = 1.0 / b(index).inertia
b(index).invInertia = 0.0
Sub polygonInitialize
(body
() As tBODY
, p
() As tPOLY
, pa
() As tPOLYATTRIB
, index
As Integer) Call polygonComputeMass
(body
(), p
(), pa
(), index
, 1.0)
Dim c
As tVECTOR2d
' centroid
k_inv3 = 1.0 / 3.0
For ii
= 0 To pa
(index
).count
p1 = p(pa(index).start + ii).vert
p2 = p(pa(index).start + arrayNextIndex(ii, pa(index).count)).vert
D = vectorCross(p1, p2)
triangleArea = .5 * D
area = area + triangleArea
weight = triangleArea * k_inv3
Call vectorAddVectorScalar
(c
, p1
, weight
) Call vectorAddVectorScalar
(c
, p2
, weight
) intx2 = p1.x * p1.x + p2.x * p1.x + p2.x * p2.x
inty2 = p1.y * p1.y + p2.y * p1.y + p2.y * p2.y
I = I + (0.25 * k_inv3 * D) * (intx2 + inty2)
Call vectorMultiplyScalar
(c
, 1.0 / area
)
For ii
= 0 To pa
(index
).count
Call vectorSubVector
(p
(pa
(index
).start
+ ii
).vert
, c
)
b(index).mass = density * area
b(index).invMass = 1.0 / b(index).mass
b(index).invMass = 0.0
b(index).inertia = I * density
b(index).invInertia = 1.0 / b(index).inertia
b(index).invInertia = 0.0
'**********************************************************************************************
' Joint Stuff Ahead
'**********************************************************************************************
Call vectorSet
(anchor
, x
, y
) Dim Rot1
As tMATRIX2d: Rot1
= body
(b1
).shape.u
'Call matrixSetRadians(Rot1, body(b1).orient) Dim Rot2
As tMATRIX2d: Rot2
= body
(b2
).shape.u
'Call matrixSetRadians(Rot2, body(b2).orient) Dim Rot1T
As tMATRIX2d:
Call matrixTranspose
(Rot1
, Rot1T
) Dim Rot2T
As tMATRIX2d:
Call matrixTranspose
(Rot2
, Rot2T
)
j.body1 = b1
j.body2 = b2
Call vectorSubVectorND
(tv
, anchor
, body
(b1
).position
) Call matrixMultiplyVector
(Rot1T
, tv
, j.localAnchor1
)
Call vectorSubVectorND
(tv
, anchor
, body
(b2
).position
) Call matrixMultiplyVector
(Rot2T
, tv
, j.localAnchor2
)
Call vectorSet
(j.P
, 0, 0)
j.softness = 0
j.biasFactor = 100
Dim Rot1
As tMATRIX2d: Rot1
= body
(j.body1
).shape.u
'Call matrixSetRadians(Rot1, body(j.body1).orient) Dim Rot2
As tMATRIX2d: Rot2
= body
(j.body2
).shape.u
'Call matrixSetRadians(Rot2, body(j.body2).orient)
Call matrixMultiplyVector
(Rot1
, j.localAnchor1
, j.r1
) Call matrixMultiplyVector
(Rot2
, j.localAnchor2
, j.r2
)
b1invMass = body(j.body1).invMass
b2invMass = body(j.body2).invMass
b1invInertia = body(j.body1).invInertia
b2invInertia = body(j.body2).invInertia
Call matrixSetScalar
(K1
, b1invMass
+ b2invMass
, 0,_
0, b1invMass + b2invMass)
Call matrixSetScalar
(K2
, b1invInertia
* j.r1.y
* j.r1.y
, -b1invInertia
* j.r1.x
* j.r1.y
,_
-b1invInertia * j.r1.x * j.r1.y, b1invInertia * j.r1.x * j.r1.x)
Call matrixSetScalar
(K3
, b2invInertia
* j.r2.y
* j.r2.y
, - b2invInertia
* j.r2.x
* j.r2.y
,_
-b2invInertia * j.r2.x * j.r2.y, b2invInertia * j.r2.x * j.r2.x)
Call matrixAddMatrix
(K1
, K2
, K
) Call matrixAddMatrix
(K3
, K
, K
) K.m00 = K.m00 + j.softness
K.m11 = K.m11 + j.softness
Call matrixInvert
(K
, j.M
)
Dim p1
As tVECTOR2d:
Call vectorAddVectorND
(p1
, body
(j.body1
).position
, j.r1
) Dim p2
As tVECTOR2d:
Call vectorAddVectorND
(p2
, body
(j.body2
).position
, j.r2
) Dim dp
As tVECTOR2d:
Call vectorSubVectorND
(dp
, p2
, p1
)
Call vectorMultiplyScalarND
(j.bias
, dp
, -j.biasFactor
* inv_dt
) 'Call vectorSet(j.bias, 0, 0)
Call vectorSet
(j.P
, 0, 0)
Sub jointApplyImpulse
(j
As tJOINT
, body
() As tBODY
)
'Vec2 dv = body2->velocity + Cross(body2->angularVelocity, r2) - body1->velocity - Cross(body1->angularVelocity, r1);
Call vectorCrossScalar
(cross2
, j.r2
, body
(j.body2
).angularVelocity
) Call vectorCrossScalar
(cross1
, j.r1
, body
(j.body1
).angularVelocity
) Call vectorAddVectorND
(dv
, body
(j.body2
).velocity
, cross2
) Call vectorSubVectorND
(dv
, dv
, body
(j.body1
).velocity
) Call vectorSubVectorND
(dv
, dv
, cross1
)
' impulse = M * (bias - dv - softness * P);
Call vectorMultiplyScalarND
(tv
, j.P
, j.softness
) Call vectorSubVectorND
(impulse
, j.bias
, dv
) Call vectorSubVectorND
(impulse
, impulse
, tv
) Call matrixMultiplyVector
(j.M
, impulse
, impulse
)
' body1->velocity -= body1->invMass * impulse;
Call vectorMultiplyScalarND
(tv
, impulse
, body
(j.body1
).invMass
) Call vectorSubVectorND
(body
(j.body1
).velocity
, body
(j.body1
).velocity
, tv
)
' body1->angularVelocity -= body1->invI * Cross(r1, impulse);
crossScalar = vectorCross(j.r1, impulse)
body(j.body1).angularVelocity = body(j.body1).angularVelocity - body(j.body1).invInertia * crossScalar
Call vectorMultiplyScalarND
(tv
, impulse
, body
(j.body2
).invMass
) Call vectorAddVectorND
(body
(j.body2
).velocity
, body
(j.body2
).velocity
, tv
)
crossScalar = vectorCross(j.r2, impulse)
body(j.body2).angularVelocity = body(j.body2).angularVelocity + body(j.body2).invInertia * crossScalar
Call vectorAddVectorND
(j.P
, j.P
, impulse
)
'**********************************************************************************************
' Vector Math Ahead
'**********************************************************************************************
v.x = x
v.y = y
Sub vectorSetVector
(o
As tVECTOR2d
, v
As tVECTOR2d
) o.x = v.x
o.y = v.y
Sub vectorNeg
(v
As tVECTOR2d
) v.x = -v.x
v.y = -v.y
Sub vectorNegND
(o
As tVECTOR2d
, v
As tVECTOR2d
) o.x = -v.x
o.y = -v.y
v.x = v.x * s
v.y = v.y * s
o.x = v.x * s
o.y = v.y * s
v.x = v.x / s
v.y = v.y / s
o.x = v.x / s
o.y = v.y / s
v.x = v.x + s
v.y = v.y + s
o.x = v.x + s
o.y = v.y + s
Sub vectorMultiplyVector
(v
As tVECTOR2d
, m
As tVECTOR2d
) v.x = v.x * m.x
v.y = v.y * m.y
Sub vectorMultiplyVectorND
(o
As tVECTOR2d
, v
As tVECTOR2d
, m
As tVECTOR2d
) o.x = v.x * m.x
o.y = v.y * m.y
Sub vectorDivideVector
(v
As tVECTOR2d
, m
As tVECTOR2d
) v.x = v.x / m.x
v.y = v.y / m.y
Sub vectorAddVector
(v
As tVECTOR2d
, m
As tVECTOR2d
) v.x = v.x + m.x
v.y = v.y + m.y
Sub vectorAddVectorND
(o
As tVECTOR2d
, v
As tVECTOR2d
, m
As tVECTOR2d
) o.x = v.x + m.x
o.y = v.y + m.y
v.x = v.x + m.x * s
v.y = v.y + m.y * s
Sub vectorAddVectorScalarND
(o
As tVECTOR2d
, v
As tVECTOR2d
, m
As tVECTOR2d
, s
As _Float) o.x = v.x + m.x * s
o.y = v.y + m.y * s
Sub vectorSubVector
(v
As tVECTOR2d
, m
As tVECTOR2d
) v.x = v.x - m.x
v.y = v.y - m.y
Sub vectorSubVectorND
(o
As tVECTOR2d
, v
As tVECTOR2d
, m
As tVECTOR2d
) o.x = v.x - m.x
o.y = v.y - m.y
vectorLengthSq = v.x * v.x + v.y * v.y
vectorLength
= Sqr(vectorLengthSq
(v
))
xp = v.x * c - v.y * s
yp = v.x * s + v.y * c
v.x = xp
v.y = yp
Sub vectorNormalize
(v
As tVECTOR2d
) lenSQ = vectorLengthSq(v)
invLen
= 1.0 / Sqr(lenSQ
) v.x = v.x * invLen
v.y = v.y * invLen
Sub vectorMin
(a
As tVECTOR2d
, b
As tVECTOR2d
, o
As tVECTOR2d
) o.x = scalarMin(a.x, b.x)
o.y = scalarMin(a.y, b.y)
Sub vectorMax
(a
As tVECTOR2d
, b
As tVECTOR2d
, o
As tVECTOR2d
) o.x = scalarMax(a.x, b.x)
o.y = scalarMax(a.y, b.y)
vectorDot = a.x * b.x + a.y * b.y
dx = b.x - a.x
dy = b.y - a.y
vectorSqDist = dx * dx + dy * dy
vectorDistance
= Sqr(vectorSqDist
(a
, b
))
vectorCross = a.x * b.y - a.y * b.x
o.x = v.y * -a
o.y = v.x * a
vectorArea = (((b.x - a.x) * (c.y - a.y)) - ((c.x - a.x) * (b.y - a.y)))
vectorLeft = vectorArea(a, b, c) > 0
Function vectorLeftOn
(a
As tVECTOR2d
, b
As tVECTOR2d
, c
As tVECTOR2d
) vectorLeftOn = vectorArea(a, b, c) >= 0
vectorRight = vectorArea(a, b, c) < 0
Function vectorRightOn
(a
As tVECTOR2d
, b
As tVECTOR2d
, c
As tVECTOR2d
) vectorRightOn = vectorArea(a, b, c) <= 0
vectorCollinear = (vectorArea(a, b, c) = 0)
ab.x = b.x - a.x
ab.y = b.y - a.y
bc.x = c.x - b.x
bc.y = c.y - b.y
dot = ab.x * bc.x + ab.y * bc.y
magA
= Sqr(ab.x
* ab.x
+ ab.y
* ab.y
) magB
= Sqr(bc.x
* bc.x
+ bc.y
* bc.y
) angle
= _Acos(dot
/ (magA
* magB
)) vectorCollinear = angle < thresholdAngle
Sub vectorGetSupport
(p
() As tPOLY
, pa
() As tPOLYATTRIB
, index
As Integer, dir
As tVECTOR2d
, bestVertex
As tVECTOR2d
) bestVertex.x = -9999999
bestVertex.y = -9999999
bestProjection = -9999999
For i
= 0 To pa
(index
).count
v = p(i + pa(index).start).vert
projection = vectorDot(v, dir)
If projection
> bestProjection
Then bestVertex = v
bestProjection = projection
'**********************************************************************************************
' Matrix Stuff Ahead
'**********************************************************************************************
m.m00 = c
m.m01 = -s
m.m10 = s
m.m11 = c
m.m00 = a
m.m01 = b
m.m10 = c
m.m11 = d
Sub matrixAbs
(m
As tMATRIX2d
, o
As tMATRIX2d
)
Sub matrixGetAxisX
(m
As tMATRIX2d
, o
As tVECTOR2d
) o.x = m.m00
o.y = m.m10
Sub matrixGetAxisY
(m
As tMATRIX2d
, o
As tVECTOR2d
) o.x = m.m01
o.y = m.m11
Sub matrixTransposeI
(m
As tMATRIX2d
)
Sub matrixTranspose
(m
As tMATRIX2d
, o
As tMATRIX2d
) tm.m00 = m.m00
tm.m01 = m.m10
tm.m10 = m.m01
tm.m11 = m.m11
o = tm
Sub matrixInvert
(m
As tMATRIX2d
, o
As tMATRIX2d
)
a = m.m00: b = m.m01: c = m.m10: d = m.m11
det = a * d - b * c
det = 1 / det
tm.m00 = det * d: tm.m01 = -det * b
tm.m10 = -det * c: tm.m11 = det * a
o = tm
Sub matrixMultiplyVector
(m
As tMATRIX2d
, v
As tVECTOR2d
, o
As tVECTOR2d
) t.x = m.m00 * v.x + m.m01 * v.y
t.y = m.m10 * v.x + m.m11 * v.y
o = t
Sub matrixAddMatrix
(m
As tMATRIX2d
, x
As tMATRIX2d
, o
As tMATRIX2d
) o.m00 = m.m00 + x.m00
o.m01 = m.m01 + x.m01
o.m10 = m.m10 + x.m10
o.m11 = m.m11 + x.m11
Sub matrixMultiplyMatrix
(m
As tMATRIX2d
, x
As tMATRIX2d
, o
As tMATRIX2d
) o.m00 = m.m00 * x.m00 + m.m01 * x.m10
o.m01 = m.m00 * x.m01 + m.m01 * x.m11
o.m10 = m.m10 * x.m00 + m.m11 * x.m10
o.m11 = m.m10 * x.m01 + m.m11 * x.m11
'**********************************************************************************************
' Mostly Unused Stuff Ahead
'**********************************************************************************************
Sub polygonMakeCCW
(obj
As tTRIANGLE
) If vectorLeft
(obj.a
, obj.b
, obj.c
) = 0 Then
polygonIsReflex = vectorRight(t.a, t.b, t.c)
scalarMin = a
scalarMin = b
scalarMax = a
scalarMax = b
Sub lineIntersection
(l1
As tLINE2d
, l2
As tLINE2d
, o
As tVECTOR2d
) o.x = 0
o.y = 0
a1 = l1.b.y - l1.a.y
b1 = l1.a.x - l1.b.x
c1 = a1 * l1.a.x + b1 * l1.a.y
a2 = l2.b.y - l2.a.y
b2 = l2.a.x - l2.b.x
c2 = a2 * l2.a.x + b2 * l2.a.y
det = a1 * b2 - a2 * b1
o.x = (b2 * c1 - b1 * c2) / det
o.y = (a1 * c2 - a2 * c1) / det
Function lineSegmentsIntersect
(l1
As tLINE2d
, l2
As tLINE2d
) dx = l1.b.x - l1.a.x
dy = l1.b.y - l1.a.y
da = l2.b.x - l2.a.x
db = l2.b.y - l2.a.y
lineSegmentsIntersect = 0
s = (dx * (l2.a.y - l1.a.y) + dy * (l1.a.x - l2.a.x)) / (da * dy - db * dx)
t = (da * (l1.a.y - l2.a.y) + db * (l2.a.x - l1.a.x)) / (db * dx - da * dy)
lineSegmentsIntersect
= (s
>= 0 And s
<= 1 And t
>= 0 And t
<= 1)
'**********************************************************************************************
' Impulse Specific Math Ahead
'**********************************************************************************************
impulseEqual
= Abs(a
- b
) <= cEPSILON
impulseClamp = min
impulseClamp = max
impulseClamp = a
impulseRound
= Int(a
+ 0.5)
impulseRandom_float
= ((max
- min
) * Rnd + min
)
impulseRandomInteger
= Int((max
- min
) * Rnd + min
)
impulseGT = (a >= b * cBIAS_RELATIVE + a * cBIAS_ABSOLUTE)
'**********************************************************************************************
' Troubleshooting Tools
'**********************************************************************************************
Print "---------------------------" Print n;
" u:"; u.m00;
"|"; u.m10
Print " "; u.m10;
"|"; u.m11
'**********************************************************************************************
' Generate Bitmap
'**********************************************************************************************
'CIRCLE QB
Data 0,30,4289110427,4,0,52,4289110427,15,0,44,4289110427,21,0,38,4289110427,7 Data 4281808695,11,4289110427,7,0,34,4289110427,5,4281808695,18,4289110427,5,0,30,4289110427,4 Data 4281808695,23,4289110427,4,0,28,4289110427,3,4281808695,27,4289110427,3,0,25,4289110427,3 Data 4281808695,31,4289110427,3,0,22,4289110427,3,4281808695,33,4289110427,3,0,20,4289110427,3 Data 4281808695,35,4289110427,3,0,18,4289110427,3,4281808695,38,4289110427,2,0,16,4289110427,3 Data 4281808695,40,4289110427,2,0,14,4289110427,3,4281808695,42,4289110427,2,0,13,4289110427,2 Data 4281808695,43,4289110427,3,0,11,4289110427,2,4281808695,45,4289110427,2,0,10,4289110427,2 Data 4281808695,47,4289110427,2,0,8,4289110427,2,4281808695,49,4289110427,2,0,7,4289110427,2 Data 4281808695,49,4289110427,2,0,6,4289110427,2,4281808695,51,4289110427,2,0,5,4289110427,2 Data 4281808695,51,4289110427,2,0,5,4289110427,1,4281808695,53,4289110427,2,0,3,4289110427,2 Data 4281808695,53,4289110427,2,0,3,4289110427,2,4281808695,54,4289110427,1,0,3,4289110427,1 Data 4281808695,7,4281084972,0,4279703319,0,4279637526,10,4280492835,0,4281808695,7,4279637526,14,4279834905,0 Data 4281742902,0,4281808695,8,4289110427,2,0,1,4289110427,2,4281808695,6,4279637526,15,4281808695,6 Data 4279637526,17,4281808695,7,4289110427,2,0,1,4289110427,2,4281808695,5,4279637526,1,4282412608,0 Data 4284394590,14,4281808695,5,4279637526,1,4284394590,15,4284394334,0,4281808695,7,4289110427,1,0,1 Data 4289110427,1,4281808695,6,4279637526,0,4280034076,0,4284394590,16,4281808695,4,4279637526,1,4284394590,16 Data 4284129114,0,4281808695,6,4289110427,1,0,1,4289110427,1,4281808695,6,4279637526,0,4284394590,17 Data 4283333454,0,4281808695,3,4279637526,1,4284394590,17,4281808695,6,4289110427,2,0,0,4289110427,1 Data 4281808695,6,4279637526,0,4284394590,3,4281808695,9,4279637526,0,4284394590,3,4281808695,3,4279637526,1 Data 4284394590,2,4281808695,9,4279637526,0,4284394590,3,4281808695,6,4289110427,2,0,0,4289110427,1 Data 4281808695,6,4279637526,0,4284394590,3,4281808695,9,4279637526,0,4284394590,3,4281808695,3,4279637526,1 Data 4284394590,2,4281808695,9,4279637526,0,4284394590,3,4281808695,6,4289110427,5,4281808695,6,4279637526,0 Data 4284394590,3,4281808695,9,4279637526,0,4284394590,3,4281808695,3,4279637526,1,4284394590,2,4281808695,9 Data 4279637526,0,4284394590,3,4281808695,6,4289110427,5,4281808695,6,4279637526,0,4284394590,3,4281808695,9 Data 4279637526,0,4284394590,3,4281808695,3,4279637526,1,4284394590,2,4279637526,10,4284394590,3,4281808695,6 Data 4289110427,5,4281808695,6,4279637526,0,4284394590,3,4281808695,9,4279637526,0,4284394590,3,4281808695,3 Data 4279637526,1,4284394590,17,4281808695,6,4289110427,5,4281808695,6,4279637526,0,4284394590,3,4281808695,9 Data 4279637526,0,4284394590,3,4281808695,3,4279637526,1,4284394590,16,4281808695,7,4289110427,5,4281808695,6 Data 4279637526,0,4284394590,3,4281808695,7,4281084972,0,4279703319,0,4279637526,0,4284394590,3,4281808695,3 Data 4279637526,1,4284394590,17,4281808695,6,4289110427,2,0,0,4289110427,1,4281808695,6,4279637526,0 Data 4284394590,3,4281808695,6,4279637526,3,4284394590,3,4281808695,3,4279637526,1,4284394590,17,4281808695,6 Data 4289110427,2,0,0,4289110427,1,4281808695,6,4279637526,0,4284394590,3,4281808695,5,4279637526,1 Data 4282412608,0,4284394590,5,4281808695,3,4279637526,1,4284394590,2,4281808695,9,4279637526,0,4284394590,3 Data 4281808695,6,4289110427,2,0,0,4289110427,1,4281808695,6,4279637526,0,4284394590,3,4281808695,5 Data 4279637526,0,4280034076,0,4284394590,6,4281808695,3,4279637526,1,4284394590,2,4281808695,9,4279637526,0 Data 4284394590,3,4281808695,6,4289110427,1,0,1,4289110427,2,4281808695,5,4279637526,0,4284394590,3 Data 4279637526,6,4284394590,7,4281808695,3,4279637526,1,4284394590,2,4279637526,10,4284394590,3,4281808695,6 Data 4289110427,1,0,1,4289110427,2,4281808695,5,4279637526,0,4284394590,16,4283532625,0,4281875000,0 Data 4281808695,3,4279637526,1,4284394590,17,4281808695,5,4289110427,2,0,2,4289110427,1,4281808695,6 Data 4284394590,15,4281808695,6,4279637526,1,4284394590,17,4281808695,5,4289110427,2,0,2,4289110427,1 Data 4281808695,7,4284394590,13,4281808695,7,4279637526,1,4284394590,16,4282803270,0,4281808695,5,4289110427,1 Data 0,3,4289110427,2,4281808695,7,4284394590,12,4281808695,9,4284394590,15,4282670916,0,4281808695,5 Data 4289110427,2,0,4,4289110427,1,4281808695,53,4289110427,2,0,4,4289110427,2,4281808695,52 Data 4289110427,1,0,5,4289110427,2,4281808695,51,4289110427,2,0,6,4289110427,2,4281808695,50 Data 4289110427,1,0,7,4289110427,2,4281808695,49,4289110427,2,0,8,4289110427,2,4281808695,47 Data 4289110427,2,0,10,4289110427,2,4281808695,46,4289110427,1,0,12,4289110427,2,4281808695,44 Data 4289110427,2,0,12,4289110427,2,4281808695,43,4289110427,2,0,14,4289110427,2,4281808695,41 Data 4289110427,2,0,16,4289110427,2,4281808695,39,4289110427,2,0,18,4289110427,3,4281808695,36 Data 4289110427,2,0,20,4289110427,3,4281808695,33,4289110427,3,0,22,4289110427,3,4281808695,31 Data 4289110427,3,0,24,4289110427,4,4281808695,28,4289110427,3,0,27,4289110427,4,4281808695,24 Data 4289110427,3,0,30,4289110427,5,4281808695,19,4289110427,5,0,33,4289110427,6,4281808695,13 Data 4289110427,6,0,37,4289110427,23,0,42,4289110427,17,0,49,4289110427,9,0,26
'BOX 64
Data 4278190160,1484,4278650685,0,4279637527,0,4279637526,13,4278190160,5,4279637526,3,4278190160,10,4279637526,3 Data 4278190160,21,4279637526,16,4278190160,5,4279637526,3,4278190160,10,4279637526,3,4278190160,20,4279637526,1 Data 4286280720,0,4290950923,16,4278190160,3,4279637526,1,4290950923,2,4278190160,9,4279637526,0,4290950923,3 Data 4278190160,19,4279637526,0,4280624149,0,4290950923,17,4278190160,3,4279637526,1,4290950923,2,4278190160,9 Data 4279637526,0,4290950923,3,4278190160,19,4279637526,0,4290950923,18,4278190160,3,4279637526,1,4290950923,2 Data 4278190160,9,4279637526,0,4290950923,3,4278190160,19,4279637526,0,4290950923,3,4278190160,18,4279637526,1 Data 4290950923,2,4278190160,9,4279637526,0,4290950923,3,4278190160,19,4279637526,0,4290950923,3,4278190160,18 Data 4279637526,1,4290950923,2,4278190160,9,4279637526,0,4290950923,3,4278190160,19,4279637526,0,4290950923,3 Data 4278190160,18,4279637526,1,4290950923,2,4278190160,9,4279637526,0,4290950923,3,4278190160,19,4279637526,0 Data 4290950923,3,4279637526,10,4279505947,0,4278190160,6,4279374370,0,4279637526,0,4290950923,2,4279637526,10 Data 4290950923,3,4278190160,19,4279637526,0,4290950923,16,4278190160,6,4279637526,0,4290950923,17,4278190160,19 Data 4279637526,0,4290950923,17,4278190160,5,4278255950,0,4290950923,17,4278190160,19,4279637526,0,4290950923,17 Data 4282070843,0,4278190160,5,4278584910,0,4290950923,16,4278190160,19,4279637526,0,4290950923,17,4290622221,0 Data 4278190160,7,4286149157,0,4290950923,14,4278190160,19,4279637526,0,4290950923,3,4278190160,9,4279637526,0 Data 4290950923,3,4278190160,18,4279637526,0,4290950923,3,4278190160,19,4279637526,0,4290950923,3,4278190160,9 Data 4279637526,0,4290950923,3,4278190160,18,4279637526,0,4290950923,3,4278190160,19,4279637526,0,4290950923,3 Data 4279637526,10,4290950923,3,4278190160,18,4279637526,0,4290950923,3,4278190160,19,4279637526,0,4290950923,17 Data 4290687756,0,4278190160,18,4279637526,0,4290950923,3,4278190160,20,4290950923,17,4282597176,0,4278190160,18 Data 4279637526,0,4290950923,3,4278190160,21,4290950923,16,4278190160,19,4279637526,0,4290950923,3,4278190160,21 Data 4278255952,0,4290950923,14,4278190160,21,4290950923,3,4278190160,1353
'Hedgehog CC0 - from Frogatto & Friends team - www.frogatto.com
Data 0,148,4282268723,0,4280889648,0,4282145364,0,4282541920,1,0,58,4282663478,0,4282143050,0 Data 4284656026,0,4285714365,0,4285914054,0,4290832070,0,4293848006,0,4293780935,0,4293650117,0,4293454274,0 Data 4293651396,0,4292602567,0,4288996553,0,4285375122,0,4282467390,0,4281546805,0,4281548088,0,0,48 Data 4281546546,0,4281822563,0,4283351467,0,4285519038,0,4286698443,0,4286229455,0,4285246658,0,4283876010,0 Data 4285518780,0,4288209609,0,4292471495,0,4294240706,0,4294042300,0,4289452478,0,4285250988,0,4281946187,0 Data 4282137394,0,0,48,4281225803,0,4284394139,0,4285847238,0,4284333241,0,4283611312,0,4283154601,0 Data 4288272314,0,4292733639,0,4294241734,0,4294963142,1,4293389510,0,4291224001,0,4286362786,0,4283662710,0 Data 4282072630,0,4283716160,0,0,46,4280360993,0,4284061579,0,4285716932,0,4283745711,0,4283614638,0 Data 4284534199,0,4290371775,0,4294963142,4,4294307270,0,4291291336,0,4288988330,0,4286939503,0,4284965458,0 Data 4283518782,0,4284768842,0,0,44,4280101432,0,4283931540,0,4285782725,0,4284205748,0,4285255865,0 Data 4287881930,0,4291881415,0,4294963142,8,4288190851,0,4281812801,0,4283520581,0,0,37,4280953127,0 Data 4280360993,4,4279842904,0,4279195808,0,4283608250,0,4286308299,1,4289521097,0,4294963142,10,4290635720,0 Data 4285515701,0,4282211158,0,4281940016,0,0,33,4281611053,1,0,0,4284391314,0,4287607966,0 Data 4291279772,3,4288330924,0,4284530112,0,4284138423,0,4283942833,1,4288075449,0,4294963142,8,4292930503,0 Data 4288865225,0,4290635720,0,4291219890,0,4284243796,0,4281940016,0,0,33,4283596917,0,4286285172,0 Data 4288389000,0,4290239421,0,4292471495,0,4294963142,3,4293061575,0,4290635720,0,4286896319,0,4284007093,0 Data 4281833640,0,4284131499,0,4289058743,0,4292338879,0,4294963142,1,4293323974,0,4290897864,0,4290635720,2 Data 4288733123,0,4285059258,0,4289847232,0,4293452220,0,4286947983,0,4283198818,0,0,32,4286225290,0 Data 4288865225,0,4292930503,0,4294963142,4,4294373062,0,4293192647,0,4293717190,0,4294963142,0,4290897864,0 Data 4287025091,0,4282355120,0,4281371305,0,4282164902,0,4288138425,0,4292799431,1,4290307784,0,4286701514,0 Data 4286308299,0,4286176969,0,4285716932,0,4284927421,0,4283807923,0,4288270525,0,4292209351,0,4289783240,0 Data 4285900437,0,4281350198,0,0,27,4281089595,0,4282880899,0,4287156403,0,4293060802,0,4294635206,0 Data 4294963142,6,4292799431,0,4287881930,0,4289848776,0,4294373062,1,4292798661,0,4287551427,0,4283474867,0 Data 4279325850,0,4283145392,0,4286174401,0,4286239939,0,4286240966,0,4286242506,0,4286176713,0,4285716933,0 Data 4283942322,0,4284002999,0,4285373646,0,4285906126,0,4287357386,0,4292209351,0,4290358930,0,4282136885,0 Data 0,25,4281545260,0,4283200618,0,4286103725,0,4290369721,0,4291224771,0,4288471752,0,4291422408,0 Data 4294963142,6,4292799431,0,4287881930,0,4286963914,0,4287881930,1,4286890933,0,4283457136,0,4281939800,0 Data 4281149267,0,4282924625,0,4284698708,0,4285616229,0,4286088592,0,4286240453,0,4284862651,0,4283875762,0 Data 4284721858,0,4285243083,0,4285504208,0,4285906126,0,4287357386,0,4292209351,0,4290358930,0,4282136885,0 Data 0,25,4283598459,0,4287412644,0,4291028936,0,4290373320,0,4288865225,0,4286767050,0,4290635720,0 Data 4294963142,4,4294635206,0,4291881415,0,4288667588,0,4285518523,0,4285121729,0,4285839566,0,4284451740,0 Data 4284375669,0,4286853466,0,4287570514,1,4288161614,0,4288555854,0,4288359511,0,4287449708,0,4286216070,0 Data 4284707957,0,4283855987,0,4285042614,0,4284387016,0,4282152887,0,4283212214,0,4285190329,0,4288339651,0 Data 4287211418,0,4282136134,0,4281806644,0,4282597686,1,4283321404,0,0,20,4284319354,0,4288535490,0 Data 4290635720,0,4291487943,0,4288144073,0,4287094986,0,4288668617,0,4291946951,0,4294963142,4,4294373062,0 Data 4289521097,0,4285519810,0,4283745711,0,4283604646,0,4284314276,0,4284235628,0,4285735502,0,4290717275,0 Data 4292290655,1,4292424285,0,4292295515,0,4291443803,0,4290002521,0,4288430166,0,4287313226,0,4286264909,0 Data 4284834187,0,4282934425,0,4280174724,0,4281891996,0,4284201400,0,4285518276,0,4285047966,0,4282792271,0 Data 4282196791,0,4282000433,0,4281147437,0,4281478192,0,4283452991,0,0,17,4280955955,0,4284259728,0 Data 4287876020,0,4292662449,0,4289318579,0,4285515701,1,4287876537,0,4292008383,0,4293190337,0,4293454274,0 Data 4293716933,0,4294110662,0,4294766278,0,4294438598,0,4293389510,0,4289127625,0,4285585603,0,4284008626,0 Data 4282809213,0,4281867840,0,4286981714,0,4290390622,0,4291635294,0,4291503964,0,4290783063,0,4291315025,0 Data 4291714381,1,4292238672,0,4293090900,0,4292689754,0,4291044955,0,4285014091,0,4282654021,1,4283847810,0 Data 4285108670,0,4285510587,0,4285110159,0,4284170819,0,4284952389,0,4285738325,0,4283310922,0,4281671227,0 Data 4280557349,0,4282597686,0,0,16,4280427043,0,4280889648,0,4281415734,0,4282071349,0,4281612341,0 Data 4281087798,1,4281091928,0,4281099414,0,4282882216,0,4284794798,0,4286503105,0,4289258697,0,4293979590,0 Data 4291619015,0,4287291594,0,4286701514,0,4286176969,0,4285979591,0,4284911494,0,4283641140,0,4287638350,0 Data 4290062942,0,4290259550,0,4287113034,0,4281803048,0,4281869607,0,4281935911,1,4285868859,0,4291768154,0 Data 4292291422,0,4291831902,0,4289800283,0,4288948570,1,4285540951,0,4282068051,0,4282134867,0,4282725193,0 Data 4283707447,0,4284952389,0,4285935190,0,4285607253,0,4284164423,0,4280951079,0,4282597686,0,0,22 Data 4281347882,0,4279972168,0,4279325072,0,4279921569,0,4280713124,0,4281435820,0,4283276465,0,4286826675,0 Data 4286107572,0,4284139445,0,4282753970,0,4282220961,0,4283067520,0,4285287524,0,4287769677,0,4289145687,0 Data 4288883030,0,4285080895,0,4284428600,0,4285154873,0,4286473550,0,4287719510,0,4288489531,0,4287304755,0 Data 4285079863,0,4289013070,0,4292159582,0,4291635294,0,4291438942,1,4289865305,0,4288095060,0,4287308883,0 Data 4285473868,0,4282983231,0,4283574590,0,4284952386,0,4287311186,0,4287376213,0,4284426565,0,4283183419,0 Data 4282466100,0,4284242501,0,0,21,4281426545,0,4281560742,0,4280378537,0,4279261856,0,4280185506,0 Data 4282356647,0,4286695345,0,4287549875,0,4287417779,0,4286032304,0,4284183443,0,4282200406,0,4285276750,0 Data 4290063198,0,4287768655,0,4285802818,0,4283839540,0,4285551169,0,4289429342,0,4290682227,0,4292121461,0 Data 4293340491,0,4290709299,0,4285927978,0,4286717242,0,4288226634,0,4290521176,0,4291438942,1,4291831902,0 Data 4291962974,0,4290718302,0,4288358488,0,4285407822,0,4285474631,0,4286459204,0,4288818005,0,4289407836,0 Data 4287835482,0,4284556870,0,4281082671,0,4283715395,0,0,19,4281224777,0,4282817418,0,4283937975,0 Data 4284257476,0,4282417079,0,4280776360,0,4283805100,0,4287746740,0,4293716675,0,4294241734,0,4293323719,0 Data 4293190599,0,4290293414,0,4283777115,0,4285276750,0,4290063198,0,4283966519,0,4281937450,0,4287192905,0 Data 4290088298,0,4292329616,1,4292582527,0,4293472334,0,4293918777,1,4287439157,0,4283185463,0,4286786890,0 Data 4288751958,0,4289931869,0,4290914654,0,4291635294,0,4290587230,0,4290063198,1,4290259550,0,4290456158,3 Data 4287440212,0,4283638343,0,4284171847,0,0,17,4280953126,0,4281822562,0,4283349669,0,4285124796,0 Data 4284069053,0,4280380583,0,4282685877,0,4286371784,0,4291552709,0,4294372548,0,4294831813,0,4291356872,0 Data 4286766027,0,4286363598,0,4284972716,0,4282397788,0,4285276750,0,4290063198,0,4283966519,0,4282399538,0 Data 4289369454,0,4292724376,0,4294699969,1,4294557608,0,4294064731,0,4293918777,1,4292239711,0,4289764210,0 Data 4283450171,0,4283769654,0,4289473114,0,4290128478,1,4290062942,0,4290063198,1,4291045726,0,4292094046,3 Data 4291897182,0,4290914137,0,4284753209,0,4280624164,3,4283650368,0,0,12,4282222713,0,4283740575,0 Data 4284795582,0,4282621107,0,4282225330,0,4283739835,0,4288139202,0,4292405959,0,4294110662,0,4293455046,0 Data 4289717705,0,4286830783,0,4284074163,0,4283940020,0,4283272856,0,4282005591,0,4285276750,0,4290063198,0 Data 4283966519,0,4282465331,0,4289567089,0,4292920220,0,4294957510,0,4289303942,0,4284830284,0,4284622899,0 Data 4288089390,0,4293329207,0,4293881980,0,4292194975,0,4283713861,0,4283376436,0,4289407578,0,4290063198,4 Data 4290390622,0,4290849118,0,4291766366,0,4292424285,0,4292889944,0,4293022295,0,4292760150,0,4290662731,0 Data 4289286212,1,4288953671,0,4288554315,0,4284428602,0,4282597686,0,4284769098,0,0,10,4287809964,0 Data 4286567352,0,4284203704,0,4280974760,0,4282549420,0,4288730307,0,4292471495,0,4294700742,0,4292340423,0 Data 4290897864,0,4290176712,0,4287617985,0,4284468152,0,4284267193,0,4283533980,0,4282070872,0,4285276750,0 Data 4290063198,0,4286588744,0,4284953409,0,4286342483,0,4287592556,0,4289101964,0,4286532958,0,4284556347,1 Data 4286061372,0,4288286012,0,4288499297,0,4287788661,0,4284235081,0,4285081412,0,4289604187,0,4290063198,5 Data 4290194014,0,4291569758,0,4292556636,0,4293221973,0,4293355092,4,4293088854,0,4292756314,0,4287639623,0 Data 4284296251,0,4283450427,0,4284045123,0,0,8,4285365355,0,4294042813,0,4288531126,0,4281966759,0 Data 4281305001,0,4285308595,0,4293189826,0,4294963142,0,4294504134,0,4290438856,0,4290045640,0,4294110662,0 Data 4291160264,0,4286241483,0,4285838286,0,4284578477,0,4282331996,0,4284358731,0,4287899479,0,4289210715,0 Data 4288686421,0,4284097592,0,4283113785,0,4283703113,0,4287571284,0,4290456158,0,4290194014,0,4287637078,0 Data 4284096586,0,4283179323,0,4283311157,0,4285934414,0,4287966554,0,4289866589,0,4290063198,0,4290128478,0 Data 4290390622,1,4290128478,0,4290063198,0,4290194014,0,4291569758,0,4292490076,0,4292956247,0,4293156181,0 Data 4293355092,3,4293222229,0,4293088854,0,4289869910,0,4286522700,0,4281737515,0,4281742638,0,4284176709,0 Data 4284900427,0,0,5,4282423431,0,4286828210,0,4294175940,0,4287079347,0,4280051877,0,4284069053,0 Data 4288996553,0,4293848518,0,4294963142,4,4291160264,0,4286241483,0,4285838286,0,4284578477,0,4282331996,0 Data 4281605186,1,4286850387,0,4290063198,3,4291307870,0,4291831902,0,4290587230,0,4290063198,7,4290325086,0 Data 4291569758,1,4290325086,0,4290063198,0,4290194014,0,4291569758,0,4292290655,1,4292756314,0,4293355092,3 Data 4292889176,0,4292290655,0,4285603916,0,4281343035,0,4280557351,0,4280360993,1,4283190076,0,0,5 Data 4289049239,0,4290108346,0,4286434737,0,4283071608,0,0,0,4288786333,0,4293455046,0,4294635206,0 Data 4294963142,2,4293323974,0,4289258697,0,4287488458,0,4286043332,0,4283988107,0,4283119456,0,4284427605,0 Data 4285805134,0,4286987595,0,4286985043,0,4287573337,0,4289473373,0,4290063198,1,4291307870,0,4292159582,0 Data 4291831902,0,4291045726,0,4290128478,0,4285933124,0,4282786352,1,4285015358,0,4289604187,0,4290063198,0 Data 4290392157,0,4292102233,0,4292626521,0,4291898973,0,4290849118,0,4290062942,0,4290390622,0,4290980190,0 Data 4292028510,0,4292756314,0,4293355092,3,4292103000,0,4290587230,0,4284948812,0,4282985029,0,4287650386,0 Data 4288174414,0,4286660162,0,4283840566,0,4281611053,0,0,4,4291279772,0,4290824103,0,4282546027,0 Data 0,1,4290358930,0,4293586118,0,4291160264,0,4290635720,0,4290897864,0,4293586118,0,4292799431,0 Data 4287357386,0,4285585603,0,4284531890,0,4282736495,0,4283049030,0,4286264911,0,4287971664,0,4288825678,0 Data 4287905872,0,4287117138,0,4286130256,0,4287374933,0,4290063198,0,4291307870,0,4292028510,0,4291438942,0 Data 4288882770,0,4285539649,0,4286007112,0,4285880905,0,4281937964,0,4283703860,0,4290455642,0,4290587230,0 Data 4290458204,0,4292301655,0,4293155925,0,4292889176,0,4289017420,0,4285211967,1,4286654023,0,4290390362,0 Data 4292100953,0,4293355092,1,4293221973,0,4292889688,0,4290722649,0,4288032090,0,4283966027,0,4283642443,0 Data 4290477417,0,4291461222,0,4289748818,0,4284824127,0,4280950321,0,0,4,4287859318,0,4287727987,0 Data 0,2,4290358930,0,4292209351,0,4287357386,0,4286308299,0,4286635978,0,4290373320,0,4290174149,0 Data 4285053886,0,4283083699,0,4281833375,0,4281683303,0,4283245382,0,4286920016,0,4288430416,0,4288825678,1 Data 4287841100,0,4284755783,0,4285016391,0,4286981962,0,4289538134,0,4290717786,0,4288161615,0,4286002245,0 Data 4284499774,0,4289231969,0,4291991925,0,4286472269,0,4285611586,0,4288292682,0,4289603412,0,4291047773,0 Data 4292498263,0,4293355092,1,4286988863,0,4280951084,0,4283186231,0,4285087811,0,4286982738,0,4289542742,0 Data 4292367191,0,4292760151,0,4292626521,0,4291833949,0,4288489560,0,4284623184,0,4284955474,0,4286666844,0 Data 4291597173,0,4292450418,0,4291462242,0,4285876560,0,4281605186,0,0,9,4290358930,0,4292077252,0 Data 4287026881,0,4285911745,0,4285977282,1,4284330936,0,4280116383,0,4279325850,0,4279455892,0,4280693091,0 Data 4282784840,0,4285537368,0,4287442519,0,4288693839,0,4288759630,0,4288825678,1,4285807166,0,4280885795,0 Data 4285736515,0,4287899729,0,4283049009,0,4285420357,0,4292320375,0,4293109117,2,4289297761,0,4281740585,0 Data 4286260800,0,4291767900,0,4292759383,0,4293026132,0,4292698451,0,4287447628,0,4282985545,0,4289690731,0 Data 4290348143,0,4283642956,0,4285474383,0,4289669468,0,4291111005,0,4291438686,0,4289997148,0,4286326353,0 Data 4282196548,0,4289033319,0,4293109117,3,4286601051,0,4281605186,0,0,9,4290358930,0,4290689436,0 Data 4283128145,0,4281942606,0,4282466395,1,4282137177,0,4281281108,0,4281149267,0,4281149010,0,4281409608,0 Data 4281801795,0,4282391622,0,4284555088,0,4287177819,0,4288166739,0,4288825678,1,4288169546,0,4287185221,0 Data 4284951878,0,4283901254,0,4286199877,0,4289422938,0,4292714105,0,4293109117,2,4291727725,0,4289030479,0 Data 4286136905,0,4284686410,0,4289670230,0,4289736789,0,4284885832,0,4287322715,0,4291071090,0,4292385913,0 Data 4292517498,0,4291202675,0,4287519583,0,4283637576,0,4287702613,0,4288620376,0,4284555339,0,4286136658,0 Data 4290014816,0,4291924082,0,4293109117,3,4286601051,0,4281605186,0,0,6,4279844709,0,0,1 Data 4284702290,0,4285233770,0,4282481260,0,4281031538,0,4280302451,0,4281149010,0,4282785349,0,4285735759,0 Data 4286325841,4,4285276240,0,4283898958,0,4286261332,0,4287902805,0,4288562255,0,4288825678,1,4286987595,0 Data 4286200137,0,4287972428,0,4290143323,0,4292185198,0,4292779127,0,4292977275,0,4292580980,0,4291922024,0 Data 4290803543,0,4288701009,0,4286662733,0,4286394190,0,4286064460,0,4285739593,0,4289359202,0,4293109117,3 Data 4290609772,0,4287386198,0,4286921804,0,4286789450,0,4287253844,0,4289423454,0,4291986024,0,4292646773,0 Data 4293109117,1,4292844920,0,4292448625,0,4286336854,0,4281605186,0,0,5,4280504174,0,4281697706,0 Data 4282218888,0,4282410591,0,4281753431,0,4281429869,0,4281635227,0,4280643211,0,4279910510,0,4283116631,0 Data 4286260048,0,4290127964,0,4290849118,4,4288161366,0,4284752204,0,4284816977,0,4285473108,0,4287443540,0 Data 4288298577,0,4288825678,3,4289813589,0,4291328608,0,4292119660,0,4292514930,0,4291789926,0,4291263325,0 Data 4290737750,1,4290014804,0,4286795597,0,4286400075,0,4288960080,0,4291264359,0,4293109117,3,4292580723,0 Data 4291657317,0,4288831827,0,4288306769,0,4291330920,0,4292382575,1,4292844664,0,4293109117,1,4292449906,0 Data 4291460449,0,4285679432,0,4281081141,0,0,4,4280965251,0,4282617263,0,4285584580,0,4285914054,0 Data 4285454018,0,4283613105,0,4281570464,0,4279721363,0,4280432988,0,4282065195,0,4287571789,0,4290783582,0 Data 4292028510,0,4292291422,0,4292423517,3,4291505501,0,4290325086,0,4284817740,0,4282457158,0,4285275222,0 Data 4287048279,0,4288562000,1,4288562255,0,4288759630,0,4289419088,0,4290342228,0,4291197278,0,4291657571,0 Data 4291000409,0,4290737750,5,4290869079,0,4291923049,0,4292976762,0,4293043068,1,4292977018,0,4292514674,0 Data 4291986024,1,4292250221,0,4292845177,0,4293109117,2,4293043324,0,4292977018,0,4291595370,0,4289424207,0 Data 4284630584,0,4280953127,0,0,4,4289834393,0,4290041019,0,4284138926,0,4283548589,0,4283021483,0 Data 4280844964,0,4279849342,0,4280102462,0,4284491843,0,4289014102,0,4290979932,0,4292028510,0,4292225118,0 Data 4292689754,0,4293221973,3,4292691545,0,4291962974,0,4285472844,0,4281670722,0,4282129476,0,4284030542,0 Data 4287045980,1,4287375706,0,4288364369,0,4288891726,0,4289023566,0,4290078036,0,4290869079,0,4290737750,5 Data 4291066202,0,4291657571,0,4291920744,0,4292184171,0,4292778871,0,4292844920,0,4292184684,0,4292052073,0 Data 4291986024,1,4292250221,0,4292845177,0,4293109117,2,4292910969,0,4292250734,0,4288177233,0,4281608743,0 Data 4283451963,0,4284834635,0,0,1,4282466100,0,4286281058,0,4289440144,0,4289516728,0,4287551935,0 Data 4283548331,0,4282224254,0,4281161555,0,4280369489,0,4281151820,0,4283378244,0,4287637840,0,4291373406,0 Data 4291045726,0,4291242334,0,4292094046,0,4292756314,0,4293355092,3,4293155669,0,4292955736,0,4289999701,0 Data 4286980688,0,4282850629,0,4281998398,0,4282785336,1,4283638078,0,4286327120,0,4287573080,1,4288628308,0 Data 4289682769,0,4290408020,0,4290737750,4,4291066203,0,4291788901,0,4291986024,1,4292250477,1,4291986280,0 Data 4291986024,2,4292052329,0,4292316270,0,4292712565,0,4293109117,1,4292515702,0,4290538334,0,4286334531,0 Data 4280360993,0,4283190076,0,0,2,4280624164,0,4288517245,0,4293848518,0,4288472009,0,4284923821,0 Data 4282155123,0,4283256660,0,4284359995,0,4283377209,0,4283771202,0,4285541715,0,4289145691,0,4292094046,0 Data 4290718302,0,4290325086,0,4291111262,0,4291966812,0,4292889688,0,4293155669,0,4293355092,3,4292689754,0 Data 4290258265,0,4283571783,0,4281081141,0,4280360993,0,4281409318,0,4282588719,0,4283571517,0,4283964739,1 Data 4284623678,0,4285217338,0,4285876797,0,4287057735,0,4288826968,0,4289419350,0,4290012499,0,4290802522,0 Data 4291460449,0,4291854694,0,4291986024,9,4292250221,0,4292580723,0,4292252270,0,4290740066,0,4286400323,0 Data 4284169016,0,4282597686,0,4284176965,0,0,2,4280624164,0,4287599230,0,4292273603,0,4287219634,0 Data 4284189571,0,4282329908,0,4286064197,0,4289604445,0,4287769946,0,4286393941,0,4285738833,0,4288949079,0 Data 4292094046,0,4290718302,0,4290063198,1,4290849118,0,4291898206,0,4292364377,0,4292827733,0,4293024342,0 Data 4293155414,1,4292557403,0,4290389594,0,4284227914,0,4282064700,0,4281540396,0,4283637047,0,4284620347,0 Data 4282721326,0,4282000426,0,4282064941,0,4281802540,0,4281540396,1,4282785336,0,4285340752,0,4286394188,0 Data 4287514440,0,4288962900,0,4289752922,1,4290540382,0,4291393379,0,4291591524,0,4291788901,0,4291920231,0 Data 4291986024,2,4291920231,0,4291788901,0,4291591267,0,4291393379,0,4289752148,0,4287388485,0,4282660912,0 Data 4282860856,0,0,4,4280624164,0,4283993216,0,4286040502,0,4282210387,0,4283444026,0,4288883287,0 Data 4289735260,0,4289997661,0,4289866589,0,4287966288,0,4284755770,0,4288162634,0,4292094046,0,4290718302,0 Data 4290063198,1,4290062942,0,4290194270,0,4290194781,0,4290784605,0,4291963998,0,4292356958,1,4292290910,0 Data 4291045725,0,4286917719,0,4285933399,0,4286389339,0,4286585947,0,4286981209,0,4287839055,0,4288559186,0 Data 4288947293,0,4287569500,0,4286389339,1,4284620106,0,4281081640,0,4280820004,0,4280886052,0,4281017636,0 Data 4281083429,1,4285020474,0,4289089360,0,4290210132,0,4291066203,0,4291788901,0,4291986024,2,4291657571,0 Data 4291000410,0,4290012243,0,4289023055,0,4283970612,0,4281741612,0,4284373830,0,4285229391,0,0,4 Data 4280624164,0,4281352510,0,4282799444,0,4285805645,0,4287965264,0,4289866332,0,4290783582,0,4291569758,1 Data 4289211217,0,4284886840,0,4287311176,0,4290783582,0,4291307870,0,4291176798,0,4290194014,0,4290063198,2 Data 4290194014,0,4290587230,0,4291373406,0,4292290655,0,4291307870,0,4289275994,0,4284425036,0,4283899718,0 Data 4285471812,0,4286983500,0,4288562003,0,4289616979,0,4289681235,0,4289085268,0,4288559955,0,4288231253,0 Data 4288554590,0,4288094299,0,4286783823,0,4286652750,2,4284686400,0,4281147430,0,4281673256,0,4282985775,0 Data 4283381296,0,4283644722,0,4283907638,0,4283973175,2,4283841845,0,4283644722,0,4283315248,0,4282985519,0 Data 4283516218,0,4284176708,0,4285163598,0,0,3,4282926649,0,4283775547,0,4285015871,0,4285211967,0 Data 4285802051,0,4288817494,0,4290063198,1,4291443035,0,4292756314,0,4292424029,0,4289997398,0,4285869640,0 Data 4286000710,0,4287245641,0,4289866327,0,4291176798,1,4290652766,0,4290063198,1,4290325086,0,4290914654,0 Data 4291176798,1,4287833429,0,4285801296,1,4284817480,0,4283243581,0,4286330182,0,4289155407,0,4290210388,0 Data 4290342228,0,4289814610,0,4289748818,0,4289945685,0,4290929256,0,4291322736,2,4291190893,0,4290532194,0 Data 4288495188,0,4285605445,0,4282982201,0,4281212466,0,4283835195,0,4283966519,0,4280950820,0,4281148196,0 Data 4282132522,1,4281673255,0,4280688930,0,4281479211,0,4282926649,0,0,6,4280360993,0,4283966519,0 Data 4289407578,0,4290325086,0,4290587230,3,4291971161,0,4293222485,0,4292757081,0,4290786395,0,4287704921,0 Data 4286197323,0,4285607487,0,4287179087,0,4288882520,0,4291242077,0,4291242334,0,4290587230,1,4290849118,0 Data 4291504478,0,4290062427,0,4287899479,0,4285276750,0,4284883276,0,4288817242,0,4287244117,0,4282654791,0 Data 4285083977,0,4287382603,0,4288698189,0,4289421138,0,4289683287,0,4290012501,0,4290473815,0,4291593577,0 Data 4292186481,0,4292450419,0,4292516211,0,4292186991,0,4290935133,0,4290008152,0,4289669985,0,4285603666,0 Data 4282064195,0,4286719828,0,4286851405,0,4281409832,0,4281935656,0,4283969331,0,4284231480,0,4283640886,0 Data 4281804329,0,4282530611,0,0,7,4280360993,0,4283966519,0,4289407578,0,4291307870,0,4292290655,3 Data 4292822873,0,4293355092,1,4292301655,0,4290458204,0,4290063198,0,4289473116,0,4284227658,0,4283703113,0 Data 4288948570,0,4290980190,0,4292290655,1,4291700830,0,4290456158,0,4286325841,0,4281605186,0,4286850387,0 Data 4290063198,1,4288490587,0,4286000983,0,4283507787,0,4282195008,0,4284030010,0,4285602886,0,4286717020,0 Data 4287903061,0,4288825678,1,4289419088,0,4290605909,0,4290737750,0,4290474069,0,4289419088,0,4289018964,0 Data 4289472096,0,4285603666,0,4281867587,0,4284623184,0,4284558153,0,4281016615,0,4281935656,0,4284034869,0 Data 4285214537,0,4285476686,0,4284297017,0,4282329387,0,4280360993,0,0,6,4280360993,0,4282852661,0 Data 4286590293,0,4285474128,0,4284489799,0,4285606464,0,4286000702,1,4286133564,0,4286463294,0,4287315021,0 Data 4289283414,0,4291908438,0,4291248474,0,4289473114,0,4283572793,0,4281147179,0,4282458671,0,4282982960,0 Data 4283375922,0,4283899967,0,4284096329,0,4283768649,0,4284228684,0,4284885585,0,4288096857,0,4290063198,1 Data 4288490587,0,4286000983,0,4283507787,0,4282720835,0,4286264646,0,4288498254,0,4289617239,0,4290012501,0 Data 4290341717,0,4290933086,0,4291592039,0,4292384370,0,4292516211,0,4292450163,0,4292186481,0,4291526505,0 Data 4290602588,0,4288696146,0,4286724938,0,4284033352,0,4282064957,0,4280623141,0,4282590772,0,4285673294,0 Data 4287704406,0,4288883802,0,4288621652,0,4284950077,0,4280360993,0,0,6,4280360993,0,4281540912,0 Data 4283311176,0,4285080654,0,4286457168,0,4287114060,0,4287769675,0,4288555851,0,4288621387,0,4288162890,0 Data 4286000709,0,4286199368,0,4288627795,0,4286854472,0,4284359739,0,4282130230,0,4280884782,0,4280426275,0 Data 4280622889,0,4281081140,0,4281343036,0,4281933375,0,4282656059,0,4283771453,0,4284821314,0,4288097363,0 Data 4290063198,1,4289342300,0,4288228442,0,4284490572,0,4282917956,0,4286987595,0,4289485137,0,4290605909,0 Data 4291131739,0,4291526498,0,4292317038,0,4292713078,0,4293043324,0,4293109117,2,4292779639,0,4292186990,0 Data 4290935135,0,4289355089,0,4284166471,0,4281277753,0,4280491813,0,4282787384,0,4286197335,0,4288490587,0 Data 4288817242,0,4286194769,0,4283441218,0,4281015603,0,4282004533,0,4283124027,0,4284900427,0,0,3 Data 4280360993,0,4281802800,0,4283965512,0,4287506005,0,4290063198,1,4290718302,0,4292094046,0,4292424029,0 Data 4291574103,0,4287050567,0,4285017925,0,4285804371,0,4285152330,0,4284368958,0,4284629064,0,4283708482,0 Data 4280886054,0,4280884783,0,4281605186,1,4282196286,0,4283509813,0,4283641141,0,4283181367,0,4286655310,0 Data 4289014876,0,4289801053,0,4290063198,1,4285276750,0,4282917956,0,4286987595,0,4289485137,0,4290605909,0 Data 4291394656,0,4292118122,0,4292779127,0,4293109117,6,4292054892,0,4290474842,0,4284561738,0,4281277753,0 Data 4280491813,0,4282787384,0,4286066262,0,4286851413,0,4286325586,0,4283964748,0,4284034639,0,4285154900,0 Data 4284432706,0,4283908665,0,4283846719,0,4284439879,0,0,2,4280360993,0,4283966519,0,4289407578,0 Data 4290063198,0,4290062942,0,4290128478,0,4290849118,0,4292159582,0,4292822873,0,4292370260,0,4288168020,0 Data 4286001237,0,4286198358,0,4289752684,0,4293109632,0,4292382576,0,4289096535,0,4281805866,0,4281015856,0 Data 4281867587,1,4282458431,0,4283837496,0,4283377467,0,4282129475,0,4284360526,0,4286459223,0,4289014620,0 Data 4289866589,0,4290063198,0,4285276750,0,4282917700,0,4287052619,0,4289484625,0,4290474069,0,4291328863,0 Data 4292118122,0,4292779127,0,4293109117,4,4293043324,0,4293043067,0,4292448881,0,4291263076,0,4284824397,0 Data 4281343290,0,4280688678,0,4282787384,0,4285475924,0,4283376713,0,4283309897,0,4286128473,0,4289748333,0 Data 4293175681,0,4292448882,0,4289818971,0,4282528302,0,4282268723,0,0,2,4280360993,0,4283966519,0 Data 4289407578,0,4290063198,0,4290259550,0,4291373406,0,4291962974,0,4292225118,0,4292822873,0,4292173648,0 Data 4287119425,0,4286005570,0,4289159506,0,4292191113,0,4294498744,0,4293374606,0,4289756771,0,4281872172,0 Data 4282459446,0,4285147987,1,4286065491,0,4288162645,0,4288686679,0,4288424024,0,4284686924,0,4283179593,0 Data 4285934420,0,4287966554,0,4290063198,0,4285276750,0,4283047495,0,4287440215,0,4289345625,0,4289154640,0 Data 4290735197,0,4292118122,0,4292779127,0,4293109117,4,4292779127,0,4292250734,0,4291526754,0,4290343511,0 Data 4284495945,0,4281999421,0,4283050545,0,4282853177,0,4282720582,0,4285543497,0,4288104782,0,4289486421,0 Data 4291991939,0,4294565308,0,4293506706,0,4290545256,0,4282660657,0,4282268723,0,0,2,4280360993,0 Data 4283966519,0,4289407578,0,4290783582,0,4291636573,0,4292560217,0,4292955736,1,4292822873,0,4291575125,0 Data 4286657599,0,4286072125,0,4289883473,0,4292254328,0,4293639062,0,4292254069,0,4288965976,0,4282395195,0 Data 4283245892,0,4286197335,0,4288425050,0,4290259548,0,4291111262,0,4290783582,0,4290063198,0,4288030551,0 Data 4286194769,0,4283900747,0,4284819279,0,4287507801,0,4284162892,0,4282260037,0,4284225102,0,4285537867,0 Data 4286262081,0,4287707475,0,4288956258,0,4290011488,0,4290802785,0,4291528036,0,4291594084,2,4291461986,0 Data 4291198045,0,4290341462,0,4289025616,0,4284034886,0,4283113540,0,4286982732,0,4284687935,0,4281278767,0 Data 4285806913,0,4289287248,0,4290342228,0,4292056691,0,4293771162,0,4292385912,0,4289492055,0,4282463021,0 Data 4282268723,0,0,2,4280360993,0,4283114545,0,4287310923,0,4288555854,0,4289343311,0,4290201427,0 Data 4290335056,0,4289876296,0,4289478219,0,4288490315,0,4285541947,0,4285480254,0,4288304465,0,4289686114,0 Data 4290213483,0,4287914064,0,4285942084,0,4283640136,0,4285081424,0,4287769945,0,4290456156,0,4292357469,0 Data 4292557403,0,4292034650,0,4291248474,0,4291048028,0,4289144665,0,4283309639,0,4283245385,0,4286000983,0 Data 4283507787,0,4282195267,0,4284031304,0,4285409094,0,4286262336,0,4287707475,0,4288956258,0,4290011488,0 Data 4290802785,0,4291528036,0,4291594084,4,4288831319,0,4286002761,0,4285147211,0,4286063440,0,4289341787,0 Data 4285802051,0,4280820004,0,4285148993,0,4288364373,0,4289023576,0,4289880420,0,4290736497,0,4288307283,0 Data 4285944127,0,4283121973,0,4283452990,0,0,2,4280953127,0,4281936682,0,4283313456,0,4284232756,0 Data 4284954427,0,4285936462,0,4285542475,0,4283903031,0,4284297782,0,4284823863,0,4284955706,0,4285545283,0 Data 4286396499,0,4286001749,0,4285082449,0,4281934641,0,4281738030,0,4285279568,0,4287835482,0,4290456158,0 Data 4291504222,0,4292556636,0,4293155414,0,4293355092,1,4292689754,0,4290324057,0,4283834437,0,4283179847,0 Data 4285410388,0,4283638604,0,4283442247,0,4287184203,0,4288825678,1,4290472027,0,4291921000,0,4292647029,0 Data 4292977019,0,4293043324,0,4293109117,2,4292977531,0,4292845432,0,4287192413,0,4282129475,0,4287374933,0 Data 4290063198,1,4285802051,0,4280754212,0,4284555590,0,4287112029,0,4287243869,0,4287177821,0,4287045980,0 Data 4282851383,0,4281282090,0,0,4,4284834635,0,4283320892,0,4281017893,0,4285877309,0,4289685585,0 Data 4288827215,0,4286592332,0,4282979397,0,4286267211,0,4290081109,0,4291200356,0,4291265893,0,4290343256,0 Data 4286137677,0,4281998914,0,4280885036,0,4281738030,0,4285279568,0,4288621658,0,4292028510,0,4292159582,0 Data 4292556636,0,4293155414,0,4293355092,1,4292689754,0,4290652503,0,4285279292,0,4283049786,0,4282129988,0 Data 4284423505,0,4286653528,0,4288167249,0,4288825678,1,4289946451,0,4291000666,0,4291789414,0,4292382576,0 Data 4293043067,0,4293109117,2,4292450418,0,4291264863,0,4286270286,0,4282129475,0,4287374933,0,4290063198,1 Data 4285802051,0,4280820259,0,4285478462,0,4288957777,0,4289880917,0,4289485140,0,4288562000,0,4283378994,0 Data 4281282090,0,0,5,4283519039,0,4280624164,0,4285414971,0,4289287504,0,4288957518,0,4286789196,0 Data 4282847304,0,4285936204,0,4289616978,0,4290802778,0,4291198556,0,4290803543,0,4285680192,0,4280950572,0 Data 4283115069,0,4285344331,0,4288162905,0,4289604444,0,4290849118,0,4291700830,0,4292357214,0,4292556636,0 Data 4292623195,1,4291440733,0,4289473366,0,4285214267,0,4282722608,0,4280688171,0,4284161352,0,4287307614,0 Data 4288686429,0,4289149015,0,4288825166,0,4289155151,0,4289616721,0,4290670936,0,4291198301,0,4291396705,0 Data 4291462242,0,4291264609,0,4290539358,0,4288108623,0,4284366902,0,4285476931,0,4287571541,0,4289210715,0 Data 4290063198,1,4285802051,0,4280885795,0,4285610301,0,4288957518,0,4289287248,0,4286596161,0,4282985519,0 Data 4283516218,0,0,6,4284374086,0,4282729527,0,4283972408,0,4285085498,1,4283968569,0,4281734967,0 Data 4283311672,0,4285217338,0,4285810749,0,4286140478,1,4283512631,0,4281278258,0,4285605964,0,4287901018,0 Data 4288162906,0,4289014620,0,4290128478,0,4290783582,0,4291307870,3,4290521694,0,4288883541,0,4285083451,0 Data 4282918450,0,4281276210,0,4283307589,0,4285536087,0,4287503454,0,4288620637,0,4289082967,0,4289148759,0 Data 4289215830,0,4289681235,0,4289880658,1,4288043336,0,4286008638,0,4285414971,0,4284363065,0,4283050040,0 Data 4286392395,0,4290063198,1,4289604445,0,4288490587,0,4284753729,0,4280623394,0,4283313712,0,4285085498,1 Data 4283972408,0,4282597686,0,4284374086,0,0,8,4283124027,0,4281282090,1,4281018663,0,4280360993,0 Data 4280889648,0,4281615424,0,4282533184,0,4282268216,0,4280886314,0,4280950321,0,4281867581,0,4287309395,0 Data 4289014876,0,4286459479,0,4287442265,0,4289276764,5,4289735517,0,4288752469,0,4284558392,0,4282786358,0 Data 4282060864,1,4282716740,0,4284684622,0,4286520918,0,4287897692,0,4288094300,0,4287964250,0,4287576144,0 Data 4287381577,0,4287250757,0,4284101172,0,4281017124,1,4282525236,0,4285345104,0,4287638873,0,4289342300,0 Data 4289801053,0,4288752473,0,4285541455,0,4283313469,0,4281282090,3,4283124027,0,0,14,4280624163,0 Data 4283136368,0,4286895295,0,4291485117,0,4290094229,0,4283053135,0,4280950321,0,4281016358,0,4287047499,0 Data 4289014876,0,4286459479,0,4286066263,0,4286197335,5,4288621659,0,4288227666,0,4282327597,0,4280492066,0 Data 4280491555,2,4280688420,0,4281212464,0,4281998402,0,4282063940,0,4282063939,0,4282064451,0,4281671481,0 Data 4280951333,0,4282263594,0,4283707185,1,4284428093,0,4285673298,0,4286066263,0,4286459479,0,4288818267,0 Data 4287703119,0,4281868843,0,4282662966,0,4285163598,3,4285295183,0,0,16,4282077259,0,4283322954,0 Data 4284110155,0,4284438604,0,4282399799,0,4280623138,0,4283836980,0,4285607492,0,4285935187,0,4286000983,4 Data 4287311193,0,4289014876,0,4287769946,0,4285737806,0,4281606699,0,4280360993,1,4279842646,0,4279454336,1 Data 4279908703,0,4280557870,0,4281146679,0,4281605186,1,4281999675,0,4282919727,0,4283510320,0,4283969587,1 Data 4283509561,0,4282851908,0,4282654791,0,4282720327,0,4283375688,0,4282851135,0,4280753958,0,4280887334,0 Data 4281611053,1,4282597686,0,4284768842,0,0,17,4282926649,1,4283716160,0,4285163598,0,4282926649,0 Data 4280426529,0,4281541927,0,4282853680,0,4284624449,0,4284952389,4,4285082434,0,4285211967,0,4284294471,0 Data 4283114564,0,4280951081,0,4280360993,1,4279971652,0,4279648620,0,4279325072,0,4279583600,0,4280230696,0 Data 4281672495,0,4282787386,1,4283115832,0,4283838259,0,4283378486,0,4282787386,1,4282918972,0,4283182656,0 Data 4284232004,0,4285215304,1,4284230467,0,4281866806,0,4283182391,0,4285483323,0,4284890169,0,4284168503,0 Data 4283188024,0,4284045123,0,0,20,4282926649,0,4280492321,0,4282134058,0,4283512113,0,4284888632,0 Data 4284428089,0,4283705400,0,4284823354,0,4285809726,0,4286139203,0,4284892221,0,4283250738,0,4282328125,0 Data 4281932607,0,4282328624,0,4282592813,0,4282922286,0,4281477414,0,4280166194,0,4279648104,0,4279777884,0 Data 4280295974,0,4281869864,0,4283050799,0,4283247412,0,4283378486,1,4282853436,0,4282393921,1,4283445058,0 Data 4285415491,0,4287317576,0,4288825678,0,4289089615,0,4287710541,0,4283834695,0,4286399053,0,4290605909,0 Data 4289814610,0,4287055684,0,4282001705,0,4282597686,0,0,20,4282926649,0,4280952100,0,4287454021,0 Data 4290210388,0,4289023567,0,4286000715,0,4282913608,0,4287581776,0,4291330399,0,4292648053,0,4292580723,0 Data 4291986024,0,4286003284,0,4283635785,0,4287577420,0,4289485137,0,4290737750,0,4284892472,0,4280360993,4 Data 4280491813,0,4281277753,0,4281605186,1,4283248449,0,4284891968,1,4286071876,0,4288301132,0,4288825678,0 Data 4288891726,0,4290078547,0,4289227088,0,4285614402,0,4287387977,0,4290737750,1,4288110664,0,4282265642,0 Data 4282597686,0,0,20,4282926649,0,4280952100,0,4287454021,0,4290605909,0,4290408020,0,4287714892,0 Data 4284890948,0,4289558114,0,4292714103,0,4292977531,0,4292977275,0,4292845177,0,4287585878,0,4285678663,0 Data 4290079580,0,4291525219,0,4291723108,0,4285286718,0,4281084712,0,4283452990,0,4284505672,1,4282137394,0 Data 4280820516,0,4283249720,0,4284234560,1,4284563264,0,4284891968,1,4286071876,0,4288301132,0,4288825678,1 Data 4289023567,0,4287578701,0,4283637319,0,4285608010,0,4289155407,1,4286924099,0,4282001705,0,4282597686,0 Data 0,20,4282926649,0,4280952100,0,4287454021,0,4290408276,0,4289748818,0,4286923851,0,4284033606,0 Data 4288635994,0,4291923049,0,4292317295,0,4292448625,1,4286860629,0,4284756040,0,4288894549,0,4290866526,0 Data 4291986024,0,4285418048,0,4281282090,0,4284176709,0,0,1,4284176965,0,4283123514,0,4282529329,0 Data 4282330926,4,4282855472,0,4283838771,0,4284035380,2,4283312948,0,4281604658,0,4282458931,0,4284035380,1 Data 4283840566,0,4283385402,0,4284176965,0,0,20,4283716160,0,4282268209,0,4285747262,0,4287124292,0 Data 4286332992,0,4284230206,0,4282128188,0,4285349953,0,4287651144,0,4288176463,0,4288308049,1,4284232004,0 Data 4282587708,0,4285346879,0,4286990918,0,4288308049,0,4284697406,0,4282597686,0,4284571464,0,0,2 Data 4285032012,0,4282795320,0,4281940016,14,4282795320,0,4284769098,0,0,22,4285163598,0,4281940016,0 Data 4280360993,13,4283190076,0,0,32
rleCount = rleCount - 1