Example #1
0
def spawn_resource(tiles, min_amount, max_amount):
    cont = bge.logic.getCurrentController()
    
    for i in range(0, random.randint(min_amount, max_amount)):
        tile = Vector(( random.randint(-128, 128), random.randint(-128, 128) ))
        
        # leave a clearing in the center of the map, but offset
        if (tile - Vector((0,-6))).length > 14:
            d = spawn_object(cont, "Large_clearance_detector", tile.to_3d())
            Detector(d, random.choice(tiles), i)
 def skin_normal(norm, pidx):
     # TODO: not sure this is right
     norm = Vector([norm[0], norm[1], norm[2], 0])
     out = Vector((0, 0, 0, 0))
     weight_sum = 0
     for joint_set, weight_set in zip(joint_sets, weight_sets):
         for j in range(0, 4):
             weight = weight_set[pidx][j]
             if weight != 0.0:
                 weight_sum += weight
                 joint = joint_set[pidx][j]
                 out += weight * (joint_mats[joint] @ norm)
     out /= weight_sum
     out = out.to_3d().normalized()
     return out
    def normals_from_colors(mesh):
        """
        Replace normals based on vertex colors,
        only applies to verts affected by __NORMALS__
        """
        #if not mesh.vertex_colors['__NORMALS__']:
        #    return

        #mesh = object.data
        if '__NORMALS__' in mesh.vertex_colors:
        	color_map = mesh.vertex_colors['__NORMALS__']

        	for poly in mesh.polygons:
        	    for vert_idx, loop_idx in zip(poly.vertices, poly.loop_indices):
        	        #groups = [grp.group for grp in mesh.vertices[vert_idx].groups]
        	        rgba = Vector(color_map.data[loop_idx].color)
        	        if rgba.x == 0 and rgba.y == 0 and rgba.z == 0: continue
        	        rgb = rgba.to_3d()
        	        normal = rgb * 2 - Vector((1,1,1))
        	        mesh.vertices[vert_idx].normal = normal
