def fromPlaneAndRadius(plane, radius=32768): normal = plane.getNormal() dist = -plane.getW() # Find the major axis x = plane.getClosestAxisToNormal() up = Vec3.unitX() if x == Vec3.unitZ() else Vec3.unitZ() v = up.dot(normal) up = BSPUtils.extrude(up, -v, normal) up.normalize() org = normal * dist right = up.cross(normal) up = up * radius right = right * radius # Project a really big axis aligned box onto the plane verts = [ org - right + up, org + right + up, org + right - up, org - right - up ] poly = Winding(verts, plane) return poly
def keyboardWatchTask(self, task): """Handle keyboard input""" dt = globalClock.getDt() for keyname, dir in self.movementDirs: if self.keyMap[keyname]: self.camera.setPos(self.camera, dir.__mul__(10 * dt)) if self.keyMap["sink"]: self.camera.setPos(self.camera.getPos() - Vec3.unitZ().__mul__(10 * dt)) if self.keyMap["rise"]: self.camera.setPos(self.camera.getPos() + Vec3.unitZ().__mul__(10 * dt)) return Task.cont
def __build_ocean_mesh(self): vdata = GeomVertexData('data', GeomVertexFormat.getV3n3c4t2(), Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') texcoord = GeomVertexWriter(vdata, 'texcoord') color = GeomVertexWriter(vdata, 'color') axes = [Vec3.unitX(), Vec3.unitY(), Vec3.unitZ()] face = 0 for x in range(3): for s in [-1, 1]: for i in range(self.__n + 1): for j in range(self.__n + 1): a = (i * 1.0 / self.__n) * (pi / 2) - (pi / 4) b = (j * 1.0 / self.__n) * (pi / 2) - (pi / 4) xAxis = axes[(x + 3) % 3] yAxis = axes[(x + 4) % 3] zAxis = axes[(x + 5) % 3] v = (xAxis * (-cos(a) * sin(b)) + yAxis * (sin(a) * cos(b)) + zAxis * (cos(a) * cos(b))) * s v.normalize() normal.addData3f(v) vertex.addData3f(v * self.__radius) texcoord.addData2f(i * 1.0, j * 1.0) color.addData4f(self.__ocean_color) face = face + 1 prim = self.__heightmap_primitive() geom = Geom(vdata) geom.addPrimitive(prim) return geom
def getClosestAxis(normal): absNormal = Vec3(abs(normal.x), abs(normal.y), abs(normal.z)) if absNormal.almostEqual(Vec3.unitX(), 0.5): return Vec3.unitX() elif absNormal.almostEqual(Vec3.unitY(), 0.5): return Vec3.unitY() else: return Vec3.unitZ()
def getClosestAxisToNormal(self): # VHE Prioritizes the axes in order of X, Y, Z norm = self.getNormal() norm[0] = abs(norm[0]) norm[1] = abs(norm[1]) norm[2] = abs(norm[2]) if norm.x >= norm.y and norm.x >= norm.z: return Vec3.unitX() if norm.y >= norm.z: return Vec3.unitY() return Vec3.unitZ()
def getCirclesBorder(cls, circle, numSlices=32, closed=False): degPerSlice = 360.0 / numSlices zVec = Vec3.unitZ() rotMat = Mat3.rotateMat(degPerSlice, zVec) projVec = Vec3.unitY() + circle.center projVec.normalize() border = [ Point3(projVec * circle.radius + circle.center), ] projVec = rotMat.xform(projVec) for i in range(1, numSlices): pt = Point3(projVec * circle.radius + circle.center) border.append(pt) projVec = rotMat.xform(projVec) if closed and border: border.append(border[0]) return border
def __build_land_mesh(self): vdata = GeomVertexData('data', GeomVertexFormat.getV3n3c4t2(), Geom.UHStatic) vertex = GeomVertexWriter(vdata, 'vertex') normal = GeomVertexWriter(vdata, 'normal') texcoord = GeomVertexWriter(vdata, 'texcoord') color = GeomVertexWriter(vdata, 'color') axes = [Vec3.unitX(), Vec3.unitY(), Vec3.unitZ()] face = 0 for x in range(3): for s in [-1, 1]: for i in range(self.__n + 1): for j in range(self.__n + 1): a = (i * 1.0 / self.__n) * (pi / 2) - (pi / 4) b = (j * 1.0 / self.__n) * (pi / 2) - (pi / 4) xAxis = axes[(x + 3) % 3] yAxis = axes[(x + 4) % 3] zAxis = axes[(x + 5) % 3] v = (xAxis * (-cos(a) * sin(b)) + yAxis * (sin(a) * cos(b)) + zAxis * (cos(a) * cos(b))) * s v.normalize() normal.addData3f(v) index = self.__height_i(face, i, j) v = v * ( 1.0 + (self.__height_factor * self.__height_unit * (self.__heightmap[index] - 0.5))) * self.__radius vertex.addData3f(v) texcoord.addData2f(i * 1.0, j * 1.0) c = self.__gradient(self.__color_gradient, self.__heightmap[index]) color.addData4f(c[0] / 255.0, c[1] / 255.0, c[2] / 255.0, 1.0) face = face + 1 prim = self.__heightmap_primitive() geom = Geom(vdata) geom.addPrimitive(prim) return geom
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