Sepehr Taghdisian avatar Sepehr Taghdisian committed d6e8abf

python anim-clip-edit tool (part of h3dimport-gui)

Comments (0)

Files changed (17)

 *.obj
 *.suo
 *.log
+*.pyc
 build
 dh_install
 *.DS_Store
 darkHAMMER Game Engine
 =======================
-Version 0.4.6 (pre-alpha)  
+Version 0.4.7 (pre-alpha)  
 [http://www.hmrengine.com](http://www.hmrengine.com)  
 [http://www.bitbucket.org/sepul/dark-hammer](http://www.bitbucket.org/sepul/dark-hammer)
 
-0.4.6
+0.4.7

src/h3dimport-gui/clipedit.py

+from PyQt4 import QtCore, QtGui
+import os, platform, sys, json, math
+import dheng
+from dhwidgets import eng_view
+from dhutil import util
+
+class qClipList(QtGui.QWidget):
+    def __init__(self, parent):
+        super(qClipList, self).__init__(parent)
+        self.setFixedWidth(200)
+
+        # layout and controls
+        layout = QtGui.QVBoxLayout()
+        self.setLayout(layout)
+
+        layout2 = QtGui.QHBoxLayout()
+        layout2.setSpacing(1)
+        self.ed_name = QtGui.QLineEdit(self)
+        self.ed_name.setMaxLength(30)
+        layout2.addWidget(self.ed_name)
+        btn_add = QtGui.QPushButton('+', self)
+        btn_remove = QtGui.QPushButton('-', self)
+        btn_add.setFixedSize(24, 24)
+        btn_remove.setFixedSize(24, 24)
+        layout2.addWidget(btn_add)
+        layout2.addWidget(btn_remove)
+        layout.addLayout(layout2)
+
+        lbl_clips = QtGui.QLabel('Clips', self)
+        self.lst_clips = QtGui.QListWidget(self)
+        self.lst_clips.setMaximumHeight(150)
+
+        layout.addWidget(lbl_clips)
+        layout.addWidget(self.lst_clips)
+        layout.addStretch()
+
+    def set_item(self):
+        pass
+
+class qClipController(QtGui.QWidget):
+    def __init__(self, parent):
+        super(qClipController, self).__init__(parent)
+        self.page_sz = 10
+        self.tick_sz = 1
+        self.frame_cnt = 60
+        self.frame_cursor = 0 # current frame number
+        self.frame_cursor_end = 0
+        self.frame_cursor_prev = 0
+        self.setMinimumHeight(24)
+        self.setMouseTracking(True)
+
+        self.mouse_dwn = False
+
+    def calc_frame_x(self, n, w):
+        return int(math.floor(n * w / self.frame_cnt))
+
+    def calc_frame_n(self, x, w):
+        f = int(math.floor(x * self.frame_cnt/w))
+        return min(f, self.frame_cnt - 1)
+
+    def paintEvent(self, e):
+        w = self.width()
+        h = self.height()
+
+        qp = QtGui.QPainter()
+        qp.begin(self)
+        qp.fillRect(-1, -1, w + 1, h + 1, QtGui.QColor(150, 150, 150))
+
+        w -= 4
+        start_x = 2
+
+        ## selection
+        if self.frame_cursor < self.frame_cursor_end:
+            x = start_x + self.calc_frame_x(self.frame_cursor, w)
+            qp.fillRect(x, 3, \
+                self.calc_frame_x(self.frame_cursor_end, w) - x + 1, h - 3, \
+                QtGui.QBrush(QtGui.QColor(70, 150, 70), QtCore.Qt.Dense4Pattern))
+
+        ## ticks
+        qp.setPen(QtGui.QPen(QtGui.QColor(0, 0, 0), 1))
+        ticks = []
+        for i in range(0, self.frame_cnt, self.tick_sz):
+            x = self.calc_frame_x(i, w)
+            ticks.append(QtCore.QLine(start_x + x, max(0, h-3), start_x + x, max(h-8, 5)))
+        qp.drawLines(ticks)
+
+        ## pages
+        qp.setPen(QtGui.QPen(QtGui.QColor(0, 0, 0), 2))
+        pages = []
+        for i in range(0, self.frame_cnt, self.page_sz):
+            x = self.calc_frame_x(i, w)
+            pages.append(QtCore.QLine(start_x + x, max(0, h-3), start_x + x, max(h-15, 12)))
+        qp.drawLines(pages)
+
+        ## indicator (snap to frames)
+        cursor_x = self.calc_frame_x(self.frame_cursor, w)
+        qp.setPen(QtGui.QPen(QtGui.QColor(200, 0, 0), 2))
+        qp.drawLine(QtCore.QLine(start_x + cursor_x, max(0, h-3), start_x + cursor_x, 3))
+
+        ## frame index
+        if self.frame_cursor == self.frame_cursor_end:
+            ftext = str(self.frame_cursor)
+            text_offset = 0
+        else:
+            ftext = str(self.frame_cursor) + '-' + str(self.frame_cursor_end)
+            text_offset = 16
+        qp.setBackground(QtGui.QColor(200, 0, 0))
+        qp.setBackgroundMode(QtCore.Qt.OpaqueMode)
+        qp.setPen(QtGui.QPen(QtGui.QColor(255, 255, 255), 1))
+        qp.drawText(w - 30 - text_offset, 3, w - 3, 24, QtCore.Qt.TextDontClip, ftext)
+
+        qp.end()
+
+    def mousePressEvent(self, e):
+        if not self.mouse_dwn:
+            w = self.width() - 4
+            cursor_x = max(e.pos().x() - 2, 0)
+
+            if e.modifiers() & QtCore.Qt.ShiftModifier:
+                self.frame_cursor_end = self.calc_frame_n(cursor_x, w)
+                if self.frame_cursor > self.frame_cursor_end:
+                    tmp = self.frame_cursor_end
+                    self.frame_cursor_end = self.frame_cursor
+                    self.frame_cursor = tmp
+            else:
+                self.frame_cursor = self.calc_frame_n(cursor_x, w)
+                self.frame_cursor_end = self.frame_cursor
+
+        self.update()
+        self.mouse_dwn = True
+
+    def mouseReleaseEvent(self, e):
+        self.mouse_dwn = False
+
+    def mouseMoveEvent(self, e):
+        if self.mouse_dwn:
+            w = self.width() - 4
+            cursor_x = max(e.pos().x() - 2, 0)
+            if e.modifiers() & QtCore.Qt.ShiftModifier:
+                self.frame_cursor_end = self.calc_frame_n(cursor_x, w)
+                if self.frame_cursor > self.frame_cursor_end:
+                    tmp = self.frame_cursor_end
+                    self.frame_cursor_end = self.frame_cursor
+                    self.frame_cursor = tmp
+            else:
+                self.frame_cursor = self.calc_frame_n(cursor_x, w)
+                self.frame_cursor_end = self.frame_cursor
+
+            self.update()
+
+    def set_pagesize(self, page_sz):
+        self.page_sz = page_sz
+    def set_framecnt(self, frame_cnt):
+        self.frame_cnt = max(frame_cnt, 1)
+    def set_ticksize(self, tick_sz):
+        self.tick_sz = tick_sz
+    def set_frame(self, f):
+        if self.frame_cursor_prev != self.frame_cursor:
+            self.update()
+            self.frame_cursor_prev = self.frame_cursor        
+
+class qClipEditDlg(QtGui.QDialog):
+    def __init__(self, parent):
+        super(qClipEditDlg, self).__init__(parent)
+        
+        self.setMinimumSize(640, 480)
+        self.setWindowTitle('Clip editor')
+        self.setSizeGripEnabled(True)
+
+        layout = QtGui.QVBoxLayout()
+
+        layout2 = QtGui.QHBoxLayout()
+        self.eng_view = eng_view.qEngineView(self)
+        layout2.addWidget(self.eng_view)
+        self.wnd_clips = qClipList(self)
+        layout2.addWidget(self.wnd_clips)
+        layout.addLayout(layout2)
+
+        layout3 = QtGui.QHBoxLayout()
+        self.btn_play = QtGui.QPushButton('P', self)
+        self.clip_ctrl = qClipController(self)
+        self.btn_play.setFixedSize(32, 32)
+        layout3.addWidget(self.btn_play)
+        layout3.addWidget(self.clip_ctrl)
+        layout.addLayout(layout3)
+
+        self.setLayout(layout)
+        self.eng_init = False
+        
+    def init_engine(self):
+        if self.eng_init:
+            return True
+
+        if not dheng.core_init(True):
+            print 'engine core init failed'
+            return False
+
+        dheng.log_outputconsole(True)
+
+        params = dheng.init_params()
+        params.flags = dheng.ENG_FLAG_DEBUG
+        params.gfx.flags = dheng.GFX_FLAG_DEBUG        
+        params.gfx.width = self.width()
+        params.gfx.height = self.height()
+        params.data_dir = os.path.abspath(util.get_exec_dir(__file__) + '/../../data') 
+
+        hwnd = dheng.str_toptr(self.eng_view.winId().__hex__())
+        if not dheng.app_init('main', params, hwnd):
+            dheng.err_sendtolog(False)
+            dheng.core_release(False)
+            return False
+
+        if not dheng.eng_init(params):
+            dheng.err_sendtolog(False)
+            dheng.app_release()
+            dheng.core_release(False)
+            dheng.err_sendtolog(True)
+            return False
+
+        dheng.gfx_set_debug_renderfunc(dheng.gfx_render_grid)
+        self.eng_view.init_props()
+
+        self.eng_init = True
+        return True
+
+    def release_engine(self):
+        if self.eng_init:
+            dheng.eng_release()
+            dheng.app_release()
+            dheng.core_release(True)
+            self.eng_init = False
+

src/h3dimport-gui/h3dimport-gui.py

 from PyQt4 import QtCore, QtGui
-import ConfigParser
-import os
-import platform
-import subprocess
-import sys
-import json
+import ConfigParser, os, platform, subprocess, sys, json
 from copy_reg import add_extension
 
 g_importerpath = ""
 g_verbosemode = False
 
 # register module path
-mod_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__)) + "/../pymodules")
+mod_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__)) + '/../pymodules')
 sys.path.append(mod_path)
