コード例 #1
0
def pointInTri2D(v, v1, v2, v3):
    global dict_matrix

    key = v1.x, v1.y, v2.x, v2.y, v3.x, v3.y

    # Commented because its slower to do teh bounds check, we should realy cache the bounds info for each face.
    '''
	# BOUNDS CHECK
	xmin= 1000000
	ymin= 1000000
	
	xmax= -1000000
	ymax= -1000000
	
	for i in (0,2,4):
		x= key[i]
		y= key[i+1]
		
		if xmax<x:	xmax= x
		if ymax<y:	ymax= y
		if xmin>x:	xmin= x
		if ymin>y:	ymin= y	
	
	x= v.x
	y= v.y
	
	if x<xmin or x>xmax or y < ymin or y > ymax:
		return False
	# Done with bounds check
	'''
    try:
        mtx = dict_matrix[key]
        if not mtx:
            return False
    except:
        side1 = v2 - v1
        side2 = v3 - v1

        nor = side1.cross(side2)

        l1 = [side1[0], side1[1], side1[2]]
        l2 = [side2[0], side2[1], side2[2]]
        l3 = [nor[0], nor[1], nor[2]]

        mtx = Matrix(l1, l2, l3)

        # Zero area 2d tri, even tho we throw away zerop area faces
        # the projection UV can result in a zero area UV.
        if not mtx.determinant():
            dict_matrix[key] = None
            return False

        mtx.invert()

        dict_matrix[key] = mtx

    uvw = (v - v1) * mtx
    return 0 <= uvw[0] and 0 <= uvw[1] and uvw[0] + uvw[1] <= 1
コード例 #2
0
def pointInTri2D(v, v1, v2, v3):
    global dict_matrix

    key = v1.x, v1.y, v2.x, v2.y, v3.x, v3.y

    # Commented because its slower to do teh bounds check, we should realy cache the bounds info for each face.
    """
	# BOUNDS CHECK
	xmin= 1000000
	ymin= 1000000
	
	xmax= -1000000
	ymax= -1000000
	
	for i in (0,2,4):
		x= key[i]
		y= key[i+1]
		
		if xmax<x:	xmax= x
		if ymax<y:	ymax= y
		if xmin>x:	xmin= x
		if ymin>y:	ymin= y	
	
	x= v.x
	y= v.y
	
	if x<xmin or x>xmax or y < ymin or y > ymax:
		return False
	# Done with bounds check
	"""
    try:
        mtx = dict_matrix[key]
        if not mtx:
            return False
    except:
        side1 = v2 - v1
        side2 = v3 - v1

        nor = side1.cross(side2)

        l1 = [side1[0], side1[1], side1[2]]
        l2 = [side2[0], side2[1], side2[2]]
        l3 = [nor[0], nor[1], nor[2]]

        mtx = Matrix(l1, l2, l3)

        # Zero area 2d tri, even tho we throw away zerop area faces
        # the projection UV can result in a zero area UV.
        if not mtx.determinant():
            dict_matrix[key] = None
            return False

        mtx.invert()

        dict_matrix[key] = mtx

    uvw = (v - v1) * mtx
    return 0 <= uvw[0] and 0 <= uvw[1] and uvw[0] + uvw[1] <= 1
コード例 #3
0
ファイル: ac3d_import.py プロジェクト: animuxOS/Genesis64
	def parse_rot(self, trash):
		i = self.i - 1
		ob = self.objlist[-1]
		rot = self.lines[i].split(' ', 1)[1]
		rot = map(float, rot.split())
		matrix = Matrix(rot[:3], rot[3:6], rot[6:])
		ob.rot = matrix
		size = matrix.scalePart() # vector
		ob.size = size
コード例 #4
0
ファイル: acc3d_import.py プロジェクト: rongzhou/speed-dreams
	def parse_rot(self, trash):
		i = self.i - 1
		ob = self.objlist[-1]
		rot = self.lines[i].split(' ', 1)[1]
		rot = map(float, rot.split())
		matrix = Matrix(rot[:3], rot[3:6], rot[6:])
		ob.rot = matrix
		size = matrix.scalePart() # vector
		ob.size = size
コード例 #5
0
def MatrixrotationOnly(mm, object):
    try:
        sx = 1 / abs(object.SizeX)
        sy = 1 / abs(object.SizeY)
        sz = 1 / abs(object.SizeZ)
        return Matrix([mm[0][0] * sx, mm[0][1] * sx, mm[0][2] * sx, 0],
                      [mm[1][0] * sy, mm[1][1] * sy, mm[1][2] * sy, 0],
                      [mm[2][0] * sz, mm[2][1] * sz, mm[2][2] * sz, 0],
                      [0, 0, 0, 1])
    except:
        # Normals are screwed by zero scale - just return anything
        return Matrix().identity().resize4x4()
コード例 #6
0
def VectoMat(vec):
    a3 = vec.__copy__().normalize()

    up = Vector(0, 0, 1)
    if abs(a3.dot(up)) == 1.0:
        up = Vector(0, 1, 0)

    a1 = a3.cross(up).normalize()
    a2 = a3.cross(a1)
    return Matrix([a1[0], a1[1], a1[2]], [a2[0], a2[1], a2[2]],
                  [a3[0], a3[1], a3[2]])
コード例 #7
0
def addattach(scene, name, matrix):
    if name.startswith('attachpt_'): name=name[9:]
    if not name: name='AttachPoint'
    obj=Object.New('Empty', name)
    scene.objects.link(obj)
    obj.layers=[1]
    obj.addProperty('name', obj.name)

    # Need to convert between right and left handed coordinate systems.
    obj.setMatrix(RotationMatrix(-90,4,'x')*matrix*Matrix([1,0,0,0],[0,0,1,0],[0,-1,0,0],[0,0,0,1]))
    obj.LocY=-obj.LocY


    return obj
コード例 #8
0
def saveBR2(filename):
	if not filename.lower().endswith('.br2'):
		filename += '.br2'
	
	if not BPyMessages.Warning_SaveOver(filename):
		return
	
	print "Start BR2 Export..."
	Blender.Window.WaitCursor(1)
	file = open( filename, 'wb')
	
	scene = Blender.Scene.GetCurrent()
	allObjects = scene.objects
	
	filedata = "// Nexus Buddy BR2 - Exported from Blender for import to Nexus Buddy 2\n"
	
	modelObs = {}
	modelMeshes = {}
	
	# will need list of these for multi-skeleton
	boneIds = {}
	
	for object in allObjects:
		if object.type == 'Armature':
			modelObs[object.name] = object
			
		if object.type == 'Mesh':
			print "Getting parent for mesh: %s" % object.name
			parentArmOb = BPyObject.getObjectArmature(object)
			if not parentArmOb.name in modelMeshes:
				modelMeshes[parentArmOb.name] = []
			modelMeshes[parentArmOb.name].append(object)

	for modelObName in modelObs.keys():
	
		# Write Skeleton
		filedata += "skeleton\n"
			
		armOb = modelObs[modelObName]
		armature = armOb.data
		
		# Calc bone depths and sort
		boneDepths = []
		for bone in armature.bones.values():
			boneDepth = getBoneTreeDepth(bone, 0)
			boneDepths.append((bone, boneDepth))
		
		boneDepths = sorted(boneDepths, key=lambda k: k[0].name)
		boneDepths = sorted(boneDepths, key=lambda k: k[1])
		sortedBones = boneDepths
		
		for boneid, boneTuple in enumerate(sortedBones):
			boneIds[boneTuple[0].name] = boneid

		boneIds[armOb.name] = -1 # Add entry for World Bone
			
		# Write World Bone
		filedata += '%d "%s" %d ' % (0, armOb.name, -1)   
		filedata += '%.8f %.8f %.8f ' % (0.0, 0.0, 0.0)
		filedata += '%.8f %.8f %.8f %.8f ' % (0.0, 0.0, 0.0, 1.0)
		filedata += '%.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f\n' % (1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 0.0, 1.0)
		
		for boneid, boneTuple in enumerate(sortedBones):
			bone = boneTuple[0]
			boneDepth = boneTuple[1]
			#boneid = boneid + 1 # World bone is zero
			
			position, orientationQuat = getTranslationOrientation(bone)
			
			# Get Inverse World Matrix for bone
			t = bone.matrix['ARMATURESPACE'].copy().invert()
			invWorldMatrix = Matrix([t[0][1], -t[0][0], t[0][2], t[0][3]],
								[t[1][1], -t[1][0], t[1][2], t[1][3]],
								[t[2][1], -t[2][0], t[2][2], t[2][3]],
								[t[3][1], -t[3][0], t[3][2], t[3][3]])
			
			outputBoneName = bone.name
			if len(outputBoneName) == 29:
				for item in armOb.getAllProperties():
					if (("B_" + outputBoneName) == item.getName()):
						outputBoneName = item.getData()
						print 'Decode Bone Name: "%s" >' % item.getName()
						print '                  "%s"' % item.getData()
						break
			
			filedata += '%d "%s" ' % (boneid + 1, outputBoneName)   # Adjust bone ids + 1 as zero is the World Bone
			
			parentBoneId = 0
			if bone.hasParent():
				parentBoneId = boneIds[bone.parent.name] + 1   # Adjust bone ids + 1 as zero is the World Bone
			
			filedata += '%d ' % parentBoneId
			filedata +='%.8f %.8f %.8f ' % (position[0], position[1] , position[2])
			filedata +='%.8f %.8f %.8f %.8f ' % (orientationQuat[1], orientationQuat[2], orientationQuat[3], orientationQuat[0]) # GR2 uses x,y,z,w for Quaternions rather than w,x,y,z
			filedata += '%.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f %.8f' % (
								invWorldMatrix[0][0], invWorldMatrix[0][1], invWorldMatrix[0][2], invWorldMatrix[0][3], 
								invWorldMatrix[1][0], invWorldMatrix[1][1], invWorldMatrix[1][2], invWorldMatrix[1][3],
								invWorldMatrix[2][0], invWorldMatrix[2][1], invWorldMatrix[2][2], invWorldMatrix[2][3],
								invWorldMatrix[3][0], invWorldMatrix[3][1], invWorldMatrix[3][2], invWorldMatrix[3][3])
			#End of bone line
			filedata += "\n"
		
		filedata += 'meshes:%d\n' % len(modelMeshes[modelObName])
		
		for meshObject in modelMeshes[modelObName]:
			
			mesh = meshObject.data
			meshName = meshObject.name
			
			filedata += 'mesh:"%s"\n' % meshName
			
			parentArmOb = BPyObject.getObjectArmature(meshObject)
			
			# Fetch long mesh names from Armature properties
			if len(meshName) == 19:
				for item in parentArmOb.getAllProperties():
					if ("M_" + meshName == item.getName()):
						meshName = item.getData()
						print 'Decode Mesh Name: %s > %s' % (item.getName(), item.getData())
						break
			
			#file.write('meshname:%s\n' % meshName)
			#file.write('parent Arm:%s\n' % parentArmOb)
			
			weights = meshNormalizedWeights(mesh)
			vertexBoneWeights = {}
			for boneName in boneIds.keys():
				vgroupDataForBone = getBoneWeights(boneName, weights)
				#file.write('bone:%s vg:%s\n' % (boneName, vgroupDataForBone))
				
				for vgData in vgroupDataForBone:
					vertexId = vgData[0]
					weight = vgData[1]
					if not vertexId in vertexBoneWeights:
						vertexBoneWeights[vertexId] = []
					vertexBoneWeights[vertexId].append((boneName, weight))
					#file.write('vert:%d bone:%s \n' % (vertexId, (boneName, weight)))
			
			grannyVertexBoneWeights = {}
			for vertId in vertexBoneWeights.keys():
				#file.write('vert:%d ' % vertId)
				
				rawBoneIdWeightTuples = []
				firstBoneId = 0
				for i in range(max(4,len(vertexBoneWeights[vertId]))):
					if i < len(vertexBoneWeights[vertId]):
						vertexBoneWeightTuple = vertexBoneWeights[vertId][i]
						boneName = vertexBoneWeightTuple[0]
						rawBoneIdWeightTuples.append((boneIds[boneName] + 1, vertexBoneWeightTuple[1]))
						if i == 0:
							firstBoneId = boneIds[boneName] + 1
					else:
						rawBoneIdWeightTuples.append((firstBoneId, 0))
				
				# Sort bone mappings by weight highest to lowest
				sortedBoneIdWeightTuples = sorted(rawBoneIdWeightTuples, key=lambda rawBoneIdWeightTuple: rawBoneIdWeightTuple[1], reverse=True)
				
				#if len(vertexBoneWeights[vertId]) > 4:
				#	print  "len(vertexBoneWeights[vertId]): %s" % len(vertexBoneWeights[vertId])
				#	print  "sortedBoneIdWeightTuples: %s" % sortedBoneIdWeightTuples
				
				# Pick first four highest weighted bones
				boneIdsList = []
				rawBoneWeightsList = []
				for i in range(4): 
					boneIdsList.append(sortedBoneIdWeightTuples[i][0])
					rawBoneWeightsList.append(sortedBoneIdWeightTuples[i][1])
				
				rawWeightTotal = 0
				for weight in rawBoneWeightsList:
					rawWeightTotal = rawWeightTotal + weight
				
				boneWeightsList = []
				for weight in rawBoneWeightsList:
					calcWeight = round(255 * weight / rawWeightTotal)
					boneWeightsList.append(calcWeight)
					
				# Ensure that total of vertex bone weights is 255
				runningTotal = 0
				for i, weight in enumerate(boneWeightsList):
					runningTotal = runningTotal + weight
					if runningTotal > 255:
						boneWeightsList[i] = weight - 1
						break
				
				if runningTotal < 255:
					boneWeightsList[0] = boneWeightsList[0] + 1
				
				runningTotal = 0
				for i, weight in enumerate(boneWeightsList):
					runningTotal = runningTotal + weight
				
				if runningTotal != 255:
					raise "Error: Vertex bone weights do not total 255!"
				
				if not vertId in grannyVertexBoneWeights:
					grannyVertexBoneWeights[vertId] = []
				grannyVertexBoneWeights[vertId] = (boneIdsList, boneWeightsList)
				
				#file.write('%s %s ' % (boneIdsList, boneWeightsList))
				#file.write("\n")
			
			position, orientationQuat = getTranslationOrientation(meshObject)
			
			#file.write('position:%.8f %.8f %.8f\n' % (position[0], position[1], position[2]))
			#file.write('orientationQuat:%.8f %.8f %.8f %.8f\n' % (orientationQuat[1], orientationQuat[2], orientationQuat[3], orientationQuat[0]))
			#file.write(meshName+"\n")
			
			filedata += "vertices\n"

			# Determine unique vertex/UVs for output
			uniqueVertSet = set()
			uniqueVertUVIndexes = {}
			uniqueVertUVs = []
			currentVertUVIndex = 0
			
			currentTriangleId = 0
			triangleVertUVIndexes = []
			
			for triangle in mesh.faces:
				vertIds = [v.index for v in triangle]
				vertIds = tuple(vertIds)
				triangleVertUVIndexes.append([])
				
				for i, uv in enumerate(triangle.uv):
					vertexId = vertIds[i]
					uvt = tuple(uv)
					vertSig = '%i|%.8f|%.8f' % (vertexId, uvt[0], uvt[1])
					
					if vertSig in uniqueVertSet:
						triangleVertUVIndex = uniqueVertUVIndexes[vertSig]
					else:
						uniqueVertSet.add(vertSig)
						uniqueVertUVIndexes[vertSig] = currentVertUVIndex
						uniqueVertUVs.append((vertexId, uvt[0], uvt[1]))
						triangleVertUVIndex = currentVertUVIndex
						currentVertUVIndex = currentVertUVIndex + 1
					
					triangleVertUVIndexes[currentTriangleId].append(triangleVertUVIndex)
				currentTriangleId = currentTriangleId + 1
			
			meshVerts = {}
			for i,vert in enumerate(mesh.verts):
				meshVerts[i] = vert
				
			# Write Vertices
			for uniqueVertUV in uniqueVertUVs:
			
				index = uniqueVertUV[0]
				vert = meshVerts[index]
				vertCoord = tuple(vert.co)
				vertNormal = tuple(vert.no)
				filedata +='%.8f %.8f %.8f ' % (vertCoord[0] + position[0], vertCoord[1] + position[1], vertCoord[2] +  position[2])
				filedata +='%.8f %.8f %.8f ' % vertNormal
				filedata +='%.8f %.8f ' % (uniqueVertUV[1], 1 - uniqueVertUV[2])

				if index in grannyVertexBoneWeights:
					vBoneWeightTuple = grannyVertexBoneWeights[index]
				else:
					raise "Error: Mesh has unweighted vertices!"
					#vBoneWeightTuple = ([-1,-1,-1,-1],[-1,-1,-1,-1]) # Unweighted vertex - raise error
				
				filedata +='%d %d %d %d ' % (vBoneWeightTuple[0][0], vBoneWeightTuple[0][1],vBoneWeightTuple[0][2],vBoneWeightTuple[0][3]) # Bone Ids
				filedata +='%d %d %d %d\n' % (vBoneWeightTuple[1][0], vBoneWeightTuple[1][1],vBoneWeightTuple[1][2],vBoneWeightTuple[1][3]) # Bone Weights
			
			# Write Triangles
			filedata += "triangles\n"
			for triangle in triangleVertUVIndexes:
				#filedata += '%i %i %i\n' % tuple(triangle)
				filedata += '%i %i %i\n' % (triangle[0],triangle[1],triangle[2])
	
	filedata += "end"
	file.write(filedata)
	file.close()
	Blender.Window.WaitCursor(0)
	print "End BR2 Export."
