def recalcCameraSphere(self): nearPlaneDist = base.camLens.getNear() hFov = base.camLens.getHfov() vFov = base.camLens.getVfov() hOff = nearPlaneDist * math.tan(deg2Rad(hFov / 2.0)) vOff = nearPlaneDist * math.tan(deg2Rad(vFov / 2.0)) camPnts = [ Point3(hOff, nearPlaneDist, vOff), Point3(-hOff, nearPlaneDist, vOff), Point3(hOff, nearPlaneDist, -vOff), Point3(-hOff, nearPlaneDist, -vOff), Point3(0.0, 0.0, 0.0) ] avgPnt = Point3(0.0, 0.0, 0.0) for camPnt in camPnts: avgPnt = avgPnt + camPnt avgPnt = avgPnt / len(camPnts) sphereRadius = 0.0 for camPnt in camPnts: dist = Vec3(camPnt - avgPnt).length() if dist > sphereRadius: sphereRadius = dist avgPnt = Point3(avgPnt) self.camRadiusPoint = avgPnt
def anglesToVector(angles): """Converts a set of HPR Euler angles to a forward vector. NOTE: Roll cannot be represented in a direction vector, so that does not factor into the result.""" return Vec3(math.cos(deg2Rad(angles[0])) * math.cos(deg2Rad(angles[1])), math.sin(deg2Rad(angles[0])) * math.cos(deg2Rad(angles[1])), math.sin(deg2Rad(angles[1])))
def announceGenerate(self): DistributedElevatorExt.DistributedElevatorExt.announceGenerate(self) angle = self.startingHpr[0] angle -= 90 radAngle = deg2Rad(angle) unitVec = Vec3(math.cos(radAngle), math.sin(radAngle), 0) unitVec *= 11.25 self.endPos = self.startingPos + unitVec self.endPos.setZ(0.5) dist = Vec3(self.endPos - self.enteringPos).length() wheelAngle = dist / (6.72 * math.pi) * 360 self.kartEnterAnimateInterval = Parallel( LerpHprInterval( self.wheels[0], 5.0, Vec3(self.wheels[0].getH(), wheelAngle, self.wheels[0].getR())), LerpHprInterval( self.wheels[1], 5.0, Vec3(self.wheels[1].getH(), wheelAngle, self.wheels[1].getR())), LerpHprInterval( self.wheels[2], 5.0, Vec3(self.wheels[2].getH(), wheelAngle, self.wheels[2].getR())), LerpHprInterval( self.wheels[3], 5.0, Vec3(self.wheels[3].getH(), wheelAngle, self.wheels[3].getR())), name='SwagKartAnimate') trolleyExitTrack1 = Parallel( Sequence( Wait(1.25), Func(self.mole.doMolePop, 0, 0.75, 5, 0.75, MoleFieldBase.HILL_MOLE)), Sequence( LerpPosInterval(self.golfKart, 2.5, self.endPos), Func(self.mole.setHillType, MoleFieldBase.HILL_WHACKED), Func(self.soundBomb.play), Func(self.soundBomb2.play), Func(self.soundUp.play), Parallel( ProjectileInterval(self.golfKart, startPos=self.endPos, endPos=self.flyToPos, duration=2, gravityMult=2.5), self.golfKart.hprInterval( 2, (self.golfKart.getH(), self.golfKart.getP() + 720, 0)))), self.kartEnterAnimateInterval, name='SwagKartExitTrack') self.trolleyExitTrack = Sequence(trolleyExitTrack1) self.trolleyEnterTrack = Sequence( Func(self.golfKart.setP, 0), LerpPosInterval(self.golfKart, 5.0, self.startingPos, startPos=self.enteringPos)) self.closeDoors = Sequence(self.trolleyExitTrack, Func(self.onDoorCloseFinish)) self.openDoors = Sequence(self.trolleyEnterTrack)
def createGizmo(self, angleDegrees=360, numSteps=16, axis=0, scale=10): data = EggData() vp = EggVertexPool('fan') data.addChild(vp) poly = EggPolygon() data.addChild(poly) v = EggVertex() v.setPos(Point3D(0, 0, 0)) poly.addVertex(vp.addVertex(v)) angleRadians = deg2Rad(angleDegrees) for i in range(numSteps + 1): a = angleRadians * i / numSteps y = math.sin(a) * scale x = math.cos(a) * scale v = EggVertex() if axis is 0: v.setPos(Point3D(x, 0, y)) elif axis is 1: v.setPos(Point3D(x, y, 0)) else: v.setPos(Point3D(0, x, y)) poly.addVertex(vp.addVertex(v)) node = loadEggData(data) return NodePath(node)
def enterMoveTires(self): for key in self.tireDict: body = self.tireDict[key]['tireBody'] body.setAngularVel(0, 0, 0) body.setLinearVel(0, 0, 0) for index in xrange(len(self.allTireInputs)): input = self.allTireInputs[index] avId = self.avIdList[index] body = self.getTireBody(avId) degs = input[1] + 90 tireNp = self.getTireNp(avId) tireH = tireNp.getH() self.notify.debug('tireH = %s' % tireH) radAngle = deg2Rad(degs) foo = NodePath('foo') dirVector = Vec3(math.cos(radAngle), math.sin(radAngle), 0) self.notify.debug('dirVector is now=%s' % dirVector) inputForce = input[0] inputForce /= self.MaxLocalForce inputForce *= self.MaxPhysicsForce force = dirVector * inputForce self.notify.debug('adding force %s to %d' % (force, avId)) body.addForce(force) self.enableAllTireBodies() self.totalPhysicsSteps = 0 self.startSim() taskMgr.add(self.__moveTiresTask, self.uniqueName('moveTiresTtask'))
def make_fov(sweep=90, steps=16, scale=100): z = 1 + random.uniform(-0.01, 0.01) data = EggData() vp = EggVertexPool('fan') data.addChild(vp) poly = EggPolygon() data.addChild(poly) v = EggVertex() v.setPos(Point3D(0, 0, z)) poly.addVertex(vp.addVertex(v)) rads = deg2Rad(sweep) for i in range(steps + 1): a = rads * i / steps y = math.sin(a) x = math.cos(a) v = EggVertex() v.setPos(Point3D(x*scale, y*scale, z)) poly.addVertex(vp.addVertex(v)) node = loadEggData(data) np = NodePath(node) np.setH(sweep/2) return np
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 server_moves_thing(self, tag, loc_x, loc_y, loc_z, speed_x, speed_y, speed_z, angle, angular_velocity): thing = Thing.get_thing(tag) thing.node_path.setPos(loc_x, loc_y, loc_z) thing.node.setLinearMovement(Vec3(speed_x, speed_y, speed_z), True) # I don't know why deg2Rad is required in the following line; I suspect it is a Panda bug. thing.node_path.setH(deg2Rad(angle)) if angular_velocity != 0: self.__rotations[thing.node] = angular_velocity elif thing.node in self.__rotations: del self.__rotations[thing.node]
def server_moves_thing(self, tag, loc_x, loc_y, loc_z, speed_x, speed_y, speed_z, angle, angular_velocity): node_path = self.render.find("**/" + tag) node_path.setPos(loc_x, loc_y, loc_z) node_path.node().setLinearMovement(Vec3(speed_x, speed_y, speed_z), True) # I don't know why deg2Rad is required in the following line; I suspect it is a Panda bug. node_path.setH(deg2Rad(angle)) if angular_velocity != 0: self.__rotations[node_path.node()] = angular_velocity elif node_path.node() in self.__rotations: del self.__rotations[node_path.node()]
def angleVectors(angles, forward = False, right = False, up = False): """ Get basis vectors for the angles. Each vector is optional. Brian: I don't know if this is even used anywhere, nor if it even works correcty. """ if forward or right or up: sh = math.sin(deg2Rad(angles[0])) ch = math.cos(deg2Rad(angles[0])) sp = math.sin(deg2Rad(angles[1])) cp = math.cos(deg2Rad(angles[1])) sr = math.sin(deg2Rad(angles[2])) cr = math.cos(deg2Rad(angles[2])) result = [] if forward: forward = Vec3(cp*ch, cp*sh, -sp) result.append(forward) if right: right = Vec3(-1*sr*sp*ch+-1*cr*-sh, -1*sr*sp*sh+-1*cr*ch, -1*sr*cp) result.append(right) if up: up = Vec3(cr*sp*ch+-sr*-sh, cr*sp*sh+-sr*ch, cr*cp) result.append(up) return result
def angleVectors(angles, forward=False, right=False, up=False): """ Get basis vectors for the angles. Each vector is optional. """ if forward or right or up: sh = math.sin(deg2Rad(angles[0])) ch = math.cos(deg2Rad(angles[0])) sp = math.sin(deg2Rad(angles[1])) cp = math.cos(deg2Rad(angles[1])) sr = math.sin(deg2Rad(angles[2])) cr = math.cos(deg2Rad(angles[2])) result = [] if forward: forward = Vec3(cp * ch, cp * sh, -sp) result.append(forward) if right: right = Vec3(-1 * sr * sp * ch + -1 * cr * -sh, -1 * sr * sp * sh + -1 * cr * ch, -1 * sr * cp) result.append(right) if up: up = Vec3(cr * sp * ch + -sr * -sh, cr * sp * sh + -sr * ch, cr * cp) result.append(up) return result
def _fit(self, c, p1, p2): #bound = c.getBounds() #r = bound.getRadius() #cp = c.getPos(self.render) #offset = Point3(0.0, r, 0.0) #dist3d = r * 2.0 n1 = c.exposeJoint(None, "modelRoot", "Head") n2 = c.exposeJoint(None, "modelRoot", "Eyes") n_root = c.exposeJoint(None, "modelRoot", "ParentNode") offset = n_root.getPos(n1) dist3d = n2.getPos(n1).length() if p1[0] != 0.0: hfov = self.base.camLens.getHfov() w = math.fabs(self.base.a2dRight) a = p1[0] Q = math.fabs(p2[1] - p1[1]) O = dist3d n = p1[1] * O / Q A = a * O / Q theta = (hfov / 2.0) * (a / w) d = A / math.tan(deg2Rad(theta)) p_1 = Point3(A, d, n) p_2 = Point3(A, d, n + O) p = Point3(A, d, n + offset[1]) else: vfov = self.base.camLens.getVfov() h = math.fabs(self.base.a2dTop) theta = (vfov / 2.0) * (p1[1] / h) Q = math.fabs(p2[1] - p1[1]) O = dist3d n = p1[1] * O / Q d = n / math.tan(deg2Rad(theta)) p_1 = Point3(p1[0], d, p1[1]) p_2 = Point3(p2[0], d, p2[1]) p = Point3(p1[0], d, n + offset[1]) c.setPos(p)
def announceGenerate(self): DistributedElevatorExt.DistributedElevatorExt.announceGenerate(self) angle = self.startingHpr[0] angle -= 90 radAngle = deg2Rad(angle) unitVec = Vec3(math.cos(radAngle), math.sin(radAngle), 0) unitVec *= 45.0 self.endPos = self.startingPos + unitVec self.endPos.setZ(0.5) dist = Vec3(self.endPos - self.enteringPos).length() wheelAngle = dist / (4.8 * 1.4 * math.pi) * 360 self.kartEnterAnimateInterval = Parallel(LerpHprInterval(self.wheels[0], 5.0, Vec3(self.wheels[0].getH(), wheelAngle, self.wheels[0].getR())), LerpHprInterval(self.wheels[1], 5.0, Vec3(self.wheels[1].getH(), wheelAngle, self.wheels[1].getR())), LerpHprInterval(self.wheels[2], 5.0, Vec3(self.wheels[2].getH(), wheelAngle, self.wheels[2].getR())), LerpHprInterval(self.wheels[3], 5.0, Vec3(self.wheels[3].getH(), wheelAngle, self.wheels[3].getR())), name='CogKartAnimate') trolleyExitTrack1 = Parallel(LerpPosInterval(self.golfKart, 5.0, self.endPos), self.kartEnterAnimateInterval, name='CogKartExitTrack') self.trolleyExitTrack = Sequence(trolleyExitTrack1) self.trolleyEnterTrack = Sequence(LerpPosInterval(self.golfKart, 5.0, self.startingPos, startPos=self.enteringPos)) self.closeDoors = Sequence(self.trolleyExitTrack, Func(self.onDoorCloseFinish)) self.openDoors = Sequence(self.trolleyEnterTrack)
def __endFireWater(self): if self.aimStart == None: return if not self.state == 'Controlled': return if not self.avId == localAvatar.doId: return taskMgr.remove(self.waterPowerTaskName) messenger.send('wakeup') self.aimStart = None origin = self.nozzle.getPos(render) target = self.boss.getPos(render) angle = deg2Rad(self.waterPitcherNode.getH() + 90) x = math.cos(angle) y = math.sin(angle) fireVector = Point3(x, y, 0) if self.power < 0.001: self.power = 0.001 self.lastPowerFired = self.power fireVector *= self.fireLength * self.power target = origin + fireVector segment = CollisionSegment(origin[0], origin[1], origin[2], target[0], target[1], target[2]) fromObject = render.attachNewNode(CollisionNode('pitcherColNode')) fromObject.node().addSolid(segment) fromObject.node().setFromCollideMask(ToontownGlobals.PieBitmask | ToontownGlobals.CameraBitmask | ToontownGlobals.FloorBitmask) fromObject.node().setIntoCollideMask(BitMask32.allOff()) queue = CollisionHandlerQueue() base.cTrav.addCollider(fromObject, queue) base.cTrav.traverse(render) queue.sortEntries() self.hitObject = None if queue.getNumEntries(): entry = queue.getEntry(0) target = entry.getSurfacePoint(render) self.hitObject = entry.getIntoNodePath() base.cTrav.removeCollider(fromObject) fromObject.removeNode() self.d_firingWater(origin, target) self.fireWater(origin, target) self.resetPowerBar() return
def makeArc(angleDegrees=360, numSteps=16, scale=2, color=(1, 1, 1, 1)): ls = LineSegs() ls.setColor(color) angleRadians = deg2Rad(angleDegrees) for i in range(numSteps + 1): a = angleRadians * i / numSteps y = np.sin(a) * scale x = np.cos(a) * scale ls.drawTo(y, x, 0) if angleDegrees != 360: for i in range(numSteps + 1): a = -angleRadians * i / numSteps y = np.sin(a) * scale x = np.cos(a) * scale ls.drawTo(y, x, 0) node = ls.create() return NodePath(node)
def spawnAsteroids(self, task): if not self.alive: return Task.cont if len(self.asteroids) <= 3: # This loads an asteroid. The texture chosen is random # from "asteroid1.png" to "asteroid3.png". asteroid = loadObject(f'asteroid{randint(1, 3)}.png', scale=AST_INIT_SCALE) self.asteroids.append(asteroid) asteroid.setX(choice(tuple(range(-SCREEN_X, SCREEN_X)))) # Y asteroid.setZ(choice(tuple(range(-SCREEN_Y + 15, SCREEN_Y)))) # Heading is a random angle in degrees, only for down heading = deg2Rad(randint(110, 250)) # Converts the heading to a vector and multiplies it by speed to # get a velocity vector v = LVector3(sin(heading), 0, cos(heading)) * AST_INIT_VEL self.setVelocity(asteroid, v) return Task.cont
def anglesToVector(angles): return Vec3( math.cos(deg2Rad(angles[0])) * math.cos(deg2Rad(angles[1])), math.sin(deg2Rad(angles[0])) * math.cos(deg2Rad(angles[1])), math.sin(deg2Rad(angles[1])))
def car_vec(self): # port (or add) this to 3D car_rad = deg2Rad(self.mediator.gfx.nodepath.h) return Vec(-sin(car_rad), cos(car_rad), 0).normalize()
def car_vec_3d(self): # port (or add) this to 3D h_rad = deg2Rad(self.mediator.gfx.nodepath.h) p_rad = deg2Rad(self.mediator.gfx.nodepath.p) return Vec(-sin(h_rad), cos(h_rad), sin(p_rad)).normalize()
def generate(self, helperInfo): color = self.mapObject.getPropertyValue("_light", default=Vec4( 255, 255, 255, 255)) color = LEGlobals.colorFromRGBScalar255(color) color = LEGlobals.vec3GammaToLinear(color) intensity = self.mapObject.getPropertyValue("_intensity", default=1.0) innerRadius = self.mapObject.getPropertyValue("_inner_radius", default=1.0) outerRadius = self.mapObject.getPropertyValue("_outer_radius", default=2.0) color[0] = color[0] * intensity color[1] = color[1] * intensity color[2] = color[2] * intensity constant = self.mapObject.getPropertyValue("_constant_attn", default=0.0) linear = self.mapObject.getPropertyValue("_linear_attn", default=0.0) quadratic = self.mapObject.getPropertyValue("_quadratic_attn", default=1.0) innerConeDeg = self.mapObject.getPropertyValue("_inner_cone") innerConeRad = deg2Rad(innerConeDeg) outerConeDeg = self.mapObject.getPropertyValue("_cone") outerConeRad = deg2Rad(outerConeDeg) depthBias = self.mapObject.getPropertyValue("_depth_bias") shadowSize = self.mapObject.getPropertyValue("_shadow_map_size") shadowCaster = self.mapObject.getPropertyValue("_shadow_caster") softnessFactor = self.mapObject.getPropertyValue("_softness_factor") normalOffsetScale = self.mapObject.getPropertyValue( "_normal_offset_scale") normalOffsetUvSpace = self.mapObject.getPropertyValue( "_normal_offset_uv_space") pl = Spotlight("lightHelper-light_spot") pl.setColor(Vec4(color[0], color[1], color[2], 1.0)) pl.setFalloff(quadratic) pl.setInnerRadius(innerRadius) pl.setOuterRadius(outerRadius) pl.setExponent(self.mapObject.getPropertyValue("_exponent")) pl.setInnerCone(innerConeDeg) pl.setOuterCone(outerConeDeg) if shadowCaster: pl.setCameraMask(DirectRender.ShadowCameraBitmask) pl.setShadowCaster(True, shadowSize, shadowSize) pl.setDepthBias(depthBias) pl.setSoftnessFactor(softnessFactor) pl.setNormalOffsetScale(normalOffsetScale) pl.setNormalOffsetUvSpace(normalOffsetUvSpace) self.light = self.mapObject.helperRoot.attachNewNode(pl) if True: #self.mapObject.doc.numlights < 64: self.mapObject.doc.render.setLight(self.light) self.mapObject.doc.numlights += 1 self.hasLight = True self.spotlightMdl = base.loader.loadModel( "models/misc/spotlight-editor.bam") #self.spotlightMdl.setState("materials/spotlight-editor.mat") #state = self.spotlightMdl.getState() #params = state.getAttrib(ShaderParamAttrib) #params = params.setParam("selfillumtint", CKeyValues.toString(color.getXyz())) #print(params) #self.spotlightMdl.setState(state.setAttrib(params)) self.spotlightMdl.reparentTo(self.light) self.spotlightMdl.setScale(0.5) self.spotlightMdl.setH(180) self.spotlightMdl.setLightOff(1) self.spotlightMdl.setRenderModeWireframe(1) self.spotlightMdl.setTextureOff(1) self.spotlightMdl.setColor(Vec4(0, 0, 0, 1)) #self.spotlightMdl.setLightOff(self.light, 1) #self.spotlightMdl.ls() innerCone = getUnitCone().copyTo(self.light) innerCone.setSy(innerRadius) innerCone.setSx((innerConeRad / 2) * innerRadius) innerCone.setSz((innerConeRad / 2) * innerRadius) innerCone.setColorScale(InnerColor) self.innerCone = innerCone outerCone = getUnitCone().copyTo(self.light) outerCone.setSy(outerRadius) outerCone.setSx((outerConeRad / 2) * outerRadius) outerCone.setSz((outerConeRad / 2) * outerRadius) outerCone.setColorScale(OuterColor) self.outerCone = outerCone if not self.mapObject.selected: innerCone.stash() outerCone.stash()
def gotModel(self, mdl, filename, context): self.currentLoadContext = None if not mdl or mdl.isEmpty(): context.createNextAsset() return # If there's no geomnode, there is no model! if mdl.find("**/+GeomNode").isEmpty(): context.createNextAsset() return mdl.reparentTo(self.render) # Determine a good offset point to take the thumbnail snapshot mins = core.Point3() maxs = core.Point3() mdl.calcTightBounds(mins, maxs) size = maxs - mins center = (mins + maxs) / 2.0 # Choose the longest axis as the radius radius = size.length() / 2 fov = self.lens.getFov() distance = (radius / float(math.tan(core.deg2Rad(min(fov[0], fov[1]) / 2.0)))) # Ensure the far plane is far enough back to see the entire object. idealFarPlane = distance + radius * 1.5 self.lens.setFar(max(self.lens.getDefaultFar(), idealFarPlane)) # And that the near plane is far enough forward. idealNearPlane = distance - radius self.lens.setNear(min(self.lens.getDefaultNear(), idealNearPlane)) self.camera.setPos(center + self.camera.getQuat().xform(core.Vec3.forward() * -distance)) # Render the model to the back buffer self.buffer.setActive(True) base.graphicsEngine.renderFrame() base.graphicsEngine.renderFrame() # Fetch the pixels into a PNMImage image = core.PNMImage() self.buffer.getScreenshot(image) self.buffer.setActive(False) mdl.removeNode() # Store the pixels in a QPixmap qimage = QtGui.QImage(image.getXSize(), image.getYSize(), QtGui.QImage.Format_RGB888) for x in range(image.getXSize()): for y in range(image.getYSize()): col = CIGlobals.vec3LinearToGamma(image.getXelA(x, y)) qimage.setPixelColor( x, y, QtGui.QColor(int(col[0] * 255), int(col[1] * 255), int(col[2] * 255), int(col[3] * 255))) pixmap = QtGui.QPixmap.fromImage(qimage) icon = QtGui.QIcon(pixmap) self.modelThumbnails[filename] = icon context.addAssetItem(icon, filename) context.createNextAsset()
def create(self, generator, mins, maxs, material, roundDecimals, temp=False): solids = [] numSides = self.numSides.getValue() if numSides < 3: return solids wallWidth = self.wallWidth.getValue() if wallWidth < 1: return solids arc = self.arc.getValue() if arc < 1: return solids startAngle = self.startAngle.getValue() if startAngle < 0 or startAngle > 359: return solids addHeight = self.addHeight.getValue() curvedRamp = self.curvedRamp.getValue() tiltAngle = self.tiltAngle.getValue() if abs(tiltAngle % 180) == 90: return solids tiltInterp = curvedRamp and self.tiltInterp.getValue() # Very similar to the pipe brush, except with options for start angle, arc, height, and tilt. width = maxs.x - mins.x length = maxs.y - mins.y height = maxs.z - mins.z majorOut = width / 2 majorIn = majorOut - wallWidth minorOut = length / 2 minorIn = minorOut - wallWidth start = deg2Rad(startAngle) tilt = deg2Rad(tiltAngle) angle = deg2Rad(arc) / numSides center = (mins + maxs) / 2 # Calculate the coordinates of the inner and outer ellipses' points. outer = [] inner = [] for i in range(numSides + 1): a = start + i * angle h = i * addHeight interp = 1 if tiltInterp: interp = math.cos(math.pi / numSides * (i - numSides / 2)) tiltHeight = wallWidth / 2 * interp * math.tan(tilt) xval = center.x + majorOut * math.cos(a) yval = center.y + minorOut * math.sin(a) zval = mins.z if curvedRamp: zval += h + tiltHeight outer.append( LEUtils.roundVector(Point3(xval, yval, zval), roundDecimals)) xval = center.x + majorIn * math.cos(a) yval = center.y + minorIn * math.sin(a) zval = mins.z if curvedRamp: zval += h - tiltHeight inner.append( LEUtils.roundVector(Point3(xval, yval, zval), roundDecimals)) color = LEUtils.getRandomSolidColor() # create the solids z = LEUtils.roundVector(Point3(0, 0, height), roundDecimals) for i in range(numSides): faces = [] # Since we are triangulating/splitting each arch segment, we need to generate 2 brushes per side if curvedRamp: # The splitting orientation depends on the curving direction of the arch if addHeight >= 0: faces.append([ outer[i], outer[i] + z, outer[i + 1] + z, outer[i + 1] ]) faces.append([ outer[i + 1], outer[i + 1] + z, inner[i] + z, inner[i] ]) faces.append( [inner[i], inner[i] + z, outer[i] + z, outer[i]]) faces.append( [outer[i] + z, inner[i] + z, outer[i + 1] + z]) faces.append([outer[i + 1], inner[i], outer[i]]) else: faces.append([ inner[i + 1], inner[i + 1] + z, inner[i] + z, inner[i] ]) faces.append([ outer[i], outer[i] + z, inner[i + 1] + z, inner[i + 1] ]) faces.append( [inner[i], inner[i] + z, outer[i] + z, outer[i]]) faces.append( [inner[i + 1] + z, outer[i] + z, inner[i] + z]) faces.append([inner[i], outer[i], inner[i + 1]]) solids.append( self.makeSolid(generator, faces, material, temp, color)) faces.clear() if addHeight >= 0: faces.append([ inner[i + 1], inner[i + 1] + z, inner[i] + z, inner[i] ]) faces.append([ inner[i], inner[i] + z, outer[i + 1] + z, outer[i + 1] ]) faces.append([ outer[i + 1], outer[i + 1] + z, inner[i + 1] + z, inner[i + 1] ]) faces.append( [inner[i + 1] + z, outer[i + 1] + z, inner[i] + z]) faces.append([inner[i], outer[i + 1], inner[i + 1]]) else: faces.append([ outer[i], outer[i] + z, outer[i + 1] + z, outer[i + 1] ]) faces.append([ inner[i + 1], inner[i + 1] + z, outer[i] + z, outer[i] ]) faces.append([ outer[i + 1], outer[i + 1] + z, inner[i + 1] + z, inner[i + 1] ]) faces.append( [outer[i] + z, inner[i + 1] + z, outer[i + 1] + z]) faces.append([outer[i + 1], inner[i + 1], outer[i]]) solids.append( self.makeSolid(generator, faces, material, temp, color)) else: h = Vec3.unitZ() * i * addHeight faces.append([ outer[i] + h, outer[i] + z + h, outer[i + 1] + z + h, outer[i + 1] + h ]) faces.append([ inner[i + 1] + h, inner[i + 1] + z + h, inner[i] + z + h, inner[i] + h ]) faces.append([ outer[i + 1] + h, outer[i + 1] + z + h, inner[i + 1] + z + h, inner[i + 1] + h ]) faces.append([ inner[i] + h, inner[i] + z + h, outer[i] + z + h, outer[i] + h ]) faces.append([ inner[i + 1] + z + h, outer[i + 1] + z + h, outer[i] + z + h, inner[i] + z + h ]) faces.append([ inner[i] + h, outer[i] + h, outer[i + 1] + h, inner[i + 1] + h ]) solids.append( self.makeSolid(generator, faces, material, temp, color)) return solids
def setup(self): num_sectors = 6 sector_length = 100 angle_incr = 360.0/num_sectors angle_offset = -180 radius = 0.5*sector_length/sin(deg2Rad(0.5*angle_incr)) y_offset = radius*cos(deg2Rad(0.5*angle_incr)) z_incr = 8 logging.info("radius = " + str(radius) + ' sector length = ' + str(2*radius*sin(deg2Rad(angle_incr))) ) dummy_node = NodePath('dummy-node') dummy_node.reparentTo(self) for i in range(0,num_sectors): # updating z value z = i*z_incr # placing dummy node dummy_node.clearTransform(self) dummy_node.setZ(self,z) dummy_node.setHpr(self,i*angle_incr,0,0) dummy_node.setY(dummy_node,-y_offset) dummy_node.setX(dummy_node,-0.5*sector_length) # creating sector tf = dummy_node.getTransform(self) sector = self.createSector(tf,'sector' + str(i)) self.__createPlatforms__(sector,i == 0) self.__createBoxes__(sector) # adding sector transitions sector = None dest_sector = None for i in range(0,num_sectors-1): sector = self.getSectors()[i] dest_sector = self.getSectors()[i+1] sector.connect(dest_sector,Vec3(100,0,28),True) continue # TODO: Unreachable code below left here for reference only, will get removed # after the whole sector transition functionality becomes more stable. if i == 0: # following sector dest_sector = self.getSectors()[i+1] sector.addTransition(dest_sector,Vec3(100,0,28),True) elif i > 0 and i < num_sectors - 1: # following sector dest_sector = self.getSectors()[i+1] sector.addTransition(dest_sector,Vec3(100,0,28),True) # preceeding sector dest_sector = self.getSectors()[i-1] sector.addTransition(dest_sector,Vec3(0,0,20),False) else: # preceeding sector dest_sector = self.getSectors()[i-1] sector.addTransition(dest_sector,Vec3(0,0,20),False) dummy_node.removeNode()
def create(self, generator, mins, maxs, material, roundDecimals, temp=False): numSides = self.numSides.getValue() if numSides < 3: return [] roundDecimals = 2 # Don't support rounding width = maxs.x - mins.x length = maxs.y - mins.y height = maxs.z - mins.z center = (maxs + mins) / 2 major = width / 2 minor = length / 2 heightRadius = height / 2 angleV = deg2Rad(180) / numSides angleH = deg2Rad(360) / numSides faces = [] bottom = LEUtils.roundVector(Point3(center.x, center.y, mins.z), roundDecimals) top = LEUtils.roundVector(Point3(center.x, center.y, maxs.z), roundDecimals) for i in range(numSides): # Top -> bottom zAngleStart = angleV * i zAngleEnd = angleV * (i + 1) zStart = heightRadius * math.cos(zAngleStart) zEnd = heightRadius * math.cos(zAngleEnd) zMultStart = math.sin(zAngleStart) zMultEnd = math.sin(zAngleEnd) for j in range(numSides): # Go around the circle in X/Y xyAngleStart = angleH * j xyAngleEnd = angleH * ((j + 1) % numSides) xyStartX = major * math.cos(xyAngleStart) xyStartY = minor * math.sin(xyAngleStart) xyEndX = major * math.cos(xyAngleEnd) xyEndY = minor * math.sin(xyAngleEnd) a = LEUtils.roundVector( Point3(xyStartX * zMultStart, xyStartY * zMultStart, zStart) + center, roundDecimals) b = LEUtils.roundVector( Point3(xyEndX * zMultStart, xyEndY * zMultStart, zStart) + center, roundDecimals) c = LEUtils.roundVector( Point3(xyEndX * zMultEnd, xyEndY * zMultEnd, zEnd) + center, roundDecimals) d = LEUtils.roundVector( Point3(xyStartX * zMultEnd, xyStartY * zMultEnd, zEnd) + center, roundDecimals) if i == 0: # Top faces are triangles faces.append([top, c, d]) elif i == (numSides - 1): # Bottom faces are also triangles faces.append([bottom, a, b]) else: # Inner faces are quads faces.append([a, b, c, d]) return [self.makeSolid(generator, faces, material, temp)]