Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Reduce DLL calls #1

Closed
Marocco2 opened this issue Nov 1, 2021 · 7 comments
Closed

Reduce DLL calls #1

Marocco2 opened this issue Nov 1, 2021 · 7 comments
Labels
enhancement New feature or request

Comments

@Marocco2
Copy link

Marocco2 commented Nov 1, 2021

self.__path = WinDLL( (os.path.abspath(__file__)+'CamTool_1-16.dll').replace("\\",'/').replace( os.path.basename(__file__),'') )

Main finding when I did my own version of Camtool is that python doesn't like DLLs on its code. Original Author did give DLL source code on his racedepartment app page. If you can replace those calls to CSP ext ones a very large amount of performance would be achieved.

@tmeedend
Copy link
Owner

tmeedend commented Nov 1, 2021

Hello Marocco2 ! Yes, removing the DLL give 50% perf boost. The link to the DLL source code is broken on the RD forum.

Are you sure we can replace these DLL calls to CSP ext functions ? Where can I find documentation about these ?

Thank you !

@Marocco2
Copy link
Author

Marocco2 commented Nov 2, 2021

I got this PoC of CSP ext functions long ago. Here's the code:

'''
AC v1.14.3 x64

Use:
- ac.freeCameraRotateHeading(angle)
- ac.freeCameraRotateRoll(angle)
- ac.freeCameraRotatePitch(angle)
to control camera rotation

WBR, kasperski95
'''

import ac
import os
import math
import ctypes
import sys
import linecache
from ctypes import*

class CamToolTool(object):
    # def __init__(self):
    #     self.__path = WinDLL( (os.path.abspath(__file__)+'CamTool_1-16.dll').replace("\\",'/').replace( os.path.basename(__file__),'') )

    def is_lmb_pressed(self):
        # self.__path.IsLeftMouseButtonPressed.restype = ctypes.c_bool
        # return self.__path.IsLeftMouseButtonPressed()
        return ac.ext_isButtonPressed(1)

    def is_async_key_pressed(self, value):
        # self.__path.IsAsyncKeyPressed.argtypes = [ctypes.c_wchar]
        # self.__path.IsAsyncKeyPressed.restype = ctypes.c_bool
        # return self.__path.IsAsyncKeyPressed(value)
        return ac.ext_isButtonPressed(value)

    def get_position(self, axis):
        # self.__path.GetPosition.restype = ctypes.c_float
        # return self.__path.GetPosition(axis)
        return ac.ext_getCameraPositionAxis(axis)

    def set_position(self, axis, value):
        # self.__path.SetPosition.argtypes = [ctypes.c_int, ctypes.c_float]
        # self.__path.SetPosition.restype = ctypes.c_bool
        # return self.__path.SetPosition(axis, value)
        return ac.ext_setCameraPositionAxis(axis, value)

    def get_heading(self):
        # self.__path.GetHeading.restype = ctypes.c_float
        # return (-1) * self.__path.GetHeading()
        return ac.ext_getCameraYawRad()

    def set_heading(self, angle, absolute=True):
        try:
            self.prev_pitch = self.get_pitch()
            self.prev_roll = self.get_roll()
            ac.freeCameraRotateRoll(0 - self.prev_roll)
            ac.freeCameraRotatePitch(0 - self.prev_pitch)

            if absolute:
                ac.freeCameraRotateHeading( angle - self.get_heading() )
            else:
                ac.freeCameraRotateHeading(angle)

            ac.freeCameraRotatePitch(self.prev_pitch)
            ac.freeCameraRotateRoll(self.prev_roll)

            return 1

        except Exception as e:
            debug(e)

    def get_pitch(self):
        # self.__path.GetPitch.restype = ctypes.c_float
        # return self.__path.GetPitch()
        return ac.ext_getCameraPitchRad()

    def set_pitch(self, angle, absolute=True):
        self.prev_roll = self.get_roll()
        self.set_roll( 0 )
        if absolute:
            ac.freeCameraRotatePitch( angle - self.get_pitch() )
        else:
            ac.freeCameraRotatePitch( angle )
        self.set_roll( self.prev_roll )
        return 1

    def set_heading_and_pitch(self, heading, pitch): #optimization
        self.prev_roll = self.get_roll()
        self.set_roll(0)
        ac.freeCameraRotatePitch(0 - self.get_pitch())
        ac.freeCameraRotateHeading(heading - self.get_heading())
        ac.freeCameraRotatePitch(pitch)
        self.set_roll(self.prev_roll)

    def set_rotation(self, pitch, roll, heading):
        ac.freeCameraRotateRoll(0 - self.get_roll())
        ac.freeCameraRotatePitch(0 - self.get_pitch())
        ac.freeCameraRotateHeading(heading - self.get_heading())
        ac.freeCameraRotatePitch(pitch)
        ac.freeCameraRotateRoll(roll)

    def get_roll(self):
        # self.__path.GetRoll.restype = ctypes.c_float
        # return math.asin( max(-1, min(1, self.__path.GetRoll() )) )
        return ac.ext_getCameraRollRad()

    def set_roll(self, angle, absolute=True):
        if absolute:
            ac.freeCameraRotateRoll( angle - self.get_roll())
        else:
            ac.freeCameraRotateRoll( angle )
        return 1


    def get_fov(self):
        # self.__path.GetFOV.restype = ctypes.c_float
        # return self.__path.GetFOV()
        return ac.ext_getCameraFov()

    def convert_fov_2_focal_length(self, val, reverse=False):
        #convert to interpolation freindly format

        if val != 0:
            self.x = 15
            if not reverse:
                return 1 / (val + self.x)
            else:
                return (1 - self.x * val) / val

        return 0.00001

        # if reverse:
        #     return 2203 / (2 * math.tan(math.pi * val / 360))
        # else:
        #     return 2 * math.atan(2203 / (2 * val)) * 180 / math.pi

    def set_fov(self, fov):
        # self.__path.SetFOV.argtypes = [ctypes.c_float]
        # self.__path.SetFOV.restype = ctypes.c_bool
        # self.near_clipping = min(2, max(0.1, (2 - (fov/50))))
        # self.set_clipping_near(self.near_clipping)
        # return self.__path.SetFOV(fov)
        return ac.ext_setCameraFov(fov)

    def get_dof_factor(self):
        # self.__path.GetDOFfactor.restype = ctypes.c_int
        # return self.__path.GetDOFfactor()
        return ac.ext_getCameraDofFactor()

    def set_dof_factor(self, strength):
        # self.__path.SetDOFfactor.argtypes = [ctypes.c_int]
        # self.__path.SetDOFfactor.restype = ctypes.c_bool
        # return self.__path.SetDOFfactor(strength)
        return ac.ext_setCameraDofFactor(strength)

    def get_focus_point(self):
        # self.__path.GetFocusPoint.restype = ctypes.c_float
        # return self.__path.GetFocusPoint()
        return ac.ext_getCameraDofFocus()

    def set_focus_point(self, value):
        # self.__path.SetFocusPoint.argtypes = [ctypes.c_float]
        # self.__path.SetFocusPoint.restype = ctypes.c_bool
        # if value < 0.1:
        #     self.set_dof_factor( 0 )
        # else:
        #     self.set_dof_factor( 1 )
        # return self.__path.SetFocusPoint(value)
        return ac.ext_setCameraDofFocus()

    def set_clipping_near(self, clipping):
        # self.__path.SetClippingNear.argtypes = [ctypes.c_float]
        # self.__path.SetClippingNear.restype = ctypes.c_bool
        # return self.__path.SetClippingNear(clipping)
        return ac.ext_setCameraClipNear(clipping)

    def set_clipping_far(self, clipping):
        # self.__path.SetClippingFar.argtypes = [ctypes.c_float]
        # self.__path.SetClippingFar.restype = ctypes.c_bool
        # return self.__path.SetClippingFar(clipping)
        return ac.ext_setCameraClipFar(clipping)

    def get_replay_position(self):
        # self.__path.GetReplayPosition.restype = ctypes.c_int
        # return self.__path.GetReplayPosition()
        return ac.ext_getReplayPosition()

    def set_replay_position(self, keyframe):
        # self.__path.SetReplayPosition.argtypes = [ctypes.c_int]
        # self.__path.SetReplayPosition.restype = ctypes.c_bool
        # return self.__path.SetReplayPosition(keyframe)
        return ac.ext_setReplayPosition(keyframe)

    def set_replay_speed(self, value):
        # self.__path.SetReplaySpeed.argtypes = [ctypes.c_float]
        # self.__path.SetReplaySpeed.restype = ctypes.c_bool
        # return self.__path.SetReplaySpeed(value)
        return ac.ext_setReplaySpeed(value)

    def get_volume(self):
        # self.__path.GetVolume.restype = ctypes.c_float
        # return self.__path.GetVolume()
        return ac.ext_getAudioVolume()

    def set_volume(self, value):
        # self.__path.SetVolume.argtypes = [ctypes.c_float]
        # self.__path.SetVolume.restype = ctypes.c_bool
        # return self.__path.SetVolume(value)
        return ac.ext_setAudioVolume(value)