コード例 #9
0
def main():

    scn = bpy.data.scenes.active
    ob = scn.objects.active
    if not ob or ob.type != 'Mesh':
        return

    is_editmode = Window.EditMode()
    if is_editmode:
        Window.EditMode(0)

    mousedown_wait()  # so the menu items clicking dosnt trigger the mouseclick

    Window.DrawProgressBar(0.0, '')
    Window.DrawProgressBar(0.1, '(1 of 3) Click on a face corner')

    # wait for a click
    mouse_buttons = Window.GetMouseButtons()
    while not mouse_buttons & LMB:
        sys.sleep(10)
        mouse_buttons = Window.GetMouseButtons()

        # Allow for RMB cancel
        if mouse_buttons & RMB:
            return

    while mouse_buttons & LMB:
        sys.sleep(10)
        mouse_buttons = Window.GetMouseButtons()

    Window.DrawProgressBar(0.2, '(2 of 3 ) Click confirms the U coords')

    mousedown_wait()

    obmat = ob.matrixWorld
    screen_x, screen_y = Window.GetMouseCoords()
    mouseInView, OriginA, DirectionA = mouseViewRay(screen_x, screen_y, obmat)

    if not mouseInView or not OriginA:
        return

    me = ob.getData(mesh=1)

    # Get the face under the mouse
    face_click, isect, side = BPyMesh.pickMeshRayFace(me, OriginA, DirectionA)
    if not face_click:
        return

    proj_z_component = face_click.no
    if not face_click:
        return

    # Find the face vertex thats closest to the mouse,
    # this vert will be used as the corner to map from.
    best_v = None
    best_length = 10000000
    vi1 = None
    for i, v in enumerate(face_click.v):
        l = (v.co - isect).length
        if l < best_length:
            best_v = v
            best_length = l
            vi1 = i

    # now get the 2 edges in the face that connect to v
    # we can work it out fairly easerly
    if len(face_click) == 4:
        if vi1 == 0: vi2, vi3 = 3, 1
        elif vi1 == 1: vi2, vi3 = 0, 2
        elif vi1 == 2: vi2, vi3 = 1, 3
        elif vi1 == 3: vi2, vi3 = 2, 0
    else:
        if vi1 == 0: vi2, vi3 = 2, 1
        elif vi1 == 1: vi2, vi3 = 0, 2
        elif vi1 == 2: vi2, vi3 = 1, 0

    face_corner_main = face_click.v[vi1].co
    face_corner_a = face_click.v[vi2].co
    face_corner_b = face_click.v[vi3].co

    line_a_len = (face_corner_a - face_corner_main).length
    line_b_len = (face_corner_b - face_corner_main).length

    orig_cursor = Window.GetCursorPos()
    Window.SetCursorPos(face_corner_main.x, face_corner_main.y,
                        face_corner_main.z)

    SHIFT = Window.Qual.SHIFT
    MODE = 0  # firstclick, 1, secondclick
    mouse_buttons = Window.GetMouseButtons()

    project_mat = Matrix([0, 0, 0], [0, 0, 0], [0, 0, 0])

    def get_face_coords(f):
        f_uv = f.uv
        return [(v.co - face_corner_main, f_uv[i]) for i, v in enumerate(f.v)]

    if me.faceUV == False:
        me.faceUV = True

    coords = [(co, uv) for f in me.faces if f.sel
              for co, uv in get_face_coords(f)]

    coords_orig = [uv.copy() for co, uv in coords]
    USE_MODIFIER = using_modifier(ob)

    while 1:
        if mouse_buttons & LMB:
            if MODE == 0:
                mousedown_wait()
                Window.DrawProgressBar(
                    0.8, '(3 of 3 ) Click confirms the V coords')
                MODE = 1  # second click

                # Se we cont continually set the length and get float error
                proj_y_component_orig = proj_y_component.copy()
            else:
                break

        elif mouse_buttons & RMB:
            # Restore old uvs
            for i, uv_orig in enumerate(coords_orig):
                coords[i][1][:] = uv_orig
            break

        mouse_buttons = Window.GetMouseButtons()
        screen_x, screen_y = Window.GetMouseCoords()
        mouseInView, OriginA, DirectionA = mouseViewRay(
            screen_x, screen_y, obmat)

        if not mouseInView:
            continue

        # Do a ray tri intersection, not clipped by the tri
        new_isect = Intersect(face_corner_main, face_corner_a, face_corner_b,
                              DirectionA, OriginA, False)
        new_isect_alt = new_isect + DirectionA * 0.0001

        # The distance from the mouse cursor ray vector to the edge
        line_isect_a_pair = LineIntersect(new_isect, new_isect_alt,
                                          face_corner_main, face_corner_a)
        line_isect_b_pair = LineIntersect(new_isect, new_isect_alt,
                                          face_corner_main, face_corner_b)

        # SHIFT to flip the axis.
        is_shift = Window.GetKeyQualifiers() & SHIFT

        if MODE == 0:
            line_dist_a = (line_isect_a_pair[0] - line_isect_a_pair[1]).length
            line_dist_b = (line_isect_b_pair[0] - line_isect_b_pair[1]).length

            if line_dist_a < line_dist_b:
                proj_x_component = face_corner_a - face_corner_main
                y_axis_length = line_b_len
                x_axis_length = (line_isect_a_pair[1] -
                                 face_corner_main).length
            else:
                proj_x_component = face_corner_b - face_corner_main
                y_axis_length = line_a_len
                x_axis_length = (line_isect_b_pair[1] -
                                 face_corner_main).length

            proj_y_component = proj_x_component.cross(proj_z_component)

            proj_y_component.length = 1 / y_axis_length
            proj_x_component.length = 1 / x_axis_length

            if is_shift: proj_x_component.negate()

        else:
            proj_y_component[:] = proj_y_component_orig
            if line_dist_a < line_dist_b:
                proj_y_component.length = 1 / (line_isect_a_pair[1] -
                                               new_isect).length
            else:
                proj_y_component.length = 1 / (line_isect_b_pair[1] -
                                               new_isect).length

            if is_shift: proj_y_component.negate()

        # Use the existing matrix to make a new 3x3 projecton matrix
        project_mat[0][:] = -proj_y_component
        project_mat[1][:] = -proj_x_component
        project_mat[2][:] = proj_z_component

        # Apply the projection matrix
        for proj_co, uv in coords:
            uv[:] = (project_mat * proj_co)[0:2]

        if USE_MODIFIER:
            me.update()

        Window.Redraw(Window.Types.VIEW3D)

    Window.SetCursorPos(*orig_cursor)
    if is_editmode:
        Window.EditMode(1)

    Window.RedrawAll()