-import dh_w_about
-from dh_util import *
+from dhdlg import about
+from dhutil import util
+import dheng
+import clipedit
 
-def util_add_extension(filepath, ext):
+def add_extension(filepath, ext):
     (filename, fileext) = os.path.splitext(filepath)
     if not ("." + ext) in fileext:
         filepath = filepath + "." + ext
         super(w_prefs, self).__init__(parent)
         self.init_ui()
         
-        
     def init_ui(self):
         self.setMinimumWidth(500)
         layout = QtGui.QVBoxLayout(self)
             self.infiledir = os.path.normpath(str(dlg.directory().path()))
             in_filepath = str(self.edit_infilepath.text())
             out_filepath = str(self.edit_outfilepath.text())
-            self.edit_outfilepath.setText(util_make_samefname(out_filepath, in_filepath, "h3dp"))
+            self.edit_outfilepath.setText(util.make_samefname(out_filepath, in_filepath, "h3dp"))
             self.enum_phxobjects()
         
     def btn_browseoutfile_click(self):
         if dlg.exec_():
             files = dlg.selectedFiles()
             filepath = os.path.normpath(str(files[0]))
-            self.edit_outfilepath.setText(util_add_extension(filepath, "h3dp"))
+            self.edit_outfilepath.setText(add_extension(filepath, "h3dp"))
             self.outfiledir = os.path.normpath(str(dlg.directory().path()))
             
     def btn_import_click(self, checked):
         self.infiledir = ""
         self.outfiledir = ""
         self.init_ui()