Example #4
0
def draw_polygon_object(mat,
                        vertices,
                        faces,
                        face_color,
                        draw_faces,
                        draw_wires,
                        wire_lines=None,
                        wire_color=(0, 0, 0),
                        face_transforms=None,
                        wire_transforms=None):
    """
    Draw a collider polygon object. It takes matrix, vertices (coordinates),
    faces (vertex index references), face color (RGB), faces drawing state (bool),
    wires drawing state (bool) and optional values wire lines (list of lists
    of vertex positions resulting in closed lines), wire color (RGB),
    face transformations (list of vertex indices)
    and wire transformations (list of vertex indices).
    :param mat:
    :param vertices:
    :param faces:
    :param face_color:
    :param draw_faces:
    :param draw_wires:
    :param wire_lines:
    :param wire_color:
    :param face_transforms:
    :param wire_transforms:
    :return:
    """
    if draw_faces:
        for face in faces:
            glBegin(GL_POLYGON)
            glColor3f(face_color[0], face_color[1], face_color[2])
            for vert in face:
                if face_transforms:
                    trans = mat
                    for transformation in face_transforms:
                        if vert in transformation[1]:
                            trans = trans * transformation[0]
                    glVertex3f(*(trans * Vector(vertices[vert])))
                else:
                    glVertex3f(*(mat * Vector(vertices[vert])))
            glEnd()
    if draw_wires:
        if wire_lines:

            # DRAW CUSTOM LINES
            vert_i_global = 0
            for line in wire_lines:
                # glLineWidth(2.0)
                glEnable(GL_LINE_STIPPLE)
                glBegin(GL_LINES)
                glColor3f(wire_color[0], wire_color[1], wire_color[2])

                for vert_i, vert1 in enumerate(line):
                    if vert_i + 1 < len(line):
                        vert2 = line[vert_i + 1]
                    else:
                        continue

                    # SEPARATE PART TRANSFORMATIONS
                    if wire_transforms:
                        trans1 = trans2 = mat
                        for transformation in wire_transforms:
                            if vert_i_global in transformation[1]:
                                trans1 = trans1 * transformation[0]
                            if vert_i_global + 1 in transformation[1]:
                                trans2 = trans2 * transformation[0]
                        glVertex3f(*(trans1 * Vector(vert1)))
                        glVertex3f(*(trans2 * Vector(vert2)))
                    else:
                        glVertex3f(*(mat * Vector(vert1)))
                        glVertex3f(*(mat * Vector(vert2)))
                    vert_i_global += 1
                vert_i_global += 1
                glEnd()
                glDisable(GL_LINE_STIPPLE)
                # glLineWidth(1.0)
        else:
            for face in faces:
                # glLineWidth(2.0)
                glEnable(GL_LINE_STIPPLE)
                glBegin(GL_LINES)
                glColor3f(wire_color[0], wire_color[1], wire_color[2])
                for vert_i, vert1 in enumerate(face):
                    if vert_i + 1 == len(face):
                        vert2 = face[0]
                    else:
                        vert2 = face[vert_i + 1]
                    if face_transforms:
                        trans1 = mat
                        trans2 = mat
                        vec1 = Vector(vertices[vert1])
                        vec2 = Vector(vertices[vert2])
                        for transformation in face_transforms:
                            if vert1 in transformation[1]:
                                trans1 = trans1 * transformation[0]
                            if vert2 in transformation[1]:
                                trans2 = trans2 * transformation[0]
                        glVertex3f(*(trans1 * vec1))
                        glVertex3f(*(trans2 * vec2))
                    else:
                        glVertex3f(*(mat * Vector(vertices[vert1])))
                        glVertex3f(*(mat * Vector(vertices[vert2])))
                glEnd()
                glDisable(GL_LINE_STIPPLE)
                # glLineWidth(1.0)
    if 0:  # DEBUG: draw points from faces geometry
        glPointSize(3.0)
        glBegin(GL_POINTS)
        glColor3f(0.5, 0.5, 1)
        for vertex_i, vertex in enumerate(vertices):
            vec = Vector(vertex)
            if face_transforms:
                trans = mat
                for transformation in face_transforms:
                    if vertex_i in transformation[1]:
                        trans = trans * transformation[0]
                glVertex3f(*(trans * vec))
            else:
                glVertex3f(*(mat * vec.to_3d()))
        glEnd()
        glPointSize(1.0)
    if 0:  # DEBUG: draw points from lines geometry
        if wire_lines:
            glPointSize(3.0)
            glBegin(GL_POINTS)
            glColor3f(1, 0, 0.5)
            vert_i_global = 0
            for line in wire_lines:
                for vert_i, vertex in enumerate(line):
                    if vert_i + 1 < len(line):
                        vec = Vector(vertex)
                    else:
                        continue
                    if wire_transforms:
                        trans = mat
                        for transformation in wire_transforms:
                            if vert_i_global in transformation[1]:
                                trans = trans * transformation[0]
                        glVertex3f(*(trans * vec.to_3d()))
                    else:
                        glVertex3f(*(mat * vec.to_3d()))
                    vert_i_global += 1
                vert_i_global += 1
            glEnd()
            glPointSize(1.0)
