def exportSkel(obj, filename): skeleton = Skeleton() skeleton.update(obj) f = open(filename, 'w') writeJoint(f, skeleton.root) f.close()
def exportSkel(obj, filename): skeleton = Skeleton() skeleton.update(obj) f = open(filename, 'w') writeJoint(f, skeleton.root) f.close()
def exportMd5(obj, filename): """ This function exports MakeHuman mesh and skeleton data to id Software's MD5 format. Parameters ---------- obj: *Object3D*. The object whose information is to be used for the export. filename: *string*. The filename of the file to export the object to. """ skeleton = Skeleton() skeleton.update(obj) f = open(filename, 'w') f.write('MD5Version 10\n') f.write('commandline ""\n\n') f.write('numJoints %d\n' % (skeleton.joints+1)) # Amount of joints + the hardcoded origin below f.write('numMeshes %d\n\n' % (1)) # TODO: 2 in case of hair f.write('joints {\n') f.write('\t"%s" %d ( %f %f %f ) ( %f %f %f )\n' % ('origin', -1, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0)) writeJoint(f, skeleton.root) f.write('}\n\n') f.write('mesh {\n') f.write('\tshader "%s"\n' % (basename(obj.texture))) # TODO: create the shader file f.write('\n\tnumverts %d\n' % (len(obj.verts))) for vert in obj.verts: if obj.uvValues: face = vert.sharedFaces[0] u, v = obj.uvValues[face.uv[face.verts.index(vert)]] else: u, v = 0, 0 # vert [vertIndex] ( [texU] [texV] ) [weightIndex] [weightElem] f.write('\tvert %d ( %f %f ) %d %d\n' % (vert.idx, u, 1.0-v, vert.idx, 1)) f.write('\n\tnumtris %d\n' % (len(obj.faces) * 2)) for face in obj.faces: # tri [triIndex] [vertIndex1] [vertIndex2] [vertIndex3] f.write('\ttri %d %d %d %d\n' % (face.idx*2, face.verts[2].idx, face.verts[1].idx, face.verts[0].idx)) f.write('\ttri %d %d %d %d\n' % (face.idx*2+1, face.verts[0].idx, face.verts[3].idx, face.verts[2].idx)) f.write('\n\tnumweights %d\n' % (len(obj.verts))) for vert in obj.verts: # TODO: We attach all vertices to the root with weight 1.0, this should become # real weights to the correct bones # weight [weightIndex] [jointIndex] [weightValue] ( [xPos] [yPos] [zPos] ) f.write('\tweight %d %d %f ( %f %f %f )\n' % (vert.idx, 0, 1.0, vert.co[0], -vert.co[2], vert.co[1])) f.write('}\n\n') f.close()
class User: def __init__(self, id, skel_cap, depth_generator): self.id = id self.skeleton = Skeleton(self, skel_cap, depth_generator) self.depth = 0 self.face = None self.image_path = '' self.choose_image() # __init__ def update(self): self.skeleton.update() # update def draw(self, surface): if self.skeleton.status: rate = 900/(self.depth-500) if rate < 0: rate = 0 try: transformed_image = pygame.transform.scale(self.face, (int(self.face.get_width()*rate), int(self.face.get_height()*rate))) surface.blit(transformed_image, (self.skeleton.head[0]-0.5*transformed_image.get_width(), self.skeleton.head[1]-0.3*transformed_image.get_height())) except: pass # try # if # draw def draw_skeleton(self, surface): if self.skeleton.status: self.skeleton.draw(surface) # draw_skeleton def choose_image(self, banned_image='none'): images = ['forever.png', 'lol.png', 'poker.png', 'spider.png', 'troll.png', 'fuckyeah.png'] try: images.remove(banned_image) except: pass random.shuffle(images) self.image_path = images[0] self.face = pygame.image.load('images/%s' % self.image_path) # choose_image def refresh(self): self.choose_image(self.image_path)
def exportSkeleton(obj, filename): """ This function exports joint information describing the structure of the MakeHuman humanoid mesh object in Biovision BVH format. Parameters ---------- obj: *Object3D*. The object whose information is to be used for the export. filename: *string*. The filename of the file to export the object to. """ skeleton = Skeleton() skeleton.update(obj) # Write bvh file f = open(filename, 'w') f.write('HIERARCHY\n') f.write('ROOT ' + skeleton.root.name + '\n') f.write('{\n') f.write("\tOFFSET %f %f %f\n" % (skeleton.root.position[0], skeleton.root.position[1], skeleton.root.position[2])) f.write( '\tCHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation\n' ) for joint in skeleton.root.children: writeJoint(f, joint, 1) f.write('}\n') f.write('MOTION\n') f.write('Frames: 1\n') f.write('Frame Time: 0.0\n') f.write(" %f %f %f" % (skeleton.root.position[0], skeleton.root.position[1], skeleton.root.position[2])) for i in xrange(skeleton.endEffectors): f.write(" 0.0000 0.0000 0.0000") f.write("\n") f.close()
def run_game(): # initialize the game and create a screen object using the pygame class. we create an instance screen pygame.init() screen = pygame.display.set_mode((1000, 600)) caption = pygame.display.set_caption("skeleton on wood race") # set the background colour bg_color = (255, 255, 0) # create an instance of skeleton skeleton = Skeleton(screen) running = True while running: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: sys.exit() if event.key == pygame.K_RIGHT: # move the skeleton to the right skeleton.moving_right = True if event.key == pygame.K_LEFT: skeleton.moving_left = True elif event.type == pygame.KEYUP: if event.key == pygame.K_RIGHT: skeleton.moving_right = False if event.key == pygame.K_LEFT: skeleton.moving_left = False skeleton.update() # redraw the screen during each pass through the loop screen.fill(bg_color) skeleton.blitme() # make the most recently drawn screen visible pygame.display.flip()
def exportSkeleton(obj, filename): """ This function exports joint information describing the structure of the MakeHuman humanoid mesh object in Biovision BVH format. Parameters ---------- obj: *Object3D*. The object whose information is to be used for the export. filename: *string*. The filename of the file to export the object to. """ skeleton = Skeleton() skeleton.update(obj) # Write bvh file f = open(filename, 'w') f.write('HIERARCHY\n') f.write('ROOT ' + skeleton.root.name + '\n') f.write('{\n') f.write("\tOFFSET %f %f %f\n" %(skeleton.root.position[0],skeleton.root.position[1],skeleton.root.position[2])) f.write('\tCHANNELS 6 Xposition Yposition Zposition Zrotation Xrotation Yrotation\n') for joint in skeleton.root.children: writeJoint(f, joint, 1) f.write('}\n') f.write('MOTION\n') f.write('Frames: 1\n') f.write('Frame Time: 0.0\n') f.write(" %f %f %f" %(skeleton.root.position[0],skeleton.root.position[1],skeleton.root.position[2]) ) for i in xrange(skeleton.endEffectors): f.write(" 0.0000 0.0000 0.0000") f.write("\n") f.close()
class PoseTaskView(gui3d.TaskView): def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Pose') self.zone = "" self.skeleton = Skeleton() self.selectedGroups = [] self.joint = None self.box = self.addView(gui3d.GroupBox([10, 80, 9.0], 'Rotation', gui3d.GroupBoxStyle._replace(height=25+36*3+4+24*3+6))) self.Xslider = self.box.addView(gui3d.Slider(value = 0.0, min = -180.0, max = 180.0, label = "RotX: %d")) self.Yslider = self.box.addView(gui3d.Slider(value = 0.0, min = -180.0, max = 180.0, label = "RotY: %d")) self.Zslider = self.box.addView(gui3d.Slider(value = 0.0, min = -180.0, max = 180.0, label = "RotZ: %d")) self.skin = self.box.addView(gui3d.CheckBox("Skin", False)) self.resetPoseButton = self.box.addView(gui3d.Button("Reset")) self.savePoseButton = self.box.addView(gui3d.Button("Save")) self.testButton = self.box.addView(gui3d.Button("Test")) #get bindings for r-shoulder-joint f = open("utils/makepose/r-shoulder-joint.txt") #f = open("utils/makepose/test.txt") self.jointVerts = [] self.bindedFaces = None while (1): line = f.readline() if not line: break self.jointVerts.append(int(line)); f.close() self.tets = None #get prejoint points to create cage from f = open("utils/makepose/r-clavicle.txt") self.preJointVerts = [] while (1): line = f.readline() if not line: break self.preJointVerts.append(int(line)); f.close() f = open("utils/makepose/r-scapula.txt") while (1): line = f.readline() if not line: break self.preJointVerts.append(int(line)); f.close() #get faces of the verts... (for volume preservation) self.preTets = None self.tets1 = None self.tets2 = None @self.testButton.event def onClicked(event): self.test() @self.savePoseButton.event def onClicked(event): exportObj(gui3d.app.selectedHuman.meshData, os.path.join(mh.getPath('exports'), "posed.obj")) @self.resetPoseButton.event def onClicked(event): self.reset() @self.Xslider.event def onChange(value): if self.joint: rotation = [value - self.joint.rotation[0], 0.0, 0.0] self.joint.rotation[0] = value self.rotateJoint(self.joint, self.joint.position, rotation) gui3d.app.selectedHuman.meshData.calcNormals() gui3d.app.selectedHuman.meshData.update() @self.Yslider.event def onChange(value): if self.joint: rotation = [0.0, value - self.joint.rotation[1], 0.0] self.joint.rotation[1] = value self.rotateJoint(self.joint, self.joint.position, rotation) gui3d.app.selectedHuman.meshData.calcNormals() gui3d.app.selectedHuman.meshData.update() @self.Zslider.event def onChange(value): if self.joint: rotation = [0.0, 0.0, value - self.joint.rotation[2]] self.joint.rotation[2] = value self.rotateJoint(self.joint, self.joint.position,rotation) gui3d.app.selectedHuman.meshData.calcNormals() gui3d.app.selectedHuman.meshData.update() def onMouseMoved(self, event): if not self.joint: human = gui3d.app.selectedHuman groups = [] self.zone = self.getJointZones(event.group.name) if self.zone: for g in human.mesh.faceGroups: if self.zone != "torso": if self.zone in g.name: groups.append(g) elif (self.zone in g.name) and not g.name.endswith("clavicle"): groups.append(g) for g in self.selectedGroups: if g not in groups: g.setColor([255, 255, 255, 255]) for g in groups: if g not in self.selectedGroups: g.setColor([0, 169, 184, 255]) self.selectedGroups = groups gui3d.app.redraw() def onMouseUp(self, event): if self.joint: self.joint = None else: self.joint = self.skeleton.getJoint(zonesToJointsMapping.get(self.zone)) if self.joint: self.Xslider.setValue(self.joint.rotation[0]) self.Yslider.setValue(self.joint.rotation[1]) self.Zslider.setValue(self.joint.rotation[2]) #todo: use a reference on human so we know if we need to compute this on every onShow def onShow(self, event): gui3d.app.selectedHuman.storeMesh() self.skeleton.update(gui3d.app.selectedHuman.meshData) #compute bounding box #must do this! because mh human changes after the init -_- bboxj = calcBBox(gui3d.app.selectedHuman.meshData.verts, self.jointVerts) #compute right shoulder joint position because we cannot rely on the diamond pos = vmul(vadd(bboxj[0],bboxj[1]),0.5) self.skeleton.getJoint('joint-r-shoulder').position = pos #new technique! #two cages between the joint instead of the joint in the middle of a single cage #get bindings for r-shoulder-joint f = open("utils/makepose/2cage-test.txt") self.jointVerts = [] while (1): line = f.readline() if not line: break self.jointVerts.append(int(line)); f.close() self.bindedFaces = module3d.getFacesFromVerts(self.jointVerts,gui3d.app.selectedHuman.meshData.verts) bboxj = calcBBox(gui3d.app.selectedHuman.meshData.verts, self.jointVerts) """ #for the new test we dont add any offset yet #adding offset bboxj[0][0]= bboxj[0][0] - 0.01 bboxj[1][0]= bboxj[1][0] + 0.01 bboxj[0][1]= bboxj[0][1] - 0.01 bboxj[1][1]= bboxj[1][1] + 0.01 bboxj[0][2]= bboxj[0][2] - 0.01 bboxj[1][2]= bboxj[1][2] + 0.01 """ bboxj1 = [bboxj[0][:], bboxj[1][:]] bboxj1[1][0] = pos[0] #print "bboxj1", bboxj1 self.tets1 = box2Tetrahedrons(bboxj1) bboxj2 = [bboxj[0][:], bboxj[1][:]] bboxj2[0][0] = pos[0] #print "bboxj2", bboxj2 self.tets2 = box2Tetrahedrons(bboxj2) #print "bboxj: ", bboxj #computing prejoint bounding box #bboxpre = calcBBox(gui3d.app.selectedHuman.meshData.verts, self.preJointVerts) #bboxpre[1][0] = min(bboxpre[1][0], bboxj[0][0]) #print "bboxpre: ", bboxpre #self.preTets = box2Tetrahedrons(bboxpre) gui3d.TaskView.onShow(self, event) def onHide(self, event): gui3d.app.selectedHuman.restoreMesh() gui3d.app.selectedHuman.meshData.update() gui3d.TaskView.onHide(self, event) def getJointZones(self, groupName): for k in jointZones: if k in groupName: return k return None def rotateJoint(self, joint, center, rotation, transform=None): src = gui3d.app.selectedHuman.meshStored dst = gui3d.app.selectedHuman.meshData.verts cage = None if not transform: transform = euler2matrix(vmul(rotation,degree2rad), "sxyz") #transform2 = euler2matrix(vmul(self.joint.rotation,degree2rad), "sxyz") elif rotation: joint.position = vadd(mtransform(transform, vsub(joint.position, center)),center) if (joint == self.joint) and self.skin.selected and (joint.name == 'joint-r-shoulder'): #transform2 = euler2matrix(vmul(self.joint.rotation,degree2rad), "sxyz") #tets2 = deformTets(self.tets, center, transform2) cages = deform2Cages([self.tets1,self.tets2], center, self.joint.rotation, 0.5) #preJointRot = [0.0,0.0,0.0] #tets = self.tets + self.preTets tets = self.tets1 + self.tets2 tets2 = cages[0] + cages[1] #jointVerts = self.jointVerts + self.preJointVerts #for i in jointVerts: for i in self.jointVerts: #using all 10 tetrahedrons as controls weights = computeAllWeights(src[i],tets) v = [0.0,0.0,0.0] """ for tet_i in xrange(0,5): for j in xrange(0,4): v= vadd(vmul(tets2[tet_i][j],weights[tet_i][j]),v) for tet_i in xrange(0,5): for j in xrange(0,4): v= vadd(vmul(self.preTets[tet_i][j],weights[tet_i+5][j]),v) #average of 10 tetrahedrons dst[i].co = vmul(v, 0.1) """ for tet_i in xrange(0,10): for j in xrange(0,4): v= vadd(vmul(tets2[tet_i][j],weights[tet_i][j]),v) dst[i].co = vmul(v, 0.1) """ #using all 5 tetrahedrons as controls weights = computeAllWeights(src[i],self.tets) v = [0.0,0.0,0.0] for tet_i in xrange(0,5): for j in xrange(0,4): v= vadd(vmul(tets2[tet_i][j],weights[tet_i][j]),v) #average of 5 tetrahedrons dst[i].co = vmul(v, 0.2) #end of using 5 """ """ #using only one tetrahedron as control j,w = computeWeights(src[i], self.tets) if not j: print src[i] v = [0.0,0.0,0.0] for k in xrange(0,4): v= vadd(vmul(tets2[j][k],w[k]),v) dst[i].co = v[:] #end of using 1 """ for i in joint.bindedVects: if (i not in self.jointVerts): dst[i].co = vadd(mtransform(transform, vsub(dst[i].co, center)),center) for child in joint.children: self.rotateJoint(child, center, rotation, transform) def reset(self): self.Xslider.setValue(0.0) self.Yslider.setValue(0.0) self.Zslider.setValue(0.0) if self.joint: rotation = [-self.joint.rotation[2],-self.joint.rotation[1],-self.joint.rotation[0]] self.joint.rotation = [0.0,0.0,0.0] transform = euler2matrix(vmul(rotation,degree2rad), "szyx") #self.joint.rotation = [0.0,0.0,0.0] self.rotateJoint(self.joint, self.joint.position,None, transform) gui3d.app.selectedHuman.meshData.calcNormals() gui3d.app.selectedHuman.meshData.update() gui3d.app.redraw() def test(self): pass
class User: def __init__(self, id, skel_cap, depth_generator): self.id = id self.skeleton = Skeleton(self, skel_cap, depth_generator) self.depth = 0 self.face = None self.image_path = '' self.choose_image() # __init__ def update(self): self.skeleton.update() # update def draw(self, surface): if self.skeleton.status: rate = 900 / (self.depth - 500) if rate < 0: rate = 0 try: transformed_image = pygame.transform.scale( self.face, (int(self.face.get_width() * rate), int(self.face.get_height() * rate))) surface.blit(transformed_image, (self.skeleton.head[0] - 0.5 * transformed_image.get_width(), self.skeleton.head[1] - 0.3 * transformed_image.get_height())) except: pass # try # if # draw def draw_skeleton(self, surface): if self.skeleton.status: self.skeleton.draw(surface) # draw_skeleton def choose_image(self, banned_image='none'): images = [ 'forever.png', 'lol.png', 'poker.png', 'spider.png', 'troll.png', 'fuckyeah.png' ] try: images.remove(banned_image) except: pass random.shuffle(images) self.image_path = images[0] self.face = pygame.image.load('images/%s' % self.image_path) # choose_image def refresh(self): self.choose_image(self.image_path)
class BvhView(gui3d.TaskView): def __init__(self, category): gui3d.TaskView.__init__(self, category, 'BVH Player') self.status = self.addView(gui3d.TextView(style=gui3d.TextViewStyle._replace(left=10, top=585, zIndex=9.1))) self.__skeleton = bvhSkeleton('data/bvhs/03_03.bvh') self.__skeleton.updateFrame(-1) self.__skeletonMesh = None self.__skeletonObject = None self.bone = None self.__humanSkeleton = Skeleton() self.optionsBox = self.addView(gui3d.GroupBox([10, 80, 9.0], 'Options', gui3d.GroupBoxStyle._replace(height=24+25+36*1+24*2+6))) self.frameSlider = self.optionsBox.addView(gui3d.Slider(value = 0, min = 0, max = self.__skeleton.frames, label = 'Frame: %d')) self.playPause = self.optionsBox.addView(gui3d.Button("Play")) self.showHuman = self.optionsBox.addView(gui3d.ToggleButton("Show human")) self.exportFrame = self.optionsBox.addView(gui3d.Button("Export frame")) @self.frameSlider.event def onChanging(value): self.__updateSkeletonMesh(value-1) self.__updateHumanMesh(self.__humanSkeleton.root) gui3d.app.selectedHuman.meshData.update() @self.frameSlider.event def onChange(value): self.__updateSkeletonMesh(value-1) self.__updateHumanMesh(self.__humanSkeleton.root) gui3d.app.selectedHuman.meshData.update() @self.playPause.event def onClicked(value): if self.playPause.label.getText() == 'Play': self.playPause.label.setText('Pause') self.timer = mh.addTimer(max(30, int(self.__skeleton.frameTime * 1000)), self.onFrameChanged) else: self.playPause.label.setText('Play') mh.removeTimer(self.timer) @self.showHuman.event def onClicked(event): self.showHuman.setSelected(not self.showHuman.selected) if self.showHuman.selected: gui3d.app.selectedHuman.show() self.getSkeleton().hide() else: gui3d.app.selectedHuman.hide() self.getSkeleton().show() @self.exportFrame.event def onClicked(event): self.exportCurrentFrame() def onFrameChanged(self): frame = self.frameSlider.getValue() + 1 if frame > self.frameSlider.max: frame = 1 self.frameSlider.setValue(frame) self.__updateSkeletonMesh(frame-1) gui3d.app.redraw() def exportCurrentFrame(self): exportPath = mh.getPath('exports') if not os.path.exists(exportPath): os.makedirs(exportPath) mh2obj.exportObj(gui3d.app.selectedHuman.meshData, os.path.join(exportPath, 'bvh_frame_%d.obj' % self.frameSlider.getValue())) def onShow(self, event): gui3d.TaskView.onShow(self, event) gui3d.app.selectedHuman.hide() self.getSkeleton().show() gui3d.app.selectedHuman.storeMesh() self.__humanSkeleton.update(gui3d.app.selectedHuman.meshData) def onHide(self, event): gui3d.TaskView.onHide(self, event) gui3d.app.selectedHuman.show() self.getSkeleton().hide() gui3d.app.selectedHuman.restoreMesh() gui3d.app.selectedHuman.meshData.calcNormals() gui3d.app.selectedHuman.meshData.update() def getSkeleton(self): human = gui3d.app.selectedHuman if not self.__skeletonObject: self.__buildSkeletonMesh() self.__skeletonObject = self.addObject(gui3d.Object(aljabr.vadd(human.getPosition(), [0.0, -20.0, 0.0]), self.__skeletonMesh)) else: self.__skeletonObject.setPosition(aljabr.vadd(human.getPosition(), [0.0, -20.0, 0.0])) self.__skeletonObject.setRotation(human.getRotation()) return self.__skeletonObject def __buildSkeletonMesh(self): self.__skeletonMesh = module3d.Object3D('skeleton') self.__skeletonMesh.uvValues = [] self.__skeletonMesh.indexBuffer = [] self.__buildBoneMesh(self.__skeleton.root) self.__skeletonMesh.setCameraProjection(0) self.__skeletonMesh.setShadeless(0) self.__skeletonMesh.setSolid(0) self.__skeletonMesh.calcNormals() self.__skeletonMesh.updateIndexBuffer() def __buildBoneMesh(self, joint): if joint.parent: position = [joint.transform[3],joint.transform[7],joint.transform[11]] parentPosition = [joint.parent.transform[3], joint.parent.transform[7], joint.parent.transform[11]] joint.p = self.__addPrism(self.__skeletonMesh, parentPosition, position, 'bone-' + joint.name) #joint.p = self.__addPrism(self.__skeletonMesh, joint.parent.position, joint.position, 'bone-' + joint.name) for child in joint.children: self.__buildBoneMesh(child) def __updateSkeletonMesh(self, frame): self.__skeleton.updateFrame(frame) index = 0 self.__updateBoneMesh(self.__skeleton.root, index) self.__skeletonMesh.calcNormals() self.__skeletonMesh.update() def __updateHumanMesh(self, joint, src=None, dst=None): # copy angles bvhName = mhToBvhMapping.get(joint.name, '') if bvhName: bvhJoint = self.__skeleton.getJoint(bvhName) joint.rotation = bvhJoint.rotation[:] else: joint.rotation = [0.0, 0.0, 0.0] joint.calcTransform(False) if not src: src = gui3d.app.selectedHuman.meshStored if not dst: dst = gui3d.app.selectedHuman.meshData.verts nsrc = gui3d.app.selectedHuman.meshStoredNormals for i in joint.bindedVects: #dst[i].co = aljabr.mtransform(joint.transform, aljabr.mtransform(joint.inverseTransform, src[i])) dst[i].co = aljabr.mtransform(joint.transform, aljabr.vsub(src[i], joint.position)) dst[i].no = aljabr.mtransform(joint.normalTransform, nsrc[i]) for child in joint.children: self.__updateHumanMesh(child, src, dst) #note: don't do skeleton update def __updateBoneMesh(self, joint, index): if joint.parent: position = [joint.transform[3],joint.transform[7],joint.transform[11]] parentPosition = [joint.parent.transform[3], joint.parent.transform[7], joint.parent.transform[11]] self.__updatePrism(self.__skeletonMesh, parentPosition, position, index, joint.p) index += 6 for child in joint.children: index = self.__updateBoneMesh(child, index) return index def __addPrism(self, mesh, o=[0.0, 0.0, 0.0], e=[0.0, 1.0, 0.0], name='prism'): fg = mesh.createFaceGroup(name) dir = aljabr.vsub(e, o) # direction vector from o to e len = aljabr.vlen(dir) # distance from o to e scale = 0.5 # the thickness is 10% of the length i = aljabr.vadd(o, aljabr.vmul(dir, 0.25)) # the thickest part is 25% from o n = aljabr.vmul(dir, 1.0 / len) # the normalized direction q = aljabr.axisAngleToQuaternion(n, pi / 2.0) # a quaternion to rotate the point p1 to obtain the other points p = p1 = aljabr.randomPointFromNormal(n) # a random point in the plane defined by 0,0,0 and n p1 = aljabr.vmul(aljabr.vnorm(p1), scale) # the point scaled to the thickness p2 = aljabr.quaternionVectorTransform(q, p1) # the other points p3 = aljabr.quaternionVectorTransform(q, p2) p4 = aljabr.quaternionVectorTransform(q, p3) p1 = aljabr.vadd(i, p1) # translate by i since we were working in the origin p2 = aljabr.vadd(i, p2) p3 = aljabr.vadd(i, p3) p4 = aljabr.vadd(i, p4) # The 6 vertices v = [] v.append(mesh.createVertex(o)) # 0 0 v.append(mesh.createVertex(p1)) # 1 /|\ v.append(mesh.createVertex(p2)) # 2 /.2.\ v.append(mesh.createVertex(p3)) # 3 1` | `3 v.append(mesh.createVertex(p4)) # 4 \`.4.`/ v.append(mesh.createVertex(e)) # 5 \ | / # \|/ # 5 # The 8 faces fg.createFace((v[0], v[1], v[4], v[0])) fg.createFace((v[0], v[4], v[3], v[0])) fg.createFace((v[0], v[3], v[2], v[0])) fg.createFace((v[0], v[2], v[1], v[0])) fg.createFace((v[5], v[4], v[1], v[5])) fg.createFace((v[5], v[1], v[2], v[5])) fg.createFace((v[5], v[2], v[3], v[5])) fg.createFace((v[5], v[3], v[4], v[5])) return p def __addCube(self, mesh, position=[0.0, 0.0, 0.0], scale=1.0, name='cube'): fg = mesh.createFaceGroup(name) # The 8 vertices v = [] v.append(mesh.createVertex(aljabr.vadd(position, [-scale, -scale, -scale]))) # 0 /0-----1\ v.append(mesh.createVertex(aljabr.vadd(position, [scale, -scale, -scale]))) # 1 / | | \ v.append(mesh.createVertex(aljabr.vadd(position, [scale, scale, -scale]))) # 2 |4---------5| v.append(mesh.createVertex(aljabr.vadd(position, [-scale, scale, -scale]))) # 3 | | | | v.append(mesh.createVertex(aljabr.vadd(position, [-scale, -scale, scale]))) # 4 | 3-----2 | v.append(mesh.createVertex(aljabr.vadd(position, [scale, -scale, scale]))) # 5 | / \ | v.append(mesh.createVertex(aljabr.vadd(position, [scale, scale, scale]))) # 6 |/ \| v.append(mesh.createVertex(aljabr.vadd(position, [-scale, scale, scale]))) # 7 |7---------6| # The 6 faces fg.createFace((v[4], v[5], v[6], v[7])) # front fg.createFace((v[1], v[0], v[3], v[2])) # back fg.createFace((v[0], v[4], v[7], v[3])) # left fg.createFace((v[5], v[1], v[2], v[6])) # right fg.createFace((v[0], v[1], v[5], v[4])) # top fg.createFace((v[7], v[6], v[2], v[3])) # bottom def __updatePrism(self, mesh, o, e, index, p): dir = aljabr.vsub(e, o) # direction vector from o to e len = aljabr.vlen(dir) # distance from o to e scale = 0.5 # the thickness is 10% of the length i = aljabr.vadd(o, aljabr.vmul(dir, 0.25)) # the thickest part is 25% from o n = aljabr.vmul(dir, 1.0 / len) # the normalized direction q = aljabr.axisAngleToQuaternion(n, pi / 2.0) # a quaternion to rotate the point p1 to obtain the other points p1 = p # a random point in the plane defined by 0,0,0 and n p1 = aljabr.vmul(aljabr.vnorm(p1), scale) # the point scaled to the thickness p2 = aljabr.quaternionVectorTransform(q, p1) # the other points p3 = aljabr.quaternionVectorTransform(q, p2) p4 = aljabr.quaternionVectorTransform(q, p3) p1 = aljabr.vadd(i, p1) # translate by i since we were working in the origin p2 = aljabr.vadd(i, p2) p3 = aljabr.vadd(i, p3) p4 = aljabr.vadd(i, p4) # The 6 vertices mesh.verts[index].co = o mesh.verts[index+1].co = p1 mesh.verts[index+2].co = p2 mesh.verts[index+3].co = p3 mesh.verts[index+4].co = p4 mesh.verts[index+5].co = e def onMouseDragged(self, event): gui3d.app.selectedHuman.show() self.getSkeleton().hide() gui3d.TaskView.onMouseDragged(self, event) if self.showHuman.selected: pass else: gui3d.app.selectedHuman.hide() self.getSkeleton().show() def onMouseWheel(self, event): if self.showHuman.selected: pass else: gui3d.app.selectedHuman.show() self.getSkeleton().hide() gui3d.TaskView.onMouseWheel(self, event) if self.showHuman.selected: pass else: gui3d.app.selectedHuman.hide() self.getSkeleton().show() def onMouseEntered(self, event): gui3d.TaskView.onMouseEntered(self, event) if 'bone' in event.group.name: self.bone = event.group self.bone.setColor([0, 255, 0, 255]) self.status.setText(event.group.name) gui3d.app.redraw() def onMouseExited(self, event): gui3d.TaskView.onMouseExited(self, event) if self.bone: self.bone.setColor([255, 255, 255, 255]) self.status.setText('') gui3d.app.redraw() def onMouseMoved(self, event): gui3d.TaskView.onMouseMoved(self, event) if 'bone' in event.group.name and self.bone != event.group: self.bone.setColor([255, 255, 255, 255]) self.bone = event.group self.bone.setColor([0, 255, 0, 255]) self.status.setText(event.group.name) gui3d.app.redraw() def onResized(self, event): self.status.setPosition([10, event.height-15, 9.1])
elif event.type == pygame.KEYDOWN: #print(event.key) key_monitor.key_down(event) elif event.type == pygame.KEYUP: key_monitor.key_up(event) # Game loop if game.started() and (time.time()*1000.0)-last_time > FRAME_TIME: last_time = time.time()*1000.0 game.tick() key_monitor.tick() witch.update() zombie.update() monster.update() skeleton.update() witch.move(SPEED) zombie.move(SPEED) monster.move(SPEED) skeleton.move(SPEED) screen.fill(black) game.check_piece([witch,zombie,monster,skeleton], key_monitor) game.draw_background(screen) screen.blit(witch.get_image(), witch.get_rect()) screen.blit(zombie.get_image(), zombie.get_rect()) screen.blit(monster.get_image(), monster.get_rect())
class SkeletonView(gui3d.TaskView): def __init__(self, category): gui3d.TaskView.__init__(self, category, 'Skeleton') self.status = self.addView(gui3d.TextView(style=gui3d.TextViewStyle._replace(left=10, top=585, zIndex=9.1))) self.__skeleton = Skeleton() self.__skeletonMesh = None self.__skeletonObject = None self.bone = None def onShow(self, event): gui3d.TaskView.onShow(self, event) human = gui3d.app.selectedHuman human.hide() self.getSkeleton().show() self.__updateSkeletonMesh(human) def onHide(self, event): gui3d.TaskView.onHide(self, event) gui3d.app.selectedHuman.show() self.getSkeleton().hide() def getSkeleton(self): human = gui3d.app.selectedHuman if not self.__skeletonObject: self.__buildSkeletonMesh(human) self.__skeletonObject = self.addObject(gui3d.Object(human.getPosition(), self.__skeletonMesh)) else: self.__skeletonObject.setPosition(human.getPosition()) self.__skeletonObject.setRotation(human.getRotation()) return self.__skeletonObject def __buildSkeletonMesh(self, human): self.__skeleton.update(human.meshData) self.__skeletonMesh = module3d.Object3D('skeleton') self.__skeletonMesh.uvValues = [] self.__skeletonMesh.indexBuffer = [] self.__buildBoneMesh(self.__skeleton.root) self.__skeletonMesh.setCameraProjection(0) self.__skeletonMesh.setShadeless(0) self.__skeletonMesh.setSolid(0) self.__skeletonMesh.calcNormals() self.__skeletonMesh.updateIndexBuffer() def __buildBoneMesh(self, joint): #self.__addCube(self.__skeletonMesh, joint.position, aljabr.vlen(joint.offset) / 10.0, joint.name.replace('joint', 'bone')) if joint.parent: position = [joint.transform[3],joint.transform[7],joint.transform[11]] parentPosition = [joint.parent.transform[3], joint.parent.transform[7], joint.parent.transform[11]] self.__addPrism(self.__skeletonMesh, position, parentPosition, joint.name.replace('joint', 'bone')) for child in joint.children: self.__buildBoneMesh(child) def __updateSkeletonMesh(self, human): self.__skeleton.update(human.meshData) index = 0 self.__updateBoneMesh(self.__skeleton.root, index) self.__skeletonMesh.calcNormals() self.__skeletonMesh.update() def __updateBoneMesh(self, joint, index): if joint.parent: self.__updatePrism(self.__skeletonMesh, joint.parent.position, joint.position, index) index += 6 for child in joint.children: index = self.__updateBoneMesh(child, index) return index def __addPrism(self, mesh, o=[0.0, 0.0, 0.0], e=[0.0, 1.0, 0.0], name='prism'): fg = mesh.createFaceGroup(name) dir = aljabr.vsub(e, o) # direction vector from o to e len = aljabr.vlen(dir) # distance from o to e scale = len * 0.1 # the thickness is 10% of the length i = aljabr.vadd(o, aljabr.vmul(dir, 0.25)) # the thickest part is 25% from o n = aljabr.vmul(dir, 1.0 / len) # the normalized direction q = aljabr.axisAngleToQuaternion(n, pi / 2.0) # a quaternion to rotate the point p1 to obtain the other points p1 = aljabr.randomPointFromNormal(n) # a random point in the plane defined by 0,0,0 and n p1 = aljabr.vmul(aljabr.vnorm(p1), scale) # the point scaled to the thickness p2 = aljabr.quaternionVectorTransform(q, p1) # the other points p3 = aljabr.quaternionVectorTransform(q, p2) p4 = aljabr.quaternionVectorTransform(q, p3) p1 = aljabr.vadd(i, p1) # translate by i since we were working in the origin p2 = aljabr.vadd(i, p2) p3 = aljabr.vadd(i, p3) p4 = aljabr.vadd(i, p4) # The 6 vertices v = [] v.append(mesh.createVertex(o)) # 0 0 v.append(mesh.createVertex(p1)) # 1 /|\ v.append(mesh.createVertex(p2)) # 2 /.2.\ v.append(mesh.createVertex(p3)) # 3 1` | `3 v.append(mesh.createVertex(p4)) # 4 \`.4.`/ v.append(mesh.createVertex(e)) # 5 \ | / # \|/ # 5 # The 8 faces fg.createFace((v[0], v[1], v[4], v[0])) fg.createFace((v[0], v[4], v[3], v[0])) fg.createFace((v[0], v[3], v[2], v[0])) fg.createFace((v[0], v[2], v[1], v[0])) fg.createFace((v[5], v[4], v[1], v[5])) fg.createFace((v[5], v[1], v[2], v[5])) fg.createFace((v[5], v[2], v[3], v[5])) fg.createFace((v[5], v[3], v[4], v[5])) def __addCube(self, mesh, position=[0.0, 0.0, 0.0], scale=1.0, name='cube'): fg = mesh.createFaceGroup(name) # The 8 vertices v = [] v.append(mesh.createVertex(aljabr.vadd(position, [-scale, -scale, -scale]))) # 0 /0-----1\ v.append(mesh.createVertex(aljabr.vadd(position, [scale, -scale, -scale]))) # 1 / | | \ v.append(mesh.createVertex(aljabr.vadd(position, [scale, scale, -scale]))) # 2 |4---------5| v.append(mesh.createVertex(aljabr.vadd(position, [-scale, scale, -scale]))) # 3 | | | | v.append(mesh.createVertex(aljabr.vadd(position, [-scale, -scale, scale]))) # 4 | 3-----2 | v.append(mesh.createVertex(aljabr.vadd(position, [scale, -scale, scale]))) # 5 | / \ | v.append(mesh.createVertex(aljabr.vadd(position, [scale, scale, scale]))) # 6 |/ \| v.append(mesh.createVertex(aljabr.vadd(position, [-scale, scale, scale]))) # 7 |7---------6| # The 6 faces fg.createFace((v[4], v[5], v[6], v[7])) # front fg.createFace((v[1], v[0], v[3], v[2])) # back fg.createFace((v[0], v[4], v[7], v[3])) # left fg.createFace((v[5], v[1], v[2], v[6])) # right fg.createFace((v[0], v[1], v[5], v[4])) # top fg.createFace((v[7], v[6], v[2], v[3])) # bottom def __updatePrism(self, mesh, o, e, index): dir = aljabr.vsub(e, o) # direction vector from o to e len = aljabr.vlen(dir) # distance from o to e scale = len * 0.1 # the thickness is 10% of the length i = aljabr.vadd(o, aljabr.vmul(dir, 0.25)) # the thickest part is 25% from o n = aljabr.vmul(dir, 1.0 / len) # the normalized direction q = aljabr.axisAngleToQuaternion(n, pi / 2.0) # a quaternion to rotate the point p1 to obtain the other points p1 = aljabr.randomPointFromNormal(n) # a random point in the plane defined by 0,0,0 and n p1 = aljabr.vmul(aljabr.vnorm(p1), scale) # the point scaled to the thickness p2 = aljabr.quaternionVectorTransform(q, p1) # the other points p3 = aljabr.quaternionVectorTransform(q, p2) p4 = aljabr.quaternionVectorTransform(q, p3) p1 = aljabr.vadd(i, p1) # translate by i since we were working in the origin p2 = aljabr.vadd(i, p2) p3 = aljabr.vadd(i, p3) p4 = aljabr.vadd(i, p4) # The 6 vertices mesh.verts[index].co = o mesh.verts[index+1].co = p1 mesh.verts[index+2].co = p2 mesh.verts[index+3].co = p3 mesh.verts[index+4].co = p4 mesh.verts[index+5].co = e def onMouseDragged(self, event): gui3d.app.selectedHuman.show() self.getSkeleton().hide() gui3d.TaskView.onMouseDragged(self, event) gui3d.app.selectedHuman.hide() self.getSkeleton().show() def onMouseWheel(self, event): gui3d.app.selectedHuman.show() self.getSkeleton().hide() gui3d.TaskView.onMouseWheel(self, event) gui3d.app.selectedHuman.hide() self.getSkeleton().show() def onMouseEntered(self, event): gui3d.TaskView.onMouseEntered(self, event) self.bone = event.group self.bone.setColor([0, 255, 0, 255]) self.status.setText(event.group.name) gui3d.app.redraw() def onMouseExited(self, event): gui3d.TaskView.onMouseExited(self, event) self.bone.setColor([255, 255, 255, 255]) self.status.setText('') gui3d.app.redraw() def onMouseMoved(self, event): gui3d.TaskView.onMouseMoved(self, event) if self.bone != event.group: self.bone.setColor([255, 255, 255, 255]) self.bone = event.group self.bone.setColor([0, 255, 0, 255]) self.status.setText(event.group.name) gui3d.app.redraw() def onResized(self, event): self.status.setPosition([10, event.height-15, 9.1])