コード例 #10
0
ファイル: BPyWindow.py プロジェクト: Synric/synricproj
def mouseViewRay(screen_x, screen_y, localMatrix=None, useMid = False):
	
	# Constant function variables
	p = mouseViewRay.p
	d = mouseViewRay.d
	
	for win3d in Window.GetScreenInfo(Window.Types.VIEW3D): # we search all 3dwins for the one containing the point (screen_x, screen_y) (could be the mousecoords for example) 
		win_min_x, win_min_y, win_max_x, win_max_y = win3d['vertices']
		# calculate a few geometric extents for this window

		win_mid_x  = (win_max_x + win_min_x + 1.0) * 0.5
		win_mid_y  = (win_max_y + win_min_y + 1.0) * 0.5
		win_size_x = (win_max_x - win_min_x + 1.0) * 0.5
		win_size_y = (win_max_y - win_min_y + 1.0) * 0.5

		#useMid is for projecting the coordinates when we subdivide the screen into bins
		if useMid: # == True
			screen_x = win_mid_x
			screen_y = win_mid_y
		
		# if the given screencoords (screen_x, screen_y) are within the 3dwin we fount the right one...
		if (win_max_x > screen_x > win_min_x) and (  win_max_y > screen_y > win_min_y):
			# first we handle all pending events for this window (otherwise the matrices might come out wrong)
			Window.QHandle(win3d['id'])
			
			# now we get a few matrices for our window...
			# sorry - i cannot explain here what they all do
			# - if you're not familiar with all those matrices take a look at an introduction to OpenGL...
			pm	= Window.GetPerspMatrix()   # the prespective matrix
			pmi  = Matrix(pm); pmi.invert() # the inverted perspective matrix
			
			if (1.0 - epsilon < pmi[3][3] < 1.0 + epsilon):
				# pmi[3][3] is 1.0 if the 3dwin is in ortho-projection mode (toggled with numpad 5)
				hms = mouseViewRay.hms
				ortho_d = mouseViewRay.ortho_d
				
				# ortho mode: is a bit strange - actually there's no definite location of the camera ...
				# but the camera could be displaced anywhere along the viewing direction.
				
				ortho_d.x, ortho_d.y, ortho_d.z = Window.GetViewVector()
				ortho_d.w = 0
				
				# all rays are parallel in ortho mode - so the direction vector is simply the viewing direction
				#hms.x, hms.y, hms.z, hms.w = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0
				hms[:] = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0
				
				# these are the homogenious screencoords of the point (screen_x, screen_y) ranging from -1 to +1
				p=(hms*pmi) + (1000*ortho_d)
				p.resize3D()
				d[:] = ortho_d[:3]
				

			# Finally we shift the position infinitely far away in
			# the viewing direction to make sure the camera if outside the scene
			# (this is actually a hack because this function
			# is used in sculpt_mesh to initialize backface culling...)
			else:
				# PERSPECTIVE MODE: here everything is well defined - all rays converge at the camera's location
				vmi  = Matrix(Window.GetViewMatrix()); vmi.invert() # the inverse viewing matrix
				fp = mouseViewRay.fp
				
				dx = pm[3][3] * (((screen_x-win_min_x)/win_size_x)-1.0) - pm[3][0]
				dy = pm[3][3] * (((screen_y-win_min_y)/win_size_y)-1.0) - pm[3][1]
				
				fp[:] = \
				pmi[0][0]*dx+pmi[1][0]*dy,\
				pmi[0][1]*dx+pmi[1][1]*dy,\
				pmi[0][2]*dx+pmi[1][2]*dy
				
				# fp is a global 3dpoint obtained from "unprojecting" the screenspace-point (screen_x, screen_y)
				#- figuring out how to calculate this took me quite some time.
				# The calculation of dxy and fp are simplified versions of my original code
				#- so it's almost impossible to explain what's going on geometrically... sorry
				
				p[:] = vmi[3][:3]
				
				# the camera's location in global 3dcoords can be read directly from the inverted viewmatrix
				#d.x, d.y, d.z =normalize_v3(sub_v3v3(p, fp))
				d[:] = p.x-fp.x, p.y-fp.y, p.z-fp.z
				
				#print 'd', d, 'p', p, 'fp', fp
				
			
			# the direction vector is simply the difference vector from the virtual camera's position
			#to the unprojected (screenspace) point fp
			
			# Do we want to return a direction in object's localspace?
			
			if localMatrix:
				localInvMatrix = Matrix(localMatrix)
				localInvMatrix.invert()
				localInvMatrix_notrans = localInvMatrix.rotationPart()
				p = p * localInvMatrix
				d = d * localInvMatrix # normalize_v3
				
				# remove the translation from d
				d.x -= localInvMatrix[3][0]
				d.y -= localInvMatrix[3][1]
				d.z -= localInvMatrix[3][2]
				
			
			d.normalize()			
			'''
			# Debugging
			me = Blender.Mesh.New()
			me.verts.extend([p[0:3]])
			me.verts.extend([(p-d)[0:3]])
			me.edges.extend([0,1])
			ob = Blender.Scene.GetCurrent().objects.new(me)
			'''
			return True, p, d # Origin, Direction	
	
	# Mouse is not in any view, return None.
	return False, None, None