Example #5
0
def draw_polygon_object(mat, vertices, faces, face_color, draw_faces, draw_wires,
                        wire_lines=None, wire_color=(0, 0, 0), face_transforms=None, wire_transforms=None):
    """
    Draw a collider polygon object. It takes matrix, vertices (coordinates),
    faces (vertex index references), face color (RGB), faces drawing state (bool),
    wires drawing state (bool) and optional values wire lines (list of lists
    of vertex positions resulting in closed lines), wire color (RGB),
    face transformations (list of vertex indices)
    and wire transformations (list of vertex indices).
    :param mat:
    :param vertices:
    :param faces:
    :param face_color:
    :param draw_faces:
    :param draw_wires:
    :param wire_lines:
    :param wire_color:
    :param face_transforms:
    :param wire_transforms:
    :return:
    """
    if draw_faces:
        for face in faces:
            glBegin(GL_POLYGON)
            glColor3f(face_color[0], face_color[1], face_color[2])
            for vert in face:
                if face_transforms:
                    trans = mat
                    for transformation in face_transforms:
                        if vert in transformation[1]:
                            trans = trans * transformation[0]
                    glVertex3f(*(trans * Vector(vertices[vert])))
                else:
                    glVertex3f(*(mat * Vector(vertices[vert])))
            glEnd()
    if draw_wires:
        if wire_lines:

            # DRAW CUSTOM LINES
            vert_i_global = 0
            for line in wire_lines:
                # glLineWidth(2.0)
                glEnable(GL_LINE_STIPPLE)
                glBegin(GL_LINES)
                glColor3f(wire_color[0], wire_color[1], wire_color[2])

                for vert_i, vert1 in enumerate(line):
                    if vert_i + 1 < len(line):
                        vert2 = line[vert_i + 1]
                    else:
                        continue

                    # SEPARATE PART TRANSFORMATIONS
                    if wire_transforms:
                        trans1 = trans2 = mat
                        for transformation in wire_transforms:
                            if vert_i_global in transformation[1]:
                                trans1 = trans1 * transformation[0]
                            if vert_i_global + 1 in transformation[1]:
                                trans2 = trans2 * transformation[0]
                        glVertex3f(*(trans1 * Vector(vert1)))
                        glVertex3f(*(trans2 * Vector(vert2)))
                    else:
                        glVertex3f(*(mat * Vector(vert1)))
                        glVertex3f(*(mat * Vector(vert2)))
                    vert_i_global += 1
                vert_i_global += 1
                glEnd()
                glDisable(GL_LINE_STIPPLE)
                # glLineWidth(1.0)
        else:
            for face in faces:
                # glLineWidth(2.0)
                glEnable(GL_LINE_STIPPLE)
                glBegin(GL_LINES)
                glColor3f(wire_color[0], wire_color[1], wire_color[2])
                for vert_i, vert1 in enumerate(face):
                    if vert_i + 1 == len(face):
                        vert2 = face[0]
                    else:
                        vert2 = face[vert_i + 1]
                    if face_transforms:
                        trans1 = mat
                        trans2 = mat
                        vec1 = Vector(vertices[vert1])
                        vec2 = Vector(vertices[vert2])
                        for transformation in face_transforms:
                            if vert1 in transformation[1]:
                                trans1 = trans1 * transformation[0]
                            if vert2 in transformation[1]:
                                trans2 = trans2 * transformation[0]
                        glVertex3f(*(trans1 * vec1))
                        glVertex3f(*(trans2 * vec2))
                    else:
                        glVertex3f(*(mat * Vector(vertices[vert1])))
                        glVertex3f(*(mat * Vector(vertices[vert2])))
                glEnd()
                glDisable(GL_LINE_STIPPLE)
                # glLineWidth(1.0)
    if 0:  # DEBUG: draw points from faces geometry
        glPointSize(3.0)
        glBegin(GL_POINTS)
        glColor3f(0.5, 0.5, 1)
        for vertex_i, vertex in enumerate(vertices):
            vec = Vector(vertex)
            if face_transforms:
                trans = mat
                for transformation in face_transforms:
                    if vertex_i in transformation[1]:
                        trans = trans * transformation[0]
                glVertex3f(*(trans * vec))
            else:
                glVertex3f(*(mat * vec.to_3d()))
        glEnd()
        glPointSize(1.0)
    if 0:  # DEBUG: draw points from lines geometry
        if wire_lines:
            glPointSize(3.0)
            glBegin(GL_POINTS)
            glColor3f(1, 0, 0.5)
            vert_i_global = 0
            for line in wire_lines:
                for vert_i, vertex in enumerate(line):
                    if vert_i + 1 < len(line):
                        vec = Vector(vertex)
                    else:
                        continue
                    if wire_transforms:
                        trans = mat
                        for transformation in wire_transforms:
                            if vert_i_global in transformation[1]:
                                trans = trans * transformation[0]
                        glVertex3f(*(trans * vec.to_3d()))
                    else:
                        glVertex3f(*(mat * vec.to_3d()))
                    vert_i_global += 1
                vert_i_global += 1
            glEnd()
            glPointSize(1.0)