ctt = CamToolTool()

def debug(e):
    exc_type, exc_obj, tb = sys.exc_info()
    f = tb.tb_frame
    lineno = tb.tb_lineno
    filename = f.f_code.co_filename
    linecache.checkcache(filename)
    line = linecache.getline(filename, lineno, f.f_globals)
    #ac.console( 'CamTool 2: EXCEPTION IN ({}, LINE {} "{}"): {}'.format(filename, lineno, line.strip(), exc_obj) )
    ac.console( 'CamTool 2: EXCEPTION IN (LINE {}): {}'.format(lineno, exc_obj) )
    ac.log( 'CamTool 2: EXCEPTION IN ({} LINE {}): {}'.format(filename, lineno, exc_obj) )

@tmeedend
Copy link
Owner

tmeedend commented Nov 2, 2021

Thank you! I'm going to try that :)

@tmeedend
Copy link
Owner

tmeedend commented Nov 4, 2021

Hello again, I have tried your code but it doesn't work for all the functions. I have tried to simplify and call ac.ext only to change the camera position, but it doesn't work.

It seems to work for some functions, like the focus point or the FOV though !

I cannot find any documentation about these functions. Do you have any ideas where can I find it ?

Thanks

@tmeedend
Copy link
Owner

tmeedend commented Nov 4, 2021

I have replaced most of the calls and the gain is approximately 25% ! Not bad ! The modified file is here: https://github.com/tmeedend/camtool/blob/csp-ext-replacement-for-better-perfs/CamTool_2/apps/python/CamTool_2/stdlib64/CamToolTool.py

@tmeedend
Copy link
Owner

tmeedend commented Nov 5, 2021

I fixed the calls to the position functions. With csp the indexes for axis were not the same. I fixed that and I got something like 50% gain I think.

@Marocco2
Copy link
Author

Marocco2 commented Nov 6, 2021

Good work! Now I can close the issue

@Marocco2 Marocco2 closed this as completed Nov 6, 2021
@tmeedend tmeedend added the enhancement New feature or request label Nov 28, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants