fix visible obj occluded by portals
This commit is contained in:
parent
39b660dbd8
commit
036b07e2be
@ -18,6 +18,8 @@ import bmesh
|
|||||||
|
|
||||||
import unicodedata
|
import unicodedata
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
|
||||||
from math import radians, degrees, floor, cos, sin, sqrt
|
from math import radians, degrees, floor, cos, sin, sqrt
|
||||||
|
|
||||||
from mathutils import Vector
|
from mathutils import Vector
|
||||||
@ -36,6 +38,8 @@ from bpy_extras.io_utils import (ExportHelper,
|
|||||||
|
|
||||||
from bpy_extras.object_utils import world_to_camera_view
|
from bpy_extras.object_utils import world_to_camera_view
|
||||||
|
|
||||||
|
from PIL import Image
|
||||||
|
|
||||||
class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
||||||
|
|
||||||
bl_idname = "export_psx.c";
|
bl_idname = "export_psx.c";
|
||||||
@ -71,11 +75,20 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
|
|
||||||
name="Use precalculated BGs",
|
name="Use precalculated BGs",
|
||||||
|
|
||||||
description="Set the BGs UV to black",
|
description="Render backgrounds and converts them to TIMs",
|
||||||
|
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# ~ exp_ShowPortals = BoolProperty(
|
||||||
|
|
||||||
|
# ~ name="Render Portals in precalculated BGs",
|
||||||
|
|
||||||
|
# ~ description="Useful for debugging",
|
||||||
|
|
||||||
|
# ~ default=False,
|
||||||
|
# ~ )
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
|
|
||||||
def triangulate_object(obj):
|
def triangulate_object(obj):
|
||||||
@ -248,6 +261,20 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
|
|
||||||
return "intersect"
|
return "intersect"
|
||||||
|
|
||||||
|
def objVertLtoW(target):
|
||||||
|
|
||||||
|
worldPos = []
|
||||||
|
|
||||||
|
mw = target.matrix_world
|
||||||
|
|
||||||
|
mesh = bpy.data.meshes[ target.name ]
|
||||||
|
|
||||||
|
for vertex in mesh.vertices:
|
||||||
|
|
||||||
|
worldPos.append( mw * vertex.co * scale )
|
||||||
|
|
||||||
|
return worldPos
|
||||||
|
|
||||||
def objVertWtoS(scene, cam, target, toScale = 1):
|
def objVertWtoS(scene, cam, target, toScale = 1):
|
||||||
|
|
||||||
screenPos = []
|
screenPos = []
|
||||||
@ -284,7 +311,7 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
|
|
||||||
vector.x = max ( 0, min ( resX, int( resX * vector.x ) ) )
|
vector.x = max ( 0, min ( resX, int( resX * vector.x ) ) )
|
||||||
|
|
||||||
vector.y = max ( 0, min ( resY, int( resY * vector.y ) ) )
|
vector.y = resY - max ( 0, min ( resY, int( resY * vector.y ) ) )
|
||||||
|
|
||||||
vector.z = int( vector.z )
|
vector.z = int( vector.z )
|
||||||
|
|
||||||
@ -357,6 +384,12 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
|
|
||||||
if o.type == 'CAMERA' and o.name.startswith("camPath"):
|
if o.type == 'CAMERA' and o.name.startswith("camPath"):
|
||||||
|
|
||||||
|
filepath = folder + os.sep + "TIM" + os.sep
|
||||||
|
|
||||||
|
filename = "bg_" + CleanName(o.name)
|
||||||
|
|
||||||
|
fileext = "." + str(bpy.context.scene.render.image_settings.file_format).lower()
|
||||||
|
|
||||||
# Set camera as active
|
# Set camera as active
|
||||||
|
|
||||||
bpy.context.scene.camera = o
|
bpy.context.scene.camera = o
|
||||||
@ -365,7 +398,30 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
|
|
||||||
bpy.ops.render.render()
|
bpy.ops.render.render()
|
||||||
|
|
||||||
bpy.data.images["Render Result"].save_render(folder + os.sep + "TIM" + os.sep + "bg_" + CleanName(o.name) + "." + str(bpy.context.scene.render.image_settings.file_format).lower())
|
bpy.data.images["Render Result"].save_render( filepath + filename + fileext )
|
||||||
|
|
||||||
|
# Convert to 256 colors png with PILlow
|
||||||
|
# TODO : Add Pillow lib
|
||||||
|
|
||||||
|
# ~ bgFile = Image.open( filepath + filename + fileext )
|
||||||
|
|
||||||
|
# ~ bgFile = bgFile.convert('RGB').convert('P', palette=Image.ADAPTIVE )
|
||||||
|
|
||||||
|
# ~ bgFile.save( filepath + filename + fileext )
|
||||||
|
|
||||||
|
# Convert to tim with img2tim ( https://github.com/Lameguy64/img2tim )
|
||||||
|
|
||||||
|
exe = ""
|
||||||
|
|
||||||
|
if os.name == 'nt':
|
||||||
|
|
||||||
|
exe = ".exe"
|
||||||
|
|
||||||
|
# ImageMagick alternative
|
||||||
|
|
||||||
|
# ~ subprocess.call( [ "convert", filepath + filename + fileext, "-colors", "256", filepath + filename + fileext ] )
|
||||||
|
|
||||||
|
# ~ subprocess.call( [ "img2tim" + exe, "-t", "-bpp", "8", "-org", "320", "0", "-plt" , "0", "481","-o", filepath + filename + ".tim", filepath + filename + fileext ] )
|
||||||
|
|
||||||
# Add camera object to camAngles
|
# Add camera object to camAngles
|
||||||
|
|
||||||
@ -533,7 +589,15 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
|
|
||||||
if bpy.data.objects[o].type == 'MESH':
|
if bpy.data.objects[o].type == 'MESH':
|
||||||
|
|
||||||
if bpy.data.objects[o].data.get('isRigidBody') or bpy.data.objects[o].data.get('isStaticBody') :
|
if (
|
||||||
|
|
||||||
|
bpy.data.objects[o].data.get('isRigidBody') or
|
||||||
|
|
||||||
|
bpy.data.objects[o].data.get('isStaticBody')
|
||||||
|
|
||||||
|
#or bpy.data.objects[o].data.get('isPortal')
|
||||||
|
|
||||||
|
):
|
||||||
|
|
||||||
rayTargets.append(bpy.data.objects[o])
|
rayTargets.append(bpy.data.objects[o])
|
||||||
|
|
||||||
@ -1324,7 +1388,7 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
|
|
||||||
# Chech object is in view frame
|
# Chech object is in view frame
|
||||||
|
|
||||||
if isInFrame(scene, camera, target):
|
if isInFrame(scene, camera, target):# and not target.data.get('isPortal') :
|
||||||
|
|
||||||
# Get normalized direction vector between camera and object
|
# Get normalized direction vector between camera and object
|
||||||
|
|
||||||
@ -1336,16 +1400,54 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
# Unpack results into several variables.
|
# Unpack results into several variables.
|
||||||
# We're only interested in 'hitObject' though
|
# We're only interested in 'hitObject' though
|
||||||
|
|
||||||
result, location, normal, index, hitObject, matrix = scene.ray_cast( camera.location, dirToTarget )
|
result, hitLocation, normal, index, hitObject, matrix = scene.ray_cast( camera.location, dirToTarget )
|
||||||
|
|
||||||
# If hitObject is the same as target, nothing is obstructing it's visibility
|
# If hitObject is the same as target, nothing is obstructing it's visibility
|
||||||
|
|
||||||
if hitObject is not None:
|
if hitObject is not None:
|
||||||
|
|
||||||
if hitObject in rayTargets:
|
# If hit object is a portal, cast a new ray from hit location to target
|
||||||
|
|
||||||
|
if hitObject.data.get('isPortal'):
|
||||||
|
|
||||||
|
# Find out if we're left or right of portal
|
||||||
|
|
||||||
|
v0 = hitObject.matrix_world * hitObject.data.vertices[0].co
|
||||||
|
v1 = hitObject.matrix_world * hitObject.data.vertices[1].co
|
||||||
|
|
||||||
|
side = checkLine(v0.x, v0.y, v1.x, v1.y , camera.location.x, camera.location.y, camera.location.x, camera.location.y )
|
||||||
|
|
||||||
|
if side == 'front':
|
||||||
|
|
||||||
|
offset = [ 1.001, 0.999, 0.999 ]
|
||||||
|
|
||||||
|
else :
|
||||||
|
|
||||||
|
offset = [ 0.999, 1.001, 1.001 ]
|
||||||
|
|
||||||
|
origin = Vector( ( hitLocation.x * offset[0], hitLocation.y * offset[1], hitLocation.z * offset[2] ) )
|
||||||
|
|
||||||
|
print(hitObject.name + " is a portal at " + str( hitLocation ) + " N : " + str(normal) + " - " + side + "Or : " + str(origin) )
|
||||||
|
|
||||||
|
result, hitLocationPort, normal, index, hitObjectPort, matrix = scene.ray_cast( origin , dirToTarget )
|
||||||
|
|
||||||
|
print( camera.name + " : recasting from " + str( origin ) + " to " + target.name )
|
||||||
|
|
||||||
|
if hitObjectPort is not None:
|
||||||
|
|
||||||
|
if hitObjectPort in rayTargets:
|
||||||
|
|
||||||
|
print(hitObjectPort.name)
|
||||||
|
|
||||||
visibleTarget.append(target)
|
visibleTarget.append(target)
|
||||||
|
|
||||||
|
elif hitObject in rayTargets:
|
||||||
|
|
||||||
|
visibleTarget.append(target)
|
||||||
|
|
||||||
|
|
||||||
|
print("\n")
|
||||||
|
|
||||||
if bpy.data.objects[ actorPtr ] not in visibleTarget:
|
if bpy.data.objects[ actorPtr ] not in visibleTarget:
|
||||||
|
|
||||||
visibleTarget.append( bpy.data.objects[ actorPtr ] )
|
visibleTarget.append( bpy.data.objects[ actorPtr ] )
|
||||||
@ -1385,22 +1487,40 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
|
|
||||||
for portal in visiblePortal:
|
for portal in visiblePortal:
|
||||||
|
|
||||||
s = objVertWtoS( scene, camera, portal )
|
w = objVertLtoW(portal)
|
||||||
|
|
||||||
# Write quad NW, NE, SE, SW
|
f.write("// " + str(portal) + "\n" )
|
||||||
|
|
||||||
|
# Write portal'vertices world coordinates NW, NE, SE, SW
|
||||||
|
|
||||||
f.write("\t{\n\t\t" +
|
f.write("\t{\n\t\t" +
|
||||||
|
|
||||||
"{ " + str( int (s[3].x ) ) + ", " + str( int (s[3].y ) ) + ", " + str( int (s[3].z ) ) + ", 0 },\n\t\t" +
|
"{ " + str( int (w[3].x ) ) + ", " + str( int (w[3].y ) ) + ", " + str( int (w[3].z ) ) + ", 0 },\n\t\t" +
|
||||||
|
|
||||||
"{ " + str( int (s[2].x ) ) + ", " + str( int (s[2].y ) ) + ", " + str( int (s[2].z ) ) + ", 0 },\n\t\t" +
|
"{ " + str( int (w[2].x ) ) + ", " + str( int (w[2].y ) ) + ", " + str( int (w[2].z ) ) + ", 0 },\n\t\t" +
|
||||||
|
|
||||||
"{ " + str( int (s[0].x ) ) + ", " + str( int (s[0].y ) ) + ", " + str( int (s[0].z ) ) + ", 0 },\n\t\t" +
|
"{ " + str( int (w[0].x ) ) + ", " + str( int (w[0].y ) ) + ", " + str( int (w[0].z ) ) + ", 0 },\n\t\t" +
|
||||||
|
|
||||||
"{ " + str( int (s[1].x ) ) + ", " + str( int (s[1].y ) ) + ", " + str( int (s[1].z ) ) + ", 0 }\n" +
|
"{ " + str( int (w[1].x ) ) + ", " + str( int (w[1].y ) ) + ", " + str( int (w[1].z ) ) + ", 0 }\n" +
|
||||||
|
|
||||||
"\t},\n" )
|
"\t},\n" )
|
||||||
|
|
||||||
|
# UNUSED : Screen coords
|
||||||
|
|
||||||
|
# ~ s = objVertWtoS( scene, camera, portal )
|
||||||
|
|
||||||
|
# ~ f.write("\t{\n\t\t" +
|
||||||
|
|
||||||
|
# ~ "{ " + str( int (s[3].x ) ) + ", " + str( int (s[3].y ) ) + ", " + str( int (s[3].z ) ) + ", 0 },\n\t\t" +
|
||||||
|
|
||||||
|
# ~ "{ " + str( int (s[2].x ) ) + ", " + str( int (s[2].y ) ) + ", " + str( int (s[2].z ) ) + ", 0 },\n\t\t" +
|
||||||
|
|
||||||
|
# ~ "{ " + str( int (s[0].x ) ) + ", " + str( int (s[0].y ) ) + ", " + str( int (s[0].z ) ) + ", 0 },\n\t\t" +
|
||||||
|
|
||||||
|
# ~ "{ " + str( int (s[1].x ) ) + ", " + str( int (s[1].y ) ) + ", " + str( int (s[1].z ) ) + ", 0 }\n" +
|
||||||
|
|
||||||
|
# ~ "\t},\n" )
|
||||||
|
|
||||||
f.write("\t" + str( len( visibleTarget ) ) + ",\n" +
|
f.write("\t" + str( len( visibleTarget ) ) + ",\n" +
|
||||||
|
|
||||||
"\t{\n")
|
"\t{\n")
|
||||||
@ -1512,8 +1632,11 @@ class ExportMyFormat(bpy.types.Operator, ExportHelper):
|
|||||||
Yvalues.append( (mw * v.co).y )
|
Yvalues.append( (mw * v.co).y )
|
||||||
|
|
||||||
LvlObjects[o.name] = {'x1' : min(Xvalues),
|
LvlObjects[o.name] = {'x1' : min(Xvalues),
|
||||||
|
|
||||||
'y1' : min(Yvalues),
|
'y1' : min(Yvalues),
|
||||||
|
|
||||||
'x2' : max(Xvalues),
|
'x2' : max(Xvalues),
|
||||||
|
|
||||||
'y2' : max(Yvalues)}
|
'y2' : max(Yvalues)}
|
||||||
|
|
||||||
# Clear X/Y lists for next iteration
|
# Clear X/Y lists for next iteration
|
||||||
|
Loading…
Reference in New Issue
Block a user