+        self.dlg_clipedit = clipedit.qClipEditDlg(self)
+
+    def __del__(self):
+        self.dlg_clipedit.release_engine()        
         
     def init_ui(self):
         layout = QtGui.QFormLayout(self)
         self.edit_fps = QtGui.QLineEdit("30", self)
         self.edit_fps.setMaximumWidth(40)
         self.check_zup = QtGui.QCheckBox(self)
+        btn_clipedit = QtGui.QPushButton('Edit clips', self)
 
         # add to layout
         layout_infile = QtGui.QHBoxLayout()
         
         layout.addRow("Fps:", self.edit_fps)
         layout.addRow("Up is Z (3dsmax):", self.check_zup)
+        layout.addRow(btn_clipedit)
         
         layout.addRow(btn_import)
         
         btn_browse_infile.clicked.connect(self.browse_infile_clicked)
         btn_browse_outfile.clicked.connect(self.browse_outfile_clicked)
         btn_import.clicked.connect(self.import_clicked)
-        
+        btn_clipedit.clicked.connect(self.btn_clipedit_clicked)
+    
+    def btn_clipedit_clicked(self, checked):
+        if not self.dlg_clipedit.init_engine():
+            print 'could not initialize dark-hammer engine'
+        else:
+            self.dlg_clipedit.exec_()
+
     def browse_infile_clicked(self):
         dlg = QtGui.QFileDialog(self, "Open animation", self.infiledir, \
             "Animation files (*.dae *.obj *.x *.ase *.ms3d)")
             self.infiledir = os.path.normpath(str(dlg.directory().path()))
             in_filepath = str(self.edit_infilepath.text())
             out_filepath = str(self.edit_outfilepath.text())