Example #6
0
    def texdata(self, face, mesh, obj):
        mat = None
        width = height = 64
        if obj.material_slots:
            mat = obj.material_slots[face.material_index].material
        if mat:
            for node in mat.node_tree.nodes:
                if node.type == 'TEX_IMAGE':
                    width, height = node.image.size
                    break
            texstring = mat.name
        else:
            texstring = self.option_skip

        V = [loop.vert.co for loop in face.loops]
        uv_layer = mesh.loops.layers.uv.active
        if uv_layer is None:
            uv_layer = mesh.loops.layers.uv.new("dummy")
        T = [loop[uv_layer].uv for loop in face.loops]

        # UV handling ported from: https://bitbucket.org/khreathor/obj-2-map

        if self.option_format == 'Valve':
            # [ Ux Uy Uz Uoffs ] [ Vx Vy Vz Voffs ] rotation scaleU scaleV
            dummy = ' [ 1 0 0 0 ] [ 0 -1 0 0 ] 0 1 1\n'

            height = -height  # workaround for flipped v

            # Set up "2d world" coordinate system with the 01 edge along X
            world01 = V[1] - V[0]
            world02 = V[2] - V[0]

            if world01.length < 0.00001 or world02.length < 0.00001:
                world01_02Angle = 0
            else:
                world01_02Angle = world01.angle(world02)

            if face.normal.dot(world01.cross(world02)) < 0:
                world01_02Angle = -world01_02Angle
            world01_2d = Vector((world01.length, 0.0))
            world02_2d = Vector((math.cos(world01_02Angle),
                                 math.sin(world01_02Angle))) * world02.length

            # Get 01 and 02 vectors in UV space and scale them
            tex01 = T[1] - T[0]
            tex02 = T[2] - T[0]
            tex01.x *= width
            tex02.x *= width
            tex01.y *= height
            tex02.y *= height
            '''
            a = world01_2d
            b = world02_2d
            p = tex01
            q = tex02

            [ px ]   [ m11 m12 0 ] [ ax ]
            [ py ] = [ m21 m22 0 ] [ ay ]
            [ 1  ]   [ 0   0   1 ] [ 1  ]

            [ qx ]   [ m11 m12 0 ] [ bx ]
            [ qy ] = [ m21 m22 0 ] [ by ]
            [ 1  ]   [ 0   0   1 ] [ 1  ]

            px = ax * m11 + ay * m12
            py = ax * m21 + ay * m22
            qx = bx * m11 + by * m12
            qy = bx * m21 + by * m22

            [ px ]   [ ax ay 0  0  ] [ m11 ]
            [ py ] = [ 0  0  ax ay ] [ m12 ]
            [ qx ]   [ bx by 0  0  ] [ m21 ]
            [ qy ]   [ 0  0  bx by ] [ m22 ]
            '''

            # Find an affine transformation to convert
            # world01_2d and world02_2d to their respective UV coords
            texCoordsVec = Vector((tex01.x, tex01.y, tex02.x, tex02.y))
            world2DMatrix = Matrix(((world01_2d.x, world01_2d.y, 0,
                                     0), (0, 0, world01_2d.x, world01_2d.y),
                                    (world02_2d.x, world02_2d.y, 0,
                                     0), (0, 0, world02_2d.x, world02_2d.y)))
            try:
                mCoeffs = solve(world2DMatrix, texCoordsVec)
            except:
                return texstring + dummy
            right_2dworld = Vector(mCoeffs[0:2])
            up_2dworld = Vector(mCoeffs[2:4])

            # These are the final scale values
            # (avoid division by 0 for degenerate or missing UVs)
            scalex = 1 / max(0.00001, right_2dworld.length)
            scaley = 1 / max(0.00001, up_2dworld.length)
            scale = Vector((scalex, scaley))

            # Get the angles of the texture axes. These are in the 2d world
            # coordinate system, so they're relative to the 01 vector
            right_2dworld_angle = math.atan2(right_2dworld.y, right_2dworld.x)
            up_2dworld_angle = math.atan2(up_2dworld.y, up_2dworld.x)

            # Recreate the texture axes in 3d world coordinates,
            # using the angles from the 01 edge
            rt = world01.normalized()
            up = rt.copy()
            rt.rotate(Matrix.Rotation(right_2dworld_angle, 3, face.normal))
            up.rotate(Matrix.Rotation(up_2dworld_angle, 3, face.normal))

            # Now we just need the offsets
            rt_full = rt.to_4d()
            up_full = up.to_4d()
            test_s = V[0].dot(rt) / (width * scale.x)
            test_t = V[0].dot(up) / (height * scale.y)
            rt_full[3] = (T[0].x - test_s) * width
            up_full[3] = (T[0].y - test_t) * height

            texstring += f" [ {self.printvec(rt_full)} ]"\
                        f" [ {self.printvec(up_full)} ]"\
                        f" 0 {self.printvec(scale)}\n"

        elif self.option_format == 'Quake':
            # offsetU offsetV rotation scaleU scaleV
            dummy = ' 0 0 0 1 1\n'

            # 01 and 02 in 3D space
            world01 = V[1] - V[0]
            world02 = V[2] - V[0]

            # 01 and 02 projected along the closest axis
            maxn = max(abs(round(crd, 5)) for crd in face.normal)
            for i in [2, 0, 1]:  # axis priority for 45 degree angles
                if round(abs(face.normal[i]), 5) == maxn:
                    axis = i
                    break
            world01_2d = Vector((world01[:axis] + world01[(axis + 1):]))
            world02_2d = Vector((world02[:axis] + world02[(axis + 1):]))

            # 01 and 02 in UV space (scaled to texture size)
            tex01 = T[1] - T[0]
            tex02 = T[2] - T[0]
            tex01.x *= width
            tex02.x *= width
            tex01.y *= height
            tex02.y *= height

            # Find affine transformation between 2D and UV
            texCoordsVec = Vector((tex01.x, tex01.y, tex02.x, tex02.y))
            world2DMatrix = Matrix(((world01_2d.x, world01_2d.y, 0,
                                     0), (0, 0, world01_2d.x, world01_2d.y),
                                    (world02_2d.x, world02_2d.y, 0,
                                     0), (0, 0, world02_2d.x, world02_2d.y)))
            try:
                mCoeffs = solve(world2DMatrix, texCoordsVec)
            except:
                return texstring + dummy

            # Build the transformation matrix and decompose it
            tformMtx = Matrix(((mCoeffs[0], mCoeffs[1], 0),
                               (mCoeffs[2], mCoeffs[3], 0), (0, 0, 1)))
            t0 = Vector((T[0].x * width, T[0].y * height)).to_3d()
            v0 = Vector((V[0][:axis] + V[0][(axis + 1):])).to_3d()

            offset = t0 - (tformMtx @ v0)
            rotation = math.degrees(tformMtx.inverted_safe().to_euler().z)
            scale = tformMtx.inverted_safe().to_scale()  # always positive

            # Compare normals between UV and projection to get the scale sign
            tn = tex01.to_3d().cross(tex02.to_3d())
            vn = world01_2d.to_3d().cross(world02_2d.to_3d())
            if tn.dot(vn) < 0: scale.x *= -1

            # fudge
            offset.x += width
            offset.y *= -1

            finvals = [offset.x, offset.y, rotation, scale.x, scale.y]
            texstring += f" {self.printvec(finvals)}\n"

        return texstring