コード例 #11
0
ファイル: ac3d_import.py プロジェクト: animuxOS/Genesis64
	if TEXTURES_DIR[-1] != dirsep: TEXTURES_DIR = "%s%s" % (TEXTURES_DIR, dirsep)
	if oldtexdir != TEXTURES_DIR: update_registry()


VERBOSE = True
rd = Registry.GetKey('General', True)
if rd:
	if rd.has_key('verbose'):
		VERBOSE = rd['verbose']

	
errmsg = ""

# Matrix to align ac3d's coordinate system with Blender's one,
# it's a -90 degrees rotation around the x axis:
AC_TO_BLEND_MATRIX = Matrix([1, 0, 0], [0, 0, 1], [0, -1, 0])

AC_WORLD = 0
AC_GROUP = 1
AC_POLY = 2
AC_LIGHT = 3
AC_OB_TYPES = {
	'world': AC_WORLD,
	'group': AC_GROUP,
	'poly':  AC_POLY,
	'light':  AC_LIGHT
	}

AC_OB_BAD_TYPES_LIST = [] # to hold references to unknown (wrong) ob types

def inform(msg):
コード例 #12
0
def file_callback (filename):
    try:
        bgl=file(filename,'rb')
    except:
        Draw.PupMenu("ERROR%%t|Can't open %s" % filename)
        return

    bgldir=dirname(filename)

    guid=None
    friendly=None
    texnames=[]	# list of texture file names
    matlist=[]	# fs9 materials
    mats=[]	# list of Blender Materials
    inde=[]
    vert=[]
    tran=[]
    amap=[]	# fsx map
    scen=[]	# (child, peer, matrix, parent)

    data={}	# (material, vert, inde, scene) by LOD
    plat={}	# (surface, vertices) by scene
    atta=[]	# (name, scene)
    attobjs=[]
    atteffects=[]
    partcount=0

    Window.WaitCursor(1)
    Window.DrawProgressBar(0, "Opening ...")
    try:
        (c,size,endmdl)=container(bgl,0)
        assert (c=='RIFF')
        assert (bgl.read(4) in ['MDL9','MDLX'])
        while bgl.tell()<endmdl:
            (c,size,end1)=container(bgl,1)
            if c=='MDLG':	# FSX guid
                guid='{%x-%x-%x-%x%x-%x%x%x%x%x%x}' % unpack('<IHH8B',bgl.read(size))
                if debug: print guid
            elif c=='MDLH':
                if size==36:	# FS9 header
                    (size,reserved,reserved,radius,reserved,reserved,reserved,reserved,reserved)=unpack('<9I', bgl.read(size))
                    if debug: print radius
                else:
                    bgl.seek(size,1)
            elif c=='MDLN':	# FSX friendly name
                friendly=bgl.read(size).strip('\0').strip()
                if debug: print friendly
            elif c=='MDLD':	# FSX data
                while bgl.tell()<end1:
                    Window.DrawProgressBar(float(bgl.tell())/(endmdl+endmdl), "Reading ...")
                    (c,size,end2)=container(bgl,2)
                    if c=='TEXT':
                        texnames=[bgl.read(64).strip('\0').strip() for i in range(0,size,64)]
                    elif c=='MATE':
                        mats.extend([getmaterialx(bgl.read(120), bgldir, texnames) for i in range(0,size,120)])
                    elif c=='INDE':
                        # reverse order of vertices in each triangle
                        for i in range(size/6):
                            t=list(unpack('<3H', bgl.read(6)))
                            t.reverse()
                            inde.extend(t)
                    elif c=='VERB':
                        while bgl.tell()<end2:
                            (c,size,end3)=container(bgl,3)
                            if c=='VERT':
                                vert.append([tuple([round(i,VROUND) for i in unpack('<8f',bgl.read(32))]) for j in range(0,size,32)])
                            else:
                                bgl.seek(size,1)
                    elif c=='TRAN':
                        for i in range(0,size,64):
                            tran.append(Matrix(*[unpack('<4f',bgl.read(16)) for j in range(4)]))
                    elif c=='AMAP':
                        for i in range(0,size,8):
                            (a,b)=unpack('<2I',bgl.read(8))
                            amap.append(b)
                    elif c=='SCEN':
                        # Assumed to be after TRAN and AMAP sections
                        count=size/8
                        for i in range(count):
                            (child,peer,offset,unk)=unpack('<4h',bgl.read(8))
                            thismatrix=tran[amap[offset/8]]
                            scen.append((child,peer,thismatrix,-1))
                    elif c=='LODT':
                        while bgl.tell()<end2:
                            (c,size,end3)=container(bgl,3)
                            if c=='LODE':
                                (lod,)=unpack('<I', bgl.read(4))
                                while bgl.tell()<end3:
                                    (c,size,end4)=container(bgl,4)
                                    if c=='PART':
                                        (typ,sceneg,material,verb,voff,vcount,ioff,icount,mouserect)=unpack('<9I', bgl.read(36))
                                        if debug: print lod, typ,sceneg,material,verb,voff,vcount,ioff,icount,mouserect
                                        assert (typ==1)	# TRIANGLE_LIST
                                        if not lod in data: data[lod]=[]
                                        data[lod].append((mats[material], vert[verb][voff:voff+vcount], inde[ioff:ioff+icount], sceneg))
                                        partcount+=1
                                    else:
                                        bgl.seek(size,1)
                            else:
                                bgl.seek(size,1)
                    elif c=='PLAL':
                        while bgl.tell()<end2:
                            (c,size,end3)=container(bgl,3)
                            if c=='PLAT':
                                (surface,sceneg,numvert,v0x,v0y,v0z,v1x,v1y,v1z,v2x,v2y,v2z)=unpack('<3I9f', bgl.read(48))
                                assert (numvert==3)
                                #print (surface,scene,numvert,v0x,v0y,v0z,v1x,v1y,v1z,v2x,v2y,v2z)
                                if not sceneg in plat: plat[sceneg]={}
                                plat[sceneg][((round(v2x,VROUND),round(v2y,VROUND),round(v2z,VROUND)),(round(v1x,VROUND),round(v1y,VROUND),round(v1z,VROUND)),(round(v0x,VROUND),round(v0y,VROUND),round(v0z,VROUND)))]=surface
                            else:
                                bgl.seek(size,1)
                    elif c=='REFL':
                        while bgl.tell()<end2:
                            (c,size,end3)=container(bgl,3)
                            if c=='REFP':
                                (sceneg,size)=unpack('<II', bgl.read(8))

                                atta.append((bgl.read(size).strip('\0').strip(),sceneg))
                            else:
                                bgl.seek(size,1)
                    elif c=='ATTO':
                        while bgl.tell()<end2:
                            (unk,flags,size)=unpack('<IHH', bgl.read(8))
                            d=bgl.read(size)
                            if flags==2:	# Attached object
                                attobjs.append((d[40:-5], '{%x-%x-%x-%x%x-%x%x%x%x%x%x}' % unpack('<IHH8B', d[20:36])))
                            elif flags==4:	# Attached effect
                                p=d[100:-5].split('\0')	# params, attachpt
                                atteffects.append((p[1], d[20:100].strip(' \0'), p[0]))
                            elif debug:
                                print "Unknown attach %d:\n%s" % (flags, d)
                    else:
                        bgl.seek(size,1)
            elif c=='EXTE':	# FS9 data
                while bgl.tell()<end1:
                    Window.DrawProgressBar(float(bgl.tell())/(endmdl+endmdl), "Reading ...")
                    (c,size,end2)=container(bgl,2)
                    if c=='TEXT':
                        (bglop,count,reserved)=unpack('<HHI', bgl.read(8))
                        assert(bglop==0xb7)
                        texnames=[unpack('<4I', bgl.read(16)) + (bgl.read(64).strip('\0').strip(),) for i in range(count)]
                        assert (bgl.read(2)=='\x22\0')	# return
                    elif c=='MATE':
                        (bglop,count,reserved)=unpack('<HHI', bgl.read(8))
                        assert(bglop==0xb6)
                        matlist.extend([unpack('<17f', bgl.read(17*4)) for i in range(count)])
                        assert (bgl.read(2)=='\x22\0')	# return
                    elif c=='VERT':
                        (bglop,count,reserved)=unpack('<HHI', bgl.read(8))
                        assert(bglop==0xb5)
                        vert.extend([tuple([round(i,VROUND) for i in unpack('<8f',bgl.read(32))]) for j in range(count)])
                        assert (bgl.read(2)=='\x22\0')	# return
                    elif c=='BGL ':
                        code=bgl.read(size)
                        lods=[0]
                        lodno=0
                        while lodno<len(lods):
                            ip=0
                            lod=lods[lodno]
                            sceneg=0
                            curmat=None
                            stack=[]
                            if debug: print "LOD >", lod
                            while True:
                                (bglop,)=unpack('<H', code[ip:ip+2])
                                if debug: print "%s%04x: %02x" % ('  '*len(stack), ip, bglop)
                                ip+=2
                                # mostly just opcodes from BGLFP.doc
                                if bglop==0x0d:		# BGL_JUMP
                                    (offset,)=unpack('<h', code[ip:ip+2])
                                    ip=ip-2+offset
                                elif bglop==0x22:	# BGLOP_RETURN
                                    ip=stack.pop()
                                elif bglop==0x23:	# BGLOP_CALL
                                    (offset,)=unpack('<h', code[ip:ip+2])
                                    stack.append(ip+2)
                                    ip=ip-2+offset
                                elif bglop==0x24:	# BGLOP_IFIN1
                                    ip+=8	# assume true
                                elif bglop==0x39:	# BGLOP_IFMASK
                                    ip+=6	# assume true
                                elif bglop==0x5f:	# BGLOP_IFSIZEV
                                    (offset,r,pixels)=unpack('<hHH', code[ip:ip+6])
                                    newlod=int(0.5+radius*2475.0/r)
                                    if newlod not in lods:
                                        lods.append(newlod)
                                    if lod<newlod:
                                        ip=ip-2+offset
                                    else:
                                        ip+=6
                                elif bglop==0x88:	# BGLOP_JUMP_32
                                    (offset,)=unpack('<i', code[ip:ip+4])
                                    ip=ip-2+offset
                                elif bglop==0x89:	# BGLOP_JUMP_32
                                    (offset,)=unpack('<i', code[ip:ip+4])
                                    assert (offset==-1)
                                    ip=ip+4
                                elif bglop==0x8a:	# BGLOP_CALL_32
                                    (offset,)=unpack('<i', code[ip:ip+4])
                                    stack.append(ip+4)
                                    ip=ip-2+offset
                                elif bglop==0xa7:	# BGLOP_SPRITE_VICALL
                                    ip+=20	# ignore
                                elif bglop==0xb3:	# BGLOP_IFINF1
                                    ip+=14	# assume true
                                elif bglop==0xb8:	# BGLOP_SET_MATERIAL
                                    (m,t)=unpack('<hh', code[ip:ip+4])
                                    ip+=4
                                    curmat=getmaterial9(bgldir, m, matlist, t, texnames)
                                elif bglop==0xb9:	# BGLOP_DRAW_TRILIST
                                    (voff,vcount,icount)=unpack('<3H', code[ip:ip+6])
                                    ip+=6
                                    inde=unpack('<%dH' % icount, code[ip:ip+2*icount])
                                    ip+=2*icount
                                    if debug: print "DATA:", lod, sceneg, voff,vcount,icount
                                    if not lod in data: data[lod]=[]
                                    data[lod].append((curmat, vert[voff:voff+vcount], inde, sceneg))
                                    partcount+=1
                                elif bglop==0xbd:	# BGLOP_END
                                    break
                                elif bglop==0xc4:	# BGLOP_SET_MATRIX_INDIRECT
                                    (sceneg,)=unpack('<H', code[ip:ip+2])
                                    ip+=2
                                else:
                                    assert 0
                            lodno+=1

                        # Shift LODs up
                        lods.sort()
                        lods.append(100)
                        for i in range(len(lods)-1,0,-1):
                            data[lods[i]]=data[lods[i-1]]
                        data[lods[0]].pop()

                    elif c=='TRAN':
                        for i in range(0,size,64):
                            tran.append(Matrix(*[unpack('<4f',bgl.read(16)) for j in range(4)]))
                            if debug:
                                print i/64
                                print tran[i/64]
                    elif c=='ANIC':
                        anicbase=bgl.tell()
                        amap=bgl.read(size)
                    elif c=='SCEN':
                        # Assumed to be after TRAN and ANIC sections
                        (count,)=unpack('<H', bgl.read(2))
                        scen=[None for i in range(count)]
                        for i in range(count):
                            (n,child,peer,size,offset)=unpack('<4hi', bgl.read(12))
                            offset=bgl.tell()-12+offset-anicbase
                            if size==6:	# Static
                                (bglop,src,dst)=unpack('<3H', amap[offset:offset+6])
                                assert (bglop==0xc6)
                                thismatrix=tran[src]
                            else:	# Animation
                                (x,y,z,dst)=unpack('<3fh', amap[offset+size-14:offset+size])
                                thismatrix=TranslationMatrix(Vector(x,y,z,0))

                            scen[n]=(child,peer,thismatrix,-1)
                    elif c=='PLAT':
                        (count,)=unpack('<I', bgl.read(4))
                        s=[]
                        for i in range(count):
                            (sceneg,offset,numvert,surface)=unpack('<HhHH', bgl.read(8))
                            assert (numvert==3)	# triangle
                            s.append((sceneg,surface))
                        # Assumes in order so can ignore offset
                        for i in range(count):
                            (sceneg,surface)=s[i]
                            (v0x,v0y,v0z,v1x,v1y,v1z,v2x,v2y,v2z)=unpack('9f', bgl.read(36))
                            if not sceneg in plat: plat[sceneg]={}
                            plat[sceneg][((round(v0x,VROUND),round(v0y,VROUND),round(v0z,VROUND)),(round(v1x,VROUND),round(v1y,VROUND),round(v1z,VROUND)),(round(v2x,VROUND),round(v2y,VROUND),round(v2z,VROUND)))]=surface

                    elif c=='ATTA':
                        (count,)=unpack('<I', bgl.read(4))
                        s=[]
                        for i in range(count):
                            (sceneg,offset)=unpack('<Hh', bgl.read(4))
                            s.append((sceneg))
                        # Assumes in order so can ignore offset
                        for i in range(count):
                            name=''
                            while True:
                                c=bgl.read(1)
                                if c=='\0': break
                                name=name+c
                            atta.append((name.strip(),s[i]))
                    elif c=='ATTO':		# same as FSX
                        while bgl.tell()<end2:
                            (unk,flags,size)=unpack('<IHH', bgl.read(8))
                            d=bgl.read(size)
                            if flags==2:	# Attached object
                                attobjs.append((d[40:-5], '{%x-%x-%x-%x%x-%x%x%x%x%x%x}' % unpack('<IHH8B', d[20:36])))
                            elif flags==4:	# Attached effect
                                p=d[100:-5].split('\0')	# params, attachpt
                                atteffects.append((p[1], d[20:100].strip(' \0'), p[0]))
                            elif debug:
                                print "Unknown attach %d:\n%s" % (flags, d)
                    else:
                        bgl.seek(size,1)
            else:
                bgl.seek(size,1)

        bgl.close()

        # Invert Child/Peer pointers to get parents
        for i in range(len(scen)):
            (child, peer, thismatrix, parent)=scen[i]
            if child!=-1:	# child's parent is me
                (xchild, xpeer, xmatrix, xparent)=scen[child]
                scen[child]=(xchild, xpeer, xmatrix, i)
            if peer!=-1:	# peer's parent is my parent
                assert (peer>i)
                (xchild, xpeer, xmatrix, xparent)=scen[peer]
                scen[peer]=(xchild, xpeer, xmatrix, parent)
        if debug:
            print "TRAN Matrices", len(tran)
            for i in range(len(tran)):
                print i
                print tran[i]
            #print "Animation map", len(amap)
            #for i in range(len(amap)):
            #    print i, '->', amap[i]
            print "Scene Graph", len(scen)
            for i in range(len(scen)):
                (child, peer, thismatrix, parent)=scen[i]
                print i, child, peer, parent
                print thismatrix

        scene=Scene.GetCurrent()
        lods=data.keys()
        lods.sort()
        lods.reverse()
        partno=0.0
        for layer in range(len(lods)):
            for (material, vert, inde, sceneg) in data[lods[layer]]:
                Window.DrawProgressBar(0.5+partno/(partcount+partcount), "Adding ...")
                (child, peer, finalmatrix, parent)=scen[sceneg]
                #print lods[layer]
                #print sceneg, child, peer, parent
                while parent!=-1:
                    (child, peer, thismatrix, parent)=scen[parent]
                    finalmatrix=finalmatrix*thismatrix
                #print finalmatrix
                if not layer and sceneg in plat:
                    adddata(scene, layer+1, material, vert, inde, finalmatrix, plat[sceneg])
                else:
                    adddata(scene, layer+1, material, vert, inde, finalmatrix)
                partno+=1
        if debug:
            for (sceneg,verts) in plat.iteritems():
                if verts:
                    print "Unallocated platforms: sceneg=%d, %d:" % (sceneg, len(verts.keys()))
                    for v in verts.keys():
                        for vt in v: print "%.4f %.4f %.4f" % vt
                        print

        # Attach points
        attachpoints={}
        for (name, sceneg) in atta:
            (child, peer, finalmatrix, parent)=scen[sceneg]
            while parent!=-1:
                (child, peer, thismatrix, parent)=scen[parent]
                finalmatrix=finalmatrix*thismatrix
            attachpoints[name]=addattach(scene, name, finalmatrix)
        for (name, obj) in attobjs:
            attachpoints[name].addProperty('guid', obj)
        for (name, effect, params) in atteffects:
            attachpoints[name].addProperty('effectName', effect)
            if params: attachpoints[name].addProperty('effectParams', params)


        addprops(scene, lods)

        Window.DrawProgressBar(1, "Finished")
        Window.WaitCursor(0)

    except:
        bgl.close()
        Window.DrawProgressBar(1, "ERROR")
        Window.WaitCursor(0)
        Draw.PupMenu("ERROR%%t|Can't read %s - is this a FSX MDL format file?" % filename)