-            self.edit_outfilepath.setText(util_make_samefname(out_filepath, in_filepath, "h3da"))
+            self.edit_outfilepath.setText(util.make_samefname(out_filepath, in_filepath, "h3da"))
         
     def browse_outfile_clicked(self):
         dlg = QtGui.QFileDialog(self, "Save h3da file", self.outfiledir, \
         if dlg.exec_():
             files = dlg.selectedFiles()
             filepath = os.path.normpath(str(files[0]))
-            self.edit_outfilepath.setText(util_add_extension(filepath, "h3da"))
+            self.edit_outfilepath.setText(add_extension(filepath, "h3da"))
             self.outfiledir = os.path.normpath(str(dlg.directory().path()))
 
     def import_clicked(self):
             # automatically set the name of the output file to the name of the input file
             in_filepath = str(self.edit_infilepath.text())
             out_filepath = str(self.edit_outfilepath.text())
-            self.edit_outfilepath.setText(util_make_samefname(out_filepath, in_filepath, "h3dm"))
+            self.edit_outfilepath.setText(util.make_samefname(out_filepath, in_filepath, "h3dm"))
             
 
     def browse_outfile_clicked(self, checked):
         if dlg.exec_():
             files = dlg.selectedFiles()
             filepath = os.path.normpath(str(files[0]))
-            self.edit_outfilepath.setText(util_add_extension(filepath, "h3dm"))
+            self.edit_outfilepath.setText(add_extension(filepath, "h3dm"))
             self.outfile_dir = os.path.normpath(str(dlg.directory().path()))
         
     def choose_texdir_clicked(self, checked):
         global g_verbosemode
         try:
             self.config = ConfigParser.SafeConfigParser()
-            f = self.config.read("h3dimport-gui.ini")
+            f = self.config.read(os.path.normpath(util.get_exec_dir(__file__) + \
+                "/h3dimport-gui.ini"))
             if len(f) == 0:
                 raise BaseException()
         except:
             
             # construct default importerpath if not defined
             if g_importerpath == "":
-                g_importerpath = os.path.normpath(util_getmydir() + "../../bin/h3dimport") 
+                g_importerpath = os.path.normpath(util.get_exec_dir(__file__) + \
+                    "/../../bin/h3dimport") 
                 if platform.system() == "Windows":
                     g_importerpath += ".exe"
 
         self.wnds["model"].save_config(self.config)
         self.wnds["anim"].save_config(self.config)
         self.wnds["phx"].save_config(self.config)
-        with open("h3dimport-gui.ini", "w") as configfile:
-            self.config.write(configfile)        
+        self.config.write(open(os.path.normpath(util.get_exec_dir(__file__) + \
+        "/h3dimport-gui.ini"), "w"))        
         
     def closeEvent(self, e):
         self.save_config()

src/hash-shadervars/hash-shadervars.py

 from optparse import OptionParser
 from ctypes import *
 
-mod_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__)) + "/../pymodules")
+mod_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__)) + '/../pymodules')
 sys.path.append(mod_path)