Example #7
0
class Ant(bge.types.BL_ArmatureObject):
    
    antlist = []
    
    def __init__(self, own):
        self["ant_init"] = True
        Ant.antlist.append(self)
        
        bge.logic.globalDict["pop"] = len(Ant.antlist)
        
        
        # Modes:
        
        # DROP: drop off self.carrying at an appropriate building
        # GOGET: go to self.collect
        # GOTO: go to self.target
        # GOBACK: go to 0,0
        
        self.mode = "GOTO"
        
        self.idle = True
        
        self.target = Vector((0, 0))

        self.collect = None
        # useful to store this in case self.collect becomes invalid due to being used up
        self.collect_category = None
        
        self.carrying = None
        self.carry_type = None
        self.carry_category = None
        
        self.destination = None
        
        self.vision_distance = 5
        self.stopping_margin = .5
        
        self.acceleration = .005
        self.max_speed = .1
        #self.max_turning_speed
        self.near_sens = self.sensors["Near"]
        
        self.zoffset = self.worldPosition.copy().z
        
        self.nearest_ant = 100
        
        self.speed = 0
        self.target_direction = Vector((0, -1, 0))
        self.direction = self.getAxisVect((0,-1,0))
        
        #self.wander_direction = Vector((.5,.5))
        
        self.currently_considering = 0
        
        self.ticks_since_last_meal = random.randint(0, 600)
        self.return_home_timer = None
    
    def eat(self):
        if self.ticks_since_last_meal > 900:
            if bge.logic.globalDict["food"] > 0:
                bge.logic.globalDict["food"] -= 1
                bge.logic.sendMessage("GUI")

                self.ticks_since_last_meal = 0
            else:
                # go without food
                self.ticks_since_last_meal = 0
                if random.random() < .3:
                    bge.logic.sendMessage("notify", "An ant starved!")
                    self.die()
                else:
                    bge.logic.sendMessage("notify", "An ant is hungry")

        self.ticks_since_last_meal += 1
        
    def die(self):
        if self.carrying is not None:
            self.carrying.endObject()
            self.carrying = None
            
        for o in self.children:
            o.endObject()
            
        Ant.antlist.remove(self)
        
        bge.logic.globalDict["pop"] = len(Ant.antlist)
        bge.logic.sendMessage("GUI")
        self.endObject()
        
    def towards_target(self):
        dist, vect, lvect = self.getVectTo(self.target.to_3d())
        
        vect.normalize()

        if dist < self.vision_distance:
            # apply braking force proportional to distance
            vect = vect - (vect * min((dist/-self.vision_distance) + 1/self.vision_distance + self.stopping_margin, 1))
            self.stopping_margin = min(self.stopping_margin +.01, 1)
        else:
            self.stopping_margin = .5
            pass
        
        return vect
    
    
    def around_obstacles(self):        
        here = self.worldPosition
        ahead = self.worldPosition + self.direction * self.vision_distance
        
        obstacle = self.rayCastTo(ahead, self.vision_distance, "obstacle")
        if obstacle:
            dist, go_around, l = self.getVectTo(obstacle)
            
            if dist < self.vision_distance:
                # apply braking force proportional to distance
                go_around = go_around - (go_around * min((dist/-self.vision_distance) + 1/self.vision_distance + self.stopping_margin, 1))
            
            return -go_around
        
        else:
            return Vector((0,0,0))
        
    def separate(self):
        # in case of death
        if len(Ant.antlist) <= self.currently_considering:
            self.currently_considering = 0
            
        if Ant.antlist[self.currently_considering] != self:
            next_ant = Ant.antlist[self.currently_considering]
        else:
            self.currently_considering = (self.currently_considering + 1) % len(Ant.antlist)
            next_ant = Ant.antlist[self.currently_considering]
        
        dist, vect, lvect = self.getVectTo(next_ant)
        
        if dist < self.nearest_ant:
            self.nearest_ant = dist
        
        self.currently_considering = (self.currently_considering + 1) % len(Ant.antlist)
        
        if self.nearest_ant < .5 and vect:
            #bge.render.drawLine(self.worldPosition, self.worldPosition + vect*10 , (.3, 0, 1))
            self.nearest_ant = 100
            return -vect
        else:
            return Vector((0,0,0))
        
        
    def wander(self):
        t = bge.logic.getRealTime()
        v = Vector((t, t, t)) + self.worldPosition
        n = noise.noise_vector(v)
        
        #return self.wander_direction
        return n.to_2d()
        
    
    def move(self):
        if not self.isPlayingAction():
            self.playAction("antwalking", 0, 12, 0, 0, 0, bge.logic.KX_ACTION_MODE_LOOP)
        
        self.setActionFrame((self.getActionFrame()+self.direction.length)%12)
        
        if not self.direction.length < 0.000001:
            self.alignAxisToVect(-self.direction, 1)
        
        self.worldPosition += self.direction * self.max_speed
        
        
    def find_nearest(self, ids):
        nearest_dist = 300
        nearest_dest = None
        for dest in bge.logic.getCurrentScene().objects:
            for id in ids:
                if dest.get("id", None) == id:
                    dist = (dest.worldPosition - self.worldPosition).length
                    if dist < nearest_dist:
                        nearest_dist = dist
                        nearest_dest = dest

        return nearest_dest
    
    
    def update_workercount(self, recount=False):
        gd = bge.logic.globalDict
        print(gd["idleworkers"])
        if recount:
            gd["foodworkers"] = 0
            gd["materialworkers"] = 0
            gd["scienceworkers"] = 0
            gd["idleworkers"] = 0
            
            for ant in Ant.antlist:
                if ant.collect is not None and not ant.collect.invalid:
                    print(ant.collect["category"])
                    gd[ant.collect["category"] + "workers"] += 1
                else:
                    gd["idleworkers"] += 1
                    
        else:
            if self.collect:
                gd[self.collect["category"] + "workers"] += 1
            else:
                gd["idleworkers"] += 1
                    
        bge.logic.sendMessage("GUI")
    
    
    def go_to(self, coords):
        self.target = coords.copy()
        self.mode = "GOTO"
        
    
    def go_get(self, obj):
        if self.carrying is not None:
            # need to drop something off first
            self.go_drop()
            if obj is not None:
                self.collect = obj
        else:
            if obj is not None:
                self.collect = obj
                self.target = self.collect.worldPosition.copy()
                self.mode = "GOGET"
            else:
                self.collect = None
                self.collect_category = None
                self.go_back()
                
        
        #self.update_workercount()
        
            
    def go_back(self):
        self.return_home_timer = None
        self.go_to(Vector((0,-3,0)))
        
        
    def go_drop(self):
        # determine nearest possible dropoff point
        destination = None
        if self.carry_type == "leaf":
            destination = self.find_nearest(['Farm'])
        elif self.carry_type == "honey":
            destination = self.find_nearest(['Honey Den'])    
        else:
            destination = self.find_nearest(['Storage', 'Den'])
        
        # if there's no special buildings to deliver to, a generic one will do    
        if destination is None:
            destination = self.find_nearest(['Storage', 'Den'])
        
        # if *still* none we now have a real problem
        if destination is None:
            bge.logic.sendMessage("notify", "Nowhere to store resources!!")
        
        self.destination = destination
        self.target = self.destination.worldPosition.copy()
        self.mode = "DROP"
        
        
    def main(self):
        scene = bge.logic.getCurrentScene()
        for s in bge.logic.getSceneList():
            if s.name == "wait for pause":
                pscene = s
        
        # check for invalid gameobject references
        if self.collect is not None and self.collect.invalid:
            self.collect = None
        if self.destination is not None and self.destination.invalid:
            self.destination = None
        
        # order taking
        if not scene.objects["Placement_Empty"]['BuildModeActive'] and pscene.objects["OpenMenuControls"]["OpenMenus?"]:
            if self["selected"]:
                if self.sensors["Click"].positive:
                    if self.sensors["CanGo"].positive:
                        
                        obj, hitPoint, normal = self.rayCast(self.sensors["CanGo"].rayTarget, self.sensors["CanGo"].raySource, 300)
                        
                        # only resources have a "points" property
                        if "points" in obj:
                            self.go_get(obj)

                        else:
                            self.go_to(self.sensors["CanGo"].hitPosition)
                    
        
        # decision making
        
        if self.mode == "GOTO":
            if self.return_home_timer is not None:
                #counting away the ticks
                self.return_home_timer -= 1
            
            #have we arrived (away from home)?
            if (Vector((0,-3,0)) - self.target).length > 1.5:
                if (self.worldPosition - self.target).length < 1.5:

                    if self.return_home_timer is not None and self.return_home_timer < 1:
                        self.go_back()
                    elif self.return_home_timer is None:
                        self.return_home_timer = 60 * 10
                    
        
        elif self.mode == "GOGET":
            # is there still something to collect?
            if self.collect is not None:
                # go get resource
                if (self.worldPosition - self.collect.worldPosition).length < 1.5:
                        
                    if self.collect["points"] > 0:
                        self.collect["points"] -= 1
                        
                        self.carry_type = self.collect["type"]
                        self.carry_category = self.collect["category"]
                        self.carrying = scene.addObject(self.carry_type + "fragment", self)
