----- COLLISION FOR NOCOLLISION OBJ -----
ok, update , this is very well done
collision obj/obj between children/parent
that simulate (or try) a obj dynamic (without rotation…no rigid body)
with a mesh
still a little error with low speed, when the sphere is on the edge , and know also where is the error.
as FPS not there confront with bullet (10 time more slow,more noticeable with big mesh)
lack totally a real optimization
the good part is which is extremely easy to use , this script must run on the sphere obj(the children)
while the mesh target is(on default) the parent.
why make all this mess?
because the “static-bug” give very annoyng and the physic constraints is full of bug.
import bge
from mathutils import geometry as geo ,Matrix
class ClassCollisionMesh(object):
def __init__(self,own, meshCollision, radius=1.0, bounce=0.5, margin=2.0):
self.owner = own
self.velocity = own.worldPosition * 0
self.radius = radius
self.bounce = bounce
self.margin = margin
try:
self.target = meshCollision
mesh = self.target.meshes[0]
except:
self.mapMesh = None
print( "wrong something")
own.endObject()
return
tar=self.target
D={}
trisList=[]
for face in range(mesh.numPolygons):
def Mapping(vertexOrder):
L=[]
for vertexFace in vertexOrder:
vertID = mesh.getPolygon(face).getVertexIndex(vertexFace)
vertPos = mesh.getVertex(0,vertID).getXYZ()
L.append( vertPos.copy() )
trisList.append(L)
trisOrQuad = mesh.getPolygon(face).getNumVertex()
if trisOrQuad==3: Mapping((0,1,2))
elif trisOrQuad==4:
Mapping((0,1,2))
Mapping((0,2,3))
triN = -1
for tri in trisList:
triN += 1
a,b,c = tri
# decompose triangle
mab = (a-b).magnitude
mbc = (b-c).magnitude
mca = (c-a).magnitude
if mab >= max(mbc,mca): tri = a, b, c
elif mbc >= max(mca,mab): tri = b, c, a
elif mca >= max(mab,mbc): tri = c, a, b
faceDir = geo.normal(a,b,c)
mAB, mBC, mCA = (a+b)/2, (b+c)/2, (c+a)/2
n = faceDir
cAB,cBC,cCA = n.cross((b-a).normalized()), n.cross((c-b).normalized()), n.cross((a-c).normalized())
tot = ((a-b).magnitude + (b-c).magnitude + (c-a).magnitude)*10
def MaxDistance(point):
dA=(point- a).magnitude
dB=(point- b).magnitude
dC=(point- c).magnitude
return max(dA,dB,dC)
def SetSensor(var):
L=[]
L.append(var)
L.append(MaxDistance(var))
sensorList.append(L)
intersect = geo.intersect_line_line(mBC,mBC+cBC, mCA,mCA+cCA)[0]
M = Matrix().to_3x3()
vx = (b-a).normalized()
vz = n
vy = n.cross(vx)
M.col[0]=vx
M.col[1]=vy
M.col[2]=vz
intLoc = (intersect - a) * M
if intLoc.y>0:
faceCenter = intersect
else:
faceCenter = mAB
sensorList=[]
v = faceCenter; SetSensor(v)#center
v = faceCenter - (faceDir * (tot)); SetSensor(v)#sensDW
v = faceCenter + (faceDir * (tot+margin)); SetSensor(v)#sensUP
v = mAB + (cAB * tot); SetSensor(v)#sensEdge
v = mBC + (cBC * tot); SetSensor(v)#sensEdge
v = mCA + (cCA * tot); SetSensor(v)#sensEdge
D[triN]={
"vertex" : (a,b,c),
"faceDir" : faceDir,
"faceCenter": faceCenter,
"sensors" : sensorList,
}
self.mapMesh = D
return
def Update(self):
if self.target.invalid: #or not "mapMesh" in dir(self):
self.owner.endObject()
return
#################################
def Globaldraw(pointList, refWP, refWO):
for i in range(len(pointList)-1):
p0 = refWP + refWO * pointList[i]
p1 = refWP + refWO * pointList[i+1]
bge.render.drawLine(p0, p1, [1,0,0])
mesh = self.target
meshWP = mesh.worldPosition
meshWO = mesh.worldOrientation
radius = self.radius
bounce = self.bounce
velocity = self.velocity * 0.9999999
velocity[2] -= 0.016
WP = self.owner.worldPosition + velocity
OLP = (WP - meshWP) * meshWO
for triN in self.mapMesh:
check = 1
tri = self.mapMesh[triN]
for s in tri["sensors"]:
dist = (s[0]-OLP).magnitude
if dist > (s[1] + radius):
check = 0
break
if check == 1 :
faceNormal = meshWO * tri["faceDir"]
oldDir = velocity.normalized()
newVel = velocity.reflect(faceNormal)
newDir = newVel.normalized()
dirDif = ((newDir-oldDir).magnitude)/2
bounce2 = 1-(dirDif*(1-bounce))
velocity = newVel*bounce2#2*bounce
draw=bge.render.drawLine
a,b,c= tri["vertex"]
faceCenter,faceDir=tri["faceCenter"],tri["faceDir"]
########
Globaldraw((a,b,c,a), meshWP, meshWO)
Globaldraw((faceCenter,faceCenter+faceDir*10), meshWP, meshWO)
break
self.velocity = velocity
self.owner.worldPosition += velocity
def main(cont):
own = cont.owner
if not "init" in own:
own["init"]=1 ####################( own, meshCollision, radius=1.0, bounce=0.5, margin=2.0)
own["ClassCollisionMesh"]=ClassCollisionMesh(own ,own.parent)
own.removeParent()
return
own["ClassCollisionMesh"].Update()
Attachments
trigono13.blend (233 KB)