-from dh_util import *
+from dhutil import util
 
 # murmur hash callback function
 hash_murmur32 = None
 
-def show_help():
-    print """
-    usage: hash-shadervars.py [-i (--input)] [-l (--libhash)] [-s (--seed)] [-o (--output)] [-v (--verbose)]\n
-    arguments:
-        -i (--input): input directory (default=./)
-        -l (--libhash): hash function library path
-        -s (--seed): hash seed (default=98424)
-        -o (--output): output header file (default=gfx-shader-hashes.h)
-        -v (--verbose): verbose mode
-    """;
-
 def recursive_glob(treeroot, pattern):
     results = []
     for base, dirs, files in os.walk(treeroot):
 
    
 def main():
-    print "Dark-hammer shader hashing tool", util_getversion()
+    print "Dark-hammer shader hashing tool", util.VERSION
     if platform.system() == "Linux":
-        libcore_path = os.path.abspath("../../bin/libcore.so")
+        libcore_path = os.path.normpath(util.get_exec_dir(__file__) + "/../../bin/libcore.so")
     elif platform.system() == "Darwin":
-        libcore_path = os.path.abspath("../../bin/libdh_core.dylib")
+        libcore_path = os.path.normpath(util.get_exec_dir(__file__) + "/../../bin/libdh_core.dylib")
     elif platform.system() == "Windows":
         if "64bit" in platform.architecture():
-            libcore_path = os.path.abspath("../pymodules/murmurhash-x64.dll")
+            libcore_path = os.path.normpath(util.get_exec_dir(__file__) + \
+                "/../pymodules/murmurhash-x64.dll")
         else:
-            libcore_path = os.path.abspath("../pymodules/murmurhash-x86.dll")
+            libcore_path = os.path.normpath(util.get_exec_dir(__file__) + \
+                "/../pymodules/murmurhash-x86.dll")
     else:
         print "Error: unknown platform"
         sys.exit(-1)        
     
     parser = OptionParser()
+    
     parser.add_option("-i", "--input", dest="inputdir", \
-                      default=os.path.normpath(util_getmydir() + "../engine/"), \
+                      default=os.path.normpath(util.get_exec_dir(__file__) + "/../engine/"), \
                       help="source input directory")
-    parser.add_option("-l", "--libhash", dest="libhash", default=os.path.normpath(libcore_path), \
+    parser.add_option("-l", "--libhash", dest="libhash", default=os.path.abspath(libcore_path), \
                       help="hash library path")
     parser.add_option("-v", "--verbose", dest="verbose", action="store_true", default=False, \
                       help="verbose mode")
     parser.add_option("-s", "--seed", dest="seed", default=98424, help="hash seed")
-    print os.path.abspath(__file__)
     parser.add_option("-o", "--output", dest="outfile", \
-                      default=os.path.abspath("../../include/engine/gfx-shader-hashes.h"), \
+                      default=os.path.normpath(util.get_exec_dir(__file__) + \
+                      "/../../include/engine/gfx-shader-hashes.h"), \
                       help="output header file")
     (options, args) = parser.parse_args()
 

src/map-editor/test.py

 from PyQt4 import QtCore, QtGui
-import os
-import platform
-import sys
+import os, platform, sys
 
 # register module path
-mod_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__)) + "/../pymodules")
+mod_path = os.path.normpath(os.path.dirname(os.path.abspath(__file__)) + '/../pymodules')
 sys.path.append(mod_path)
 