#                        if self.collect_type == "honey":
#                            print("replacing mesh")
#                            self.replaceMesh("Cube.001")
                    
                    # if we grabbed the last one, make resource vanish
                    if self.collect["points"] <= 0:
                
                        self.collect.parent.endObject()
                        self.collect.endObject()  
                        
                    self.go_drop()
                        
            else:
                #send him back
                #self.update_workercount(recount=True)
                self.go_get(None)
                self.go_back()
                
            
        elif self.mode == "DROP":
            # return with resource
            if (self.worldPosition - self.destination.worldPosition).length < 1.5:
                
                if self.carry_category == "food":
                    if "stored" in self.destination:
                        self.destination['stored'] += 1
                    else:
                        increase_resource(self, "food")
                else:
                    increase_resource(self, self.carry_category)
                
                if self.carrying:
                    self.carrying.endObject()
                    self.carrying = None
                
                # go back for more
                self.go_get(self.collect)
                
            
        elif self.mode == "GOBACK":
            # if resource is gone but we still are carrying some around
            if self.carrying is not None:
                self.mode = "DROP"
            
        if self.carrying is not None and not self.carrying.invalid:
            self.carrying.worldPosition = self.worldPosition                

        
        
        # other stuff        
        
        # insist upon being at ground level at all times
        obj, hitpoint, normal = self.rayCast(self.worldPosition + Vector((0,0,-1)), self.worldPosition + Vector((0,0,1)), 10, "Ground", 0, 1)
        self.worldPosition.z = hitpoint.z + self.zoffset
        self.alignAxisToVect(normal, 2)
        
        #self.accelerate()
        
        #bge.render.drawLine(self.worldPosition, self.target.to_3d(), (1, 1, 1))
        
        o = self.around_obstacles()
        t = self.towards_target()
        s = self.separate()
        w = self.wander()
        
        self.target_direction = o.to_2d() + t.to_2d() + s.to_2d()
        self.target_direction = self.target_direction + (w.to_2d() * self.target_direction.length)
        self.target_direction.resize_3d()
        self.target_direction.normalize()
        
        #bge.render.drawLine(self.worldPosition, self.worldPosition + self.target_direction*10, (1, 0, 0))
        
        self.direction = self.direction.lerp(self.target_direction, .05)
        
        self.move()
        self.eat()