コード例 #13
0
def adddata(scene, layer, material, vert, inde, matrix, plat=None):
    # Need to convert between right and left handed coordinate systems.
    matrix=matrix*Matrix([1,0,0,0],[0,0,1,0],[0,1,0,0],[0,0,0,1])

    # This results in a negatively scaled matrix, which causes  problems
    # for face normals. So separate out and apply scale&rotation parts.
    tran=TranslationMatrix(matrix.translationPart())
    matrix[3]=[0,0,0,1]

    # detect back-to-back duplicate faces
    facelookup={}
    newvert=[[]]
    for i in range(0, len(inde), 3):
        face=[(vert[inde[j]][0], vert[inde[j]][1], vert[inde[j]][2]) for j in range(i+2,i-1,-1)]
        # duplicate faces may be rotated - eg Oil_Rig_Sample
        if tuple(face) in facelookup or (face[1],face[2],face[0]) in facelookup or (face[2],face[0],face[1]) in facelookup:
            # back-to-back duplicate - start new mesh
            newvert.append([])
            facelookup={}
        face.reverse()
        facelookup[tuple(face)]=True
        newvert[-1].extend([vert[inde[j]] for j in range(i,i+3)])

    for vert in newvert:
        mesh=Mesh.New('Mesh')
        mesh.mode &= ~(Mesh.Modes.TWOSIDED|Mesh.Modes.AUTOSMOOTH)
        mesh.mode |= Mesh.Modes.NOVNORMALSFLIP
        mesh.materials+=[material]
        mesh.verts.extend([v[0:3] for v in vert])
        mesh.faces.extend([[i,i+1,i+2] for i in range(0, len(vert), 3)], ignoreDups=True)
        mesh.faceUV=True

        mtex=material.getTextures()[0]
        if mtex:
            image=mtex.tex.image
        else:
            image=None

        surface=None

        i=0
        for face in mesh.faces:
            face.mode &= ~(Mesh.FaceModes.TWOSIDE|Mesh.FaceModes.TILES)
            if image:
                face.mode|=Mesh.FaceModes.TEX
                face.image=image
            face.uv=[Vector(v[6],1-v[7]) for v in [vert[j] for j in range(i,i+3)]]
            # smooth if vertex normals are different
            face.smooth=not (vert[i][3:6]==vert[i+1][3:6]==vert[i+2][3:6])

            # is this a platform?
            if plat:
                v=(vert[i][:3], vert[i+1][:3], vert[i+2][:3])
                #for vt in v: print "%.4f %.4f %.4f" % vt
                #print
                if v in plat:
                    face.mode&=~Mesh.FaceModes.DYNAMIC
                    surface=plat.pop(v)
                else:
                    face.mode |= Mesh.FaceModes.DYNAMIC
            else:
                face.mode |= Mesh.FaceModes.DYNAMIC

            i+=3

        ob = Object.New('Mesh')
        ob.link(mesh)
        scene.objects.link(ob)
        ob.layers=[layer]
        ob.setMatrix(tran)
        if surface!=None: ob.addProperty('surfaceType', SURFACES[surface])

        # following must be after object linked to scene
        mesh.transform(matrix)
        mesh.sel=True
        mesh.remDoubles(0.001)	# 1/10mm
        mesh.sel=True
        mesh.calcNormals()	# calculate vertex normals
        mesh.sel=False
