def Torus(mNumSegSection=64, mNumSegCircle=64, mRadius=1.0, mSectionRadius=0.2): (gvw, prim, geom, path) = empty('t') deltaSection = (pi * 2 / mNumSegSection) deltaCircle = (pi * 2 / mNumSegCircle) offset = 0 for i in range(0, mNumSegCircle + 1): for j in range(0, mNumSegSection + 1): v0 = Vec3(mRadius + mSectionRadius * cos(j * deltaSection), mSectionRadius * sin(j * deltaSection), 0.0) q = Quat() q.setFromAxisAngleRad(i * deltaCircle, Vec3(0, 1, 0)) v = q.xform(v0) gvw.addData3f(v) if i != mNumSegCircle: prim.addVertices(offset + mNumSegSection + 1, offset, offset + mNumSegSection) prim.addVertices(offset + mNumSegSection + 1, offset + 1, offset) offset += 1 prim.closePrimitive() geom.addPrimitive(prim) return path
def __updateParticleParent(self): if not CIGlobals.isNodePathOk(self.waterStreamParent): return time = globalClock.getFrameTime() streamPos = self.waterStreamParent.getPos(render) distance = self.sprayParticleDist if self.isLocal(): camQuat = camera.getQuat(render) pFrom = camera.getPos(render) push = (streamPos - pFrom).length() pFrom += camQuat.xform(Vec3.forward()) * push pTo = pFrom + camQuat.xform( Vec3.forward()) * (self.sprayParticleDist + (pFrom - streamPos).length()) hitPos = Point3(pTo) result = base.physicsWorld.rayTestClosest(pFrom, pTo, CIGlobals.WorldGroup) if result.hasHit(): node = result.getNode() hitPos = result.getHitPos() distance = (hitPos - streamPos).length() if time - self.lastSprayTime >= self.SprayTraceIval and not self.released: if result.hasHit(): self.__doSplat(distance, hitPos) self.getFPSCam().addViewPunch( Vec3(random.uniform(-0.6, 0.6), random.uniform(0.25, 1.0), 0.0)) self.primaryFirePress(True) self.lastSprayTime = time else: pFrom = self.avatar.getPos(render) + self.avatar.getEyePoint() + ( 1, 0, 0) quat = Quat() quat.setHpr( self.avatar.getHpr(render) + (0, self.avatar.lookPitch, 0)) pTo = pFrom + quat.xform( Vec3.forward()) * (self.sprayParticleDist + (pFrom - streamPos).length()) hitPos = Point3(pTo) hit = PhysicsUtils.rayTestClosestNotMe( self.avatar, pFrom, pTo, CIGlobals.WorldGroup | CIGlobals.LocalAvGroup) if hit is not None: hitPos = hit.getHitPos() distance = (hitPos - streamPos).length() self.waterStreamParent.lookAt(render, hitPos) if self.sprayParticle: system = self.sprayParticle.getParticlesNamed('particles-1') # Make the particles die off at the hit point. lifespan = min( 1, distance / self.sprayParticleDist) * self.sprayParticleLife system.factory.setLifespanBase(lifespan)
def setTextureRotation(self, angle): # Rotate texture around the face normal rads = deg2Rad(self.rotation - angle) # Rotate around the face normal texNorm = self.vAxis.cross(self.uAxis).normalized() transform = Quat() transform.setFromAxisAngleRad(rads, texNorm) self.uAxis = transform.xform(self.uAxis) self.vAxis = transform.xform(self.vAxis) self.rotation = angle
def rotateAround(self, node, point, axis, angle, relative): quat = Quat() quat.setFromAxisAngle(angle, render.getRelativeVector(relative, axis)) relativePos = node.getPos(render) - point relativePosRotated = quat.xform(relativePos) absolutePosRotated = relativePosRotated + point node.setPos(render, absolutePosRotated) node.setQuat(render, node.getQuat(render) * quat)
def rotateAround(self, node, point, axis, angle, relative): quat = Quat() quat.setFromAxisAngle(angle, render.getRelativeVector(relative, axis)) relativePos = node.getPos(render) - point relativePosRotated = quat.xform(relativePos) absolutePosRotated = relativePosRotated + point node.setPos(render, absolutePosRotated) node.setQuat(render, node.getQuat(render) * quat)
def getUnitCircle(): global UnitCircle if not UnitCircle: segs = LineSegs('unitCircle') vertices = LEUtils.circle(0, 0, 1, 64) angles = [Vec3(0, 0, 0), Vec3(90, 0, 0), Vec3(0, 90, 0)] for angle in angles: quat = Quat() quat.setHpr(angle) for i in range(len(vertices)): x1, y1 = vertices[i] x2, y2 = vertices[(i + 1) % len(vertices)] pFrom = quat.xform(Vec3(x1, 0, y1)) pTo = quat.xform(Vec3(x2, 0, y2)) segs.moveTo(pFrom) segs.drawTo(pTo) UnitCircle = NodePath(segs.create()) UnitCircle.setAntialias(AntialiasAttrib.MLine) UnitCircle.setLightOff(1) UnitCircle.setFogOff(1) UnitCircle.hide(DirectRender.ShadowCameraBitmask | DirectRender.ReflectionCameraBitmask) return UnitCircle
def start(self): Gag.start(self) self.hitSfx.play() gag = self.gag if self.isLocal(): vm = self.getViewModel() fpsCam = self.getFPSCam() fpsCam.setVMAnimTrack( Sequence(ActorInterval(vm, "sg_shoot_begin"), ActorInterval(vm, "sg_shoot_end"), Func(vm.loop, "sg_idle"))) gag = self.getVMGag() nozzle = gag.find("**/joint_nozzle") if self.isLocal() and base.localAvatar.battleControls: if base.localAvatar.isFirstPerson(): self.getFPSCam().resetViewPunch() self.getFPSCam().addViewPunch( Vec3(random.uniform(-0.6, 0.6), random.uniform(-0.25, -0.5), 0.0)) startPos = camera.getPos(render) else: startPos = nozzle.getPos(render) hitPos = PhysicsUtils.getHitPosFromCamera() else: startPos = nozzle.getPos(render) quat = Quat() quat.setHpr( self.avatar.getHpr(render) + (0, self.avatar.lookPitch, 0)) hitPos = quat.xform(Vec3.forward() * 10000) hit = PhysicsUtils.rayTestClosestNotMe( self.avatar, startPos, hitPos, CIGlobals.WorldGroup | CIGlobals.LocalAvGroup) if hit is not None: hitPos = hit.getHitPos() pellet = WaterPellet(self.isLocal()) pellet.addToWorld(nozzle.getPos(render), lookAt=hitPos, velo=Vec3.forward() * self.pelletSpeed) if self.isLocal(): base.localAvatar.sendUpdate('usedGag', [self.id])
def moveCamera( self, task ): is_down = base.mouseWatcherNode.is_button_down if base.mouseWatcherNode.hasMouse(): x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() if is_down( MouseButton.two() ): dx = self.lastMousePos[0] - x self.ang -= dx #self.ang = max( 0, min( self.ang, math.pi*0.49 ) ) dy = self.lastMousePos[1] - y self.angY -= dy self.angY = max( 0.01, min( self.angY, math.pi ) ) self.lastMousePos = (x,y) speed = self.speed if is_down( self.bSpeed ): speed = speed*3 if self.attachmentNode and self.attached: self.focusPoint = self.attachmentNode.getPos() else: sideways = (is_down(self.bRight)-is_down(self.bLeft))*speed forward = (is_down(self.bForward)-is_down(self.bBackward))*speed quat = Quat() quat.setFromAxisAngle( -180*self.ang/math.pi, LVector3f.unitZ()) rotated = quat.xform( LVector3f( -forward, sideways, 0 )) self.focusPoint += rotated self.focusNode.setPos( self.focusPoint ) radius = self.zoom self.angY = max( 0, min( math.pi*0.4, self.angY ) ) rY = math.sin( self.angY ) self.nodePos = self.focusPoint + LVector3f( rY*math.cos(self.ang)*radius, -rY*math.sin(self.ang)*radius, radius*math.cos( self.angY) ) self.node.setPos( self.nodePos ) self.node.lookAt( self.focusNode, LVector3f.unitZ() ) return Task.cont
def moveCamera(self, task): is_down = base.mouseWatcherNode.is_button_down if base.mouseWatcherNode.hasMouse(): x = base.mouseWatcherNode.getMouseX() y = base.mouseWatcherNode.getMouseY() if is_down(MouseButton.two()): dx = self.lastMousePos[0] - x self.heading += dx * 25 #self.ang = max( 0, min( self.ang, math.pi*0.49 ) ) dy = self.lastMousePos[1] - y self.pitch -= dy * 25 self.pitch = max(self.pitch, -80) self.pitch = min(self.pitch, 80) #self.angY = max( 0.01, min( self.angY, math.pi ) ) self.lastMousePos = (x, y) speed = self.speed if is_down(self.bSpeed): speed = speed * 3 if not self.attached: forward = (is_down(self.bRight) - is_down(self.bLeft)) * speed sideways = -(is_down(self.bForward) - is_down(self.bBackward)) * speed quat = Quat() quat.setFromAxisAngle(self.heading, LVector3f.unitZ()) rotated = quat.xform(LVector3f(-forward, sideways, 0)) self.headingNode.setPos(self.headingNode.getPos() - rotated) #self.angY = max( 0, min( math.pi*0.4, self.angY ) ) #rY = math.sin( self.angY ) #self.nodePos = self.focusPoint + LVector3f( math.sin(self.angY)*math.cos(self.ang)*radius, -math.sin(self.ang)*radius, radius*math.cos( self.angY) ) self.node.lookAt(self.headingNode) self.node.setPos(0, -self.zoom, 0) self.pitchNode.setHpr(0, self.pitch, 0) self.headingNode.setHpr(self.heading, 0, 0) return Task.cont
def __updateParticleParent(self, task=None): time = globalClock.getFrameTime() streamPos = self.waterStreamParent.getPos(render) distance = self.sprayParticleDist if self.isLocal(): if base.localAvatar.backpack.getSupply(self.id) <= 0: base.localAvatar.b_gagThrow(self.id) return task.done camQuat = camera.getQuat(render) pFrom = camera.getPos(render) push = (streamPos - pFrom).length() pFrom += camQuat.xform(Vec3.forward()) * push pTo = pFrom + camQuat.xform( Vec3.forward()) * (self.sprayParticleDist + (pFrom - streamPos).length()) hitPos = Point3(pTo) result = base.physicsWorld.rayTestClosest(pFrom, pTo, CIGlobals.WorldGroup) if result.hasHit(): node = result.getNode() hitPos = result.getHitPos() distance = (hitPos - streamPos).length() if time - self.lastDmgTime >= self.dmgIval: self._handleSprayCollision(NodePath(node), hitPos, distance) self.lastDmgTime = time if time - self.lastSprayTime >= self.dmgIval: self.getFPSCam().addViewPunch( Vec3(random.uniform(-0.6, 0.6), random.uniform(0.25, 1.0), 0.0)) base.localAvatar.sendUpdate('usedGag', [self.id]) self.lastSprayTime = time else: pFrom = self.avatar.getPos(render) + self.avatar.getEyePoint() + ( 1, 0, 0) quat = Quat() quat.setHpr( self.avatar.getHpr(render) + (0, self.avatar.lookPitch, 0)) pTo = pFrom + quat.xform( Vec3.forward()) * (self.sprayParticleDist + (pFrom - streamPos).length()) hitPos = Point3(pTo) hit = PhysicsUtils.rayTestClosestNotMe( self.avatar, pFrom, pTo, CIGlobals.WorldGroup | CIGlobals.LocalAvGroup) if hit is not None: hitPos = hit.getHitPos() distance = (hitPos - streamPos).length() self.waterStreamParent.lookAt(render, hitPos) if self.sprayParticle: system = self.sprayParticle.getParticlesNamed('particles-1') # Make the particles die off at the hit point. lifespan = min( 1, distance / self.sprayParticleDist) * self.sprayParticleLife system.factory.setLifespanBase(lifespan) if task: return task.cont
def release(self): Gag.release(self) base.audio3d.attachSoundToObject(self.woosh, self.gag) base.playSfx(self.woosh, node=self.gag) if self.isLocal() and base.localAvatar.battleControls: if base.localAvatar.isFirstPerson(): # Add a small kick to the camera to give more feedback self.getFPSCam().addViewPunch( Vec3(random.uniform(.5, 1), random.uniform(-.5, -1), 0)) startPos = camera.getPos(render) + camera.getQuat( render).xform(Vec3.right()) push = 0.0 else: startPos = self.handJoint.getPos(render) push = (startPos - camera.getPos(render)).length() hitPos = PhysicsUtils.getHitPosFromCamera() else: startPos = self.handJoint.getPos(render) quat = Quat() quat.setHpr( self.avatar.getHpr(render) + (0, self.avatar.lookPitch, 0)) hitPos = quat.xform(Vec3.forward() * self.power) hit = PhysicsUtils.rayTestClosestNotMe( self.avatar, startPos, hitPos, CIGlobals.WorldGroup | CIGlobals.LocalAvGroup) if hit is not None: hitPos = hit.getHitPos() throwDir = (hitPos - startPos).normalized() endPos = startPos + (throwDir * self.power) - (0, 0, 90) entity = self.gag if not entity: entity = self.build() gagRoot = render.attachNewNode('gagRoot') gagRoot.setPos(startPos) entity.reparentTo(render) entity.setPos(0, 0, 0) entity.headsUp(throwDir) rot = entity.getHpr(render) entity.reparentTo(gagRoot) entity.setHpr(rot[0], -90, 0) self.gag = None if not self.handJoint: self.handJoint = self.avatar.find('**/def_joint_right_hold') track = FlightProjectileInterval(gagRoot, startPos=startPos, endPos=endPos, gravityMult=1.07, duration=2.5) event = self.avatar.uniqueName('throwIvalDone') + '-' + str( hash(entity)) track.setDoneEvent(event) base.acceptOnce(event, self.__handlePieIvalDone, [entity]) track.start() if self.isLocal(): collider = self.buildCollisions(entity) self.entities.append([gagRoot, track, collider]) base.localAvatar.sendUpdate('usedGag', [self.id]) else: self.entities.append([gagRoot, track, NodePath()]) self.reset()
def get_unit(hpr): q = Quat() q.setHpr(hpr) return q.xform(Vec3(0, 1, 0))
def __updateTask(self, task): # TODO -- This function does a lot of math, I measured it to take .5 ms on my laptop # That's a lot of time for something miniscule like sway and bob. dt = globalClock.getDt() time = globalClock.getFrameTime() if base.localAvatar.isFirstPerson(): eyePoint = base.localAvatar.getEyePoint() if base.localAvatar.walkControls.crouching: eyePoint[2] = eyePoint[2] / 2.0 eyePoint[2] = CIGlobals.lerpWithRatio(eyePoint[2], self.lastEyeHeight, 0.4) self.lastEyeHeight = eyePoint[2] camRootAngles = Vec3(0) # Mouse look around mw = base.mouseWatcherNode if mw.hasMouse(): md = base.win.getPointer(0) center = Point2(base.win.getXSize() / 2, base.win.getYSize() / 2) xDist = md.getX() - center.getX() yDist = md.getY() - center.getY() sens = self.__getMouseSensitivity() angular = -(xDist * sens) / dt base.localAvatar.walkControls.controller.setAngularMovement( angular) camRootAngles.setY(self.lastPitch - yDist * sens) if camRootAngles.getY() > FPSCamera.MaxP: camRootAngles.setY(FPSCamera.MaxP) yDist = 0 elif camRootAngles.getY() < FPSCamera.MinP: yDist = 0 camRootAngles.setY(FPSCamera.MinP) base.win.movePointer(0, int(center.getX()), int(center.getY())) if base.localAvatar.isFirstPerson(): # Camera / viewmodel bobbing vmBob = Point3(0) vmAngles = Vec3(0) vmRaise = Point3(0) camBob = Point3(0) maxSpeed = base.localAvatar.walkControls.BattleRunSpeed * 16.0 speed = base.localAvatar.walkControls.speeds.length() * 16.0 speed = max(-maxSpeed, min(maxSpeed, speed)) bobOffset = CIGlobals.remapVal(speed, 0, maxSpeed, 0.0, 1.0) self.bobTime += (time - self.lastBobTime) * bobOffset self.lastBobTime = time # Calculate the vertical bob cycle = self.bobTime - int( self.bobTime / self.BobCycleMax) * self.BobCycleMax cycle /= self.BobCycleMax if cycle < self.BobUp: cycle = math.pi * cycle / self.BobUp else: cycle = math.pi + math.pi * (cycle - self.BobUp) / (1.0 - self.BobUp) verticalBob = speed * 0.005 verticalBob = verticalBob * 0.3 + verticalBob * 0.7 * math.sin( cycle) verticalBob = max(-7.0, min(4.0, verticalBob)) verticalBob /= 16.0 # Calculate the lateral bob cycle = self.bobTime - int( self.bobTime / self.BobCycleMax * 2) * self.BobCycleMax * 2 cycle /= self.BobCycleMax * 2 if cycle < self.BobUp: cycle = math.pi * cycle / self.BobUp else: cycle = math.pi + math.pi * (cycle - self.BobUp) / (1.0 - self.BobUp) lateralBob = speed * 0.005 lateralBob = lateralBob * 0.3 + lateralBob * 0.7 * math.sin(cycle) lateralBob = max(-7.0, min(4.0, lateralBob)) lateralBob /= 16.0 # Apply bob, but scaled down a bit vmBob.set(lateralBob * 0.8, 0, verticalBob * 0.1) # Z bob a bit more vmBob[2] += verticalBob * 0.1 # Bob the angles vmAngles[2] += verticalBob * 0.5 vmAngles[1] -= verticalBob * 0.4 vmAngles[0] -= lateralBob * 0.3 # ================================================================ # Viewmodel lag/sway angles = self.camRoot.getHpr(render) quat = Quat() quat.setHpr(angles) invQuat = Quat() invQuat.invertFrom(quat) maxVMLag = 1.5 lagforward = quat.getForward() if dt != 0.0: lagdifference = lagforward - self.lastFacing lagspeed = 5.0 lagdiff = lagdifference.length() if (lagdiff > maxVMLag) and (maxVMLag > 0.0): lagscale = lagdiff / maxVMLag lagspeed *= lagscale self.lastFacing = CIGlobals.extrude(self.lastFacing, lagspeed * dt, lagdifference) self.lastFacing.normalize() lfLocal = invQuat.xform(lagdifference) vmBob = CIGlobals.extrude(vmBob, 5.0 / 16.0, lfLocal * -1.0) pitch = angles[1] if pitch > 180: pitch -= 360 elif pitch < -180: pitch += 360 vmBob = CIGlobals.extrude(vmBob, pitch * (0.035 / 16), Vec3.forward()) vmBob = CIGlobals.extrude(vmBob, pitch * (0.03 / 16), Vec3.right()) vmBob = CIGlobals.extrude(vmBob, pitch * (0.02 / 16), Vec3.up()) # ================================================================ vmRaise.set( 0, 0, 0 ) #(0, abs(camRootAngles.getY()) * -0.002, camRootAngles.getY() * 0.002) camBob.set(0, 0, 0) # Apply bob, raise, and sway to the viewmodel. self.viewModel.setPos(vmBob + vmRaise + self.lastVMPos) self.vmRoot2.setHpr(vmAngles) self.camRoot.setPos(eyePoint + camBob) newPitch = camRootAngles.getY() if abs(newPitch - self.lastPitch) > self.PitchUpdateEpsilon: # Broadcast where our head is looking head = base.localAvatar.getPart("head") if head and not head.isEmpty(): # Constrain the head pitch a little bit so it doesn't look like their head snapped headPitch = max(-47, newPitch) headPitch = min(75, headPitch) base.localAvatar.b_setLookPitch(headPitch) self.lastPitch = newPitch if base.localAvatar.isFirstPerson(): # Apply punch angle self.decayPunchAngle() camRootAngles += self.punchAngle self.camRoot.setHpr(camRootAngles) return task.cont
def rotate(self, point): quat = Quat() quat.setHpr(self.getViewHpr()) return quat.xform(point)
def makeForwardAxis(vec, quat): invQuat = Quat() invQuat.invertFrom(quat) result = invQuat.xform(vec) result.setY(0.0) return result