Initial commit
3
.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
10
.idea/AugmentWebviewStateStore.xml
generated
Normal file
14
.idea/EG.iml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.10 (eg)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyDocumentationSettings">
|
||||
<option name="format" value="PLAIN" />
|
||||
<option name="myDocStringFormat" value="Plain" />
|
||||
</component>
|
||||
</module>
|
||||
15
.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,15 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyCompatibilityInspection" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ourVersions">
|
||||
<value>
|
||||
<list size="2">
|
||||
<item index="0" class="java.lang.String" itemvalue="2.7" />
|
||||
<item index="1" class="java.lang.String" itemvalue="3.14" />
|
||||
</list>
|
||||
</value>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
6
.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
7
.idea/misc.xml
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="Black">
|
||||
<option name="sdkName" value="Python 3.12 (PythonProject)" />
|
||||
</component>
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (eg)" project-jdk-type="Python SDK" />
|
||||
</project>
|
||||
8
.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/EG.iml" filepath="$PROJECT_DIR$/.idea/EG.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
6
.idea/vcs.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
4
.vscode/settings.json
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"python-envs.pythonProjects": [],
|
||||
"kiroAgent.configureMCP": "Disabled"
|
||||
}
|
||||
279
QPanda3D/Helpers/Env_Grid_Maker.py
Normal file
@ -0,0 +1,279 @@
|
||||
# -*- coding: utf-8-*-
|
||||
"""
|
||||
Module : Env_Grid_Maker
|
||||
Author : Saifeddine ALOUI + code from Forklift 's code snippet could be found on panda3D's website
|
||||
Description :
|
||||
Creates a 3D implementation of grid that shows axes in 3 possible planes
|
||||
|
||||
"""
|
||||
from panda3d.core import *
|
||||
from direct.interval.IntervalGlobal import *
|
||||
|
||||
class Env_Grid_Maker:
|
||||
def __init__(self, XYPlaneShow = True, XZPlaneShow = False, YZPlaneShow = False, endCapLinesShow = True, XSize = 50, YSize = 50, ZSize = 50, gridStep = 10, subdiv = 10):
|
||||
#Create line objects
|
||||
self.axisLines = LineSegs()
|
||||
self.gridLines = LineSegs()
|
||||
self.subdivLines = LineSegs()
|
||||
|
||||
#Init passed variables
|
||||
self.XSize = XSize
|
||||
self.YSize = YSize
|
||||
self.ZSize = ZSize
|
||||
self.gridStep = gridStep
|
||||
self.subdiv = subdiv
|
||||
|
||||
#Init default variables
|
||||
|
||||
#Plane and end cap line visibility (1 is show, 0 is hide)
|
||||
self.XYPlaneShow = XYPlaneShow
|
||||
self.XZPlaneShow = XZPlaneShow
|
||||
self.YZPlaneShow = YZPlaneShow
|
||||
self.endCapLinesShow = endCapLinesShow
|
||||
|
||||
#Alpha variables for each plane
|
||||
#self.XYPlaneAlpha = 1
|
||||
#self.XZPlaneAlpha = 1
|
||||
#self.YZPlaneAlpha = 1
|
||||
|
||||
#Colors (RGBA passed as a VBase4 object)
|
||||
self.XAxisColor = VBase4(1, 0, 0, 1)
|
||||
self.YAxisColor = VBase4(0, 1, 0, 1)
|
||||
self.ZAxisColor = VBase4(0, 0, 1, 1)
|
||||
self.gridColor = VBase4(1, 1, 1, 1)
|
||||
self.subdivColor = VBase4(.35, .35, .35, 1)
|
||||
|
||||
#Line thicknesses (in pixels)
|
||||
self.axisThickness = 3
|
||||
self.gridThickness = 1
|
||||
self.subdivThickness = 1
|
||||
|
||||
|
||||
def create(self):
|
||||
#Set line thicknesses
|
||||
self.axisLines.setThickness(self.axisThickness)
|
||||
self.gridLines.setThickness(self.gridThickness)
|
||||
self.subdivLines.setThickness(self.subdivThickness)
|
||||
|
||||
if(self.XSize != 0):
|
||||
#Draw X axis line
|
||||
self.axisLines.setColor(self.XAxisColor)
|
||||
self.axisLines.moveTo(-(self.XSize), 0, 0)
|
||||
self.axisLines.drawTo(self.XSize, 0, 0)
|
||||
|
||||
if(self.YSize != 0):
|
||||
#Draw Y axis line
|
||||
self.axisLines.setColor(self.YAxisColor)
|
||||
self.axisLines.moveTo(0, -(self.YSize), 0)
|
||||
self.axisLines.drawTo(0, self.YSize, 0)
|
||||
|
||||
if(self.ZSize != 0):
|
||||
#Draw Z axis line
|
||||
self.axisLines.setColor(self.ZAxisColor)
|
||||
self.axisLines.moveTo(0, 0, -(self.ZSize))
|
||||
self.axisLines.drawTo(0, 0, self.ZSize)
|
||||
|
||||
#Check to see if primary grid lines should be drawn at all
|
||||
if(self.gridStep != 0):
|
||||
|
||||
#Draw primary grid lines
|
||||
self.gridLines.setColor(self.gridColor)
|
||||
|
||||
#Draw primary grid lines metering x axis if any x-length
|
||||
if(self.XSize != 0):
|
||||
if((self.YSize != 0) and (self.XYPlaneShow)):
|
||||
#Draw y lines across x axis starting from center moving out
|
||||
#XY Plane
|
||||
for x in self.myfrange(0, self.XSize, self.gridStep):
|
||||
self.gridLines.moveTo(x, -(self.YSize), 0)
|
||||
self.gridLines.drawTo(x, self.YSize, 0)
|
||||
self.gridLines.moveTo(-x, -(self.YSize), 0)
|
||||
self.gridLines.drawTo(-x, self.YSize, 0)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(self.XSize, -(self.YSize), 0)
|
||||
self.gridLines.drawTo(self.XSize, self.YSize, 0)
|
||||
self.gridLines.moveTo(-(self.XSize), -(self.YSize), 0)
|
||||
self.gridLines.drawTo(-(self.XSize), self.YSize, 0)
|
||||
|
||||
if((self.ZSize != 0) and (self.XZPlaneShow)):
|
||||
#Draw z lines across x axis starting from center moving out
|
||||
#XZ Plane
|
||||
for x in self.myfrange(0, self.XSize, self.gridStep):
|
||||
self.gridLines.moveTo(x, 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(x, 0, self.ZSize)
|
||||
self.gridLines.moveTo(-x, 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(-x, 0, self.ZSize)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(self.XSize, 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(self.XSize, 0, self.ZSize)
|
||||
self.gridLines.moveTo(-(self.XSize), 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(-(self.XSize), 0, self.ZSize)
|
||||
|
||||
#Draw primary grid lines metering y axis if any y-length
|
||||
if(self.YSize != 0):
|
||||
|
||||
if((self.YSize != 0) and (self.XYPlaneShow)):
|
||||
#Draw x lines across y axis
|
||||
#XY Plane
|
||||
for y in self.myfrange(0, self.YSize, self.gridStep):
|
||||
self.gridLines.moveTo(-(self.XSize), y, 0)
|
||||
self.gridLines.drawTo(self.XSize, y, 0)
|
||||
self.gridLines.moveTo(-(self.XSize), -y, 0)
|
||||
self.gridLines.drawTo(self.XSize, -y, 0)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(-(self.XSize), self.YSize, 0)
|
||||
self.gridLines.drawTo(self.XSize, self.YSize, 0)
|
||||
self.gridLines.moveTo(-(self.XSize), -(self.YSize), 0)
|
||||
self.gridLines.drawTo(self.XSize, -(self.YSize), 0)
|
||||
|
||||
if((self.ZSize != 0) and (self.YZPlaneShow)):
|
||||
#Draw z lines across y axis
|
||||
#YZ Plane
|
||||
for y in self.myfrange(0, self.YSize, self.gridStep):
|
||||
self.gridLines.moveTo(0, y, -(self.ZSize))
|
||||
self.gridLines.drawTo(0, y, self.ZSize)
|
||||
self.gridLines.moveTo(0, -y, -(self.ZSize))
|
||||
self.gridLines.drawTo(0, -y, self.ZSize)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(0, self.YSize, -(self.ZSize))
|
||||
self.gridLines.drawTo(0, self.YSize, self.ZSize)
|
||||
self.gridLines.moveTo(0, -(self.YSize), -(self.ZSize))
|
||||
self.gridLines.drawTo(0, -(self.YSize), self.ZSize)
|
||||
|
||||
#Draw primary grid lines metering z axis if any z-length
|
||||
if(self.ZSize != 0):
|
||||
if((self.XSize != 0) and (self.XZPlaneShow)):
|
||||
#Draw x lines across z axis
|
||||
#XZ Plane
|
||||
for z in self.myfrange(0, self.ZSize, self.gridStep):
|
||||
self.gridLines.moveTo(-(self.XSize), 0, z)
|
||||
self.gridLines.drawTo(self.XSize, 0, z)
|
||||
self.gridLines.moveTo(-(self.XSize), 0, -z)
|
||||
self.gridLines.drawTo(self.XSize, 0, -z)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(-(self.XSize), 0, self.ZSize)
|
||||
self.gridLines.drawTo(self.XSize, 0, self.ZSize)
|
||||
self.gridLines.moveTo(-(self.XSize), 0, -(self.ZSize))
|
||||
self.gridLines.drawTo(self.XSize, 0, -(self.ZSize))
|
||||
|
||||
if((self.YSize != 0) and (self.YZPlaneShow)):
|
||||
#Draw y lines across z axis
|
||||
#YZ Plane
|
||||
for z in self.myfrange(0, self.ZSize, self.gridStep):
|
||||
self.gridLines.moveTo(0, -(self.YSize), z)
|
||||
self.gridLines.drawTo(0, self.YSize, z)
|
||||
self.gridLines.moveTo(0, -(self.YSize), -z)
|
||||
self.gridLines.drawTo(0, self.YSize, -z)
|
||||
|
||||
if(self.endCapLinesShow):
|
||||
#Draw endcap lines
|
||||
self.gridLines.moveTo(0, -(self.YSize), self.ZSize)
|
||||
self.gridLines.drawTo(0, self.YSize, self.ZSize)
|
||||
self.gridLines.moveTo(0, -(self.YSize), -(self.ZSize))
|
||||
self.gridLines.drawTo(0, self.YSize, -(self.ZSize))
|
||||
|
||||
#Check to see if secondary grid lines should be drawn
|
||||
if(self.subdiv != 0):
|
||||
|
||||
#Draw secondary grid lines
|
||||
self.subdivLines.setColor(self.subdivColor)
|
||||
|
||||
if(self.XSize != 0):
|
||||
adjustedstep = self.gridStep / self.subdiv
|
||||
if((self.YSize != 0) and (self.XYPlaneShow)):
|
||||
#Draw y lines across x axis starting from center moving out
|
||||
#XY
|
||||
for x in self.myfrange(0, self.XSize, adjustedstep):
|
||||
self.subdivLines.moveTo(x, -(self.YSize), 0)
|
||||
self.subdivLines.drawTo(x, self.YSize, 0)
|
||||
self.subdivLines.moveTo(-x, -(self.YSize), 0)
|
||||
self.subdivLines.drawTo(-x, self.YSize, 0)
|
||||
|
||||
if((self.ZSize != 0) and (self.XZPlaneShow)):
|
||||
#Draw z lines across x axis starting from center moving out
|
||||
#XZ
|
||||
for x in self.myfrange(0, self.XSize, adjustedstep):
|
||||
self.subdivLines.moveTo(x, 0, -(self.ZSize))
|
||||
self.subdivLines.drawTo(x, 0, self.ZSize)
|
||||
self.subdivLines.moveTo(-x, 0, -(self.ZSize))
|
||||
self.subdivLines.drawTo(-x, 0, self.ZSize)
|
||||
|
||||
if(self.YSize != 0):
|
||||
if((self.YSize != 0) and (self.XYPlaneShow)):
|
||||
#Draw x lines across y axis
|
||||
#XY
|
||||
for y in self.myfrange(0, self.YSize, adjustedstep):
|
||||
self.subdivLines.moveTo(-(self.XSize), y, 0)
|
||||
self.subdivLines.drawTo(self.XSize, y, 0)
|
||||
self.subdivLines.moveTo(-(self.XSize), -y, 0)
|
||||
self.subdivLines.drawTo(self.XSize, -y, 0)
|
||||
if((self.ZSize != 0) and (self.YZPlaneShow)):
|
||||
#Draw z lines across y axis
|
||||
#YZ
|
||||
for y in self.myfrange(0, self.YSize, adjustedstep):
|
||||
self.subdivLines.moveTo(0, y, -(self.ZSize))
|
||||
self.subdivLines.drawTo(0, y, self.ZSize)
|
||||
self.subdivLines.moveTo(0, -y, -(self.ZSize))
|
||||
self.subdivLines.drawTo(0, -y, self.ZSize)
|
||||
|
||||
if(self.ZSize != 0):
|
||||
|
||||
if((self.XSize != 0) and (self.XZPlaneShow)):
|
||||
#Draw x lines across z axis
|
||||
#XZ
|
||||
for z in self.myfrange(0, self.ZSize, adjustedstep):
|
||||
self.subdivLines.moveTo(-(self.XSize), 0, z)
|
||||
self.subdivLines.drawTo(self.XSize, 0, z)
|
||||
self.subdivLines.moveTo(-(self.XSize), 0, -z)
|
||||
self.subdivLines.drawTo(self.XSize, 0, -z)
|
||||
|
||||
if((self.YSize != 0) and (self.YZPlaneShow)):
|
||||
#Draw y lines across z axis
|
||||
#YZ
|
||||
for z in self.myfrange(0, self.ZSize, adjustedstep):
|
||||
self.subdivLines.moveTo(0, -(self.YSize), z)
|
||||
self.subdivLines.drawTo(0, self.YSize, z)
|
||||
self.subdivLines.moveTo(0, -(self.YSize), -z)
|
||||
self.subdivLines.drawTo(0, self.YSize, -z)
|
||||
|
||||
#Create ThreeAxisGrid nodes and nodepaths
|
||||
#Create parent node and path
|
||||
self.parentNode = PandaNode('threeaxisgrid-parentnode')
|
||||
self.parentNodePath = NodePath(self.parentNode)
|
||||
|
||||
#Create axis lines node and path, then reparent
|
||||
self.axisLinesNode = self.axisLines.create()
|
||||
self.axisLinesNodePath = NodePath(self.axisLinesNode)
|
||||
self.axisLinesNodePath.reparentTo(self.parentNodePath)
|
||||
|
||||
#Create grid lines node and path, then reparent
|
||||
self.gridLinesNode = self.gridLines.create()
|
||||
self.gridLinesNodePath = NodePath(self.gridLinesNode)
|
||||
self.gridLinesNodePath.reparentTo(self.parentNodePath)
|
||||
|
||||
#Create subdivision lines node and path then reparent
|
||||
self.subdivLinesNode = self.subdivLines.create()
|
||||
self.subdivLinesNodePath = NodePath(self.subdivLinesNode)
|
||||
self.subdivLinesNodePath.reparentTo(self.parentNodePath)
|
||||
|
||||
return self.parentNodePath
|
||||
def myfrange(self, start, stop=None, step=None):
|
||||
if stop is None:
|
||||
stop = float(start)
|
||||
start = 0.0
|
||||
if step is None:
|
||||
step = 1.0
|
||||
cur = float(start)
|
||||
while cur < stop:
|
||||
yield cur
|
||||
cur += step
|
||||
2
QPanda3D/Helpers/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
name="QPanda3D"
|
||||
__all__ = ["Env_Grid_Maker"]
|
||||
BIN
QPanda3D/Helpers/__pycache__/Env_Grid_Maker.cpython-312.pyc
Normal file
BIN
QPanda3D/Helpers/__pycache__/__init__.cpython-312.pyc
Normal file
193
QPanda3D/Panda3DWorld.py
Normal file
@ -0,0 +1,193 @@
|
||||
# -*- coding: utf-8-*-
|
||||
"""
|
||||
Module : Panda3DWorld
|
||||
Author : Saifeddine ALOUI
|
||||
Description :
|
||||
Inherit this object to create your custom world
|
||||
"""
|
||||
import sys
|
||||
import os
|
||||
|
||||
from core.CustomMouseController import CustomMouseController
|
||||
|
||||
# 获取 RenderPipelineFile 的路径
|
||||
render_pipeline_path = './RenderPipelineFile'
|
||||
# 将该路径添加到 sys.path 中,确保 Python 能够找到它
|
||||
project_root = os.path.dirname(os.path.abspath(__file__))
|
||||
sys.path.insert(0, project_root)
|
||||
sys.path.insert(0, render_pipeline_path)
|
||||
|
||||
# 现在你可以导入 RenderPipelineFile 中的模块了
|
||||
# 例如,如果你想导入 RenderPipelineFile 中的 RenderPipeline 模块
|
||||
from RenderPipelineFile.rpcore import RenderPipeline
|
||||
_global_render_pipeline = None
|
||||
|
||||
# PyQt imports
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
# Panda imports
|
||||
from panda3d.core import *
|
||||
# from panda3d.core import loadPrcFileData
|
||||
# loadPrcFileData("", "window-type none") # Set Panda to draw its main window in an offscreen buffer
|
||||
from direct.showbase.DirectObject import DirectObject
|
||||
from panda3d.core import GraphicsOutput, Texture, ConfigVariableManager, WindowProperties
|
||||
|
||||
# Set up Panda environment
|
||||
from direct.showbase.ShowBase import ShowBase
|
||||
import platform
|
||||
|
||||
# Local imports
|
||||
from QPanda3D.QMouseWatcherNode import QMouseWatcherNode
|
||||
|
||||
from RenderPipelineFile.rpcore.render_target import RenderTarget
|
||||
__all__ = ["Panda3DWorld"]
|
||||
|
||||
_global_world_instance=None
|
||||
import builtins
|
||||
|
||||
|
||||
class Panda3DWorld(ShowBase):
|
||||
"""
|
||||
Panda3DWorld : A class to handle all panda3D world manipulation
|
||||
"""
|
||||
|
||||
def __init__(self, width=1254, height=729, is_fullscreen=False, size=1.0, clear_color=LVecBase4f(0, 0.5, 0, 1),
|
||||
name="qpanda3D"):
|
||||
|
||||
global _global_world_instance
|
||||
global _global_render_pipeline
|
||||
|
||||
_global_world_instance = self
|
||||
|
||||
sort = -100
|
||||
self.parent = None
|
||||
|
||||
# 设置基本配置
|
||||
loadPrcFileData("", "show-frame-rate-meter 0")
|
||||
loadPrcFileData("", "window-type offscreen") # 设置为离屏渲染
|
||||
loadPrcFileData("", f"win-size {width} {height}")
|
||||
loadPrcFileData("", "win-fixed-size #f") # 允许窗口调整大小
|
||||
|
||||
if (is_fullscreen):
|
||||
loadPrcFileData("", "fullscreen #t")
|
||||
|
||||
self.render_pipeline = RenderPipeline()
|
||||
self.render_pipeline.pre_showbase_init()
|
||||
|
||||
ShowBase.__init__(self)
|
||||
|
||||
# 初始化渲染管线并设置可调整大小的标志
|
||||
self.render_pipeline.create(self)
|
||||
_global_render_pipeline = self.render_pipeline
|
||||
|
||||
# 创建 Qt 能读的 RGBA8 贴图
|
||||
self.qt_output_tex = Texture("qt_output_tex")
|
||||
self.qt_output_tex.set_format(Texture.F_rgba8)
|
||||
self.qt_output_tex.set_component_type(Texture.T_unsigned_byte)
|
||||
|
||||
# # 获取图形管线对象
|
||||
# gsg = self.win.getGsg()
|
||||
# host = gsg.getEngine().getHost()
|
||||
|
||||
self.win.add_render_texture(self.qt_output_tex, GraphicsOutput.RTM_copy_ram)
|
||||
|
||||
#self.screenTexture = Texture()
|
||||
#self.screenTexture.setMinfilter(Texture.FTLinear)
|
||||
#self.screenTexture.setFormat(Texture.FRgba32)
|
||||
#self.screenTexture.set_wrap_u(Texture.WM_clamp)
|
||||
#self.screenTexture.set_wrap_v(Texture.WM_clamp)
|
||||
|
||||
# buff_size_x = int(self.win.get_x_size() * size)
|
||||
# buff_size_y = int(self.win.get_y_size() * size)
|
||||
# winprops = WindowProperties()
|
||||
# winprops.set_size(buff_size_x, buff_size_y)
|
||||
#
|
||||
#
|
||||
# props = FrameBufferProperties()
|
||||
# props.set_rgb_color(True)
|
||||
# props.set_rgba_bits(8, 8, 8, 8)
|
||||
# props.set_depth_bits(8)
|
||||
|
||||
# self.buff = self.graphicsEngine.make_output(
|
||||
# self.pipe, name, sort,
|
||||
# props, winprops,
|
||||
# GraphicsPipe.BF_resizeable,
|
||||
# self.win.get_gsg(), self.win)
|
||||
|
||||
#self.screenTexture = render_pipeline._final_stage.target.color_tex
|
||||
|
||||
#self.buff.addRenderTexture(self.screenTexture, GraphicsOutput.RTMCopyRam)
|
||||
# self.buff.set_sort(sort)
|
||||
|
||||
|
||||
|
||||
#self.cam = self.makeCamera(self.buff)
|
||||
#self.render_pipeline._showbase.cam=self.makeCamera(self.buff)
|
||||
|
||||
#self.render_pipeline._showbase.cam=self.makeCamera(self.buff)
|
||||
|
||||
#self.render_pipeline._showbase.camera.reparentTo(self.render)
|
||||
#base.camera.reparentTo(self.render)
|
||||
#self.cam.reparentTo(self.render) # 可选同步
|
||||
|
||||
#render_pipeline.set_camera(self.cam)
|
||||
|
||||
#添加渲染效果<E69588><E69E9C>
|
||||
self.cam = self.render_pipeline._showbase.cam
|
||||
self.camNode = self.cam.node()
|
||||
self.camLens = self.camNode.get_lens()
|
||||
self.render_pipeline._showbase.camera = self.render_pipeline._showbase.cam
|
||||
#self.render_pipeline.daytime_mgr.update()
|
||||
|
||||
|
||||
# if clear_color is None:
|
||||
# self.buff.set_clear_active(GraphicsOutput.RTPColor, False)
|
||||
# else:
|
||||
# self.buff.set_clear_color(clear_color)
|
||||
# self.buff.set_clear_active(GraphicsOutput.RTPColor, True)
|
||||
|
||||
# self.disableMouse()
|
||||
self.mouse_controller = CustomMouseController(self)
|
||||
self.mouse_controller.setUp()
|
||||
|
||||
def render_pipeline(self):
|
||||
"""获取 RenderPipeline 实例"""
|
||||
return self._render_pipeline
|
||||
|
||||
|
||||
def set_parent(self, parent: QWidget):
|
||||
self.parent = parent
|
||||
self.mouseWatcherNode = QMouseWatcherNode(parent)
|
||||
|
||||
def getAspectRatio(self, win = None):
|
||||
if win is None and self.parent is not None:
|
||||
return float(self.parent.width()) / float(self.parent.height())
|
||||
else:
|
||||
return super().getAspectRatio(win)
|
||||
|
||||
def get_render_pipeline():
|
||||
"""获取全局 RenderPipeline 单例"""
|
||||
if _global_render_pipeline is None:
|
||||
raise RuntimeError(
|
||||
"RenderPipeline has not been initialized yet. Please create a Panda3DWorld instance first.")
|
||||
return _global_render_pipeline
|
||||
|
||||
def resize_buffer(self, width: int, height: int):
|
||||
"""根据新窗口尺寸调整 Panda3D 渲染输出尺寸"""
|
||||
# 设置 Panda3D 的窗口尺寸(offscreen 模式下对应输出区域)
|
||||
props = WindowProperties()
|
||||
props.set_size(width, height)
|
||||
self.win.request_properties(props)
|
||||
|
||||
# 重新分配输出贴图的大小
|
||||
self.qt_output_tex.set_x_size(width)
|
||||
self.qt_output_tex.set_y_size(height)
|
||||
|
||||
# 更新 lens 的 aspect ratio
|
||||
if self.camLens:
|
||||
self.camLens.set_film_size(width, height) # 或 set_aspect_ratio(width / height)
|
||||
|
||||
# 强制更新窗口(有时在 Qt 内嵌时需要)
|
||||
self.graphicsEngine.open_windows()
|
||||
41
QPanda3D/QMouseWatcherNode.py
Normal file
@ -0,0 +1,41 @@
|
||||
# -*- coding: utf-8-*-
|
||||
"""
|
||||
Module : QMouseWatcherNode
|
||||
Author : Niklas Mevenkamp
|
||||
Description :
|
||||
This is a MouseWatcherNode implementation that accesses
|
||||
mouse position and button states through a parent QWidget.
|
||||
"""
|
||||
|
||||
# PyQt imports
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
# Panda imports
|
||||
from panda3d.core import *
|
||||
|
||||
__all__ = ["QMouseWatcherNode"]
|
||||
|
||||
|
||||
class QMouseWatcherNode(MouseWatcher):
|
||||
def __init__(self, parent):
|
||||
super().__init__()
|
||||
|
||||
self.parent = parent
|
||||
|
||||
def getMouse(self, *args, **kwargs):
|
||||
# map global QCursor pixel position to parent Widget coordinates
|
||||
pos = self.parent.mapFromGlobal(QCursor.pos())
|
||||
|
||||
# map absolute pixel positions to relative ones
|
||||
rel_x = -1 + 2 * pos.x() / self.parent.width()
|
||||
rel_y = -1 + 2 * pos.y() / self.parent.height()
|
||||
|
||||
# invert y
|
||||
rel_y = -rel_y
|
||||
|
||||
return LPoint2(rel_x, rel_y)
|
||||
|
||||
def hasMouse(self):
|
||||
return isinstance(self.parent, QWidget)
|
||||
335
QPanda3D/QPanda3DWidget.py
Normal file
@ -0,0 +1,335 @@
|
||||
# -*- coding: utf-8-*-
|
||||
"""
|
||||
Module : QPanda3DWidget
|
||||
Author : Saifeddine ALOUI
|
||||
Description :
|
||||
This is the QWidget to be inserted in your standard PyQt5 application.
|
||||
It takes a Panda3DWorld object at init time.
|
||||
You should first create the Panda3DWorkd object before creating this widget.
|
||||
"""
|
||||
# PyQt imports
|
||||
from PyQt5 import QtWidgets, QtGui
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
# Panda imports
|
||||
from panda3d.core import Texture, WindowProperties, CallbackGraphicsWindow
|
||||
from panda3d.core import loadPrcFileData
|
||||
|
||||
from QPanda3D.QPanda3D_Buttons_Translation import QPanda3D_Button_translation
|
||||
from QPanda3D.QPanda3D_Keys_Translation import QPanda3D_Key_translation
|
||||
from QPanda3D.QPanda3D_Modifiers_Translation import QPanda3D_Modifier_translation
|
||||
|
||||
__all__ = ["QPanda3DWidget"]
|
||||
|
||||
|
||||
class QPanda3DSynchronizer(QTimer):
|
||||
def __init__(self, qPanda3DWidget, FPS=60):
|
||||
QTimer.__init__(self)
|
||||
self.qPanda3DWidget = qPanda3DWidget
|
||||
dt = 1000 / FPS
|
||||
self.setInterval(int(dt))
|
||||
self.timeout.connect(self.tick)
|
||||
|
||||
def tick(self):
|
||||
taskMgr.step()
|
||||
self.qPanda3DWidget.update()
|
||||
|
||||
|
||||
def get_panda_key_modifiers(evt):
|
||||
panda_mods = []
|
||||
qt_mods = evt.modifiers()
|
||||
for qt_mod, panda_mod in QPanda3D_Modifier_translation.items():
|
||||
if (qt_mods & qt_mod) == qt_mod:
|
||||
panda_mods.append(panda_mod)
|
||||
return panda_mods
|
||||
|
||||
|
||||
def get_panda_key_modifiers_prefix(evt):
|
||||
# join all modifiers (except NoModifier, which is None) with '-'
|
||||
prefix = "-".join([mod for mod in get_panda_key_modifiers(evt) if mod is not None])
|
||||
|
||||
# if the prefix is not empty, append a '-'
|
||||
if prefix:
|
||||
prefix += '-'
|
||||
|
||||
return prefix
|
||||
|
||||
|
||||
class QPanda3DWidget(QWidget):
|
||||
"""
|
||||
An interactive panda3D QWidget
|
||||
Parent : Parent QT Widget
|
||||
FPS : Number of frames per socond to refresh the screen
|
||||
debug: Switch printing key events to console on/off
|
||||
"""
|
||||
|
||||
def __init__(self, panda3DWorld, parent=None, FPS=60, debug=False):
|
||||
QWidget.__init__(self, parent)
|
||||
self.rp_sync_requested = False
|
||||
# set fixed geometry
|
||||
self.panda3DWorld = panda3DWorld
|
||||
self.panda3DWorld.set_parent(self)
|
||||
# Setup a timer in Qt that runs taskMgr.step() to simulate Panda's own main loop
|
||||
# pandaTimer = QTimer(self)
|
||||
# pandaTimer.timeout.connect()
|
||||
# pandaTimer.start(0)
|
||||
|
||||
self.setFocusPolicy(Qt.StrongFocus)
|
||||
|
||||
# Setup another timer that redraws this widget in a specific FPS
|
||||
# redrawTimer = QTimer(self)
|
||||
# redrawTimer.timeout.connect(self.update)
|
||||
# redrawTimer.start(1000/FPS)
|
||||
|
||||
self.paintSurface = QPainter()
|
||||
self.rotate = QTransform()
|
||||
self.rotate.rotate(180)
|
||||
self.out_image = QImage()
|
||||
|
||||
size = self.panda3DWorld.cam.node().get_lens().get_film_size()
|
||||
self.initial_film_size = QSizeF(size.x, size.y)
|
||||
self.initial_size = self.size()
|
||||
|
||||
self.synchronizer = QPanda3DSynchronizer(self, FPS)
|
||||
self.synchronizer.start()
|
||||
|
||||
self.debug = debug
|
||||
|
||||
def mousePressEvent(self, evt):
|
||||
button = evt.button()
|
||||
try:
|
||||
b = "{}{}".format(get_panda_key_modifiers_prefix(evt), QPanda3D_Button_translation[button])
|
||||
if self.debug:
|
||||
print(b)
|
||||
messenger.send(b,[{"x":evt.x(),"y":evt.y()}])
|
||||
except:
|
||||
print("Unimplemented button. Please send an issue on github to fix this problem")
|
||||
|
||||
def mouseMoveEvent(self, evt:QtGui.QMouseEvent):
|
||||
button = evt.button()
|
||||
try:
|
||||
b = "mouse-move"
|
||||
if self.debug:
|
||||
print(b)
|
||||
messenger.send(b,[{"x":evt.x(),"y":evt.y()}])
|
||||
except:
|
||||
print("Unimplemented button. Please send an issue on github to fix this problem")
|
||||
|
||||
|
||||
def mouseReleaseEvent(self, evt):
|
||||
button = evt.button()
|
||||
try:
|
||||
b = "{}{}-up".format(get_panda_key_modifiers_prefix(evt), QPanda3D_Button_translation[button])
|
||||
if self.debug:
|
||||
print(b)
|
||||
messenger.send(b,[{"x":evt.x(),"y":evt.y()}])
|
||||
except:
|
||||
print("Unimplemented button. Please send an issue on github to fix this problem")
|
||||
|
||||
def wheelEvent(self, evt):
|
||||
delta = evt.angleDelta().y()
|
||||
try:
|
||||
if self.debug:
|
||||
print(f"wheel {delta}")
|
||||
messenger.send('wheel',[{"delta":delta}])
|
||||
except:
|
||||
print("Unimplemented button. Please send an issue on github to fix this problem")
|
||||
|
||||
def keyPressEvent(self, evt):
|
||||
key = evt.key()
|
||||
try:
|
||||
k = "{}{}".format(get_panda_key_modifiers_prefix(evt), QPanda3D_Key_translation[key])
|
||||
if self.debug:
|
||||
print(k)
|
||||
messenger.send(k)
|
||||
except:
|
||||
print("Unimplemented key. Please send an issue on github to fix this problem")
|
||||
|
||||
def keyReleaseEvent(self, evt):
|
||||
key = evt.key()
|
||||
try:
|
||||
k = "{}{}-up".format(get_panda_key_modifiers_prefix(evt), QPanda3D_Key_translation[key])
|
||||
if self.debug:
|
||||
print(k)
|
||||
messenger.send(k)
|
||||
except:
|
||||
print("Unimplemented key. Please send an issue on github to fix this problem")
|
||||
|
||||
def resizeEvent(self, evt):
|
||||
width = evt.size().width()
|
||||
height = evt.size().height()
|
||||
print(f"width:{width}")
|
||||
print(f"height:{height}")
|
||||
|
||||
from Panda3DWorld import resize_buffer
|
||||
#resize_buffer(width, height)
|
||||
|
||||
lens = self.panda3DWorld.cam.node().get_lens()
|
||||
# lens.set_film_size(self.initial_film_size.width() * evt.size().width() / self.initial_size.width(),
|
||||
# self.initial_film_size.height() * evt.size().height() / self.initial_size.height())
|
||||
#self.sync_panda3d_window_size(width, height)
|
||||
|
||||
#self.panda3DWorld.buff.setSize(evt.size().width(), evt.size().height())
|
||||
|
||||
def minimumSizeHint(self):
|
||||
return QSize(400, 300)
|
||||
|
||||
# Use the paint event to pull the contents of the panda texture to the widget
|
||||
# def paintEvent(self, event):
|
||||
# if self.panda3DWorld.screenTexture.mightHaveRamImage():
|
||||
# tex = self.panda3DWorld.screenTexture
|
||||
# gsg = base.win.getGsg()
|
||||
# #self.panda3DWorld.screenTexture.store(gsg)
|
||||
# base.graphicsEngine.extractTextureData(tex, gsg)
|
||||
# self.panda3DWorld.screenTexture.setFormat(Texture.FRgba32)
|
||||
# data = self.panda3DWorld.screenTexture.getRamImage().getData()
|
||||
# img = QImage(data, self.panda3DWorld.screenTexture.getXSize(), self.panda3DWorld.screenTexture.getYSize(),
|
||||
# QImage.Format_ARGB32).mirrored()
|
||||
# self.paintSurface.begin(self)
|
||||
# self.paintSurface.drawImage(0, 0, img)
|
||||
# self.paintSurface.end()
|
||||
|
||||
# def paintEvent(self, event):
|
||||
# tex = self.panda3DWorld.qt_output_tex
|
||||
#
|
||||
# gsg = base.win.getGsg()
|
||||
#
|
||||
#
|
||||
# if not self.rp_sync_requested:
|
||||
# base.graphicsEngine.extractTextureData(tex, gsg)
|
||||
# self.rp_sync_requested = True
|
||||
# self.update()
|
||||
# return
|
||||
#
|
||||
# if tex.hasRamImage():
|
||||
# data = tex.getRamImage().getData()
|
||||
# width = tex.getXSize()
|
||||
# height = tex.getYSize()
|
||||
#
|
||||
# # ✅ 应该 data 长度 = width * height * 4
|
||||
# img = QImage(data, width, height, QImage.Format_ARGB32).mirrored()
|
||||
#
|
||||
# painter = QPainter(self)
|
||||
# painter.drawImage(0, 0, img)
|
||||
# painter.end()
|
||||
#
|
||||
# self.rp_sync_requested = False
|
||||
# else:
|
||||
# print("⚠️ Texture has no RAM image yet, retrying next frame")
|
||||
# self.rp_sync_requested = False
|
||||
# self.update()
|
||||
|
||||
# def paintEvent(self, event):
|
||||
# tex = self.panda3DWorld.qt_output_tex
|
||||
#
|
||||
# gsg = base.win.getGsg()
|
||||
#
|
||||
# if not tex.hasRamImage():
|
||||
# base.graphicsEngine.extractTextureData(tex, gsg)
|
||||
# self.update() # 请求下一帧更新
|
||||
# return
|
||||
#
|
||||
# data = tex.getRamImage().getData()
|
||||
# width = tex.getXSize()
|
||||
# height = tex.getYSize()
|
||||
# expected_len = width * height * 4
|
||||
#
|
||||
# if len(data) != expected_len:
|
||||
# print(f"⚠️ 像素数据长度异常({len(data)} != {expected_len}),跳过绘制")
|
||||
# self.update()
|
||||
# return
|
||||
#
|
||||
# # 一切正常才绘制
|
||||
# img = QImage(data, width, height, QImage.Format_ARGB32).mirrored()
|
||||
#
|
||||
# painter = QPainter(self)
|
||||
# painter.drawImage(0, 0, img)
|
||||
# painter.end()
|
||||
|
||||
def paintEvent(self, event):
|
||||
tex = self.panda3DWorld.qt_output_tex
|
||||
gsg = base.win.getGsg()
|
||||
|
||||
if not gsg:
|
||||
self.update()
|
||||
return
|
||||
|
||||
if not tex.hasRamImage():
|
||||
base.graphicsEngine.extractTextureData(tex, gsg)
|
||||
self.update()
|
||||
return
|
||||
|
||||
data = tex.getRamImage().getData()
|
||||
tex_width = tex.getXSize()
|
||||
tex_height = tex.getYSize()
|
||||
expected_len = tex_width * tex_height * 4
|
||||
|
||||
if len(data) != expected_len:
|
||||
print(f"⚠️ 像素数据长度异常({len(data)} != {expected_len}),跳过绘制")
|
||||
self.update()
|
||||
return
|
||||
|
||||
img = QImage(data, tex_width, tex_height, QImage.Format_ARGB32).mirrored()
|
||||
|
||||
widget_width = self.width()
|
||||
widget_height = self.height()
|
||||
|
||||
painter = QPainter(self)
|
||||
|
||||
# 【保持宽高比的缩放】
|
||||
scaled_img = img.scaled(widget_width, widget_height, Qt.KeepAspectRatio, Qt.SmoothTransformation)
|
||||
|
||||
# 居中绘制
|
||||
x_offset = (widget_width - scaled_img.width()) // 2
|
||||
y_offset = (widget_height - scaled_img.height()) // 2
|
||||
|
||||
painter.drawImage(x_offset, y_offset, scaled_img)
|
||||
painter.end()
|
||||
|
||||
def sync_panda3d_window_size(self, width, height):
|
||||
"""同步 Panda3D 窗口尺寸到 Qt 窗口尺寸"""
|
||||
try:
|
||||
from panda3d.core import WindowProperties, LVecBase2i
|
||||
|
||||
# 确保尺寸是4的倍数(RenderPipeline 要求)
|
||||
adjusted_width = width - width % 4
|
||||
adjusted_height = height - height % 4
|
||||
|
||||
# 更新窗口属性
|
||||
props = WindowProperties()
|
||||
props.setSize(adjusted_width, adjusted_height)
|
||||
|
||||
# 对于 offscreen 渲染,直接更新窗口属性
|
||||
if self.panda3DWorld.win:
|
||||
self.panda3DWorld.win.request_properties(props)
|
||||
|
||||
# 手动触发 RenderPipeline 的尺寸更新逻辑
|
||||
if hasattr(self.panda3DWorld, 'render_pipeline'):
|
||||
# 更新全局分辨率
|
||||
from RenderPipelineFile.rpcore.globals import Globals
|
||||
Globals.native_resolution = LVecBase2i(adjusted_width, adjusted_height)
|
||||
|
||||
# 重新计算渲染分辨率
|
||||
self.panda3DWorld.render_pipeline._compute_render_resolution()
|
||||
|
||||
# 通知各个管理器处理尺寸变化
|
||||
self.panda3DWorld.render_pipeline.light_mgr.compute_tile_size()
|
||||
self.panda3DWorld.render_pipeline.stage_mgr.handle_window_resize()
|
||||
if hasattr(self.panda3DWorld.render_pipeline, 'debugger'):
|
||||
self.panda3DWorld.render_pipeline.debugger.handle_window_resize()
|
||||
|
||||
# 触发插件的窗口尺寸变化钩子
|
||||
self.panda3DWorld.render_pipeline.plugin_mgr.trigger_hook("window_resized")
|
||||
|
||||
print(f"Panda3D 窗口尺寸已同步为: {adjusted_width} x {adjusted_height}")
|
||||
|
||||
except Exception as e:
|
||||
print(f"同步 Panda3D 窗口尺寸失败: {str(e)}")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
52
QPanda3D/QPanda3D_Buttons_Translation.py
Normal file
@ -0,0 +1,52 @@
|
||||
# -*- coding: utf-8-*-
|
||||
"""
|
||||
Module : QPanda3D_Translation_Buttons
|
||||
Author : Niklas Mevenkamp
|
||||
Description :
|
||||
Contains a dictionary that translates QT mouse events to panda3d
|
||||
mouse events.
|
||||
"""
|
||||
# PyQt imports
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
import sys
|
||||
__all__ = ["QPanda3D_Keys_Translation"]
|
||||
|
||||
QPanda3D_Button_translation ={
|
||||
Qt.NoButton:'',
|
||||
Qt.AllButtons:'unknown',
|
||||
Qt.LeftButton:'mouse1',
|
||||
Qt.RightButton:'mouse2',
|
||||
Qt.MidButton:'mouse3',
|
||||
Qt.MiddleButton:'mouse3',
|
||||
Qt.BackButton:'unknown',
|
||||
Qt.XButton1:'unknown',
|
||||
Qt.ExtraButton1:'unknown',
|
||||
Qt.ForwardButton:'unknown',
|
||||
Qt.XButton2:'unknown',
|
||||
Qt.ExtraButton2:'unknown',
|
||||
Qt.TaskButton:'unknown',
|
||||
Qt.ExtraButton3:'unknown',
|
||||
Qt.ExtraButton4:'unknown',
|
||||
Qt.ExtraButton5:'unknown',
|
||||
Qt.ExtraButton6:'unknown',
|
||||
Qt.ExtraButton7:'unknown',
|
||||
Qt.ExtraButton8:'unknown',
|
||||
Qt.ExtraButton9:'unknown',
|
||||
Qt.ExtraButton10:'unknown',
|
||||
Qt.ExtraButton11:'unknown',
|
||||
Qt.ExtraButton12:'unknown',
|
||||
Qt.ExtraButton13:'unknown',
|
||||
Qt.ExtraButton14:'unknown',
|
||||
Qt.ExtraButton15:'unknown',
|
||||
Qt.ExtraButton16:'unknown',
|
||||
Qt.ExtraButton17:'unknown',
|
||||
Qt.ExtraButton18:'unknown',
|
||||
Qt.ExtraButton19:'unknown',
|
||||
Qt.ExtraButton20:'unknown',
|
||||
Qt.ExtraButton21:'unknown',
|
||||
Qt.ExtraButton22:'unknown',
|
||||
Qt.ExtraButton23:'unknown',
|
||||
Qt.ExtraButton24:'unknown',
|
||||
}
|
||||
486
QPanda3D/QPanda3D_Keys_Translation.py
Normal file
@ -0,0 +1,486 @@
|
||||
# -*- coding: utf-8-*-
|
||||
"""
|
||||
Module : QPanda3D_Translation_Keys
|
||||
Author : Saifeddine ALOUI
|
||||
Description :
|
||||
Contains a dictionary that translates QT keyboard events to panda3d
|
||||
keyboard events.
|
||||
"""
|
||||
# PyQt imports
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
import sys
|
||||
__all__ = ["QPanda3D_Keys_Translation"]
|
||||
|
||||
QPanda3D_Key_translation ={
|
||||
Qt.Key_0:'0',
|
||||
Qt.Key_1:'1',
|
||||
Qt.Key_2:'2',
|
||||
Qt.Key_3:'3',
|
||||
Qt.Key_4:'4',
|
||||
Qt.Key_5:'5',
|
||||
Qt.Key_6:'6',
|
||||
Qt.Key_7:'7',
|
||||
Qt.Key_8:'8',
|
||||
Qt.Key_9:'9',
|
||||
Qt.Key_A:'a',
|
||||
Qt.Key_AE:'ae',
|
||||
Qt.Key_Aacute:'unknown',
|
||||
Qt.Key_Acircumflex:'unknown',
|
||||
Qt.Key_AddFavorite:'unknown',
|
||||
Qt.Key_Adiaeresis:'unknown',
|
||||
Qt.Key_Agrave:'unknown',
|
||||
Qt.Key_Alt:'lalt',
|
||||
Qt.Key_AltGr:'unknown',
|
||||
Qt.Key_Ampersand:'unknown',
|
||||
Qt.Key_Any:'unknown',
|
||||
Qt.Key_Apostrophe:'unknown',
|
||||
Qt.Key_ApplicationLeft:'unknown',
|
||||
Qt.Key_ApplicationRight:'unknown',
|
||||
Qt.Key_Aring:'unknown',
|
||||
Qt.Key_AsciiCircum:'unknown',
|
||||
Qt.Key_AsciiTilde:'unknown',
|
||||
Qt.Key_Asterisk:'unknown',
|
||||
Qt.Key_At:'unknown',
|
||||
Qt.Key_Atilde:'unknown',
|
||||
Qt.Key_AudioCycleTrack:'unknown',
|
||||
Qt.Key_AudioForward:'unknown',
|
||||
Qt.Key_AudioRandomPlay:'unknown',
|
||||
Qt.Key_AudioRepeat:'unknown',
|
||||
Qt.Key_AudioRewind:'unknown',
|
||||
Qt.Key_Away:'unknown',
|
||||
Qt.Key_B:'b',
|
||||
Qt.Key_Back:'unknown',
|
||||
Qt.Key_BackForward:'unknown',
|
||||
Qt.Key_Backslash:'unknown',
|
||||
Qt.Key_Backspace:'unknown',
|
||||
Qt.Key_Backtab:'unknown',
|
||||
Qt.Key_Bar:'unknown',
|
||||
Qt.Key_BassBoost:'unknown',
|
||||
Qt.Key_BassDown:'unknown',
|
||||
Qt.Key_BassUp:'unknown',
|
||||
Qt.Key_Battery:'unknown',
|
||||
Qt.Key_Blue:'unknown',
|
||||
Qt.Key_Bluetooth:'unknown',
|
||||
Qt.Key_Book:'unknown',
|
||||
Qt.Key_BraceLeft:'unknown',
|
||||
Qt.Key_BraceRight:'unknown',
|
||||
Qt.Key_BracketLeft:'unknown',
|
||||
Qt.Key_BracketRight:'unknown',
|
||||
Qt.Key_BrightnessAdjust:'unknown',
|
||||
Qt.Key_C:'c',
|
||||
Qt.Key_CD:'unknown',
|
||||
Qt.Key_Calculator:'unknown',
|
||||
Qt.Key_Calendar:'unknown',
|
||||
Qt.Key_Call:'unknown',
|
||||
Qt.Key_Camera:'unknown',
|
||||
Qt.Key_CameraFocus:'unknown',
|
||||
Qt.Key_Cancel:'unknown',
|
||||
Qt.Key_CapsLock:'unknown',
|
||||
Qt.Key_Ccedilla:'unknown',
|
||||
Qt.Key_ChannelDown:'unknown',
|
||||
Qt.Key_ChannelUp:'unknown',
|
||||
Qt.Key_Clear:'unknown',
|
||||
Qt.Key_ClearGrab:'unknown',
|
||||
Qt.Key_Close:'unknown',
|
||||
Qt.Key_Codeinput:'unknown',
|
||||
Qt.Key_Colon:'unknown',
|
||||
Qt.Key_Comma:'unknown',
|
||||
Qt.Key_Community:'unknown',
|
||||
Qt.Key_Context1:'unknown',
|
||||
Qt.Key_Context2:'unknown',
|
||||
Qt.Key_Context3:'unknown',
|
||||
Qt.Key_Context4:'unknown',
|
||||
Qt.Key_ContrastAdjust:'unknown',
|
||||
Qt.Key_Control:'control',
|
||||
Qt.Key_Copy:'unknown',
|
||||
Qt.Key_Cut:'unknown',
|
||||
Qt.Key_D:'d',
|
||||
Qt.Key_DOS:'unknown',
|
||||
Qt.Key_Dead_A:'unknown',
|
||||
Qt.Key_Dead_Abovecomma:'unknown',
|
||||
Qt.Key_Dead_Abovedot:'unknown',
|
||||
Qt.Key_Dead_Abovereversedcomma:'unknown',
|
||||
Qt.Key_Dead_Abovering:'unknown',
|
||||
Qt.Key_Dead_Aboveverticalline:'unknown',
|
||||
Qt.Key_Dead_Acute:'unknown',
|
||||
Qt.Key_Dead_Belowbreve:'unknown',
|
||||
Qt.Key_Dead_Belowcircumflex:'unknown',
|
||||
Qt.Key_Dead_Belowcomma:'unknown',
|
||||
Qt.Key_Dead_Belowdiaeresis:'unknown',
|
||||
Qt.Key_Dead_Belowdot:'unknown',
|
||||
Qt.Key_Dead_Belowmacron:'unknown',
|
||||
Qt.Key_Dead_Belowring:'unknown',
|
||||
Qt.Key_Dead_Belowtilde:'unknown',
|
||||
Qt.Key_Dead_Belowverticalline:'unknown',
|
||||
Qt.Key_Dead_Breve:'unknown',
|
||||
Qt.Key_Dead_Capital_Schwa:'unknown',
|
||||
Qt.Key_Dead_Caron:'unknown',
|
||||
Qt.Key_Dead_Cedilla:'unknown',
|
||||
Qt.Key_Dead_Circumflex:'unknown',
|
||||
Qt.Key_Dead_Currency:'unknown',
|
||||
Qt.Key_Dead_Diaeresis:'unknown',
|
||||
Qt.Key_Dead_Doubleacute:'unknown',
|
||||
Qt.Key_Dead_Doublegrave:'unknown',
|
||||
Qt.Key_Dead_E:'unknown',
|
||||
Qt.Key_Dead_Grave:'unknown',
|
||||
Qt.Key_Dead_Greek:'unknown',
|
||||
Qt.Key_Dead_Hook:'unknown',
|
||||
Qt.Key_Dead_Horn:'unknown',
|
||||
Qt.Key_Dead_I:'unknown',
|
||||
Qt.Key_Dead_Invertedbreve:'unknown',
|
||||
Qt.Key_Dead_Iota:'unknown',
|
||||
Qt.Key_Dead_Longsolidusoverlay:'unknown',
|
||||
Qt.Key_Dead_Lowline:'unknown',
|
||||
Qt.Key_Dead_Macron:'unknown',
|
||||
Qt.Key_Dead_O:'unknown',
|
||||
Qt.Key_Dead_Ogonek:'unknown',
|
||||
Qt.Key_Dead_Semivoiced_Sound:'unknown',
|
||||
Qt.Key_Dead_Small_Schwa:'unknown',
|
||||
Qt.Key_Dead_Stroke:'unknown',
|
||||
Qt.Key_Dead_Tilde:'unknown',
|
||||
Qt.Key_Dead_U:'unknown',
|
||||
Qt.Key_Dead_Voiced_Sound:'unknown',
|
||||
Qt.Key_Dead_a:'unknown',
|
||||
Qt.Key_Dead_e:'unknown',
|
||||
Qt.Key_Dead_i:'unknown',
|
||||
Qt.Key_Dead_o:'unknown',
|
||||
Qt.Key_Dead_u:'unknown',
|
||||
Qt.Key_Delete:'delete',
|
||||
Qt.Key_Direction_L:'unknown',
|
||||
Qt.Key_Direction_R:'unknown',
|
||||
Qt.Key_Display:'unknown',
|
||||
Qt.Key_Documents:'unknown',
|
||||
Qt.Key_Dollar:'unknown',
|
||||
Qt.Key_Down:'arrow_down',
|
||||
Qt.Key_E:'e',
|
||||
Qt.Key_ETH:'unknown',
|
||||
Qt.Key_Eacute:'unknown',
|
||||
Qt.Key_Ecircumflex:'unknown',
|
||||
Qt.Key_Ediaeresis:'unknown',
|
||||
Qt.Key_Egrave:'unknown',
|
||||
Qt.Key_Eisu_Shift:'unknown',
|
||||
Qt.Key_Eisu_toggle:'unknown',
|
||||
Qt.Key_Eject:'unknown',
|
||||
Qt.Key_End:'unknown',
|
||||
Qt.Key_Enter:'unknown',
|
||||
Qt.Key_Equal:'unknown',
|
||||
Qt.Key_Escape:'escape',
|
||||
Qt.Key_Excel:'unknown',
|
||||
Qt.Key_Exclam:'unknown',
|
||||
Qt.Key_Execute:'unknown',
|
||||
Qt.Key_Exit:'unknown',
|
||||
Qt.Key_Explorer:'unknown',
|
||||
Qt.Key_F:'f',
|
||||
Qt.Key_F1:'f1',
|
||||
Qt.Key_F10:'f10',
|
||||
Qt.Key_F11:'f11',
|
||||
Qt.Key_F12:'f12',
|
||||
Qt.Key_F13:'f13',
|
||||
Qt.Key_F14:'f14',
|
||||
Qt.Key_F15:'f15',
|
||||
Qt.Key_F16:'f16',
|
||||
Qt.Key_F17:'f17',
|
||||
Qt.Key_F18:'f18',
|
||||
Qt.Key_F19:'unknown',
|
||||
Qt.Key_F2:'unknown',
|
||||
Qt.Key_F20:'unknown',
|
||||
Qt.Key_F21:'unknown',
|
||||
Qt.Key_F22:'unknown',
|
||||
Qt.Key_F23:'unknown',
|
||||
Qt.Key_F24:'unknown',
|
||||
Qt.Key_F25:'unknown',
|
||||
Qt.Key_F26:'unknown',
|
||||
Qt.Key_F27:'unknown',
|
||||
Qt.Key_F28:'unknown',
|
||||
Qt.Key_F29:'unknown',
|
||||
Qt.Key_F3:'f3',
|
||||
Qt.Key_F30:'unknown',
|
||||
Qt.Key_F31:'unknown',
|
||||
Qt.Key_F32:'unknown',
|
||||
Qt.Key_F33:'unknown',
|
||||
Qt.Key_F34:'unknown',
|
||||
Qt.Key_F35:'unknown',
|
||||
Qt.Key_F4:'f4',
|
||||
Qt.Key_F5:'f5',
|
||||
Qt.Key_F6:'f6',
|
||||
Qt.Key_F7:'f7',
|
||||
Qt.Key_F8:'f8',
|
||||
Qt.Key_F9:'f9',
|
||||
Qt.Key_Favorites:'unknown',
|
||||
Qt.Key_Finance:'unknown',
|
||||
Qt.Key_Find:'unknown',
|
||||
Qt.Key_Flip:'unknown',
|
||||
Qt.Key_Forward:'unknown',
|
||||
Qt.Key_G:'g',
|
||||
Qt.Key_Game:'unknown',
|
||||
Qt.Key_Go:'unknown',
|
||||
Qt.Key_Greater:'unknown',
|
||||
Qt.Key_Green:'unknown',
|
||||
Qt.Key_Guide:'unknown',
|
||||
Qt.Key_H:'h',
|
||||
Qt.Key_Hangul:'unknown',
|
||||
Qt.Key_Hangul_Banja:'unknown',
|
||||
Qt.Key_Hangul_End:'unknown',
|
||||
Qt.Key_Hangul_Hanja:'unknown',
|
||||
Qt.Key_Hangul_Jamo:'unknown',
|
||||
Qt.Key_Hangul_Jeonja:'unknown',
|
||||
Qt.Key_Hangul_PostHanja:'unknown',
|
||||
Qt.Key_Hangul_PreHanja:'unknown',
|
||||
Qt.Key_Hangul_Romaja:'unknown',
|
||||
Qt.Key_Hangul_Special:'unknown',
|
||||
Qt.Key_Hangul_Start:'unknown',
|
||||
Qt.Key_Hangup:'unknown',
|
||||
Qt.Key_Hankaku:'unknown',
|
||||
Qt.Key_Help:'unknown',
|
||||
Qt.Key_Henkan:'unknown',
|
||||
Qt.Key_Hibernate:'unknown',
|
||||
Qt.Key_Hiragana:'unknown',
|
||||
Qt.Key_Hiragana_Katakana:'unknown',
|
||||
Qt.Key_History:'unknown',
|
||||
Qt.Key_Home:'home',
|
||||
Qt.Key_HomePage:'unknown',
|
||||
Qt.Key_HotLinks:'unknown',
|
||||
Qt.Key_Hyper_L:'unknown',
|
||||
Qt.Key_Hyper_R:'unknown',
|
||||
Qt.Key_I:'i',
|
||||
Qt.Key_Iacute:'unknown',
|
||||
Qt.Key_Icircumflex:'unknown',
|
||||
Qt.Key_Idiaeresis:'unknown',
|
||||
Qt.Key_Igrave:'unknown',
|
||||
Qt.Key_Info:'unknown',
|
||||
Qt.Key_Insert:'unknown',
|
||||
Qt.Key_J:'j',
|
||||
Qt.Key_K:'k',
|
||||
Qt.Key_Kana_Lock:'unknown',
|
||||
Qt.Key_Kana_Shift:'unknown',
|
||||
Qt.Key_Kanji:'unknown',
|
||||
Qt.Key_Katakana:'unknown',
|
||||
Qt.Key_KeyboardBrightnessDown:'unknown',
|
||||
Qt.Key_KeyboardBrightnessUp:'unknown',
|
||||
Qt.Key_KeyboardLightOnOff:'unknown',
|
||||
Qt.Key_L:'l',
|
||||
Qt.Key_LastNumberRedial:'unknown',
|
||||
Qt.Key_Launch0:'unknown',
|
||||
Qt.Key_Launch1:'unknown',
|
||||
Qt.Key_Launch2:'unknown',
|
||||
Qt.Key_Launch3:'unknown',
|
||||
Qt.Key_Launch4:'unknown',
|
||||
Qt.Key_Launch5:'unknown',
|
||||
Qt.Key_Launch6:'unknown',
|
||||
Qt.Key_Launch7:'unknown',
|
||||
Qt.Key_Launch8:'unknown',
|
||||
Qt.Key_Launch9:'unknown',
|
||||
Qt.Key_LaunchA:'unknown',
|
||||
Qt.Key_LaunchB:'unknown',
|
||||
Qt.Key_LaunchC:'unknown',
|
||||
Qt.Key_LaunchD:'unknown',
|
||||
Qt.Key_LaunchE:'unknown',
|
||||
Qt.Key_LaunchF:'unknown',
|
||||
Qt.Key_LaunchG:'unknown',
|
||||
Qt.Key_LaunchH:'unknown',
|
||||
Qt.Key_LaunchMail:'unknown',
|
||||
Qt.Key_LaunchMedia:'unknown',
|
||||
Qt.Key_Left:'arrow_left',
|
||||
Qt.Key_Less:'unknown',
|
||||
Qt.Key_LightBulb:'unknown',
|
||||
Qt.Key_LogOff:'unknown',
|
||||
Qt.Key_M:'m',
|
||||
Qt.Key_MailForward:'unknown',
|
||||
Qt.Key_Market:'unknown',
|
||||
Qt.Key_Massyo:'unknown',
|
||||
Qt.Key_MediaLast:'unknown',
|
||||
Qt.Key_MediaNext:'unknown',
|
||||
Qt.Key_MediaPause:'unknown',
|
||||
Qt.Key_MediaPlay:'unknown',
|
||||
Qt.Key_MediaPrevious:'unknown',
|
||||
Qt.Key_MediaRecord:'unknown',
|
||||
Qt.Key_MediaStop:'unknown',
|
||||
Qt.Key_MediaTogglePlayPause:'unknown',
|
||||
Qt.Key_Meeting:'unknown',
|
||||
Qt.Key_Memo:'unknown',
|
||||
Qt.Key_Menu:'unknown',
|
||||
Qt.Key_MenuKB:'unknown',
|
||||
Qt.Key_MenuPB:'unknown',
|
||||
Qt.Key_Messenger:'unknown',
|
||||
Qt.Key_Meta:'unknown',
|
||||
Qt.Key_MicMute:'unknown',
|
||||
Qt.Key_MicVolumeDown:'unknown',
|
||||
Qt.Key_MicVolumeUp:'unknown',
|
||||
Qt.Key_Minus:'unknown',
|
||||
Qt.Key_Mode_switch:'unknown',
|
||||
Qt.Key_MonBrightnessDown:'unknown',
|
||||
Qt.Key_MonBrightnessUp:'unknown',
|
||||
Qt.Key_Muhenkan:'unknown',
|
||||
Qt.Key_Multi_key:'unknown',
|
||||
Qt.Key_MultipleCandidate:'unknown',
|
||||
Qt.Key_Music:'unknown',
|
||||
Qt.Key_MySites:'unknown',
|
||||
Qt.Key_N:'n',
|
||||
Qt.Key_New:'unknown',
|
||||
Qt.Key_News:'unknown',
|
||||
Qt.Key_No:'unknown',
|
||||
Qt.Key_Ntilde:'unknown',
|
||||
Qt.Key_NumLock:'unknown',
|
||||
Qt.Key_NumberSign:'unknown',
|
||||
Qt.Key_O:'o',
|
||||
Qt.Key_Oacute:'unknown',
|
||||
Qt.Key_Ocircumflex:'unknown',
|
||||
Qt.Key_Odiaeresis:'unknown',
|
||||
Qt.Key_OfficeHome:'unknown',
|
||||
Qt.Key_Ograve:'unknown',
|
||||
Qt.Key_Ooblique:'unknown',
|
||||
Qt.Key_Open:'unknown',
|
||||
Qt.Key_OpenUrl:'unknown',
|
||||
Qt.Key_Option:'unknown',
|
||||
Qt.Key_Otilde:'unknown',
|
||||
Qt.Key_P:'p',
|
||||
Qt.Key_PageDown:'unknown',
|
||||
Qt.Key_PageUp:'unknown',
|
||||
Qt.Key_ParenLeft:'unknown',
|
||||
Qt.Key_ParenRight:'unknown',
|
||||
Qt.Key_Paste:'unknown',
|
||||
Qt.Key_Pause:'unknown',
|
||||
Qt.Key_Percent:'unknown',
|
||||
Qt.Key_Period:'unknown',
|
||||
Qt.Key_Phone:'unknown',
|
||||
Qt.Key_Pictures:'unknown',
|
||||
Qt.Key_Play:'unknown',
|
||||
Qt.Key_Plus:'unknown',
|
||||
Qt.Key_PowerDown:'unknown',
|
||||
Qt.Key_PowerOff:'unknown',
|
||||
Qt.Key_PreviousCandidate:'unknown',
|
||||
Qt.Key_Print:'unknown',
|
||||
Qt.Key_Printer:'unknown',
|
||||
Qt.Key_Q:'q',
|
||||
Qt.Key_Question:'unknown',
|
||||
Qt.Key_QuoteDbl:'unknown',
|
||||
Qt.Key_QuoteLeft:'unknown',
|
||||
Qt.Key_R:'r',
|
||||
Qt.Key_Red:'unknown',
|
||||
Qt.Key_Redo:'unknown',
|
||||
Qt.Key_Refresh:'unknown',
|
||||
Qt.Key_Reload:'unknown',
|
||||
Qt.Key_Reply:'unknown',
|
||||
Qt.Key_Return:'unknown',
|
||||
Qt.Key_Right:'arrow_right',
|
||||
Qt.Key_Romaji:'unknown',
|
||||
Qt.Key_RotateWindows:'unknown',
|
||||
Qt.Key_RotationKB:'unknown',
|
||||
Qt.Key_RotationPB:'unknown',
|
||||
Qt.Key_S:'s',
|
||||
Qt.Key_Save:'unknown',
|
||||
Qt.Key_ScreenSaver:'unknown',
|
||||
Qt.Key_ScrollLock:'unknown',
|
||||
Qt.Key_Search:'unknown',
|
||||
Qt.Key_Select:'unknown',
|
||||
Qt.Key_Semicolon:'unknown',
|
||||
Qt.Key_Send:'unknown',
|
||||
Qt.Key_Settings:'unknown',
|
||||
Qt.Key_Shift:'unknown',
|
||||
Qt.Key_Shop:'unknown',
|
||||
Qt.Key_SingleCandidate:'unknown',
|
||||
Qt.Key_Slash:'unknown',
|
||||
Qt.Key_Sleep:'unknown',
|
||||
Qt.Key_Space:'space',
|
||||
Qt.Key_Spell:'unknown',
|
||||
Qt.Key_SplitScreen:'unknown',
|
||||
Qt.Key_Standby:'unknown',
|
||||
Qt.Key_Stop:'unknown',
|
||||
Qt.Key_Subtitle:'unknown',
|
||||
Qt.Key_Super_L:'unknown',
|
||||
Qt.Key_Super_R:'unknown',
|
||||
Qt.Key_Support:'unknown',
|
||||
Qt.Key_Suspend:'unknown',
|
||||
Qt.Key_SysReq:'unknown',
|
||||
Qt.Key_T:'t',
|
||||
Qt.Key_THORN:'unknown',
|
||||
Qt.Key_Tab:'unknown',
|
||||
Qt.Key_TaskPane:'unknown',
|
||||
Qt.Key_Terminal:'unknown',
|
||||
Qt.Key_Time:'unknown',
|
||||
Qt.Key_ToDoList:'unknown',
|
||||
Qt.Key_ToggleCallHangup:'unknown',
|
||||
Qt.Key_Tools:'unknown',
|
||||
Qt.Key_TopMenu:'unknown',
|
||||
Qt.Key_TouchpadOff:'unknown',
|
||||
Qt.Key_TouchpadOn:'unknown',
|
||||
Qt.Key_TouchpadToggle:'unknown',
|
||||
Qt.Key_Touroku:'unknown',
|
||||
Qt.Key_Travel:'unknown',
|
||||
Qt.Key_TrebleDown:'unknown',
|
||||
Qt.Key_TrebleUp:'unknown',
|
||||
Qt.Key_U:'u',
|
||||
Qt.Key_UWB:'unknown',
|
||||
Qt.Key_Uacute:'unknown',
|
||||
Qt.Key_Ucircumflex:'unknown',
|
||||
Qt.Key_Udiaeresis:'unknown',
|
||||
Qt.Key_Ugrave:'unknown',
|
||||
Qt.Key_Underscore:'unknown',
|
||||
Qt.Key_Undo:'unknown',
|
||||
Qt.Key_Up:'arrow_up',
|
||||
Qt.Key_V:'v',
|
||||
Qt.Key_Video:'unknown',
|
||||
Qt.Key_View:'unknown',
|
||||
Qt.Key_VoiceDial:'unknown',
|
||||
Qt.Key_VolumeDown:'unknown',
|
||||
Qt.Key_VolumeMute:'unknown',
|
||||
Qt.Key_VolumeUp:'unknown',
|
||||
Qt.Key_W:'w',
|
||||
Qt.Key_WLAN:'unknown',
|
||||
Qt.Key_WWW:'unknown',
|
||||
Qt.Key_WakeUp:'unknown',
|
||||
Qt.Key_WebCam:'unknown',
|
||||
Qt.Key_Word:'unknown',
|
||||
Qt.Key_X:'x',
|
||||
Qt.Key_Xfer:'unknown',
|
||||
Qt.Key_Y:'y',
|
||||
Qt.Key_Yacute:'unknown',
|
||||
Qt.Key_Yellow:'unknown',
|
||||
Qt.Key_Yes:'unknown',
|
||||
Qt.Key_Z:'z',
|
||||
Qt.Key_Zenkaku:'unknown',
|
||||
Qt.Key_Zenkaku_Hankaku:'unknown',
|
||||
Qt.Key_Zoom:'unknown',
|
||||
Qt.Key_ZoomIn:'unknown',
|
||||
Qt.Key_ZoomOut:'unknown',
|
||||
Qt.Key_acute:'unknown',
|
||||
Qt.Key_brokenbar:'unknown',
|
||||
Qt.Key_cedilla:'unknown',
|
||||
Qt.Key_cent:'unknown',
|
||||
Qt.Key_copyright:'unknown',
|
||||
Qt.Key_currency:'unknown',
|
||||
Qt.Key_degree:'unknown',
|
||||
Qt.Key_diaeresis:'unknown',
|
||||
Qt.Key_division:'unknown',
|
||||
Qt.Key_exclamdown:'unknown',
|
||||
Qt.Key_guillemotleft:'unknown',
|
||||
Qt.Key_guillemotright:'unknown',
|
||||
Qt.Key_hyphen:'unknown',
|
||||
Qt.Key_iTouch:'unknown',
|
||||
Qt.Key_macron:'unknown',
|
||||
Qt.Key_masculine:'unknown',
|
||||
Qt.Key_mu:'unknown',
|
||||
Qt.Key_multiply:'unknown',
|
||||
Qt.Key_nobreakspace:'unknown',
|
||||
Qt.Key_notsign:'unknown',
|
||||
Qt.Key_onehalf:'unknown',
|
||||
Qt.Key_onequarter:'unknown',
|
||||
Qt.Key_onesuperior:'unknown',
|
||||
Qt.Key_ordfeminine:'unknown',
|
||||
Qt.Key_paragraph:'unknown',
|
||||
Qt.Key_periodcentered:'unknown',
|
||||
Qt.Key_plusminus:'unknown',
|
||||
Qt.Key_questiondown:'unknown',
|
||||
Qt.Key_registered:'unknown',
|
||||
Qt.Key_section:'unknown',
|
||||
Qt.Key_ssharp:'unknown',
|
||||
Qt.Key_sterling:'unknown',
|
||||
Qt.Key_threequarters:'unknown',
|
||||
Qt.Key_threesuperior:'unknown',
|
||||
Qt.Key_twosuperior:'unknown',
|
||||
Qt.Key_unknown:'unknown',
|
||||
Qt.Key_ydiaeresis:'unknown',
|
||||
Qt.Key_yen:'unknown',
|
||||
}
|
||||
24
QPanda3D/QPanda3D_Modifiers_Translation.py
Normal file
@ -0,0 +1,24 @@
|
||||
# -*- coding: utf-8-*-
|
||||
"""
|
||||
Module : QPanda3D_Translation_Modifiers
|
||||
Author : Niklas Mevenkamp
|
||||
Description :
|
||||
Contains a dictionary that translates QT keyboard events to panda3d
|
||||
keyboard events.
|
||||
"""
|
||||
# PyQt imports
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
import sys
|
||||
__all__ = ["QPanda3D_Modifiers_Translation"]
|
||||
|
||||
QPanda3D_Modifier_translation ={
|
||||
Qt.NoModifier:None,
|
||||
Qt.ShiftModifier:'shift',
|
||||
Qt.ControlModifier:'control',
|
||||
Qt.AltModifier:'alt',
|
||||
Qt.MetaModifier:'unknown',
|
||||
Qt.KeypadModifier:'unknown',
|
||||
Qt.GroupSwitchModifier:'unknown',
|
||||
}
|
||||
2
QPanda3D/Tools/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
name="QPanda3D"
|
||||
__all__ = ["generate_qt_to_pd3d_translator"]
|
||||
BIN
QPanda3D/Tools/__pycache__/__init__.cpython-312.pyc
Normal file
11
QPanda3D/Tools/generate_qt_to_pd3d_translator.py
Normal file
@ -0,0 +1,11 @@
|
||||
from PyQt5.QtCore import *
|
||||
from PyQt5.QtGui import *
|
||||
from PyQt5.QtWidgets import *
|
||||
|
||||
H=Qt.__dict__
|
||||
lst = [a for a in H if a.startswith("Key_")]
|
||||
QPanda3D_Key_translation ="QPanda3D_Key_translation ={"
|
||||
for i in range(len(lst)):
|
||||
QPanda3D_Key_translation +="Qt.{}:'unknown',\n".format(lst[i])
|
||||
QPanda3D_Key_translation += "}"
|
||||
print(QPanda3D_Key_translation)
|
||||
2
QPanda3D/__init__.py
Normal file
@ -0,0 +1,2 @@
|
||||
name="QPanda3D"
|
||||
__all__ = ["QPanda3DWidget", "Panda3DWorld", "QPanda3D_Keys_Translation"]
|
||||
BIN
QPanda3D/__pycache__/Panda3DWorld.cpython-310.pyc
Normal file
BIN
QPanda3D/__pycache__/Panda3DWorld.cpython-312.pyc
Normal file
BIN
QPanda3D/__pycache__/QMouseWatcherNode.cpython-310.pyc
Normal file
BIN
QPanda3D/__pycache__/QMouseWatcherNode.cpython-312.pyc
Normal file
BIN
QPanda3D/__pycache__/QPanda3DWidget.cpython-310.pyc
Normal file
BIN
QPanda3D/__pycache__/QPanda3DWidget.cpython-312.pyc
Normal file
BIN
QPanda3D/__pycache__/QPanda3D_Keys_Translation.cpython-310.pyc
Normal file
BIN
QPanda3D/__pycache__/QPanda3D_Keys_Translation.cpython-312.pyc
Normal file
BIN
QPanda3D/__pycache__/__init__.cpython-310.pyc
Normal file
BIN
QPanda3D/__pycache__/__init__.cpython-312.pyc
Normal file
4
RenderPipelineFile/.flake8
Normal file
@ -0,0 +1,4 @@
|
||||
[flake8]
|
||||
max-line-length=100
|
||||
exclude=rplibs/*,data/*,hosek_wilkie_scattering,bake_gi,_DEV,*_generated.py,resources_rc.py
|
||||
|
||||
60
RenderPipelineFile/.gitignore
vendored
Normal file
@ -0,0 +1,60 @@
|
||||
# --- Ignored extensions ---
|
||||
*.pyd
|
||||
*.pyc
|
||||
*.ignore
|
||||
*.old
|
||||
*.egg
|
||||
*.psd
|
||||
*.blend1
|
||||
*.blend2
|
||||
*.pdb
|
||||
*.stackdump
|
||||
*.exr
|
||||
*.trace
|
||||
*.autogen*
|
||||
*.mip
|
||||
mitsuba.*.log
|
||||
*.exr
|
||||
*.txo.pz
|
||||
|
||||
|
||||
# --- Ignored folders and patterns ---
|
||||
temp/
|
||||
models/
|
||||
data/film_grain/*.png
|
||||
data/default_cubemap/filtered/
|
||||
_DEV
|
||||
toolkit/pathtracing_reference/mitsuba/
|
||||
toolkit/pathtracing_reference/scene*.png
|
||||
toolkit/pathtracing_reference/Scene*.blend
|
||||
toolkit/pathtracing_reference/envmap.png
|
||||
rpplugins/clouds/resources/slices/*
|
||||
|
||||
toolkit/rp_distributor/built/
|
||||
|
||||
# --- Ignored files ---
|
||||
TODO.txt
|
||||
*.flag
|
||||
desktop.ini
|
||||
scattering_lut.png
|
||||
old/
|
||||
data/gui/loading_screen
|
||||
data/environment_brdf/scene.png
|
||||
data/environment_brdf/res/scene.png
|
||||
toolkit/pathtracing_reference/batch_compare/
|
||||
toolkit/pathtracing_reference/difference.png
|
||||
toolkit/pathtracing_reference/res/Scene.blend
|
||||
toolkit/pathtracing_reference/res/scene.png
|
||||
toolkit/pathtracing_reference/scene*.png
|
||||
toolkit/pathtracing_reference/res/tex/envmap.png
|
||||
_tmp_material.py
|
||||
|
||||
*/poisson_disk_generator/source/config_module*
|
||||
|
||||
_bake_params*
|
||||
raw-bake.png
|
||||
toolkit/bake_gi/resources/*.bam
|
||||
toolkit/bake_gi/resources/*.blend
|
||||
toolkit/bake_gi/scene
|
||||
|
||||
.vscode
|
||||
3
RenderPipelineFile/.idea/.gitignore
generated
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
# 默认忽略的文件
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
14
RenderPipelineFile/.idea/RenderPipeline-master.iml
generated
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="PYTHON_MODULE" version="4">
|
||||
<component name="NewModuleRootManager">
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<excludeFolder url="file://$MODULE_DIR$/.venv" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="Python 3.10 (RenderPipeline-master) (2)" jdkType="Python SDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
</component>
|
||||
<component name="PyDocumentationSettings">
|
||||
<option name="format" value="PLAIN" />
|
||||
<option name="myDocStringFormat" value="Plain" />
|
||||
</component>
|
||||
</module>
|
||||
12
RenderPipelineFile/.idea/inspectionProfiles/Project_Default.xml
generated
Normal file
@ -0,0 +1,12 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<profile version="1.0">
|
||||
<option name="myName" value="Project Default" />
|
||||
<inspection_tool class="PyStubPackagesAdvertiser" enabled="true" level="WARNING" enabled_by_default="true">
|
||||
<option name="ignoredPackages">
|
||||
<list>
|
||||
<option value="PyQt5-stubs==5.15.6.0" />
|
||||
</list>
|
||||
</option>
|
||||
</inspection_tool>
|
||||
</profile>
|
||||
</component>
|
||||
6
RenderPipelineFile/.idea/inspectionProfiles/profiles_settings.xml
generated
Normal file
@ -0,0 +1,6 @@
|
||||
<component name="InspectionProjectProfileManager">
|
||||
<settings>
|
||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||
<version value="1.0" />
|
||||
</settings>
|
||||
</component>
|
||||
7
RenderPipelineFile/.idea/misc.xml
generated
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.10 (RenderPipeline-master) (2)" project-jdk-type="Python SDK" />
|
||||
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||
<option name="version" value="3" />
|
||||
</component>
|
||||
</project>
|
||||
8
RenderPipelineFile/.idea/modules.xml
generated
Normal file
@ -0,0 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="ProjectModuleManager">
|
||||
<modules>
|
||||
<module fileurl="file://$PROJECT_DIR$/.idea/RenderPipeline-master.iml" filepath="$PROJECT_DIR$/.idea/RenderPipeline-master.iml" />
|
||||
</modules>
|
||||
</component>
|
||||
</project>
|
||||
379
RenderPipelineFile/.pylintrc
Normal file
@ -0,0 +1,379 @@
|
||||
[MASTER]
|
||||
|
||||
# Specify a configuration file.
|
||||
#rcfile=
|
||||
|
||||
# Python code to execute, usually for sys.path manipulation such as
|
||||
# pygtk.require().
|
||||
init-hook=
|
||||
|
||||
# Add files or directories to the blacklist. They should be base names, not
|
||||
# paths.
|
||||
ignore=CVS,rplibs,.git,scripts,build.py
|
||||
|
||||
# Pickle collected data for later comparisons.
|
||||
persistent=yes
|
||||
|
||||
# List of plugins (as comma separated values of python modules names) to load,
|
||||
# usually to register additional checkers.
|
||||
load-plugins=
|
||||
|
||||
# Use multiple processes to speed up Pylint.
|
||||
jobs=1
|
||||
|
||||
# Allow loading of arbitrary C extensions. Extensions are imported into the
|
||||
# active Python interpreter and may run arbitrary code.
|
||||
unsafe-load-any-extension=no
|
||||
|
||||
# A comma-separated list of package or module names from where C extensions may
|
||||
# be loaded. Extensions are loading into the active Python interpreter and may
|
||||
# run arbitrary code
|
||||
extension-pkg-whitelist=
|
||||
|
||||
# Allow optimization of some AST trees. This will activate a peephole AST
|
||||
# optimizer, which will apply various small optimizations. For instance, it can
|
||||
# be used to obtain the result of joining multiple strings with the addition
|
||||
# operator. Joining a lot of strings can lead to a maximum recursion error in
|
||||
# Pylint and this flag can prevent that. It has one side effect, the resulting
|
||||
# AST will be different than the one from reality.
|
||||
optimize-ast=yes
|
||||
|
||||
|
||||
[MESSAGES CONTROL]
|
||||
|
||||
# Only show warnings with the listed confidence levels. Leave empty to show
|
||||
# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED
|
||||
confidence=
|
||||
|
||||
# Enable the message, report, category or checker with the given id(s). You can
|
||||
# either give multiple identifier separated by comma (,) or put this option
|
||||
# multiple time. See also the "--disable" option for examples.
|
||||
#enable=
|
||||
|
||||
# Disable the message, report, category or checker with the given id(s). You
|
||||
# can either give multiple identifiers separated by comma (,) or put this
|
||||
# option multiple times (only on the command line, not in the configuration
|
||||
# file where it should appear only once).You can also use "--disable=all" to
|
||||
# disable everything first and then reenable specific checks. For example, if
|
||||
# you want to run only the similarities checker, you can use "--disable=all
|
||||
# --enable=similarities". If you want to run only the classes checker, but have
|
||||
# no Warning level messages displayed, use"--disable=all --enable=classes
|
||||
# --disable=W"
|
||||
disable=import-star-module-level,old-octal-literal,oct-method,print-statement,unpacking-in-except,parameter-unpacking,backtick,old-raise-syntax,old-ne-operator,long-suffix,dict-view-method,dict-iter-method,metaclass-assignment,next-method-called,raising-string,indexing-exception,raw_input-builtin,long-builtin,file-builtin,execfile-builtin,coerce-builtin,cmp-builtin,buffer-builtin,basestring-builtin,apply-builtin,filter-builtin-not-iterating,using-cmp-argument,useless-suppression,range-builtin-not-iterating,suppressed-message,no-absolute-import,old-division,cmp-method,reload-builtin,zip-builtin-not-iterating,intern-builtin,unichr-builtin,reduce-builtin,standarderror-builtin,unicode-builtin,xrange-builtin,coerce-method,delslice-method,getslice-method,setslice-method,input-builtin,round-builtin,hex-method,nonzero-method,map-builtin-not-iterating,E0611,W0622,W0201,C0111,R0201,R0913,R0902,R0904,R0914
|
||||
|
||||
|
||||
[REPORTS]
|
||||
|
||||
# Set the output format. Available formats are text, parseable, colorized, msvs
|
||||
# (visual studio) and html. You can also give a reporter class, eg
|
||||
# mypackage.mymodule.MyReporterClass.
|
||||
output-format=text
|
||||
|
||||
# Put messages in a separate file for each module / package specified on the
|
||||
# command line instead of printing them on stdout. Reports (if any) will be
|
||||
# written in a file name "pylint_global.[txt|html]".
|
||||
files-output=no
|
||||
|
||||
# Tells whether to display a full report or only the messages
|
||||
reports=yes
|
||||
|
||||
# Python expression which should return a note less than 10 (10 is the highest
|
||||
# note). You have access to the variables errors warning, statement which
|
||||
# respectively contain the number of errors / warnings messages and the total
|
||||
# number of statements analyzed. This is used by the global evaluation report
|
||||
# (RP0004).
|
||||
evaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)
|
||||
|
||||
# Template used to display messages. This is a python new-style format string
|
||||
# used to format the message information. See doc for all details
|
||||
#msg-template=
|
||||
|
||||
|
||||
[BASIC]
|
||||
|
||||
# List of builtins function names that should not be used, separated by a comma
|
||||
bad-functions=map,filter,input,xrange,iteritems,raw_input
|
||||
|
||||
# Good variable names which should always be accepted, separated by a comma
|
||||
good-names=i,j,k,ex,Run,_,x,y,r,g,b,a,uv,w,h,np
|
||||
|
||||
# Bad variable names which should always be refused, separated by a comma
|
||||
bad-names=foo,bar,baz,toto,tutu,tata,tmp,temp
|
||||
|
||||
# Colon-delimited sets of names that determine each other's naming style when
|
||||
# the name regexes allow several styles.
|
||||
name-group=
|
||||
|
||||
# Include a hint for the correct naming format with invalid-name
|
||||
include-naming-hint=no
|
||||
|
||||
# Regular expression matching correct function names
|
||||
function-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Naming hint for function names
|
||||
function-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression matching correct variable names
|
||||
variable-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Naming hint for variable names
|
||||
variable-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression matching correct constant names
|
||||
const-rgx=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Naming hint for constant names
|
||||
const-name-hint=(([A-Z_][A-Z0-9_]*)|(__.*__))$
|
||||
|
||||
# Regular expression matching correct attribute names
|
||||
attr-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Naming hint for attribute names
|
||||
attr-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression matching correct argument names
|
||||
argument-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Naming hint for argument names
|
||||
argument-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression matching correct class attribute names
|
||||
class-attribute-rgx=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Naming hint for class attribute names
|
||||
class-attribute-name-hint=([A-Za-z_][A-Za-z0-9_]{2,30}|(__.*__))$
|
||||
|
||||
# Regular expression matching correct inline iteration names
|
||||
inlinevar-rgx=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Naming hint for inline iteration names
|
||||
inlinevar-name-hint=[A-Za-z_][A-Za-z0-9_]*$
|
||||
|
||||
# Regular expression matching correct class names
|
||||
class-rgx=[A-Z_][a-zA-Z0-9]+$
|
||||
|
||||
# Naming hint for class names
|
||||
class-name-hint=[A-Z_][a-zA-Z0-9]+$
|
||||
|
||||
# Regular expression matching correct module names
|
||||
module-rgx=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Naming hint for module names
|
||||
module-name-hint=(([a-z_][a-z0-9_]*)|([A-Z][a-zA-Z0-9]+))$
|
||||
|
||||
# Regular expression matching correct method names
|
||||
method-rgx=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Naming hint for method names
|
||||
method-name-hint=[a-z_][a-z0-9_]{2,30}$
|
||||
|
||||
# Regular expression which should only match function or class names that do
|
||||
# not require a docstring.
|
||||
no-docstring-rgx=^_
|
||||
|
||||
# Minimum line length for functions/classes that require docstrings, shorter
|
||||
# ones are exempt.
|
||||
docstring-min-length=-1
|
||||
|
||||
|
||||
[ELIF]
|
||||
|
||||
# Maximum number of nested blocks for function / method body
|
||||
max-nested-blocks=4
|
||||
|
||||
|
||||
[FORMAT]
|
||||
|
||||
# Maximum number of characters on a single line.
|
||||
max-line-length=100
|
||||
|
||||
# Regexp for a line that is allowed to be longer than the limit.
|
||||
ignore-long-lines=^\s*(# )?<?https?://\S+>?$
|
||||
|
||||
# Allow the body of an if to be on the same line as the test if there is no
|
||||
# else.
|
||||
single-line-if-stmt=no
|
||||
|
||||
# List of optional constructs for which whitespace checking is disabled. `dict-
|
||||
# separator` is used to allow tabulation in dicts, etc.: {1 : 1,\n222: 2}.
|
||||
# `trailing-comma` allows a space between comma and closing bracket: (a, ).
|
||||
# `empty-line` allows space-only lines.
|
||||
no-space-check=trailing-comma,dict-separator
|
||||
|
||||
# Maximum number of lines in a module
|
||||
max-module-lines=1000
|
||||
|
||||
# String used as indentation unit. This is usually " " (4 spaces) or "\t" (1
|
||||
# tab).
|
||||
indent-string=' '
|
||||
|
||||
# Number of spaces of indent required inside a hanging or continued line.
|
||||
indent-after-paren=4
|
||||
|
||||
# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.
|
||||
expected-line-ending-format=
|
||||
|
||||
|
||||
[LOGGING]
|
||||
|
||||
# Logging modules to check that the string format arguments are in logging
|
||||
# function parameter format
|
||||
logging-modules=logging
|
||||
|
||||
|
||||
[MISCELLANEOUS]
|
||||
|
||||
# List of note tags to take in consideration, separated by a comma.
|
||||
notes=
|
||||
|
||||
|
||||
[SIMILARITIES]
|
||||
|
||||
# Minimum lines number of a similarity.
|
||||
min-similarity-lines=8
|
||||
|
||||
# Ignore comments when computing similarities.
|
||||
ignore-comments=yes
|
||||
|
||||
# Ignore docstrings when computing similarities.
|
||||
ignore-docstrings=yes
|
||||
|
||||
# Ignore imports when computing similarities.
|
||||
ignore-imports=no
|
||||
|
||||
|
||||
[SPELLING]
|
||||
|
||||
# Spelling dictionary name. Available dictionaries: none. To make it working
|
||||
# install python-enchant package.
|
||||
spelling-dict=
|
||||
|
||||
# List of comma separated words that should not be checked.
|
||||
spelling-ignore-words=
|
||||
|
||||
# A path to a file that contains private dictionary; one word per line.
|
||||
spelling-private-dict-file=
|
||||
|
||||
# Tells whether to store unknown words to indicated private dictionary in
|
||||
# --spelling-private-dict-file option instead of raising a message.
|
||||
spelling-store-unknown-words=no
|
||||
|
||||
|
||||
[TYPECHECK]
|
||||
|
||||
# Tells whether missing members accessed in mixin class should be ignored. A
|
||||
# mixin class is detected if its name ends with "mixin" (case insensitive).
|
||||
ignore-mixin-members=yes
|
||||
|
||||
# List of module names for which member attributes should not be checked
|
||||
# (useful for modules/projects where namespaces are manipulated during runtime
|
||||
# and thus existing member attributes cannot be deduced by static analysis. It
|
||||
# supports qualified module names, as well as Unix pattern matching.
|
||||
ignored-modules=
|
||||
|
||||
# List of classes names for which member attributes should not be checked
|
||||
# (useful for classes with attributes dynamically set). This supports can work
|
||||
# with qualified names.
|
||||
ignored-classes=
|
||||
|
||||
# List of members which are set dynamically and missed by pylint inference
|
||||
# system, and so shouldn't trigger E1101 when accessed. Python regular
|
||||
# expressions are accepted.
|
||||
generated-members=
|
||||
|
||||
|
||||
[VARIABLES]
|
||||
|
||||
# Tells whether we should check for unused import in __init__ files.
|
||||
init-import=no
|
||||
|
||||
# A regular expression matching the name of dummy variables (i.e. expectedly
|
||||
# not used).
|
||||
dummy-variables-rgx=_$|dummy
|
||||
|
||||
# List of additional names supposed to be defined in builtins. Remember that
|
||||
# you should avoid to define new builtins when possible.
|
||||
additional-builtins=
|
||||
|
||||
# List of strings which can identify a callback function by name. A callback
|
||||
# name must start or end with one of those strings.
|
||||
callbacks=cb_,_cb
|
||||
|
||||
|
||||
[CLASSES]
|
||||
|
||||
# List of method names used to declare (i.e. assign) instance attributes.
|
||||
defining-attr-methods=__init__,__new__,setup,init,load,create
|
||||
|
||||
# List of valid names for the first argument in a class method.
|
||||
valid-classmethod-first-arg=cls
|
||||
|
||||
# List of valid names for the first argument in a metaclass class method.
|
||||
valid-metaclass-classmethod-first-arg=mcs
|
||||
|
||||
# List of member names, which should be excluded from the protected access
|
||||
# warning.
|
||||
exclude-protected=_asdict,_fields,_replace,_source,_make
|
||||
|
||||
|
||||
[DESIGN]
|
||||
|
||||
# Maximum number of arguments for function / method
|
||||
max-args=5
|
||||
|
||||
# Argument names that match this expression will be ignored. Default to name
|
||||
# with leading underscore
|
||||
ignored-argument-names=_.*
|
||||
|
||||
# Maximum number of locals for function / method body
|
||||
max-locals=15
|
||||
|
||||
# Maximum number of return / yield for function / method body
|
||||
max-returns=6
|
||||
|
||||
# Maximum number of branch for function / method body
|
||||
max-branches=12
|
||||
|
||||
# Maximum number of statements in function / method body
|
||||
max-statements=50
|
||||
|
||||
# Maximum number of parents for a class (see R0901).
|
||||
max-parents=7
|
||||
|
||||
# Maximum number of attributes for a class (see R0902).
|
||||
max-attributes=7
|
||||
|
||||
# Minimum number of public methods for a class (see R0903).
|
||||
min-public-methods=2
|
||||
|
||||
# Maximum number of public methods for a class (see R0904).
|
||||
max-public-methods=20
|
||||
|
||||
# Maximum number of boolean expressions in a if statement
|
||||
max-bool-expr=5
|
||||
|
||||
|
||||
[IMPORTS]
|
||||
|
||||
# Deprecated modules which should not be used, separated by a comma
|
||||
deprecated-modules=regsub,TERMIOS,Bastion,rexec
|
||||
|
||||
# Create a graph of every (i.e. internal and external) dependencies in the
|
||||
# given file (report RP0402 must not be disabled)
|
||||
import-graph=
|
||||
|
||||
# Create a graph of external dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
ext-import-graph=
|
||||
|
||||
# Create a graph of internal dependencies in the given file (report RP0402 must
|
||||
# not be disabled)
|
||||
int-import-graph=
|
||||
|
||||
|
||||
[EXCEPTIONS]
|
||||
|
||||
# Exceptions that will emit a warning when being caught. Defaults to
|
||||
# "Exception"
|
||||
overgeneral-exceptions=Exception
|
||||
|
||||
18
RenderPipelineFile/.travis.yml
Normal file
@ -0,0 +1,18 @@
|
||||
language: cpp
|
||||
sudo: required
|
||||
dist: trusty
|
||||
compiler: gcc
|
||||
addons:
|
||||
apt:
|
||||
sources:
|
||||
- sourceline: "deb http://archive.panda3d.org/ubuntu/ trusty-dev main"
|
||||
packages:
|
||||
- cmake
|
||||
- libeigen3-dev
|
||||
- libfreetype6-dev
|
||||
- panda3d1.10
|
||||
|
||||
script:
|
||||
- export PYTHONPATH=${PYTHONPATH}:/usr/lib/python2.7/dist-packages
|
||||
- export PYTHONPATH=${PYTHONPATH}:/usr/share/panda3d
|
||||
- python2.7 setup.py --ci-build
|
||||
BIN
RenderPipelineFile/Default_NRM_2K.png
Normal file
|
After Width: | Height: | Size: 369 B |
BIN
RenderPipelineFile/Default_Rough.png
Normal file
|
After Width: | Height: | Size: 1.2 MiB |
22
RenderPipelineFile/LICENSE.txt
Normal file
@ -0,0 +1,22 @@
|
||||
|
||||
RenderPipeline
|
||||
|
||||
Copyright (c) 2014-2016 tobspr <tobias.springer1@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
70
RenderPipelineFile/README.md
Normal file
@ -0,0 +1,70 @@
|
||||
[](https://gitter.im/tobspr/RenderPipeline?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
||||
[](https://travis-ci.org/tobspr/RenderPipeline)
|
||||
<!-- # Render Pipeline -->
|
||||
|
||||
<img src="http://i.imgur.com/PO4OK4a.png" alt="Deferred Rendering Pipeline with Physically Based Shading" />
|
||||
|
||||
Deferred Realtime Rendering Pipeline with Physically Based Shading for the <a href="http://github.com/panda3d/panda3d">Panda3D Game Engine</a>.
|
||||
|
||||
### Core Features
|
||||
|
||||
- Physically Based Shading
|
||||
- Deferred Rendering
|
||||
- Advanced Post-Processing Effects and Framework
|
||||
- Time of Day System
|
||||
- Plugin System
|
||||
|
||||
## Screenshots
|
||||
|
||||
You can click on the images to enlarge them. Besides of that, you can find many more screenshots in my <a href="https://www.dropbox.com/sh/dq4wu3g9jwjqnht/AAABSOPnglDHZYsG5HXR-mhWa" target="_blank">dropbox folder</a>.
|
||||
|
||||
**Forest**
|
||||
<img src="http://i.imgur.com/fD88ZMU.png" />
|
||||
|
||||
**Material demo**
|
||||
<img src="http://i.imgur.com/M5YtvYR.png" />
|
||||
|
||||
**Screen space reflections**
|
||||
<img src="http://i.imgur.com/oOwLXAK.png" />
|
||||
|
||||
**Car rendering**
|
||||
<img src="http://i.imgur.com/hFD4qjV.png" alt="Car rendering" />
|
||||
|
||||
**Plugin and Time of Day editor:**
|
||||
<img src="http://i.imgur.com/a8VpiHS.png" />
|
||||
|
||||
**Terrain and volumetric clouds**
|
||||
<img src="http://i.imgur.com/zE0ywPl.png" />
|
||||
|
||||
|
||||
See the <a target="_blank" href="https://github.com/tobspr/RenderPipeline/wiki/Features">Feature List</a>
|
||||
for a list of features, and list of techniques I intend to implement.
|
||||
|
||||
You can find my todo list for the render pipeline here: <a href="https://trello.com/b/Li2JQi0q/render-pipeline" target="_blank">Render Pipeline Roadmap</a>.
|
||||
|
||||
### Getting Started / Wiki
|
||||
|
||||
You should checkout the wiki if you want to find out more about the pipeline:
|
||||
<a target="_blank" href="https://github.com/tobspr/RenderPipeline/wiki">Render Pipeline WIKI</a>
|
||||
|
||||
There is also a page about getting started there: <a target="_blank" href="https://github.com/tobspr/RenderPipeline/wiki/Getting%20Started">Getting Started</a>
|
||||
|
||||
### Requirements
|
||||
|
||||
- OpenGL 4.3 capable GPU (and drivers)
|
||||
- <a target="_blank" href="https://github.com/panda3d/panda3d">Panda3D</a> Development Build
|
||||
- 1 GB Graphics Memory recommended *(Can run with less, depends on enabled plugins and resolution)*
|
||||
|
||||
**Notice**: It seems that the drivers for Intel HD Graphics on Linux are not
|
||||
capable of all 4.3 features, so the pipeline is not able to run there!
|
||||
|
||||
If you want to use the C++ Modules, checkout <a href="https://github.com/tobspr/RenderPipeline/wiki/Building%20the%20CPP%20Modules" target="_blank">
|
||||
Building the C++ Modules</a> to get a list of requirements for them.
|
||||
|
||||
### Reporting Bugs / Contributing
|
||||
|
||||
If you find bugs, or find information missing in the wiki, or want to contribute,
|
||||
you can find me most of the time in the `#panda3d` channel on freenode.
|
||||
|
||||
If I shouldn't be there, feel free to contact me per E-Mail: `tobias.springer1@googlemail.com`
|
||||
|
||||
0
RenderPipelineFile/__init__.py
Normal file
27
RenderPipelineFile/config/daytime.yaml
Normal file
30
RenderPipelineFile/config/debugging.yaml
Normal file
@ -0,0 +1,30 @@
|
||||
|
||||
# This file contains all available debug modes.
|
||||
# You can add or remove debug modes here, aswell as
|
||||
# disable or enable them, whatever fits to you.
|
||||
|
||||
# NOTICE: This file only has effect if debugging is enabled
|
||||
# in the pipeline.yaml (settings.pipeline.display_debuger == True)
|
||||
|
||||
# Usually you don't have to touch this file, except when developing
|
||||
# new plugins or adding new features.
|
||||
|
||||
render_modes:
|
||||
- { name: "Shading Model", key: "SHADING_MODEL" }
|
||||
- { name: "Diffuse", key: "DIFFUSE" }
|
||||
- { name: "Roughness", key: "ROUGHNESS" }
|
||||
- { name: "Specular", key: "SPECULAR" }
|
||||
- { name: "Normal", key: "NORMAL" }
|
||||
- { name: "Metallic", key: "METALLIC" }
|
||||
- { name: "Translucency", key: "TRANSLUCENCY" }
|
||||
- { name: "PSSM Splits", key: "PSSM_SPLITS", requires: "pssm", cxx_only: true }
|
||||
- { name: "Ambient Occlusion", key: "OCCLUSION", requires: "ao" }
|
||||
- { name: "Sky AO", key: "SKY_AO", requires: "sky_ao" }
|
||||
- { name: "Scattering", key: "SCATTERING", requires: "scattering" }
|
||||
- { name: "Velocity", key: "VELOCITY" }
|
||||
- { name: "Diffuse Ambient", key: "DIFFUSE_AMBIENT" }
|
||||
- { name: "Specular Ambient", key: "SPECULAR_AMBIENT" }
|
||||
- { name: "Luminance", key: "LUMINANCE", special: true }
|
||||
- { name: "Probe Count", key: "ENVPROBE_COUNT", requires: "env_probes" }
|
||||
- { name: "Light Count", key: "LIGHT_COUNT" }
|
||||
- { name: "Light Tiles", key: "LIGHT_TILES", special: true }
|
||||
174
RenderPipelineFile/config/panda3d-config.prc
Normal file
@ -0,0 +1,174 @@
|
||||
|
||||
|
||||
# This is the config file used to configure basic settings for Panda3D.
|
||||
# The pipeline loads it at startup to ensure the environment is setup properly.
|
||||
|
||||
# -------------- Development options --------------
|
||||
|
||||
pstats-gpu-timing #t
|
||||
gl-debug #t
|
||||
gl-debug-object-labels #t
|
||||
|
||||
# -------------- Production options ---------------
|
||||
|
||||
# pstats-gpu-timing #f
|
||||
# gl-debug #f
|
||||
# gl-debug-object-labels #f
|
||||
|
||||
# ----------------- Misc Settings -----------------
|
||||
|
||||
# Disable V-Sync
|
||||
sync-video #f
|
||||
|
||||
# Limit the pstats-rate. This causes huge lag on windows 10.
|
||||
pstats-max-rate 200
|
||||
|
||||
# No stack trace on assertion, set this to true to make panda crash on assertions
|
||||
# (which will allow to debug it)
|
||||
# assert-abort #t
|
||||
# show-dll-error-dialog #f
|
||||
|
||||
# File system should be case sensitive
|
||||
# NOTICE: Set this to #f if you are using tempfile, since it returns
|
||||
# wrong cased directory paths
|
||||
vfs-case-sensitive #t
|
||||
|
||||
# Enable state cache, this seems to actually help the performance by a lot
|
||||
state-cache #t
|
||||
transform-cache #t
|
||||
|
||||
# Hide frame rate meter (we have our own)
|
||||
show-frame-rate-meter #f
|
||||
|
||||
# Set text settings
|
||||
text-minfilter linear
|
||||
text-magfilter linear
|
||||
text-page-size 512 512
|
||||
text-rwap-mode WM_border_clor
|
||||
|
||||
# Better text performance since rdb's patch
|
||||
text-flatten 0
|
||||
text-dynamic-merge 1
|
||||
|
||||
# For smoother animations
|
||||
# even-animation #t
|
||||
|
||||
# Threading, really buggy!
|
||||
#threading-model App/Cull/Draw
|
||||
|
||||
# Disable stencil, not supported/required
|
||||
support-stencil #f
|
||||
framebuffer-stencil #f
|
||||
|
||||
# Don't use srgb correction, we do that in the final shader
|
||||
framebuffer-srgb #f
|
||||
|
||||
# Don't use multisamples
|
||||
framebuffer-multisample #f
|
||||
multisamples 0
|
||||
|
||||
# Don't rescale textures which are no power-of-2
|
||||
textures-power-2 none
|
||||
|
||||
# Set default texture filters
|
||||
texture-anisotropic-degree 16
|
||||
texture-magfilter linear
|
||||
texture-minfilter linear
|
||||
texture-quality-level fastest
|
||||
|
||||
# Enable seamless cubemap filtering, important for environment filtering
|
||||
gl-cube-map-seamless #t
|
||||
|
||||
# Disable caching of textures
|
||||
model-cache-textures #f
|
||||
|
||||
# Disable the annoying SRGB warning from pnmimage
|
||||
notify-level-pnmimage error
|
||||
|
||||
# Disable the buffer viewer, we have our own
|
||||
show-buffers #f
|
||||
|
||||
# Use the default coordinate system, this makes our matrix transformations
|
||||
# faster because we don't have have to transform them to a different coordinate
|
||||
# system before
|
||||
gl-coordinate-system default
|
||||
|
||||
# This makes animations smoother, especially if they were exported at 30 FPS
|
||||
# and are played at 60 FPS
|
||||
interpolate-frames #t
|
||||
|
||||
# Disable workarround in panda which causes our shadow atlas to take twice
|
||||
# the amount of vram it should, due to an intel driver bug.
|
||||
gl-force-fbo-color #f
|
||||
|
||||
# ----------- OpenGL / Performance Settings ------------
|
||||
|
||||
# Require OpenGL 4.3 at least, necessary for Intel drivers on Linux
|
||||
gl-version 4 3
|
||||
|
||||
# Animations on the gpu. The default shader has to get adjusted to support this
|
||||
# feature before this option can be turned on.
|
||||
# hardware-animated-vertices #t
|
||||
|
||||
# Try this options for performance
|
||||
# uniquify-matrix #t
|
||||
# uniquify-transforms #t
|
||||
# uniquify-states #t
|
||||
# uniquify-attribs #f
|
||||
|
||||
# Enable garbarge collection
|
||||
garbage-collect-states #t
|
||||
# garbage-collect-states-rate 0.2
|
||||
|
||||
# Compress textures on the drivers?
|
||||
# driver-compress-textures #t
|
||||
|
||||
# Faster animations? (Have to test)
|
||||
# matrix-palette #t
|
||||
# display-list-animation #t
|
||||
|
||||
# Better GL performance by not using gl-finish and so on
|
||||
gl-finish #f
|
||||
gl-force-no-error #t
|
||||
gl-check-errors #f
|
||||
gl-force-no-flush #t
|
||||
gl-force-no-scissor #t
|
||||
|
||||
# Eventually disable memory barriers, have to check if this is faster
|
||||
gl-enable-memory-barriers #f
|
||||
|
||||
# Disable threading
|
||||
lock-to-one-cpu #t
|
||||
support-threads #f
|
||||
|
||||
# Let the driver generate the mipmaps
|
||||
driver-generate-mipmaps #t
|
||||
|
||||
# Use immutable texture storage, it is *supposed* to be faster, but might not be
|
||||
# XXX: Seems to produce an GL_INVALID_VALUE when disabled
|
||||
gl-immutable-texture-storage #t
|
||||
|
||||
# Default window settings
|
||||
# depth-bits 0
|
||||
color-bits 0
|
||||
framebuffer-depth #f
|
||||
|
||||
# Small performance gain by specifying fixed vertex attribute locations.
|
||||
# Might cause issues with some (incorrectly converted/loaded) meshes though
|
||||
gl-fixed-vertex-attrib-locations #f
|
||||
|
||||
# Disable the fragment shader performance warning
|
||||
gl-validate-shaders #f
|
||||
gl-skip-shader-recompilation-warnings #t
|
||||
|
||||
alpha-scale-via-texture #f
|
||||
pstats-name Render Pipeline Stats
|
||||
rescale-normals #f
|
||||
screenshot-extension png
|
||||
|
||||
# Required for correct velocity
|
||||
always-store-prev-transform #t
|
||||
allow-incomplete-render #t
|
||||
|
||||
|
||||
no-singular-invert #f
|
||||
84
RenderPipelineFile/config/pipeline.yaml
Normal file
@ -0,0 +1,84 @@
|
||||
|
||||
|
||||
# This file stores internal settings of the pipeline. It does not contain the
|
||||
# plugin settings, but just the basic settings of the internal pipeline components.
|
||||
pipeline:
|
||||
|
||||
# This controls whether to show or hide the onscreen debugger. Not showing
|
||||
# it will also disable the hotkeys, and give a small performance boost.
|
||||
# Most likely you also don't want to show it in your own game, so set
|
||||
# it to false in that case.
|
||||
display_debugger: False
|
||||
|
||||
# Affects which debugging information is displayed. If this is set to false,
|
||||
# only frame time is displayed, otherwise much more information is visible.
|
||||
# Has no effect when display_debugger is set to false.
|
||||
advanced_debugging_info: False
|
||||
|
||||
# Whether to use the GL_R11F_G11F_B10F texture format to save memory
|
||||
# and bandwidth. Usually you want to enable this, however it can
|
||||
# cause banding sometimes, in which case you can disable this setting.
|
||||
use_r11_g11_b10: false
|
||||
|
||||
# Enables to render at a higher or lower resolution than the window size.
|
||||
# A value of 2.0 for example renders at twice the resolution (supoersampling)
|
||||
# whereas a value of 0.5 would render at half resolution.
|
||||
resolution_scale: 1.0
|
||||
|
||||
# Whether to render in a special reference mode, which displays the
|
||||
# environment map as a background, and disable special effects like color
|
||||
# grading and so on. This is used by the pathtracing reference.
|
||||
reference_mode: false
|
||||
|
||||
# This are the settings affecting the lighting part of the pipeline,
|
||||
# including builtin shadows and lights.
|
||||
lighting:
|
||||
|
||||
# The pipeline uses clustered deferred shading, this means that the
|
||||
# screen gets divided into tiles, and for each tile, the lights affecting
|
||||
# that tile are accumulated. You can adjust the tile size here (in pixels),
|
||||
# optimal is a tile size which is not too big (to avoid unecessary shading),
|
||||
# but also not too small (to avoid excessive culling).
|
||||
culling_grid_size_x: 24
|
||||
culling_grid_size_y: 16
|
||||
|
||||
# The view frustum is additionally divived into slices, to be able to do
|
||||
# better culling. If you use a higher amount of slices, the culling will
|
||||
# get more exact, but also more expensive. You have to find the optimal
|
||||
# size depending on your scene.
|
||||
culling_grid_slices: 32
|
||||
|
||||
# This controls the maximum culling distance in world space. After this
|
||||
# distance, no lights are rendered anymore. If you choose a lower
|
||||
# distance, this *can* positively impact performance, but you should not
|
||||
# set it too low, to avoid getting artifacts.
|
||||
culling_max_distance: 500.0
|
||||
|
||||
# Controls the size of a slice in culling. Lower values might produce
|
||||
# better performance for less amount of lights, but higher values should
|
||||
# be used when using many lights, e.g. > 1024, to get better coherency.
|
||||
culling_slice_width: 2048
|
||||
|
||||
# Controls the maximum amount of lights for each cell. If this value
|
||||
# is set too low, you might get artifacts when having many lights.
|
||||
# In general, try to set this value as low as possible without getting
|
||||
# artifacts
|
||||
max_lights_per_cell: 64
|
||||
|
||||
shadows:
|
||||
|
||||
# The size of the global shadow atlas, used for point and spot light
|
||||
# shadows. This should be a power of 2.
|
||||
atlas_size: 4096
|
||||
|
||||
# Maximum of shadow updates which may occur at one time. All updates
|
||||
# which are beyond that count will get delayed to the next frame.
|
||||
# If you set this too low, artifacts may occur because of shadows not
|
||||
# getting updated fast enough. However, this also affects the performance
|
||||
# quite a bit, since for every shadow map a part of the scene has
|
||||
# to get re-rendered.
|
||||
max_updates: 8
|
||||
|
||||
# Sets the maximum distance until which shadows are updated. If a shadow
|
||||
# source is further away, it will no longer recieve updates
|
||||
max_update_distance: 150.0
|
||||
199
RenderPipelineFile/config/plugins.yaml
Normal file
@ -0,0 +1,199 @@
|
||||
|
||||
# Render Pipeline Plugin Configuration
|
||||
# Instead of editing this file, prefer to use the Plugin Configurator
|
||||
# Any formatting and comments will be lost
|
||||
|
||||
enabled:
|
||||
- ao
|
||||
- bloom
|
||||
- color_correction
|
||||
- env_probes
|
||||
- forward_shading
|
||||
- motion_blur
|
||||
- pssm
|
||||
- scattering
|
||||
- skin_shading
|
||||
- sky_ao
|
||||
- smaa
|
||||
- ssr
|
||||
# - clouds
|
||||
# - dof
|
||||
# - fxaa
|
||||
# - volumetrics
|
||||
# - vxgi
|
||||
|
||||
|
||||
overrides:
|
||||
ao:
|
||||
blur_quality: MEDIUM
|
||||
blur_normal_factor: 2.97
|
||||
blur_depth_factor: 0.88158
|
||||
occlusion_strength: 2.19
|
||||
clip_length: 4
|
||||
technique: SSAO
|
||||
ssao_sample_radius: 95.29
|
||||
ssao_sequence: halton_3D_8
|
||||
ssao_bias: 0.0143
|
||||
ssao_max_distance: 7.5
|
||||
hbao_sample_radius: 255.0
|
||||
hbao_ray_count: 4
|
||||
hbao_ray_steps: 3
|
||||
hbao_tangent_bias: 0.64997
|
||||
hbao_max_distance: 11.5
|
||||
ssvo_sequence: halton_2D_8
|
||||
ssvo_sphere_radius: 18.0
|
||||
ssvo_max_distance: 3.19
|
||||
alchemy_sample_radius: 38.86
|
||||
alchemy_sequence: halton_2D_8
|
||||
alchemy_max_distance: 5.86
|
||||
ue4ao_sample_radius: 50.14286
|
||||
ue4ao_sample_sequence: halton_2D_8
|
||||
ue4ao_max_distance: 1.47
|
||||
|
||||
bloom:
|
||||
num_mipmaps: 6
|
||||
bloom_strength: 0.8003
|
||||
remove_fireflies: False
|
||||
lens_dirt_factor: 0.0
|
||||
|
||||
clouds:
|
||||
raymarch_steps: 160
|
||||
|
||||
color_correction:
|
||||
tonemap_operator: optimized
|
||||
reinhard_version: rgb
|
||||
exponential_factor: 1.23
|
||||
uc2t_shoulder_strength: 0.3352
|
||||
uc2t_linear_strength: 0.5339
|
||||
uc2t_linear_angle: 0.1797
|
||||
uc2t_toe_strength: 0.3919
|
||||
uc2t_toe_numerator: 0.0029
|
||||
uc2t_toe_denumerator: 0.2787
|
||||
uc2t_reference_white: 10.05
|
||||
vignette_strength: 0.1286
|
||||
film_grain_strength: 0.1286
|
||||
color_lut: film_luts/default_lut.png
|
||||
use_chromatic_aberration: True
|
||||
chromatic_aberration_strength: 0.019
|
||||
chromatic_aberration_samples: 2
|
||||
manual_camera_parameters: False
|
||||
min_exposure_value: 0.01
|
||||
max_exposure_value: 1.0
|
||||
exposure_scale: 1.0
|
||||
brightness_adaption_rate: 3.6
|
||||
darkness_adaption_rate: 0.7
|
||||
use_sharpen: True
|
||||
sharpen_strength: 0.5
|
||||
sharpen_twice: False
|
||||
|
||||
dof:
|
||||
focal_point: 1000.0
|
||||
focal_size: 994.0
|
||||
blur_strength: 0.0
|
||||
near_blur_strength: 0.4286
|
||||
|
||||
env_probes:
|
||||
probe_resolution: 128
|
||||
diffuse_probe_resolution: 2
|
||||
max_probes: 16
|
||||
max_probes_per_cell: 3
|
||||
|
||||
forward_shading:
|
||||
|
||||
fxaa:
|
||||
quality: ultra
|
||||
subpixel_quality: 0.5
|
||||
edge_threshold: 0.166
|
||||
min_threshold: 0.833
|
||||
|
||||
motion_blur:
|
||||
num_camera_samples: 6
|
||||
camera_blur_factor: 0.4
|
||||
enable_object_blur: False
|
||||
blur_factor: 0.5
|
||||
tile_size: 32
|
||||
max_blur_radius: 10.0
|
||||
num_samples: 12
|
||||
|
||||
pssm:
|
||||
max_distance: 50.0
|
||||
logarithmic_factor: 3.0
|
||||
sun_distance: 100.0
|
||||
split_count: 4
|
||||
resolution: 1024
|
||||
border_bias: 0.058
|
||||
use_pcf: True
|
||||
filter_sequence: halton_2D_32
|
||||
filter_radius: 0.7
|
||||
fixed_bias: 0.11429
|
||||
slope_bias: 0.0
|
||||
normal_bias: 0.67
|
||||
use_pcss: False
|
||||
pcss_sequence: halton_2D_16
|
||||
pcss_penumbra_size: 2.38
|
||||
pcss_min_penumbra_size: 7.0
|
||||
use_distant_shadows: True
|
||||
dist_shadow_resolution: 4096
|
||||
dist_shadow_clipsize: 400.0
|
||||
dist_shadow_sundist: 300.0
|
||||
scene_shadow_resolution: 512
|
||||
scene_shadow_sundist: 300.0
|
||||
|
||||
scattering:
|
||||
scattering_method: eric_bruneton
|
||||
ground_reflectance: 0.1231
|
||||
rayleigh_factor: 0.5
|
||||
rayleigh_height_scale: 8.0
|
||||
mie_height_scale: 1.3
|
||||
mie_phase_factor: 0.3
|
||||
beta_mie_scattering: 4.0
|
||||
enable_godrays: False
|
||||
atmosphere_start: 549.61
|
||||
|
||||
skin_shading:
|
||||
quality: medium
|
||||
blur_scale: 0.43
|
||||
|
||||
sky_ao:
|
||||
sample_radius: 17.17
|
||||
max_radius: 500.0
|
||||
resolution: 1024
|
||||
sample_sequence: poisson_2D_32
|
||||
ao_multiplier: 0.83
|
||||
ao_bias: 0.0
|
||||
blend_factor: 0.01
|
||||
capture_height: 568.75
|
||||
|
||||
smaa:
|
||||
use_reprojection: True
|
||||
smaa_quality: ultra
|
||||
jitter_pattern: halton8
|
||||
history_length: 8
|
||||
jitter_amount: 0.16143
|
||||
|
||||
ssr:
|
||||
effect_scale: 1.0
|
||||
trace_steps: 64
|
||||
history_length: 16
|
||||
abort_on_object_infront: True
|
||||
intial_bias: 0.1
|
||||
hit_tolerance: 0.1
|
||||
roughness_fade: 0.72
|
||||
skip_invalid_samples: False
|
||||
border_fade: 0.005
|
||||
|
||||
volumetrics:
|
||||
enable_volumetric_shadows: True
|
||||
volumetric_shadow_intensity: 8.31
|
||||
volumetric_shadow_brightness: 1.66
|
||||
volumetric_shadow_pow: 1.15999
|
||||
volumetric_max_distance: 79.41429
|
||||
volumetric_shadow_fadein_distance: 9.49
|
||||
volumetric_num_steps: 128
|
||||
|
||||
vxgi:
|
||||
grid_resolution: 256
|
||||
grid_ws_size: 100.0
|
||||
diffuse_cone_steps: 32
|
||||
specular_cone_steps: 150
|
||||
|
||||
67
RenderPipelineFile/config/stages.yaml
Normal file
@ -0,0 +1,67 @@
|
||||
|
||||
# This file controls the order of all render stages.
|
||||
|
||||
# Usually you do not have to modify this, except if you are adding new plugins.
|
||||
# If you move stages, you should know what you do.
|
||||
|
||||
# Commenting out a stage won't disable it, but instead produce an error when
|
||||
# it is created.
|
||||
|
||||
global_stage_order:
|
||||
|
||||
# Shadows, Environment and Voxelization
|
||||
- PSSMShadowStage
|
||||
- PSSMDistShadowStage
|
||||
- PSSMSceneShadowStage
|
||||
- ScatteringEnvmapStage
|
||||
- SkyAOCaptureStage
|
||||
- EnvironmentCaptureStage
|
||||
- VoxelizationStage
|
||||
|
||||
# Main scene
|
||||
- GBufferStage
|
||||
- ShadowStage
|
||||
- DownscaleZStage
|
||||
- CombineVelocityStage
|
||||
|
||||
# Light(-culling)
|
||||
- FlagUsedCellsStage
|
||||
- CollectUsedCellsStage
|
||||
- CullLightsStage
|
||||
- CullProbesStage
|
||||
|
||||
# Plugins
|
||||
- CloudVoxelStage
|
||||
- AOStage
|
||||
- SkyAOStage
|
||||
- ApplyLightsStage
|
||||
- PSSMStage
|
||||
- ScatteringStage
|
||||
- ApplyEnvprobesStage
|
||||
- VXGIStage
|
||||
- SSRStage
|
||||
|
||||
- AmbientStage
|
||||
- ForwardStage
|
||||
|
||||
- ApplyCloudsStage
|
||||
- GodrayStage
|
||||
- VolumetricsStage
|
||||
- AutoExposureStage
|
||||
- ManualExposureStage
|
||||
|
||||
# Post AA & Effects
|
||||
- BloomStage
|
||||
- TonemappingStage
|
||||
- SMAAStage
|
||||
- FXAAStage
|
||||
- DoFStage
|
||||
- MotionBlurStage
|
||||
- SkinShadingStage
|
||||
- SharpenStage
|
||||
- ColorCorrectionStage
|
||||
|
||||
# Finishing stages, do not insert anything below
|
||||
- UpscaleStage
|
||||
- FinalStage
|
||||
- UpdatePreviousPipesStage
|
||||
33
RenderPipelineFile/config/task-scheduler.yaml
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
# This file controls which tasks are allowed to run each frame.
|
||||
# Usually you do not have to edit this file, except when developing plugins.
|
||||
|
||||
frame_cycles: !!omap
|
||||
|
||||
- frame1:
|
||||
- envprobes_select_and_cull
|
||||
- pssm_scene_shadows
|
||||
|
||||
- frame2:
|
||||
- envprobes_capture_envmap_face0
|
||||
- pssm_distant_shadows
|
||||
|
||||
- frame3:
|
||||
- envprobes_capture_envmap_face1
|
||||
- pssm_convert_distant_to_esm
|
||||
|
||||
- frame4:
|
||||
- envprobes_capture_envmap_face2
|
||||
- pssm_blur_distant_vert
|
||||
|
||||
- frame5:
|
||||
- pssm_blur_distant_horiz
|
||||
- envprobes_capture_envmap_face3
|
||||
- envprobes_capture_envmap_face4
|
||||
|
||||
- frame6:
|
||||
- envprobes_capture_envmap_face5
|
||||
- scattering_update_envmap
|
||||
|
||||
- frame7:
|
||||
- envprobes_filter_and_store_envmap
|
||||
7
RenderPipelineFile/data/Materials/GroundMaterial.yaml
Normal file
@ -0,0 +1,7 @@
|
||||
material:
|
||||
name: GroundMaterial
|
||||
base_color: "../Textures/ground_diffuse.png"
|
||||
normal: "../Textures/ground_normal.png"
|
||||
roughness: 0.8
|
||||
metallic: 0.0
|
||||
two_sided: true
|
||||
16
RenderPipelineFile/data/builtin_models/skybox/SOURCE.txt
Normal file
@ -0,0 +1,16 @@
|
||||
|
||||
The skydomes for the skybox were taken from:
|
||||
|
||||
|
||||
Skybox.jpg:
|
||||
|
||||
http://www.gravis.com.ua/gal/content/photoprint/sky/sk_21.jpg
|
||||
|
||||
|
||||
Skybox2.jpg:
|
||||
|
||||
http://www.artist-reference.com/wp-content/gallery/marlin-studios-gallery/sky-dome-panorma.jpg
|
||||
|
||||
|
||||
|
||||
I couldn't find a direct license for those photos. If there is one, please contact me.
|
||||
BIN
RenderPipelineFile/data/builtin_models/skybox/skybox-2.jpg
Normal file
|
After Width: | Height: | Size: 2.1 MiB |
BIN
RenderPipelineFile/data/builtin_models/skybox/skybox-blend.zip
Normal file
BIN
RenderPipelineFile/data/builtin_models/skybox/skybox.bam
Normal file
BIN
RenderPipelineFile/data/builtin_models/skybox/skybox.jpg
Normal file
|
After Width: | Height: | Size: 985 KiB |
116
RenderPipelineFile/data/default_cubemap/filter.compute.glsl
Normal file
@ -0,0 +1,116 @@
|
||||
#version 430
|
||||
|
||||
// Shader to pre-filter the cubemap using importance sampling
|
||||
|
||||
layout (local_size_x = 16, local_size_y = 16, local_size_z = 1) in;
|
||||
|
||||
|
||||
#define M_PI 3.1415926535897932384626433
|
||||
|
||||
vec3 get_transformed_coord(vec2 coord, uint face) {
|
||||
float f = 1.0;
|
||||
switch (face) {
|
||||
case 1: return vec3(-f, coord);
|
||||
case 2: return vec3(coord, -f);
|
||||
case 0: return vec3(f, -coord.x, coord.y);
|
||||
case 3: return vec3(coord.xy * vec2(1, -1), f);
|
||||
case 4: return vec3(coord.x, f, coord.y);
|
||||
case 5: return vec3(-coord.x, -f, coord.y);
|
||||
}
|
||||
return vec3(0);
|
||||
}
|
||||
|
||||
// From:
|
||||
// http://www.trentreed.net/blog/physically-based-shading-and-image-based-lighting/
|
||||
vec2 hammersley(uint i, uint N)
|
||||
{
|
||||
return vec2(float(i) / float(N), float(bitfieldReverse(i)) * 2.3283064365386963e-10);
|
||||
}
|
||||
|
||||
// From:
|
||||
// http://www.gamedev.net/topic/655431-ibl-problem-with-consistency-using-ggx-anisotropy/
|
||||
vec3 importance_sample_ggx(vec2 xi, float roughness)
|
||||
{
|
||||
float r_square = roughness * roughness;
|
||||
float phi = 2 * M_PI * xi.x;
|
||||
float cos_theta = sqrt((1 - xi.y) / (1 + (r_square * r_square - 1) * xi.y));
|
||||
float sin_theta = sqrt(1 - cos_theta * cos_theta);
|
||||
|
||||
return vec3(sin_theta * cos(phi), sin_theta * sin(phi), cos_theta);
|
||||
}
|
||||
|
||||
// Converts a normalized spherical coordinate (r = 1) to cartesian coordinates
|
||||
vec3 spherical_to_vector(float theta, float phi) {
|
||||
float sin_theta = sin(theta);
|
||||
return normalize(vec3(
|
||||
sin_theta * cos(phi),
|
||||
sin_theta * sin(phi),
|
||||
cos(theta)
|
||||
));
|
||||
}
|
||||
|
||||
float brdf_distribution_ggx(float NxH, float roughness) {
|
||||
float nxh_sq = NxH * NxH;
|
||||
float tan_sq = (1 - nxh_sq) / nxh_sq;
|
||||
float f = roughness / max(1e-10, nxh_sq * (roughness * roughness + tan_sq));
|
||||
return f * f / M_PI;
|
||||
}
|
||||
|
||||
// Finds a tangent and bitangent vector based on a given normal
|
||||
void find_arbitrary_tangent(vec3 normal, out vec3 tangent, out vec3 bitangent) {
|
||||
vec3 v0 = abs(normal.z) < 0.999 ? vec3(0, 0, 1) : vec3(0, 1, 0);
|
||||
tangent = normalize(cross(v0, normal));
|
||||
bitangent = normalize(cross(tangent, normal));
|
||||
}
|
||||
|
||||
vec3 transform_cubemap_coordinates(vec3 coord) {
|
||||
return normalize(coord.xyz * vec3(1, -1, 1));
|
||||
}
|
||||
|
||||
uniform samplerCube SourceTex;
|
||||
uniform int currentSize;
|
||||
uniform int currentMip;
|
||||
uniform int currentFace;
|
||||
layout(rgba16f) uniform imageCube DestTex;
|
||||
|
||||
void main() {
|
||||
ivec2 coord = ivec2(gl_GlobalInvocationID.xy);
|
||||
|
||||
vec2 texcoord = vec2(coord + 0.5) / float(currentSize);
|
||||
texcoord = texcoord * 2.0 - 1.0;
|
||||
|
||||
vec3 n = get_transformed_coord(texcoord, currentFace);
|
||||
n = normalize(n);
|
||||
n = transform_cubemap_coordinates(n);
|
||||
float roughness = clamp(float(currentMip) / 7.0, 0.001, 1.0);
|
||||
// roughness *= roughness;
|
||||
|
||||
vec3 tangent, binormal;
|
||||
find_arbitrary_tangent(n, tangent, binormal);
|
||||
|
||||
vec4 accum = vec4(0);
|
||||
const uint num_samples = 512;
|
||||
|
||||
// Ultra high quality, might cause TDR on low-end systems
|
||||
// const uint num_samples = 4096;
|
||||
for (uint i = 0; i < num_samples; ++i) {
|
||||
vec2 xi = hammersley(i, num_samples);
|
||||
vec3 r = importance_sample_ggx(xi, roughness);
|
||||
vec3 h = normalize(r.x * tangent + r.y * binormal + r.z * n);
|
||||
vec3 l = 2.0 * dot(n, h) * h - n;
|
||||
|
||||
float NxL = clamp(dot(n, l), 0.0, 1.0);
|
||||
float NxH = clamp(dot(n, h), 0.0, 1.0);
|
||||
|
||||
vec3 sampled = textureLod(SourceTex, l, 0).rgb;
|
||||
|
||||
float weight = 1;
|
||||
weight = clamp(weight, 0.0, 1.0);
|
||||
accum += vec4(sampled, 1) * weight;
|
||||
}
|
||||
|
||||
accum /= max(0.1, accum.w);
|
||||
accum.xyz = pow(accum.xyz, vec3(2.2));
|
||||
|
||||
imageStore(DestTex, ivec3(coord, currentFace), vec4(accum.xyz, 1.0));
|
||||
}
|
||||
106
RenderPipelineFile/data/default_cubemap/filter.py
Normal file
@ -0,0 +1,106 @@
|
||||
"""
|
||||
|
||||
RenderPipeline
|
||||
|
||||
Copyright (c) 2014-2016 tobspr <tobias.springer1@gmail.com>
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import print_function, division
|
||||
|
||||
import os
|
||||
import shutil
|
||||
from os.path import dirname, realpath
|
||||
from panda3d.core import *
|
||||
from direct.stdpy.file import isdir, isfile, join
|
||||
from direct.showbase.ShowBase import ShowBase
|
||||
|
||||
class Application(ShowBase):
|
||||
def __init__(self):
|
||||
load_prc_file_data("", """
|
||||
textures-power-2 none
|
||||
window-type offscreen
|
||||
win-size 100 100
|
||||
gl-coordinate-system default
|
||||
notify-level-display error
|
||||
print-pipe-types #f
|
||||
gl-version 4 3
|
||||
""")
|
||||
|
||||
ShowBase.__init__(self)
|
||||
|
||||
base_path = realpath(dirname(__file__))
|
||||
os.chdir(base_path)
|
||||
filter_dir = join(base_path, "tmp/")
|
||||
if isdir(filter_dir):
|
||||
shutil.rmtree(filter_dir)
|
||||
os.makedirs(filter_dir)
|
||||
|
||||
source_path = join(base_path, "source")
|
||||
extension = ".jpg"
|
||||
if isfile(join(source_path, "1.png")):
|
||||
extension = ".png"
|
||||
|
||||
cubemap = self.loader.loadCubeMap(
|
||||
Filename.from_os_specific(join(source_path, "#" + extension)))
|
||||
mipmap, size = -1, 1024
|
||||
|
||||
cshader = Shader.load_compute(Shader.SL_GLSL, "filter.compute.glsl")
|
||||
|
||||
while size > 1:
|
||||
size = size // 2
|
||||
mipmap += 1
|
||||
print("Filtering mipmap", mipmap)
|
||||
|
||||
dest_cubemap = Texture("Dest")
|
||||
dest_cubemap.setup_cube_map(size, Texture.T_float, Texture.F_rgba16)
|
||||
node = NodePath("")
|
||||
|
||||
for i in range(6):
|
||||
node.set_shader(cshader)
|
||||
node.set_shader_inputs(
|
||||
SourceTex=cubemap,
|
||||
DestTex=dest_cubemap,
|
||||
currentSize=size,
|
||||
currentMip=mipmap,
|
||||
currentFace=i)
|
||||
attr = node.get_attrib(ShaderAttrib)
|
||||
self.graphicsEngine.dispatch_compute(
|
||||
( (size + 15) // 16, (size+15) // 16, 1), attr, self.win.gsg)
|
||||
|
||||
print(" Extracting data ..")
|
||||
|
||||
self.graphicsEngine.extract_texture_data(dest_cubemap, self.win.gsg)
|
||||
|
||||
print(" Writing data ..")
|
||||
dest_cubemap.write(join(filter_dir, "{}-#.png".format(mipmap)), 0, 0, True, False)
|
||||
|
||||
|
||||
print("Reading in data back in ..")
|
||||
tex = self.loader.loadCubeMap(Filename.from_os_specific(join(base_path, "tmp/#-#.png")), readMipmaps="True")
|
||||
|
||||
print("Writing txo ..")
|
||||
tex.write("cubemap.txo.pz")
|
||||
|
||||
shutil.rmtree(join(base_path, "tmp"))
|
||||
|
||||
|
||||
Application()
|
||||
BIN
RenderPipelineFile/data/default_cubemap/source/0.png
Normal file
|
After Width: | Height: | Size: 346 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source/1.png
Normal file
|
After Width: | Height: | Size: 334 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source/2.png
Normal file
|
After Width: | Height: | Size: 482 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source/3.png
Normal file
|
After Width: | Height: | Size: 237 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source/4.png
Normal file
|
After Width: | Height: | Size: 369 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source/5.png
Normal file
|
After Width: | Height: | Size: 348 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source_2/0.jpg
Normal file
|
After Width: | Height: | Size: 672 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source_2/1.jpg
Normal file
|
After Width: | Height: | Size: 652 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source_2/2.jpg
Normal file
|
After Width: | Height: | Size: 600 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source_2/3.jpg
Normal file
|
After Width: | Height: | Size: 763 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source_2/4.jpg
Normal file
|
After Width: | Height: | Size: 735 KiB |
BIN
RenderPipelineFile/data/default_cubemap/source_2/5.jpg
Normal file
|
After Width: | Height: | Size: 689 KiB |
7
RenderPipelineFile/data/empty_textures/README.md
Normal file
@ -0,0 +1,7 @@
|
||||
|
||||
### Empty textures
|
||||
|
||||
This are the empty textures you can use in your models in case you don't have
|
||||
a detailmap for example.
|
||||
|
||||
See the wiki for further information.
|
||||
BIN
RenderPipelineFile/data/empty_textures/empty_basecolor.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
RenderPipelineFile/data/empty_textures/empty_normal.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
RenderPipelineFile/data/empty_textures/empty_roughness.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
BIN
RenderPipelineFile/data/empty_textures/empty_specular.png
Normal file
|
After Width: | Height: | Size: 2.7 KiB |
120
RenderPipelineFile/data/environment_brdf/generate_reference.py
Normal file
@ -0,0 +1,120 @@
|
||||
"""
|
||||
|
||||
Uses mitsuba to generate the environment brdf
|
||||
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import os
|
||||
import sys
|
||||
import math
|
||||
from panda3d.core import PNMImage, load_prc_file_data, Vec3
|
||||
|
||||
load_prc_file_data("", "notify-level error")
|
||||
load_prc_file_data("", "notify-level-pnmimage error")
|
||||
|
||||
configs = {
|
||||
"normal": {
|
||||
"out_dir": "slices",
|
||||
"out_name": "env_brdf_{}.png",
|
||||
"template_suffix": "",
|
||||
"sequence": xrange(7),
|
||||
"samples": 32,
|
||||
},
|
||||
"metallic": {
|
||||
"out_dir": "slices_metal",
|
||||
"out_name": "env_brdf.png",
|
||||
"template_suffix": "-metal",
|
||||
"sequence": [1],
|
||||
"samples": 32,
|
||||
},
|
||||
"clearcoat": {
|
||||
"out_dir": "slices_coat",
|
||||
"out_name": "env_brdf.png",
|
||||
"template_suffix": "-coat",
|
||||
"sequence": [1],
|
||||
"samples": 2048,
|
||||
}
|
||||
}
|
||||
|
||||
# configs_to_run = ["normal", "metallic", "clearcoat"]
|
||||
configs_to_run = ["clearcoat"]
|
||||
|
||||
for config_name in configs_to_run:
|
||||
|
||||
config = configs[config_name]
|
||||
|
||||
if not os.path.isdir(config["out_dir"]):
|
||||
os.makedirs(config["out_dir"])
|
||||
|
||||
|
||||
for pass_index in config["sequence"]:
|
||||
|
||||
ior = 1.01 + 0.2 * pass_index
|
||||
|
||||
dest_size = 512
|
||||
dest_h = 32
|
||||
dest = PNMImage(dest_size, dest_h)
|
||||
|
||||
# run mitsuba
|
||||
print("Running mitsuba for ior =", ior, "( index =", pass_index,")")
|
||||
with open("res/scene" + config["template_suffix"] + ".templ.xml", "r") as handle:
|
||||
content = handle.read()
|
||||
|
||||
content = content.replace("%IOR%", str(ior))
|
||||
content = content.replace("%SAMPLES%", str(config["samples"]))
|
||||
|
||||
with open("res/scene.xml", "w") as handle:
|
||||
handle.write(content)
|
||||
|
||||
os.system("run_mitsuba.bat")
|
||||
|
||||
img = PNMImage("scene.png")
|
||||
source_w = img.get_x_size()
|
||||
|
||||
print("Converting ..")
|
||||
|
||||
indices = []
|
||||
nxv_values = []
|
||||
|
||||
# Generate nonlinear NxV sequence
|
||||
for i in xrange(source_w):
|
||||
v = 1 - i / float(source_w)
|
||||
NxV = math.sqrt(1 - v*v)
|
||||
nxv_values.append(NxV)
|
||||
|
||||
# Generate lerp indices and weights
|
||||
for x in xrange(dest_size):
|
||||
NxV = (x) / float(dest_size)
|
||||
index = 0
|
||||
for i, s_nxv in enumerate(reversed(nxv_values)):
|
||||
if NxV >= s_nxv:
|
||||
index = i
|
||||
break
|
||||
index = len(nxv_values) - index - 1
|
||||
next_index = index + 1 if index < dest_size - 1 else index
|
||||
|
||||
curr_nxv = nxv_values[index]
|
||||
next_nxv = nxv_values[next_index]
|
||||
|
||||
lerp_factor = (NxV - curr_nxv) / max(1e-10, abs(next_nxv - curr_nxv))
|
||||
lerp_factor = max(0.0, min(1.0, lerp_factor))
|
||||
indices.append((index, next_index, lerp_factor))
|
||||
|
||||
# Generate the final linear lut using the lerp weights
|
||||
for y in xrange(dest_h):
|
||||
for x in xrange(dest_size):
|
||||
curr_i, next_i, lerp = indices[x]
|
||||
curr_v = img.get_xel(curr_i, y)
|
||||
next_v = img.get_xel(next_i, y)
|
||||
dest.set_xel(x, y, curr_v * (1 - lerp) + next_v * lerp)
|
||||
|
||||
|
||||
out_name = config["out_name"].replace("{}", str(pass_index))
|
||||
dest.write(config["out_dir"] + "/" + out_name)
|
||||
|
||||
try:
|
||||
os.remove("scene.png")
|
||||
except:
|
||||
pass
|
||||
BIN
RenderPipelineFile/data/environment_brdf/res/environment.png
Normal file
|
After Width: | Height: | Size: 4.1 KiB |
BIN
RenderPipelineFile/data/environment_brdf/res/roughness.png
Normal file
|
After Width: | Height: | Size: 44 KiB |
@ -0,0 +1,68 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
|
||||
<scene version="0.5.0">
|
||||
<integrator type="path">
|
||||
<integer name="maxDepth" value="2"/>
|
||||
</integrator>
|
||||
|
||||
<shape type="cylinder">
|
||||
<float name="radius" value="1" />
|
||||
<point name="p0" x="0" y="0.5" z="0" />
|
||||
<point name="p1" x="0" y="-0.5" z="0" />
|
||||
|
||||
<bsdf type="roughcoating">
|
||||
<string name="distribution" value="ggx" />
|
||||
<rgb name="specularReflectance" value="0, 1, 0" />
|
||||
<float name="alpha" value="0.0001" />
|
||||
<float name="thickness" value="5.0" />
|
||||
<float name="intIOR" value="1.51" />
|
||||
|
||||
<bsdf type="roughconductor">
|
||||
<rgb name="specularReflectance" value="1, 0, 0" />
|
||||
<string name="material" value="none"/>
|
||||
<!-- <string name="distribution" value="ggx"/> -->
|
||||
<texture name="alpha" type="bitmap">
|
||||
<string name="filename" value="roughness.png"/>
|
||||
</texture>
|
||||
<!-- <float name="alpha" value="0.5" /> -->
|
||||
</bsdf>
|
||||
|
||||
</bsdf>
|
||||
|
||||
</shape>
|
||||
|
||||
<emitter type="envmap">
|
||||
<string name="filename" value="environment.png" />
|
||||
<float name="gamma" value="1.0" />
|
||||
</emitter>
|
||||
|
||||
<sensor type="orthographic">
|
||||
<float name="nearClip" value="0.05"/>
|
||||
<float name="farClip" value="15"/>
|
||||
|
||||
<!-- <float name="fov" value="40"/> -->
|
||||
|
||||
<string name="fovAxis" value="x"/>
|
||||
|
||||
<transform name="toWorld">
|
||||
<scale x="0.5" y="128" />
|
||||
<lookat origin="0.5, 0.0, -3.5" target="0.5, 0.0, 0" up="0, 1, 0"/>
|
||||
</transform>
|
||||
|
||||
<sampler type="ldsampler">
|
||||
<integer name="sampleCount" value="%SAMPLES%" />
|
||||
</sampler>
|
||||
|
||||
<film type="hdrfilm">
|
||||
<boolean name="banner" value="false"/>
|
||||
|
||||
<boolean name="attachLog" value="false" />
|
||||
<!-- <boolean name="highQualityEdges" value="true" /> -->
|
||||
|
||||
<integer name="height" value="32"/>
|
||||
<integer name="width" value="8192"/>
|
||||
|
||||
<!-- <rfilter type="box"/> -->
|
||||
</film>
|
||||
</sensor>
|
||||
</scene>
|
||||
@ -0,0 +1,56 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
|
||||
<scene version="0.5.0">
|
||||
<integrator type="path">
|
||||
<integer name="maxDepth" value="2"/>
|
||||
</integrator>
|
||||
|
||||
<shape type="cylinder">
|
||||
<float name="radius" value="1" />
|
||||
<point name="p0" x="0" y="0.5" z="0" />
|
||||
<point name="p1" x="0" y="-0.5" z="0" />
|
||||
|
||||
<bsdf type="roughconductor">
|
||||
<string name="material" value="Ag"/>
|
||||
<string name="distribution" value="ggx"/>
|
||||
<texture name="alpha" type="bitmap">
|
||||
<string name="filename" value="roughness.png"/>
|
||||
</texture>
|
||||
</bsdf>
|
||||
</shape>
|
||||
|
||||
<emitter type="envmap">
|
||||
<string name="filename" value="environment.png" />
|
||||
<float name="gamma" value="1.0" />
|
||||
</emitter>
|
||||
|
||||
<sensor type="orthographic">
|
||||
<float name="nearClip" value="0.05"/>
|
||||
<float name="farClip" value="15"/>
|
||||
|
||||
<!-- <float name="fov" value="40"/> -->
|
||||
|
||||
<string name="fovAxis" value="x"/>
|
||||
|
||||
<transform name="toWorld">
|
||||
<scale x="0.5" y="128" />
|
||||
<lookat origin="0.5, 0.0, -3.5" target="0.5, 0.0, 0" up="0, 1, 0"/>
|
||||
</transform>
|
||||
|
||||
<sampler type="ldsampler">
|
||||
<integer name="sampleCount" value="%SAMPLES%" />
|
||||
</sampler>
|
||||
|
||||
<film type="hdrfilm">
|
||||
<boolean name="banner" value="false"/>
|
||||
|
||||
<boolean name="attachLog" value="false" />
|
||||
<!-- <boolean name="highQualityEdges" value="true" /> -->
|
||||
|
||||
<integer name="height" value="32"/>
|
||||
<integer name="width" value="8192"/>
|
||||
|
||||
<!-- <rfilter type="box"/> -->
|
||||
</film>
|
||||
</sensor>
|
||||
</scene>
|
||||
62
RenderPipelineFile/data/environment_brdf/res/scene.templ.xml
Normal file
@ -0,0 +1,62 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
|
||||
<scene version="0.5.0">
|
||||
<integrator type="path">
|
||||
<integer name="maxDepth" value="2"/>
|
||||
</integrator>
|
||||
|
||||
<shape type="cylinder">
|
||||
<float name="radius" value="1" />
|
||||
<point name="p0" x="0" y="0.5" z="0" />
|
||||
<point name="p1" x="0" y="-0.5" z="0" />
|
||||
|
||||
<bsdf type="roughplastic">
|
||||
<!-- <string name="material" value="Cu"/> -->
|
||||
<string name="distribution" value="ggx"/>
|
||||
<rgb name="diffuseReflectance" value="0,1,0" />
|
||||
<rgb name="specularReflectance" value="1,0,0" />
|
||||
<float name="intIOR" value="%IOR%"/>
|
||||
|
||||
<texture name="alpha" type="bitmap">
|
||||
<string name="filename" value="roughness.png"/>
|
||||
</texture>
|
||||
|
||||
|
||||
</bsdf>
|
||||
</shape>
|
||||
|
||||
<emitter type="envmap">
|
||||
<string name="filename" value="environment.png" />
|
||||
<float name="gamma" value="1.0" />
|
||||
</emitter>
|
||||
|
||||
<sensor type="orthographic">
|
||||
<float name="nearClip" value="0.05"/>
|
||||
<float name="farClip" value="15"/>
|
||||
|
||||
<!-- <float name="fov" value="40"/> -->
|
||||
|
||||
<string name="fovAxis" value="x"/>
|
||||
|
||||
<transform name="toWorld">
|
||||
<scale x="0.5" y="128" />
|
||||
<lookat origin="0.5, 0.0, -3.5" target="0.5, 0.0, 0" up="0, 1, 0"/>
|
||||
</transform>
|
||||
|
||||
<sampler type="ldsampler">
|
||||
<integer name="sampleCount" value="%SAMPLES%" />
|
||||
</sampler>
|
||||
|
||||
<film type="hdrfilm">
|
||||
<boolean name="banner" value="false"/>
|
||||
|
||||
<boolean name="attachLog" value="false" />
|
||||
<!-- <boolean name="highQualityEdges" value="true" /> -->
|
||||
|
||||
<integer name="height" value="32"/>
|
||||
<integer name="width" value="8192"/>
|
||||
|
||||
<!-- <rfilter type="box"/> -->
|
||||
</film>
|
||||
</sensor>
|
||||
</scene>
|
||||
68
RenderPipelineFile/data/environment_brdf/res/scene.xml
Normal file
@ -0,0 +1,68 @@
|
||||
<?xml version='1.0' encoding='utf-8'?>
|
||||
|
||||
<scene version="0.5.0">
|
||||
<integrator type="path">
|
||||
<integer name="maxDepth" value="2"/>
|
||||
</integrator>
|
||||
|
||||
<shape type="cylinder">
|
||||
<float name="radius" value="1" />
|
||||
<point name="p0" x="0" y="0.5" z="0" />
|
||||
<point name="p1" x="0" y="-0.5" z="0" />
|
||||
|
||||
<bsdf type="roughcoating">
|
||||
<string name="distribution" value="ggx" />
|
||||
<rgb name="specularReflectance" value="0, 1, 0" />
|
||||
<float name="alpha" value="0.0001" />
|
||||
<float name="thickness" value="5.0" />
|
||||
<float name="intIOR" value="1.51" />
|
||||
|
||||
<bsdf type="roughconductor">
|
||||
<rgb name="specularReflectance" value="1, 0, 0" />
|
||||
<string name="material" value="none"/>
|
||||
<!-- <string name="distribution" value="ggx"/> -->
|
||||
<texture name="alpha" type="bitmap">
|
||||
<string name="filename" value="roughness.png"/>
|
||||
</texture>
|
||||
<!-- <float name="alpha" value="0.5" /> -->
|
||||
</bsdf>
|
||||
|
||||
</bsdf>
|
||||
|
||||
</shape>
|
||||
|
||||
<emitter type="envmap">
|
||||
<string name="filename" value="environment.png" />
|
||||
<float name="gamma" value="1.0" />
|
||||
</emitter>
|
||||
|
||||
<sensor type="orthographic">
|
||||
<float name="nearClip" value="0.05"/>
|
||||
<float name="farClip" value="15"/>
|
||||
|
||||
<!-- <float name="fov" value="40"/> -->
|
||||
|
||||
<string name="fovAxis" value="x"/>
|
||||
|
||||
<transform name="toWorld">
|
||||
<scale x="0.5" y="128" />
|
||||
<lookat origin="0.5, 0.0, -3.5" target="0.5, 0.0, 0" up="0, 1, 0"/>
|
||||
</transform>
|
||||
|
||||
<sampler type="ldsampler">
|
||||
<integer name="sampleCount" value="2048" />
|
||||
</sampler>
|
||||
|
||||
<film type="hdrfilm">
|
||||
<boolean name="banner" value="false"/>
|
||||
|
||||
<boolean name="attachLog" value="false" />
|
||||
<!-- <boolean name="highQualityEdges" value="true" /> -->
|
||||
|
||||
<integer name="height" value="32"/>
|
||||
<integer name="width" value="8192"/>
|
||||
|
||||
<!-- <rfilter type="box"/> -->
|
||||
</film>
|
||||
</sensor>
|
||||
</scene>
|
||||
10
RenderPipelineFile/data/environment_brdf/run_mitsuba.bat
Normal file
@ -0,0 +1,10 @@
|
||||
@echo off
|
||||
|
||||
"C:/mitsuba/mitsuba" -p 6 res/scene.xml
|
||||
echo ""
|
||||
echo Rendering done
|
||||
echo ""
|
||||
echo ""
|
||||
echo ""
|
||||
"C:/mitsuba/mtsutil" tonemap -g 2.0 res/scene.exr
|
||||
copy res\scene.png scene.png
|
||||
BIN
RenderPipelineFile/data/environment_brdf/slices/env_brdf_0.png
Normal file
|
After Width: | Height: | Size: 10 KiB |
BIN
RenderPipelineFile/data/environment_brdf/slices/env_brdf_1.png
Normal file
|
After Width: | Height: | Size: 12 KiB |
BIN
RenderPipelineFile/data/environment_brdf/slices/env_brdf_10.png
Normal file
|
After Width: | Height: | Size: 13 KiB |