-from dh_util import *
-import dh_w_about
+from dhutil import util
+from dhdlg import about
 import dheng
 
 ##################################################################################################
         self.close()
 
     def mnu_help_about(self, checked):
-        about_wnd = dh_w_about.w_about(self, "map-editor", "Editor for level layout and gameplay")
+        about_wnd = about.qtAboutDlg(self, "map-editor", "Editor for level layout and gameplay")
         about_wnd.exec_()
 
 def load_stuff():
     dheng.scn_setactive(scn)
     dheng.scn_setcam(g_cam)
     
-    dheng.io_addvdir(os.path.abspath(util_getmydir() + '../../'), False)
+    dheng.io_addvdir(os.path.abspath(util.get_exec_dir(__file__) + '/../../'), False)
     dheng.sct_runfile('test-data/test6.lua')
 
 def main():
     params.gfx.height = 480
     params.gfx.refresh_rate = 60
     params.dev.webserver_port = 8888
-    params.data_dir = os.path.abspath(util_getmydir() + "../../data")
+    params.data_dir = os.path.abspath(util.get_exec_dir(__file__) + "/../../data")
 
     hwnd = dheng.str_toptr(main_wnd.get_view3d().winId().__hex__())
     print main_wnd.get_view3d().winId()
Add a comment to this file

src/pymodules/__init__.py

Empty file added.

src/pymodules/dh_util.py

-import os
-
-def util_getmydir():
-    return os.path.dirname(os.path.abspath(__file__)) + "/"
-
-def util_getfiledir(fpath):
-    return os.path.dirname(os.path.abspath(fpath)) + "/"
-    
-def util_getversion():
-    try:
-        f = open(util_getmydir() + "../VERSION", "r")
-    except IOError as fe:
-        return ""
-    else:
-        version = f.readline()
-        f.close()
-        return version
-    
-def util_make_samefname(out_filepath, in_filepath, file_ext):
-    (in_dir, in_nameext) = os.path.split(in_filepath)
-    (in_name, in_ext) = os.path.splitext(in_nameext)
-    (out_dir, out_nameext) = os.path.split(out_filepath)
-    return os.path.normpath(out_dir + "/" + in_name + "." + file_ext)

src/pymodules/dh_w_about.py

-from PyQt4 import QtCore, QtGui
-from dh_util import *
-
-class w_about(QtGui.QDialog):
-    def __init__(self, parent, title, desc):
-        super(w_about, self).__init__(parent)
-        self.setFixedSize(400, 250)
-        
-        layout = QtGui.QVBoxLayout(self)
-        lbl_title = QtGui.QLabel("Dark-hammer " + title + " Tool", self)
-        lbl_title.setFont(QtGui.QFont("Arial", 12, 8))
-        layout.addWidget(lbl_title)
-        
-        lbl_ver = QtGui.QLabel("v" + util_getversion())
-        layout.addWidget(lbl_ver)
-        
-        lbl_credits = QtGui.QLabel("Programmer: Sepehr Taghdisian (sep.tagh@gmail.com)")
-        lbl_credits.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
-        layout.addWidget(lbl_credits)
-                                   
-        lbl_link = QtGui.QLabel("<a href='http://www.hmrengine.com'>http://www.hmrengine.com</a>",\
-                             self)
-        lbl_link.setOpenExternalLinks(True)
-        lbl_link.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
-        layout.addWidget(lbl_link)
-        
-        desc += """<br><br>This software is open-source and is also written using following """\
-        """open-source software :\n<br>"""\
-        """Python: <a href='http://python.org/'>http://python.org/</a><br>""" \
-        """PyQt4: <a href='http://www.riverbankcomputing.com/software/pyqt/intro'>http://www.riverbankcomputing.com/software/pyqt/intro</a><br>"""
-         
-        
-        txt_desc = QtGui.QTextEdit(desc, self)
-        txt_desc.setFrameStyle(QtGui.QFrame.Panel)
-        txt_desc.setLineWidth(1)
-        txt_desc.setMinimumHeight(50)
-        txt_desc.setReadOnly(True)
-        layout.addWidget(txt_desc)
-        
-        layout.addStretch()
-        btn_ok = QtGui.QPushButton("Ok", self)
-        btn_ok.clicked.connect(self.btn_ok_click)
-        layout.addWidget(btn_ok)
-    
-    def btn_ok_click(self, checked):
-        self.accept()
Add a comment to this file