コード例 #14
0
def mouseViewRay(screen_x, screen_y, localMatrix=None, useMid=False):

    # Constant function variables
    p = mouseViewRay.p
    d = mouseViewRay.d

    for win3d in Window.GetScreenInfo(
            Window.Types.VIEW3D
    ):  # we search all 3dwins for the one containing the point (screen_x, screen_y) (could be the mousecoords for example)
        win_min_x, win_min_y, win_max_x, win_max_y = win3d['vertices']
        # calculate a few geometric extents for this window

        win_mid_x = (win_max_x + win_min_x + 1.0) * 0.5
        win_mid_y = (win_max_y + win_min_y + 1.0) * 0.5
        win_size_x = (win_max_x - win_min_x + 1.0) * 0.5
        win_size_y = (win_max_y - win_min_y + 1.0) * 0.5

        #useMid is for projecting the coordinates when we subdivide the screen into bins
        if useMid:  # == True
            screen_x = win_mid_x
            screen_y = win_mid_y

        # if the given screencoords (screen_x, screen_y) are within the 3dwin we fount the right one...
        if (win_max_x > screen_x > win_min_x) and (win_max_y > screen_y >
                                                   win_min_y):
            # first we handle all pending events for this window (otherwise the matrices might come out wrong)
            Window.QHandle(win3d['id'])

            # now we get a few matrices for our window...
            # sorry - i cannot explain here what they all do
            # - if you're not familiar with all those matrices take a look at an introduction to OpenGL...
            pm = Window.GetPerspMatrix()  # the prespective matrix
            pmi = Matrix(pm)
            pmi.invert()  # the inverted perspective matrix

            if (1.0 - epsilon < pmi[3][3] < 1.0 + epsilon):
                # pmi[3][3] is 1.0 if the 3dwin is in ortho-projection mode (toggled with numpad 5)
                hms = mouseViewRay.hms
                ortho_d = mouseViewRay.ortho_d

                # ortho mode: is a bit strange - actually there's no definite location of the camera ...
                # but the camera could be displaced anywhere along the viewing direction.

                ortho_d.x, ortho_d.y, ortho_d.z = Window.GetViewVector()
                ortho_d.w = 0

                # all rays are parallel in ortho mode - so the direction vector is simply the viewing direction
                #hms.x, hms.y, hms.z, hms.w = (screen_x-win_mid_x) /win_size_x, (screen_y-win_mid_y) / win_size_y, 0.0, 1.0
                hms[:] = (screen_x - win_mid_x) / win_size_x, (
                    screen_y - win_mid_y) / win_size_y, 0.0, 1.0

                # these are the homogenious screencoords of the point (screen_x, screen_y) ranging from -1 to +1
                p = (hms * pmi) + (1000 * ortho_d)
                p.resize3D()
                d[:] = ortho_d[:3]

            # Finally we shift the position infinitely far away in
            # the viewing direction to make sure the camera if outside the scene
            # (this is actually a hack because this function
            # is used in sculpt_mesh to initialize backface culling...)
            else:
                # PERSPECTIVE MODE: here everything is well defined - all rays converge at the camera's location
                vmi = Matrix(Window.GetViewMatrix())
                vmi.invert()  # the inverse viewing matrix
                fp = mouseViewRay.fp

                dx = pm[3][3] * ((
                    (screen_x - win_min_x) / win_size_x) - 1.0) - pm[3][0]
                dy = pm[3][3] * ((
                    (screen_y - win_min_y) / win_size_y) - 1.0) - pm[3][1]

                fp[:] = \
                pmi[0][0]*dx+pmi[1][0]*dy,\
                pmi[0][1]*dx+pmi[1][1]*dy,\
                pmi[0][2]*dx+pmi[1][2]*dy

                # fp is a global 3dpoint obtained from "unprojecting" the screenspace-point (screen_x, screen_y)
                #- figuring out how to calculate this took me quite some time.
                # The calculation of dxy and fp are simplified versions of my original code
                #- so it's almost impossible to explain what's going on geometrically... sorry

                p[:] = vmi[3][:3]

                # the camera's location in global 3dcoords can be read directly from the inverted viewmatrix
                #d.x, d.y, d.z =normalize_v3(sub_v3v3(p, fp))
                d[:] = p.x - fp.x, p.y - fp.y, p.z - fp.z

                #print 'd', d, 'p', p, 'fp', fp

            # the direction vector is simply the difference vector from the virtual camera's position
            #to the unprojected (screenspace) point fp

            # Do we want to return a direction in object's localspace?

            if localMatrix:
                localInvMatrix = Matrix(localMatrix)
                localInvMatrix.invert()
                localInvMatrix_notrans = localInvMatrix.rotationPart()
                p = p * localInvMatrix
                d = d * localInvMatrix  # normalize_v3

                # remove the translation from d
                d.x -= localInvMatrix[3][0]
                d.y -= localInvMatrix[3][1]
                d.z -= localInvMatrix[3][2]

            d.normalize()
            '''
			# Debugging
			me = Blender.Mesh.New()
			me.verts.extend([p[0:3]])
			me.verts.extend([(p-d)[0:3]])
			me.edges.extend([0,1])
			ob = Blender.Scene.GetCurrent().objects.new(me)
			'''
            return True, p, d  # Origin, Direction

    # Mouse is not in any view, return None.
    return False, None, None