Example #8
0
    def build_matrix(self):

        #the largest dimeions of image is scaled to 1 blender unit
        #in the empty image
        #unsure how things work with non square pixels
        img_scl = 1 / max([self.image.size[0], self.image.size[1]])

        print('the world unit to pixel scale is')
        print(img_scl)

        #Condyle Position
        center = Vector((self.pixel_coords[0][0],
                         self.image.size[1] - self.pixel_coords[0][1]))

        tV = -img_scl * center.to_3d()
        T = Matrix.Translation(tV)

        #Frankfurt Horizontal is desired to align with X axis
        X = self.pixel_coords[1] - self.pixel_coords[0]
        X[1] = -X[1]  #the Y coodinates go from the top down
        print(X)
        X.normalize()
        X = X.to_3d()

        #The Image Z should ultimately be the world -Y
        Y = Vector((0, 0, -1))

        Z = X.cross(Y)

        #build a rotation matrix from x,y,z
        R = Matrix.Identity(3)  #make the columns of matrix U, V, W
        R[0][0], R[0][1], R[0][2] = X[0], Y[0], Z[0]
        R[1][0], R[1][1], R[1][2] = X[1], Y[1], Z[1]
        R[2][0], R[2][1], R[2][2] = X[2], Y[2], Z[2]

        Q = R.to_quaternion()
        Qi = Q.inverted()

        Rqi = Qi.to_matrix().to_4x4()
        Rr = R.to_4x4()
        Ri = R.to_4x4().inverted()

        #scale factor and occlusal plane
        vy = self.pixel_coords[3] - self.pixel_coords[2]
        #remember dumb y axis is top down
        vy[1] = -vy[1]

        scl_x = 100 / vy.length / img_scl

        vz = self.pixel_coords[4] - self.pixel_coords[5]
        scl_y = 40 / vz.length / img_scl

        print('Are scl_x and scl_y close?')
        print((scl_x, scl_y))

        scl_final = .5 * (scl_x + scl_y)

        S = Matrix.Identity(4)
        S[0][0], S[1][1] = scl_final, scl_final

        self.empty.matrix_world = Ri * S * T

        return