src/pymodules/dhdlg/__init__.py

Empty file added.

src/pymodules/dhdlg/about.py

+from PyQt4 import QtCore, QtGui
+from dhutil import util
+
+class qtAboutDlg(QtGui.QDialog):
+    def __init__(self, parent, title, desc):
+        super(qtAboutDlg, self).__init__(parent)
+        self.setFixedSize(400, 250)
+        
+        layout = QtGui.QVBoxLayout(self)
+        lbl_title = QtGui.QLabel('DarkHAMMER: ' + title, self)
+        lbl_title.setFont(QtGui.QFont("Arial", 12, 8))
+        layout.addWidget(lbl_title)
+        
+        lbl_ver = QtGui.QLabel('v' + util.VERSION)
+        layout.addWidget(lbl_ver)
+        
+        lbl_credits = QtGui.QLabel("Copyright (c) 2013 - Sepehr Taghdisian (sep.tagh@gmail.com)")
+        lbl_credits.setTextInteractionFlags(QtCore.Qt.TextSelectableByMouse)
+        layout.addWidget(lbl_credits)
+                                   
+        lbl_link = QtGui.QLabel("<a href='http://www.hmrengine.com'>http://www.hmrengine.com</a>",\
+                             self)
+        lbl_link.setOpenExternalLinks(True)
+        lbl_link.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse)
+        layout.addWidget(lbl_link)
+        
+        desc += """<br><br>This software is open-source and is also written using following """\
+        """open-source software :\n<br>"""\
+        """Python: <a href='http://python.org/'>http://python.org/</a><br>""" \
+        """PyQt4: <a href='http://www.riverbankcomputing.com/software/pyqt/intro'>http://www.riverbankcomputing.com/software/pyqt/intro</a><br>"""
+        
+        txt_desc = QtGui.QTextEdit(desc, self)
+        txt_desc.setFrameStyle(QtGui.QFrame.Panel)
+        txt_desc.setLineWidth(1)
+        txt_desc.setMinimumHeight(50)
+        txt_desc.setReadOnly(True)
+        layout.addWidget(txt_desc)
+        
+        layout.addStretch()
+        btn_ok = QtGui.QPushButton("Ok", self)
+        btn_ok.clicked.connect(self.btn_ok_click)
+        layout.addWidget(btn_ok)
+    
+    def btn_ok_click(self, checked):
+        self.accept()
Add a comment to this file

src/pymodules/dhutil/__init__.py

Empty file added.

src/pymodules/dhutil/log.py

+

src/pymodules/dhutil/util.py

+import os, sys
+
+VERSION = '0.4.7'
+
+def get_exec_dir(pyfile):
+    if sys.executable.lower().find('python') != -1:
+        return os.path.dirname(os.path.abspath(pyfile))
+    else:
+        return os.path.abspath(os.path.dirname(sys.executable))
+
+def make_samefname(out_filepath, in_filepath, file_ext):
+    (in_dir, in_nameext) = os.path.split(in_filepath)
+    (in_name, in_ext) = os.path.splitext(in_nameext)
+    (out_dir, out_nameext) = os.path.split(out_filepath)
+    return os.path.normpath(out_dir + '/' + in_name + '.' + file_ext)
Add a comment to this file

src/pymodules/dhwidgets/__init__.py

Empty file added.

src/pymodules/dhwidgets/eng_view.py

+from PyQt4 import QtCore, QtGui
+import dheng
+
+class qEngineView(QtGui.QWidget):
+    def __init__(self, parent):
+        super(qEngineView, self).__init__(parent)
+
+        self.setAttribute(QtCore.Qt.WA_PaintOnScreen, True)
+        self.setAttribute(QtCore.Qt.WA_NativeWindow, True)
+        self.setFocusPolicy(QtCore.Qt.StrongFocus)
+        self.setMouseTracking(True)
+        self.setMinimumSize(64, 64)
+        self.setSizePolicy(\
+            QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding))        
+
+        self.timer = QtCore.QTimer(self)
+        self.sz_timer = QtCore.QTimer(self)
+        self.sz_timer.setSingleShot(True)
+        self.timer.start(20)
+
+        self.prev_x = 0
+        self.prev_y = 0
+        self.mouse_dwn = False
+        self.cam = None
+
+        # events
+        self.timer.timeout.connect(self.update)
+        self.sz_timer.timeout.connect(self.resize)
+
+    def init_props(self):
+        cam = dheng.camera()
+        pos = dheng.vec4f()
+        lookat = dheng.vec4f()
+
+        pos.y = 2
+        pos.z = -5
+        dheng.cam_init(cam, pos, lookat, 0.2, 300, dheng.math_torad(60))
+        dheng.cam_update(cam)
+        dheng.cam_set_viewsize(cam, self.width(), self.height())
+
+        scn = dheng.scn_create_scene('main')
+        dheng.scn_setactive(scn)
+        dheng.scn_setcam(cam)
+
+        self.cam = cam
+        self.scene = scn
+
+    def paintEvent(self, e):
+        if not self.cam:
+            return
+        dheng.eng_update()
+
+    def paintEngine(self):
+        return None
+
+    def resize(self):
+        if not self.cam:
+            return
+        dheng.app_resize_window('main', self.width(), self.height())
+        dheng.cam_set_viewsize(self.cam, self.width(), self.height())
+
+    def keyPressEvent(self, e):
+        if not self.cam:
+            return
+        if self.mouse_dwn:
+            cam = dheng.scn_getcam()
+            key = e.key()
+            if key == QtCore.Qt.Key_W or key == QtCore.Qt.Key_Up:
+                dheng.cam_fwd(self.cam, 0.5)
+            elif e.key() == QtCore.Qt.Key_S or key == QtCore.Qt.Key_Down:
+                dheng.cam_fwd(self.cam, -0.5)
+            elif e.key() == QtCore.Qt.Key_D or key == QtCore.Qt.Key_Right:
+                dheng.cam_strafe(self.cam, 0.5)
+            elif e.key() == QtCore.Qt.Key_A or key == QtCore.Qt.Key_Left:
+                dheng.cam_strafe(self.cam, -0.5)
+    
+    def mouseMoveEvent(self, e):
+        if not self.cam:
+            return
+        pt = e.pos()
+
+        if self.mouse_dwn:
+            cam = dheng.scn_getcam()
+            dx = pt.x() - self.prev_x
+            dy = pt.y() - self.prev_y
+            dheng.cam_yaw(cam, dx*0.01)
+            dheng.cam_pitch(cam, dy*0.01)
+            
+        self.prev_x = pt.x()
+        self.prev_y = pt.y()
+
+    def resizeEvent(self, e):
+        if not self.cam:
+            return
+        if not self.sz_timer.isActive():
+            self.sz_timer.start(500)
+
+    def update(self):
+        if not self.cam:
+            return
+        dheng.cam_update(self.cam)
+        dheng.eng_update()
+
+    def mousePressEvent(self, e):
+        self.mouse_dwn = True
+
+    def mouseReleaseEvent(self, e):
+        self.mouse_dwn = False
+
+    def wheelEvent(self, e):
+        if not self.cam:
+            return
+        steps = e.delta()/15
+        dheng.cam_fwd(self.cam, steps)
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.