Compare commits
	
		
			318 Commits
		
	
	
		
			9c5fc5d1d3
			...
			e2002e
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 316441b954 | |||
| 9d7613be8f | |||
| c989f3254f | |||
| f8d76929ae | |||
| a51c28b607 | |||
| 9142371f88 | |||
| 35f92341fa | |||
| a8d1eebdaf | |||
| 87922c9389 | |||
| 38287f56b0 | |||
| 42ad5b01c1 | |||
| 2b46d6ebca | |||
| 953ad8391c | |||
| 1458ecd84f | |||
| 288b085d0c | |||
| aa0b2b1b7e | |||
| acede01167 | |||
| 92a2b0305e | |||
| 4886953722 | |||
| 601860b242 | |||
| f00cef2e21 | |||
| e733dca053 | |||
| 387be05826 | |||
| c5b21a9bb3 | |||
| 5b2c7bfc84 | |||
| 47d913ab64 | |||
| 878ce14254 | |||
| 9075931c51 | |||
| 39ab42f2da | |||
| 30cab4d79b | |||
| 8ee2aaa70a | |||
| 2f9694632d | |||
| 7b8d73cd84 | |||
| 3d8bd77c59 | |||
| 290289f413 | |||
| 2732210fc9 | |||
| 68900fb992 | |||
| ef724ae323 | |||
| 6d4c1a680b | |||
| 8aeaa0368e | |||
| 7969286fdc | |||
| cde2bead97 | |||
| c42e4c09a8 | |||
| b8c8ccad9d | |||
| 335f3541f1 | |||
| 808dcef817 | |||
| 6ac06cc504 | |||
| 86de9617f3 | |||
| 29761ec9e6 | |||
| ea7cf849b8 | |||
| 5d559734b9 | |||
| 939346c896 | |||
| f2dcfc0ffa | |||
| e78bd17d93 | |||
| f9a02f03cb | |||
| 21a4ee0af7 | |||
| 9bf83bc49f | |||
| d88e1f0f42 | |||
| 96f4e29778 | |||
| 1d705d2ca2 | |||
| 0979cd976f | |||
| db6d786ee4 | |||
| 06319131fd | |||
| c08e1d3835 | |||
| 27bd360317 | |||
| 82a53a868a | |||
| 94eaba7319 | |||
| 8d1c2c51bd | |||
| 07d98639f2 | |||
| 1944fc97b8 | |||
| d69e3438ff | |||
| 62e52a7316 | |||
| c4b48c2d87 | |||
| 96f69a7cfe | |||
| 90950970f0 | |||
| 106e36e30d | |||
| e71b0849b3 | |||
| e079c94832 | |||
| 5572494f3d | |||
| 8f03927391 | |||
| 6586d90177 | |||
| 952cee36a3 | |||
| 35bfdf3715 | |||
| 135aaa0669 | |||
| c6b776a329 | |||
| 67c7443985 | |||
| 42273470c3 | |||
| 4dfc6be702 | |||
| 92e1abcfdc | |||
| 764eefeb06 | |||
| 979dfc605d | |||
| 55fb300901 | |||
| c59e6a66d4 | |||
| 659802b888 | |||
| 33f6fcaaaf | |||
| d37b41b181 | |||
| 70742b823f | |||
| da8f9d23e4 | |||
| ff886e6d46 | |||
| 70a603cf7a | |||
| bfc4c2644f | |||
| f101124d24 | |||
| c6f672bd61 | |||
| 7f38b15fe7 | |||
| 2bb296028f | |||
| 5628493493 | |||
| f8a08a41b1 | |||
| 2cd91f598c | |||
| a20d6b581c | |||
| e34ed0794f | |||
| bdcf4c980b | |||
| 25d7ba3e72 | |||
| 30e5acf9bf | |||
| c3435b9533 | |||
| 8765e894f5 | |||
| 2c5c8d0e4f | |||
| 4805dd06a7 | |||
| 2bc2ab43a1 | |||
| bf7b4416ec | |||
| a2d03cfe6e | |||
| 95f0ecfc54 | |||
| 07f59224fc | |||
| 02259985be | |||
| 6b8585c81a | |||
| 5d78eabf94 | |||
| 41c1459c4e | |||
| 304a497565 | |||
| 9fa399371a | |||
| 4625fdb6b2 | |||
| 79553927aa | |||
| 86661c1012 | |||
| 03967c7a2b | |||
| 61fd48a12f | |||
| 519039b8b6 | |||
| 5244b1b3e8 | |||
| 7ae3bbe496 | |||
| 001be2f8da | |||
| 6a25b3c5d7 | |||
| 8d4ac7251a | |||
| ae63b252c6 | |||
| ee73823206 | |||
| af2850e20c | |||
| bc4a31d415 | |||
| 5303ad3ac6 | |||
| 5153cff790 | |||
| abe17870ce | |||
| c798f122d0 | |||
| d1edb1464e | |||
| ee8d3314b5 | |||
| c6139282ed | |||
| 559a3b8b39 | |||
| 8d072ae481 | |||
| 293a612e9c | |||
| 8020599513 | |||
| 4fbc1aba7f | |||
| 1380585297 | |||
| beee036a3d | |||
| 76b2ba8f80 | |||
| e7143cc740 | |||
| bd0886b1d7 | |||
| 8eb8c0bd98 | |||
| dd06e490a7 | |||
| 5e4ac6dd0b | |||
| be0a9149ad | |||
| 7ab3398941 | |||
| c10e988d2d | |||
| caafeea2f1 | |||
| 2edee3fe68 | |||
| af147c9c63 | |||
| 8e4c20647b | |||
| 594cbeffbe | |||
| e1d48e4289 | |||
| 7960ca94a6 | |||
| 72f14f59bf | |||
| d994d040ef | |||
| 1e18795d29 | |||
| 9557b82970 | |||
| 88949c63c5 | |||
| 7cab325397 | |||
| 8792ef5cee | |||
| 761b1832ad | |||
| 074a51866f | |||
| c382460355 | |||
| 4a3544b5d8 | |||
| 7cebe8340f | |||
| ecaea8ad9d | |||
| cae7963b21 | |||
| 7a2976ced1 | |||
| aae64aa8f8 | |||
| ef25d15aed | |||
| 01bcf029f9 | |||
| 2b9baef712 | |||
| 489057018e | |||
| 501a064d25 | |||
| 9478e4e957 | |||
| 32c6535f8a | |||
| 21c2abe67c | |||
| 2b1b56bc0a | |||
| 9e47c1db6d | |||
| 6be977da7e | |||
| 693fa36ee1 | |||
| 6ec480930a | |||
| a627a52d46 | |||
| be63323c09 | |||
| 38595db46b | |||
| 48d28f6873 | |||
| eb033149a0 | |||
| db1c3bdf4c | |||
| 2b16b565a8 | |||
| 8c758bf51f | |||
| 1764081740 | |||
| c90bde8719 | |||
| bfb11275df | |||
| 3185f61f39 | |||
| fb00ca88ff | |||
| 78109cfee2 | |||
| fa65c02e8a | |||
| cb93ede7d7 | |||
| 2a3f8db0bc | |||
| 3ab9123000 | |||
| d6b4b6eeea | |||
| 2f1e6783a4 | |||
| 603a976adf | |||
| 1e0d32a88d | |||
| 82a7075308 | |||
| de8f7d08ed | |||
| caf95e2611 | |||
| b639f06aba | |||
| de41800e1c | |||
| d2746fb087 | |||
| 62d3e65796 | |||
| 74473087b5 | |||
| 392da64d1f | |||
| 30748390ca | |||
| f9d463ca1d | |||
| b8771e9d81 | |||
| 1f52eed66c | |||
| e562b626cb | |||
| ccb554ba16 | |||
| 972775b432 | |||
| ee984c332e | |||
| 038e5123c9 | |||
| b5575e5a48 | |||
| 76d79e6e18 | |||
| ca8fd0b357 | |||
| 87fa82e3d3 | |||
| 9fa58d9d7c | |||
| 864568d66b | |||
| f3e96546ae | |||
| fcc114aed3 | |||
| df33848bee | |||
| c17516a4e2 | |||
| 9b9acd5e15 | |||
| 3b0eb0e075 | |||
| f5b3da3a15 | |||
| b71275d0d5 | |||
| 6aeb9b0f22 | |||
| 609477737e | |||
| a747f89438 | |||
| 0bd0c57a00 | |||
| f3ab801928 | |||
| 9b821d4b8e | |||
| f2a0dbe36c | |||
| 12e66d8cf1 | |||
| 4b6424b702 | |||
| e66e082cc7 | |||
| 42eff22cbb | |||
| 448898a634 | |||
| 15ec41b1f0 | |||
| c5a7746c84 | |||
| 51aa8ea1d4 | |||
| ccdfc4246f | |||
| aead4c4903 | |||
| d2f4c0e221 | |||
| 887eeebe27 | |||
| 83077e3f15 | |||
| f5c20c5a13 | |||
| 4bd4995b6e | |||
| 381744e678 | |||
| 34c15c29cd | |||
| 0346e27657 | |||
| 9087b9c98c | |||
| f2cbcc88a7 | |||
| b8d9ea2aff | |||
| 37a09d0a21 | |||
| ed932e3fa4 | |||
| f00edd882f | |||
| f403955fcd | |||
| a562af9b60 | |||
| bdd9b0197f | |||
| f200933375 | |||
| 829ef5f269 | |||
| 0d73133f36 | |||
| 181b860360 | |||
| 20db9cc24d | |||
| c67b38ea1e | |||
| adb95eab1e | |||
| 93addd1200 | |||
| 7f9a7c9b4a | |||
| 7433409cda | |||
| 2a6e05aff1 | |||
| 348d7bf343 | |||
| 4c6df16aa7 | |||
| 8a7f5ee519 | |||
| 1958342a74 | |||
| 16e8e00783 | |||
| bcdcbfb106 | |||
| 28afefbbf7 | |||
| 3d2130e26a | |||
| 9761719dd5 | |||
| b2a781c7c2 | |||
| 7121737297 | |||
| b0991a8928 | |||
| b84fc93899 | |||
| 06c0c430a8 | |||
| 0f0c67dc07 | |||
| 3bb2d65faa | |||
| 20e33afeac | 
@ -1,268 +1,268 @@
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 *  Platform-specific and custom entropy polling functions
 | 
					 *  Platform-specific and custom entropy polling functions
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
 | 
					 *  Copyright (C) 2006-2016, ARM Limited, All Rights Reserved
 | 
				
			||||||
 *  SPDX-License-Identifier: Apache-2.0
 | 
					 *  SPDX-License-Identifier: Apache-2.0
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
					 *  Licensed under the Apache License, Version 2.0 (the "License"); you may
 | 
				
			||||||
 *  not use this file except in compliance with the License.
 | 
					 *  not use this file except in compliance with the License.
 | 
				
			||||||
 *  You may obtain a copy of the License at
 | 
					 *  You may obtain a copy of the License at
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  http://www.apache.org/licenses/LICENSE-2.0
 | 
					 *  http://www.apache.org/licenses/LICENSE-2.0
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  Unless required by applicable law or agreed to in writing, software
 | 
					 *  Unless required by applicable law or agreed to in writing, software
 | 
				
			||||||
 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
					 *  distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 | 
				
			||||||
 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
					 *  WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
				
			||||||
 *  See the License for the specific language governing permissions and
 | 
					 *  See the License for the specific language governing permissions and
 | 
				
			||||||
 *  limitations under the License.
 | 
					 *  limitations under the License.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 *  This file is part of mbed TLS (https://tls.mbed.org)
 | 
					 *  This file is part of mbed TLS (https://tls.mbed.org)
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
 | 
					#define _GNU_SOURCE
 | 
				
			||||||
#if !defined(MBEDTLS_CONFIG_FILE)
 | 
					#if !defined(MBEDTLS_CONFIG_FILE)
 | 
				
			||||||
#include "mbedtls/config.h"
 | 
					#include "mbedtls/config.h"
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#include MBEDTLS_CONFIG_FILE
 | 
					#include MBEDTLS_CONFIG_FILE
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(MBEDTLS_ENTROPY_C)
 | 
					#if defined(MBEDTLS_ENTROPY_C)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "mbedtls/entropy.h"
 | 
					#include "mbedtls/entropy.h"
 | 
				
			||||||
#include "mbedtls/entropy_poll.h"
 | 
					#include "mbedtls/entropy_poll.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(MBEDTLS_TIMING_C)
 | 
					#if defined(MBEDTLS_TIMING_C)
 | 
				
			||||||
#include <string.h>
 | 
					#include <string.h>
 | 
				
			||||||
#include "mbedtls/timing.h"
 | 
					#include "mbedtls/timing.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#if defined(MBEDTLS_HAVEGE_C)
 | 
					#if defined(MBEDTLS_HAVEGE_C)
 | 
				
			||||||
#include "mbedtls/havege.h"
 | 
					#include "mbedtls/havege.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
 | 
					#if defined(MBEDTLS_ENTROPY_NV_SEED)
 | 
				
			||||||
#include "mbedtls/platform.h"
 | 
					#include "mbedtls/platform.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
 | 
					#if !defined(MBEDTLS_NO_PLATFORM_ENTROPY)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
 | 
					#if !defined(unix) && !defined(__unix__) && !defined(__unix) && \
 | 
				
			||||||
    !defined(__APPLE__) && !defined(_WIN32)
 | 
					    !defined(__APPLE__) && !defined(_WIN32)
 | 
				
			||||||
#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
 | 
					#error "Platform entropy sources only work on Unix and Windows, see MBEDTLS_NO_PLATFORM_ENTROPY in config.h"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 | 
					#if defined(_WIN32) && !defined(EFIX64) && !defined(EFI32)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if !defined(_WIN32_WINNT)
 | 
					#if !defined(_WIN32_WINNT)
 | 
				
			||||||
#define _WIN32_WINNT 0x0400
 | 
					#define _WIN32_WINNT 0x0400
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#include <windows.h>
 | 
					#include <windows.h>
 | 
				
			||||||
#include <wincrypt.h>
 | 
					#include <wincrypt.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
 | 
					int mbedtls_platform_entropy_poll( void *data, unsigned char *output, size_t len,
 | 
				
			||||||
                           size_t *olen )
 | 
					                           size_t *olen )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    HCRYPTPROV provider;
 | 
					    HCRYPTPROV provider;
 | 
				
			||||||
    ((void) data);
 | 
					    ((void) data);
 | 
				
			||||||
    *olen = 0;
 | 
					    *olen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( CryptAcquireContext( &provider, NULL, NULL,
 | 
					    if( CryptAcquireContext( &provider, NULL, NULL,
 | 
				
			||||||
                              PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
 | 
					                              PROV_RSA_FULL, CRYPT_VERIFYCONTEXT ) == FALSE )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
					        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
 | 
					    if( CryptGenRandom( provider, (DWORD) len, output ) == FALSE )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        CryptReleaseContext( provider, 0 );
 | 
					        CryptReleaseContext( provider, 0 );
 | 
				
			||||||
        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
					        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    CryptReleaseContext( provider, 0 );
 | 
					    CryptReleaseContext( provider, 0 );
 | 
				
			||||||
    *olen = len;
 | 
					    *olen = len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return( 0 );
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#else /* _WIN32 && !EFIX64 && !EFI32 */
 | 
					#else /* _WIN32 && !EFIX64 && !EFI32 */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
 * Test for Linux getrandom() support.
 | 
					 * Test for Linux getrandom() support.
 | 
				
			||||||
 * Since there is no wrapper in the libc yet, use the generic syscall wrapper
 | 
					 * Since there is no wrapper in the libc yet, use the generic syscall wrapper
 | 
				
			||||||
 * available in GNU libc and compatible libc's (eg uClibc).
 | 
					 * available in GNU libc and compatible libc's (eg uClibc).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
#if defined(__linux__) && defined(__GLIBC__)
 | 
					#if defined(__linux__) && defined(__GLIBC__)
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
#include <sys/syscall.h>
 | 
					#include <sys/syscall.h>
 | 
				
			||||||
#if defined(SYS_getrandom)
 | 
					#if defined(SYS_getrandom)
 | 
				
			||||||
#define HAVE_GETRANDOM
 | 
					#define HAVE_GETRANDOM
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
 | 
					static int getrandom_wrapper( void *buf, size_t buflen, unsigned int flags )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    /* MemSan cannot understand that the syscall writes to the buffer */
 | 
					    /* MemSan cannot understand that the syscall writes to the buffer */
 | 
				
			||||||
#if defined(__has_feature)
 | 
					#if defined(__has_feature)
 | 
				
			||||||
#if __has_feature(memory_sanitizer)
 | 
					#if __has_feature(memory_sanitizer)
 | 
				
			||||||
    memset( buf, 0, buflen );
 | 
					    memset( buf, 0, buflen );
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return( syscall( SYS_getrandom, buf, buflen, flags ) );
 | 
					    return( syscall( SYS_getrandom, buf, buflen, flags ) );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <sys/utsname.h>
 | 
					#include <sys/utsname.h>
 | 
				
			||||||
/* Check if version is at least 3.17.0 */
 | 
					/* Check if version is at least 3.17.0 */
 | 
				
			||||||
static int check_version_3_17_plus( void )
 | 
					static int check_version_3_17_plus( void )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int minor;
 | 
					    int minor;
 | 
				
			||||||
    struct utsname un;
 | 
					    struct utsname un;
 | 
				
			||||||
    const char *ver;
 | 
					    const char *ver;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Get version information */
 | 
					    /* Get version information */
 | 
				
			||||||
    uname(&un);
 | 
					    uname(&un);
 | 
				
			||||||
    ver = un.release;
 | 
					    ver = un.release;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Check major version; assume a single digit */
 | 
					    /* Check major version; assume a single digit */
 | 
				
			||||||
    if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
 | 
					    if( ver[0] < '3' || ver[0] > '9' || ver [1] != '.' )
 | 
				
			||||||
        return( -1 );
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( ver[0] - '0' > 3 )
 | 
					    if( ver[0] - '0' > 3 )
 | 
				
			||||||
        return( 0 );
 | 
					        return( 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Ok, so now we know major == 3, check minor.
 | 
					    /* Ok, so now we know major == 3, check minor.
 | 
				
			||||||
     * Assume 1 or 2 digits. */
 | 
					     * Assume 1 or 2 digits. */
 | 
				
			||||||
    if( ver[2] < '0' || ver[2] > '9' )
 | 
					    if( ver[2] < '0' || ver[2] > '9' )
 | 
				
			||||||
        return( -1 );
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    minor = ver[2] - '0';
 | 
					    minor = ver[2] - '0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( ver[3] >= '0' && ver[3] <= '9' )
 | 
					    if( ver[3] >= '0' && ver[3] <= '9' )
 | 
				
			||||||
        minor = 10 * minor + ver[3] - '0';
 | 
					        minor = 10 * minor + ver[3] - '0';
 | 
				
			||||||
    else if( ver [3] != '.' )
 | 
					    else if( ver [3] != '.' )
 | 
				
			||||||
        return( -1 );
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( minor < 17 )
 | 
					    if( minor < 17 )
 | 
				
			||||||
        return( -1 );
 | 
					        return( -1 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return( 0 );
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
static int has_getrandom = -1;
 | 
					static int has_getrandom = -1;
 | 
				
			||||||
#endif /* SYS_getrandom */
 | 
					#endif /* SYS_getrandom */
 | 
				
			||||||
#endif /* __linux__ */
 | 
					#endif /* __linux__ */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <stdio.h>
 | 
					#include <stdio.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int mbedtls_platform_entropy_poll( void *data,
 | 
					int mbedtls_platform_entropy_poll( void *data,
 | 
				
			||||||
                           unsigned char *output, size_t len, size_t *olen )
 | 
					                           unsigned char *output, size_t len, size_t *olen )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    FILE *file;
 | 
					    FILE *file;
 | 
				
			||||||
    size_t read_len;
 | 
					    size_t read_len;
 | 
				
			||||||
    ((void) data);
 | 
					    ((void) data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(HAVE_GETRANDOM)
 | 
					#if defined(HAVE_GETRANDOM)
 | 
				
			||||||
    if( has_getrandom == -1 )
 | 
					    if( has_getrandom == -1 )
 | 
				
			||||||
        has_getrandom = ( check_version_3_17_plus() == 0 );
 | 
					        has_getrandom = ( check_version_3_17_plus() == 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( has_getrandom )
 | 
					    if( has_getrandom )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        int ret;
 | 
					        int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
 | 
					        if( ( ret = getrandom_wrapper( output, len, 0 ) ) < 0 )
 | 
				
			||||||
            return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
					            return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        *olen = ret;
 | 
					        *olen = ret;
 | 
				
			||||||
        return( 0 );
 | 
					        return( 0 );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
#endif /* HAVE_GETRANDOM */
 | 
					#endif /* HAVE_GETRANDOM */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *olen = 0;
 | 
					    *olen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    file = fopen( "/dev/urandom", "rb" );
 | 
					    file = fopen( "/dev/urandom", "rb" );
 | 
				
			||||||
    if( file == NULL )
 | 
					    if( file == NULL )
 | 
				
			||||||
        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
					        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    read_len = fread( output, 1, len, file );
 | 
					    read_len = fread( output, 1, len, file );
 | 
				
			||||||
    if( read_len != len )
 | 
					    if( read_len != len )
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
        fclose( file );
 | 
					        fclose( file );
 | 
				
			||||||
        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
					        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fclose( file );
 | 
					    fclose( file );
 | 
				
			||||||
    *olen = len;
 | 
					    *olen = len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return( 0 );
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif /* _WIN32 && !EFIX64 && !EFI32 */
 | 
					#endif /* _WIN32 && !EFIX64 && !EFI32 */
 | 
				
			||||||
#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
 | 
					#endif /* !MBEDTLS_NO_PLATFORM_ENTROPY */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(MBEDTLS_TEST_NULL_ENTROPY)
 | 
					#if defined(MBEDTLS_TEST_NULL_ENTROPY)
 | 
				
			||||||
int mbedtls_null_entropy_poll( void *data,
 | 
					int mbedtls_null_entropy_poll( void *data,
 | 
				
			||||||
                    unsigned char *output, size_t len, size_t *olen )
 | 
					                    unsigned char *output, size_t len, size_t *olen )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ((void) data);
 | 
					    ((void) data);
 | 
				
			||||||
    ((void) output);
 | 
					    ((void) output);
 | 
				
			||||||
    *olen = 0;
 | 
					    *olen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( len < sizeof(unsigned char) )
 | 
					    if( len < sizeof(unsigned char) )
 | 
				
			||||||
        return( 0 );
 | 
					        return( 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *olen = sizeof(unsigned char);
 | 
					    *olen = sizeof(unsigned char);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return( 0 );
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(MBEDTLS_TIMING_C)
 | 
					#if defined(MBEDTLS_TIMING_C)
 | 
				
			||||||
int mbedtls_hardclock_poll( void *data,
 | 
					int mbedtls_hardclock_poll( void *data,
 | 
				
			||||||
                    unsigned char *output, size_t len, size_t *olen )
 | 
					                    unsigned char *output, size_t len, size_t *olen )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned long timer = mbedtls_timing_hardclock();
 | 
					    unsigned long timer = mbedtls_timing_hardclock();
 | 
				
			||||||
    ((void) data);
 | 
					    ((void) data);
 | 
				
			||||||
    *olen = 0;
 | 
					    *olen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( len < sizeof(unsigned long) )
 | 
					    if( len < sizeof(unsigned long) )
 | 
				
			||||||
        return( 0 );
 | 
					        return( 0 );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memcpy( output, &timer, sizeof(unsigned long) );
 | 
					    memcpy( output, &timer, sizeof(unsigned long) );
 | 
				
			||||||
    *olen = sizeof(unsigned long);
 | 
					    *olen = sizeof(unsigned long);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return( 0 );
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif /* MBEDTLS_TIMING_C */
 | 
					#endif /* MBEDTLS_TIMING_C */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(MBEDTLS_HAVEGE_C)
 | 
					#if defined(MBEDTLS_HAVEGE_C)
 | 
				
			||||||
int mbedtls_havege_poll( void *data,
 | 
					int mbedtls_havege_poll( void *data,
 | 
				
			||||||
                 unsigned char *output, size_t len, size_t *olen )
 | 
					                 unsigned char *output, size_t len, size_t *olen )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
 | 
					    mbedtls_havege_state *hs = (mbedtls_havege_state *) data;
 | 
				
			||||||
    *olen = 0;
 | 
					    *olen = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( mbedtls_havege_random( hs, output, len ) != 0 )
 | 
					    if( mbedtls_havege_random( hs, output, len ) != 0 )
 | 
				
			||||||
        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
					        return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    *olen = len;
 | 
					    *olen = len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return( 0 );
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif /* MBEDTLS_HAVEGE_C */
 | 
					#endif /* MBEDTLS_HAVEGE_C */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if defined(MBEDTLS_ENTROPY_NV_SEED)
 | 
					#if defined(MBEDTLS_ENTROPY_NV_SEED)
 | 
				
			||||||
int mbedtls_nv_seed_poll( void *data,
 | 
					int mbedtls_nv_seed_poll( void *data,
 | 
				
			||||||
                          unsigned char *output, size_t len, size_t *olen )
 | 
					                          unsigned char *output, size_t len, size_t *olen )
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
 | 
					    unsigned char buf[MBEDTLS_ENTROPY_BLOCK_SIZE];
 | 
				
			||||||
    size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
 | 
					    size_t use_len = MBEDTLS_ENTROPY_BLOCK_SIZE;
 | 
				
			||||||
    ((void) data);
 | 
					    ((void) data);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
 | 
					    memset( buf, 0, MBEDTLS_ENTROPY_BLOCK_SIZE );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
 | 
					    if( mbedtls_nv_seed_read( buf, MBEDTLS_ENTROPY_BLOCK_SIZE ) < 0 )
 | 
				
			||||||
      return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
					      return( MBEDTLS_ERR_ENTROPY_SOURCE_FAILED );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if( len < use_len )
 | 
					    if( len < use_len )
 | 
				
			||||||
      use_len = len;
 | 
					      use_len = len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    memcpy( output, buf, use_len );
 | 
					    memcpy( output, buf, use_len );
 | 
				
			||||||
    *olen = use_len;
 | 
					    *olen = use_len;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return( 0 );
 | 
					    return( 0 );
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif /* MBEDTLS_ENTROPY_NV_SEED */
 | 
					#endif /* MBEDTLS_ENTROPY_NV_SEED */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif /* MBEDTLS_ENTROPY_C */
 | 
					#endif /* MBEDTLS_ENTROPY_C */
 | 
				
			||||||
 | 
				
			|||||||
@ -9,6 +9,7 @@ if (platform == Platform.OSX) project.addDefine('KORE_DEBUGDIR="osx-hl"');
 | 
				
			|||||||
if (platform == Platform.iOS) project.addDefine('KORE_DEBUGDIR="ios-hl"');
 | 
					if (platform == Platform.iOS) project.addDefine('KORE_DEBUGDIR="ios-hl"');
 | 
				
			||||||
if (platform !== Platform.Windows || audio !== AudioApi.DirectSound) {
 | 
					if (platform !== Platform.Windows || audio !== AudioApi.DirectSound) {
 | 
				
			||||||
	project.addDefine('KORE_MULTITHREADED_AUDIO');
 | 
						project.addDefine('KORE_MULTITHREADED_AUDIO');
 | 
				
			||||||
 | 
						project.addDefine('KINC_MULTITHREADED_AUDIO');
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
project.addDefine('KORE');
 | 
					project.addDefine('KORE');
 | 
				
			||||||
 | 
				
			|||||||
@ -1,31 +1,70 @@
 | 
				
			|||||||
package kha.graphics4;
 | 
					package kha.graphics4;
 | 
				
			||||||
 | 
					using StringTools;
 | 
				
			||||||
import kha.Blob;
 | 
					import kha.Blob;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class FragmentShader {
 | 
					class FragmentShader {
 | 
				
			||||||
	public var _shader: Pointer;
 | 
						public var _shader: Pointer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(sources: Array<Blob>, files: Array<String>) {
 | 
						public function new(sources: Array<Blob>, files: Array<String>) {
 | 
				
			||||||
		initShader(sources[0]);
 | 
							//initShader(sources[0]);
 | 
				
			||||||
	}
 | 
							var shaderBlob: Blob = null;
 | 
				
			||||||
 | 
							var shaderFile: String = null;
 | 
				
			||||||
	function initShader(source: Blob): Void {
 | 
					
 | 
				
			||||||
		_shader = kinc_create_fragmentshader(source.bytes.getData(), source.bytes.getData().length);
 | 
							#if kha_opengl
 | 
				
			||||||
	}
 | 
							final expectedExtension = ".glsl";
 | 
				
			||||||
 | 
							#elseif kha_direct3d11
 | 
				
			||||||
	public static function fromSource(source: String): FragmentShader {
 | 
							final expectedExtension = ".d3d11";
 | 
				
			||||||
		var sh = new FragmentShader(null, null);
 | 
							#elseif kha_direct3d12
 | 
				
			||||||
		sh._shader = kinc_fragmentshader_from_source(StringHelper.convert(source));
 | 
							final expectedExtension = ".d3d12";
 | 
				
			||||||
		return sh;
 | 
							#elseif kha_metal
 | 
				
			||||||
	}
 | 
							final expectedExtension = ".metal";
 | 
				
			||||||
 | 
							#elseif kha_vulkan
 | 
				
			||||||
	public function delete(): Void {}
 | 
							final expectedExtension = ".spirv";
 | 
				
			||||||
 | 
							#else
 | 
				
			||||||
	@:hlNative("std", "kinc_create_fragmentshader") static function kinc_create_fragmentshader(data: hl.Bytes, length: Int): Pointer {
 | 
							final expectedExtension = ".glsl";
 | 
				
			||||||
		return null;
 | 
							#end
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
 | 
							if (sources != null && files != null) {
 | 
				
			||||||
	@:hlNative("std", "kinc_fragmentshader_from_source") static function kinc_fragmentshader_from_source(source: hl.Bytes): Pointer {
 | 
								for (i in 0...files.length) {
 | 
				
			||||||
		return null;
 | 
									if (files[i].endsWith(expectedExtension)) {
 | 
				
			||||||
	}
 | 
										shaderBlob = sources[i];
 | 
				
			||||||
}
 | 
										shaderFile = files[i];
 | 
				
			||||||
 | 
										break;
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (shaderBlob == null && sources != null && sources.length > 0) {
 | 
				
			||||||
 | 
								trace('Warning: Could not find shader with extension ${expectedExtension}. Falling back to sources[0]: ${files != null && files.length > 0 ? files[0] : "Unknown"}');
 | 
				
			||||||
 | 
								shaderBlob = sources[0];
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (shaderBlob != null) {
 | 
				
			||||||
 | 
								initShader(shaderBlob);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								trace('Error: No suitable fragment shader source found!');
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function initShader(source: Blob): Void {
 | 
				
			||||||
 | 
							//_shader = kinc_create_fragmentshader(source.bytes.getData(), source.bytes.getData().length);
 | 
				
			||||||
 | 
							_shader = kinc_create_fragmentshader(source.bytes.getData(), source.length); // Use source.length here
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static function fromSource(source: String): FragmentShader {
 | 
				
			||||||
 | 
							var sh = new FragmentShader(null, null);
 | 
				
			||||||
 | 
							sh._shader = kinc_fragmentshader_from_source(StringHelper.convert(source));
 | 
				
			||||||
 | 
							return sh;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public function delete(): Void {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@:hlNative("std", "kinc_create_fragmentshader") static function kinc_create_fragmentshader(data: hl.Bytes, length: Int): Pointer {
 | 
				
			||||||
 | 
							return null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						@:hlNative("std", "kinc_fragmentshader_from_source") static function kinc_fragmentshader_from_source(source: hl.Bytes): Pointer {
 | 
				
			||||||
 | 
							return null;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,179 +1,38 @@
 | 
				
			|||||||
#include <kinc/compute/compute.h>
 | 
					#include <kinc/graphics4/compute.h>
 | 
				
			||||||
#include <kinc/graphics4/texture.h>
 | 
					#include <kinc/graphics4/texture.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <hl.h>
 | 
					#include <hl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_compute_create_shader(vbyte *data, int length) {
 | 
					vbyte *hl_kinc_compute_create_shader(vbyte *data, int length) {
 | 
				
			||||||
	kinc_compute_shader_t *shader = (kinc_compute_shader_t *)malloc(sizeof(kinc_compute_shader_t));
 | 
						kinc_g4_compute_shader *shader = (kinc_g4_compute_shader *)malloc(sizeof(kinc_g4_compute_shader));
 | 
				
			||||||
	kinc_compute_shader_init(shader, data, length);
 | 
						kinc_g4_compute_shader_init(shader, data, length);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_compute_delete_shader(vbyte *shader) {
 | 
					void hl_kinc_compute_delete_shader(vbyte *shader) {
 | 
				
			||||||
	kinc_compute_shader_t *sh = (kinc_compute_shader_t *)shader;
 | 
						kinc_g4_compute_shader *sh = (kinc_g4_compute_shader *)shader;
 | 
				
			||||||
	kinc_compute_shader_destroy(sh);
 | 
						kinc_g4_compute_shader_destroy(sh);
 | 
				
			||||||
	free(sh);
 | 
						free(sh);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_compute_get_constantlocation(vbyte *shader, vbyte *name) {
 | 
					vbyte *hl_kinc_compute_get_constantlocation(vbyte *shader, vbyte *name) {
 | 
				
			||||||
	kinc_compute_shader_t *sh = (kinc_compute_shader_t *)shader;
 | 
						kinc_g4_compute_shader *sh = (kinc_g4_compute_shader *)shader;
 | 
				
			||||||
	kinc_compute_constant_location_t *location = (kinc_compute_constant_location_t *)malloc(sizeof(kinc_compute_constant_location_t));
 | 
						kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)malloc(sizeof(kinc_g4_constant_location_t));
 | 
				
			||||||
	*location = kinc_compute_shader_get_constant_location(sh, (char *)name), sizeof(kinc_compute_constant_location_t);
 | 
						*location = kinc_g4_compute_shader_get_constant_location(sh, (char *)name);
 | 
				
			||||||
	return (vbyte *)location;
 | 
						return (vbyte *)location;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_compute_get_textureunit(vbyte *shader, vbyte *name) {
 | 
					vbyte *hl_kinc_compute_get_textureunit(vbyte *shader, vbyte *name) {
 | 
				
			||||||
	kinc_compute_shader_t *sh = (kinc_compute_shader_t *)shader;
 | 
						kinc_g4_compute_shader *sh = (kinc_g4_compute_shader *)shader;
 | 
				
			||||||
	kinc_compute_texture_unit_t *unit = (kinc_compute_texture_unit_t *)malloc(sizeof(kinc_compute_texture_unit_t));
 | 
						kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)malloc(sizeof(kinc_g4_texture_unit_t));
 | 
				
			||||||
	*unit = kinc_compute_shader_get_texture_unit(sh, (char *)name), sizeof(kinc_compute_texture_unit_t);
 | 
						*unit = kinc_g4_compute_shader_get_texture_unit(sh, (char *)name);
 | 
				
			||||||
	return (vbyte *)unit;
 | 
						return (vbyte *)unit;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_compute_set_bool(vbyte *location, bool value) {
 | 
					void hl_kinc_set_compute_shader(vbyte *shader) {
 | 
				
			||||||
	kinc_compute_constant_location_t *loc = (kinc_compute_constant_location_t *)location;
 | 
						kinc_g4_set_compute_shader((kinc_g4_compute_shader *)shader);
 | 
				
			||||||
	kinc_compute_set_bool(*loc, value);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_compute_set_int(vbyte *location, int value) {
 | 
					void hl_kinc_compute(int x, int y, int z) {
 | 
				
			||||||
	kinc_compute_constant_location_t *loc = (kinc_compute_constant_location_t *)location;
 | 
						kinc_g4_compute(x, y, z);
 | 
				
			||||||
	kinc_compute_set_int(*loc, value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_float(vbyte *location, float value) {
 | 
					 | 
				
			||||||
	kinc_compute_constant_location_t *loc = (kinc_compute_constant_location_t *)location;
 | 
					 | 
				
			||||||
	kinc_compute_set_float(*loc, value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_float2(vbyte *location, float value1, float value2) {
 | 
					 | 
				
			||||||
	kinc_compute_constant_location_t *loc = (kinc_compute_constant_location_t *)location;
 | 
					 | 
				
			||||||
	kinc_compute_set_float2(*loc, value1, value2);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_float3(vbyte *location, float value1, float value2, float value3) {
 | 
					 | 
				
			||||||
	kinc_compute_constant_location_t *loc = (kinc_compute_constant_location_t *)location;
 | 
					 | 
				
			||||||
	kinc_compute_set_float3(*loc, value1, value2, value3);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_float4(vbyte *location, float value1, float value2, float value3, float value4) {
 | 
					 | 
				
			||||||
	kinc_compute_constant_location_t *loc = (kinc_compute_constant_location_t *)location;
 | 
					 | 
				
			||||||
	kinc_compute_set_float4(*loc, value1, value2, value3, value4);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_floats(vbyte *location, vbyte *values, int count) {
 | 
					 | 
				
			||||||
	kinc_compute_constant_location_t *loc = (kinc_compute_constant_location_t *)location;
 | 
					 | 
				
			||||||
	kinc_compute_set_floats(*loc, (float *)values, count);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_matrix(vbyte *location, float _00, float _10, float _20, float _30, float _01, float _11, float _21, float _31, float _02, float _12,
 | 
					 | 
				
			||||||
                                float _22, float _32, float _03, float _13, float _23, float _33) {
 | 
					 | 
				
			||||||
	kinc_compute_constant_location_t *loc = (kinc_compute_constant_location_t *)location;
 | 
					 | 
				
			||||||
	kinc_matrix4x4_t value;
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 0, 0, _00);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 0, 1, _01);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 0, 2, _02);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 0, 3, _03);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 1, 0, _10);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 1, 1, _11);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 1, 2, _12);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 1, 3, _13);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 2, 0, _20);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 2, 1, _21);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 2, 2, _22);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 2, 3, _23);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 3, 0, _30);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 3, 1, _31);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 3, 2, _32);
 | 
					 | 
				
			||||||
	kinc_matrix4x4_set(&value, 3, 3, _33);
 | 
					 | 
				
			||||||
	kinc_compute_set_matrix4(*loc, &value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_matrix3(vbyte *location, float _00, float _10, float _20, float _01, float _11, float _21, float _02, float _12, float _22) {
 | 
					 | 
				
			||||||
	kinc_compute_constant_location_t *loc = (kinc_compute_constant_location_t *)location;
 | 
					 | 
				
			||||||
	kinc_matrix3x3_t value;
 | 
					 | 
				
			||||||
	kinc_matrix3x3_set(&value, 0, 0, _00);
 | 
					 | 
				
			||||||
	kinc_matrix3x3_set(&value, 0, 1, _01);
 | 
					 | 
				
			||||||
	kinc_matrix3x3_set(&value, 0, 2, _02);
 | 
					 | 
				
			||||||
	kinc_matrix3x3_set(&value, 1, 0, _10);
 | 
					 | 
				
			||||||
	kinc_matrix3x3_set(&value, 1, 1, _11);
 | 
					 | 
				
			||||||
	kinc_matrix3x3_set(&value, 1, 2, _12);
 | 
					 | 
				
			||||||
	kinc_matrix3x3_set(&value, 2, 0, _20);
 | 
					 | 
				
			||||||
	kinc_matrix3x3_set(&value, 2, 1, _21);
 | 
					 | 
				
			||||||
	kinc_matrix3x3_set(&value, 2, 2, _22);
 | 
					 | 
				
			||||||
	kinc_compute_set_matrix3(*loc, &value);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_texture(vbyte *unit, vbyte *texture, int access) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
 | 
					 | 
				
			||||||
	kinc_compute_set_texture(*u, tex, (kinc_compute_access_t)access);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_target(vbyte *unit, vbyte *renderTarget, int access) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
 | 
					 | 
				
			||||||
	kinc_compute_set_render_target(*u, rt, (kinc_compute_access_t)access);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_sampled_texture(vbyte *unit, vbyte *texture) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
 | 
					 | 
				
			||||||
	kinc_compute_set_sampled_texture(*u, tex);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_sampled_target(vbyte *unit, vbyte *renderTarget) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
 | 
					 | 
				
			||||||
	kinc_compute_set_sampled_render_target(*u, rt);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_sampled_depth_target(vbyte *unit, vbyte *renderTarget) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
 | 
					 | 
				
			||||||
	kinc_compute_set_sampled_depth_from_render_target(*u, rt);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_sampled_cubemap_texture(vbyte *unit, vbyte *texture) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_g4_texture_t *tex = (kinc_g4_texture_t *)texture;
 | 
					 | 
				
			||||||
	kinc_compute_set_sampled_texture(*u, tex);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_sampled_cubemap_target(vbyte *unit, vbyte *renderTarget) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
 | 
					 | 
				
			||||||
	kinc_compute_set_sampled_render_target(*u, rt);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_sampled_cubemap_depth_target(vbyte *unit, vbyte *renderTarget) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_g4_render_target_t *rt = (kinc_g4_render_target_t *)renderTarget;
 | 
					 | 
				
			||||||
	kinc_compute_set_sampled_depth_from_render_target(*u, rt);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_texture_parameters(vbyte *unit, int uAddressing, int vAddressing, int minificationFilter, int magnificationFilter, int mipmapFilter) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_compute_set_texture_addressing(*u, KINC_G4_TEXTURE_DIRECTION_U, (kinc_g4_texture_addressing_t)uAddressing);
 | 
					 | 
				
			||||||
	kinc_compute_set_texture_addressing(*u, KINC_G4_TEXTURE_DIRECTION_V, (kinc_g4_texture_addressing_t)vAddressing);
 | 
					 | 
				
			||||||
	kinc_compute_set_texture_minification_filter(*u, (kinc_g4_texture_filter_t)minificationFilter);
 | 
					 | 
				
			||||||
	kinc_compute_set_texture_magnification_filter(*u, (kinc_g4_texture_filter_t)magnificationFilter);
 | 
					 | 
				
			||||||
	kinc_compute_set_texture_mipmap_filter(*u, (kinc_g4_mipmap_filter_t)mipmapFilter);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_texture3d_parameters(vbyte *unit, int uAddressing, int vAddressing, int wAddressing, int minificationFilter, int magnificationFilter,
 | 
					 | 
				
			||||||
                                              int mipmapFilter) {
 | 
					 | 
				
			||||||
	kinc_compute_texture_unit_t *u = (kinc_compute_texture_unit_t *)unit;
 | 
					 | 
				
			||||||
	kinc_compute_set_texture3d_addressing(*u, KINC_G4_TEXTURE_DIRECTION_U, (kinc_g4_texture_addressing_t)uAddressing);
 | 
					 | 
				
			||||||
	kinc_compute_set_texture3d_addressing(*u, KINC_G4_TEXTURE_DIRECTION_V, (kinc_g4_texture_addressing_t)vAddressing);
 | 
					 | 
				
			||||||
	kinc_compute_set_texture3d_addressing(*u, KINC_G4_TEXTURE_DIRECTION_W, (kinc_g4_texture_addressing_t)wAddressing);
 | 
					 | 
				
			||||||
	kinc_compute_set_texture3d_minification_filter(*u, (kinc_g4_texture_filter_t)minificationFilter);
 | 
					 | 
				
			||||||
	kinc_compute_set_texture3d_magnification_filter(*u, (kinc_g4_texture_filter_t)magnificationFilter);
 | 
					 | 
				
			||||||
	kinc_compute_set_texture3d_mipmap_filter(*u, (kinc_g4_mipmap_filter_t)mipmapFilter);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_set_shader(vbyte *shader) {
 | 
					 | 
				
			||||||
	kinc_compute_set_shader((kinc_compute_shader_t *)shader);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
void hl_kinc_compute_compute(int x, int y, int z) {
 | 
					 | 
				
			||||||
	kinc_compute(x, y, z);
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,127 +1,129 @@
 | 
				
			|||||||
#include <kinc/audio2/audio.h>
 | 
					#include <kinc/audio2/audio.h>
 | 
				
			||||||
#include <kinc/graphics4/graphics.h>
 | 
					#include <kinc/graphics4/graphics.h>
 | 
				
			||||||
#include <kinc/io/filereader.h>
 | 
					#include <kinc/io/filereader.h>
 | 
				
			||||||
#include <kinc/log.h>
 | 
					#include <kinc/log.h>
 | 
				
			||||||
#include <kinc/system.h>
 | 
					#include <kinc/system.h>
 | 
				
			||||||
#include <kinc/window.h>
 | 
					#include <kinc/window.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <hl.h>
 | 
					#include <hl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void frame();
 | 
					void frame();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool visible = true;
 | 
					static bool visible = true;
 | 
				
			||||||
static bool paused = false;
 | 
					static bool paused = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*FN_AUDIO_CALL_CALLBACK)(int);
 | 
					typedef void (*FN_AUDIO_CALL_CALLBACK)(int);
 | 
				
			||||||
typedef float (*FN_AUDIO_READ_SAMPLE)(void);
 | 
					typedef float (*FN_AUDIO_READ_SAMPLE)(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void (*audioCallCallback)(int);
 | 
					void (*audioCallCallback)(int);
 | 
				
			||||||
float (*audioReadSample)(void);
 | 
					float (*audioReadSample)(void);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void update(void *data) {
 | 
					static void update(void *data) {
 | 
				
			||||||
	if (paused) {
 | 
						if (paused) {
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	kinc_a2_update();
 | 
						kinc_a2_update();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int windowCount = kinc_count_windows();
 | 
						int windowCount = kinc_count_windows();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (int windowIndex = 0; windowIndex < windowCount; ++windowIndex) {
 | 
						for (int windowIndex = 0; windowIndex < windowCount; ++windowIndex) {
 | 
				
			||||||
		if (visible) {
 | 
							if (visible) {
 | 
				
			||||||
			kinc_g4_begin(windowIndex);
 | 
								kinc_g4_begin(windowIndex);
 | 
				
			||||||
			frame();
 | 
								frame();
 | 
				
			||||||
			kinc_g4_end(windowIndex);
 | 
								kinc_g4_end(windowIndex);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if (!kinc_g4_swap_buffers()) {
 | 
						if (!kinc_g4_swap_buffers()) {
 | 
				
			||||||
		kinc_log(KINC_LOG_LEVEL_ERROR, "Graphics context lost.");
 | 
							kinc_log(KINC_LOG_LEVEL_ERROR, "Graphics context lost.");
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static bool mixThreadregistered = false;
 | 
					static bool mixThreadregistered = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void mix(kinc_a2_buffer_t *buffer, int samples) {
 | 
					static void mix(kinc_a2_buffer_t *buffer, uint32_t samples, void *userdata) {
 | 
				
			||||||
#ifdef KORE_MULTITHREADED_AUDIO
 | 
					#ifdef KINC_MULTITHREADED_AUDIO
 | 
				
			||||||
	if (!mixThreadregistered) {
 | 
						if (!mixThreadregistered) {
 | 
				
			||||||
		vdynamic *ret;
 | 
							vdynamic *ret;
 | 
				
			||||||
		hl_register_thread(&ret);
 | 
							hl_register_thread(&ret);
 | 
				
			||||||
		mixThreadregistered = true;
 | 
							mixThreadregistered = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	hl_blocking(true);
 | 
						hl_blocking(true);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	audioCallCallback(samples);
 | 
						audioCallCallback(samples);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (int i = 0; i < samples; ++i) {
 | 
						for (uint32_t i = 0; i < samples; i += 2) {
 | 
				
			||||||
		float value = audioReadSample();
 | 
							float left_value = audioReadSample();
 | 
				
			||||||
		*(float *)&buffer->data[buffer->write_location] = value;
 | 
							float right_value = audioReadSample();
 | 
				
			||||||
		buffer->write_location += 4;
 | 
							*(float *)&buffer->channels[0][buffer->write_location] = left_value;
 | 
				
			||||||
		if (buffer->write_location >= buffer->data_size) {
 | 
							*(float *)&buffer->channels[1][buffer->write_location] = right_value;
 | 
				
			||||||
			buffer->write_location = 0;
 | 
							buffer->write_location += 1;
 | 
				
			||||||
		}
 | 
							if (buffer->write_location >= buffer->data_size) {
 | 
				
			||||||
	}
 | 
								buffer->write_location = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
#ifdef KORE_MULTITHREADED_AUDIO
 | 
						}
 | 
				
			||||||
	hl_blocking(false);
 | 
					
 | 
				
			||||||
#endif
 | 
					#ifdef KINC_MULTITHREADED_AUDIO
 | 
				
			||||||
}
 | 
						hl_blocking(false);
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
void hl_init_kore(vbyte *title, int width, int height, int samplesPerPixel, bool vSync, int windowMode, int windowFeatures) {
 | 
					}
 | 
				
			||||||
	kinc_log(KINC_LOG_LEVEL_INFO, "Starting KincHL");
 | 
					
 | 
				
			||||||
 | 
					void hl_init_kore(vbyte *title, int width, int height, int samplesPerPixel, bool vSync, int windowMode, int windowFeatures) {
 | 
				
			||||||
	kinc_window_options_t win;
 | 
						kinc_log(KINC_LOG_LEVEL_INFO, "Starting KincHL");
 | 
				
			||||||
	kinc_window_options_set_defaults(&win);
 | 
					
 | 
				
			||||||
	win.title = (char *)title;
 | 
						kinc_window_options_t win;
 | 
				
			||||||
	win.width = width;
 | 
						kinc_window_options_set_defaults(&win);
 | 
				
			||||||
	win.height = height;
 | 
						win.title = (char *)title;
 | 
				
			||||||
	win.x = -1;
 | 
						win.width = width;
 | 
				
			||||||
	win.y = -1;
 | 
						win.height = height;
 | 
				
			||||||
	win.mode = (kinc_window_mode_t)windowMode;
 | 
						win.x = -1;
 | 
				
			||||||
	win.window_features = windowFeatures;
 | 
						win.y = -1;
 | 
				
			||||||
	kinc_framebuffer_options_t frame;
 | 
						win.mode = (kinc_window_mode_t)windowMode;
 | 
				
			||||||
	kinc_framebuffer_options_set_defaults(&frame);
 | 
						win.window_features = windowFeatures;
 | 
				
			||||||
	frame.vertical_sync = vSync;
 | 
						kinc_framebuffer_options_t frame;
 | 
				
			||||||
	frame.samples_per_pixel = samplesPerPixel;
 | 
						kinc_framebuffer_options_set_defaults(&frame);
 | 
				
			||||||
	kinc_init((char *)title, width, height, &win, &frame);
 | 
						frame.vertical_sync = vSync;
 | 
				
			||||||
 | 
						frame.samples_per_pixel = samplesPerPixel;
 | 
				
			||||||
	kinc_set_update_callback(update, NULL);
 | 
						kinc_init((char *)title, width, height, &win, &frame);
 | 
				
			||||||
}
 | 
					
 | 
				
			||||||
 | 
						kinc_set_update_callback(update, NULL);
 | 
				
			||||||
void hl_kinc_init_audio(vclosure *callCallback, vclosure *readSample, int *outSamplesPerSecond) {
 | 
					}
 | 
				
			||||||
	audioCallCallback = *((FN_AUDIO_CALL_CALLBACK *)(&callCallback->fun));
 | 
					
 | 
				
			||||||
	audioReadSample = *((FN_AUDIO_READ_SAMPLE *)(&readSample->fun));
 | 
					void hl_kinc_init_audio(vclosure *callCallback, vclosure *readSample, int *outSamplesPerSecond) {
 | 
				
			||||||
	kinc_a2_set_callback(mix);
 | 
						audioCallCallback = *((FN_AUDIO_CALL_CALLBACK *)(&callCallback->fun));
 | 
				
			||||||
	kinc_a2_init();
 | 
						audioReadSample = *((FN_AUDIO_READ_SAMPLE *)(&readSample->fun));
 | 
				
			||||||
	*outSamplesPerSecond = kinc_a2_samples_per_second;
 | 
						kinc_a2_init();
 | 
				
			||||||
}
 | 
						kinc_a2_set_callback(mix, NULL);
 | 
				
			||||||
 | 
						*outSamplesPerSecond = kinc_a2_samples_per_second();
 | 
				
			||||||
void hl_run_kore(void) {
 | 
					}
 | 
				
			||||||
	kinc_start();
 | 
					
 | 
				
			||||||
}
 | 
					void hl_run_kore(void) {
 | 
				
			||||||
 | 
						kinc_start();
 | 
				
			||||||
vbyte *hl_kinc_file_contents(vbyte *name, int *size) {
 | 
					}
 | 
				
			||||||
	int len;
 | 
					
 | 
				
			||||||
	int p = 0;
 | 
					vbyte *hl_kinc_file_contents(vbyte *name, int *size) {
 | 
				
			||||||
	vbyte *content;
 | 
						int len;
 | 
				
			||||||
	kinc_file_reader_t file;
 | 
						int p = 0;
 | 
				
			||||||
	if (!kinc_file_reader_open(&file, (char *)name, KINC_FILE_TYPE_ASSET)) {
 | 
						vbyte *content;
 | 
				
			||||||
		return NULL;
 | 
						kinc_file_reader_t file;
 | 
				
			||||||
	}
 | 
						if (!kinc_file_reader_open(&file, (char *)name, KINC_FILE_TYPE_ASSET)) {
 | 
				
			||||||
	hl_blocking(true);
 | 
							return NULL;
 | 
				
			||||||
	len = (int)kinc_file_reader_size(&file);
 | 
						}
 | 
				
			||||||
	if (size) {
 | 
						hl_blocking(true);
 | 
				
			||||||
		*size = len;
 | 
						len = (int)kinc_file_reader_size(&file);
 | 
				
			||||||
	}
 | 
						if (size) {
 | 
				
			||||||
	hl_blocking(false);
 | 
							*size = len;
 | 
				
			||||||
	content = (vbyte *)hl_gc_alloc_noptr(size ? len : len + 1);
 | 
						}
 | 
				
			||||||
	hl_blocking(true);
 | 
						hl_blocking(false);
 | 
				
			||||||
	if (!size) {
 | 
						content = (vbyte *)hl_gc_alloc_noptr(size ? len : len + 1);
 | 
				
			||||||
		content[len] = 0; // final 0 for UTF8
 | 
						hl_blocking(true);
 | 
				
			||||||
	}
 | 
						if (!size) {
 | 
				
			||||||
	kinc_file_reader_read(&file, content, len);
 | 
							content[len] = 0; // final 0 for UTF8
 | 
				
			||||||
	kinc_file_reader_close(&file);
 | 
						}
 | 
				
			||||||
	hl_blocking(false);
 | 
						kinc_file_reader_read(&file, content, len);
 | 
				
			||||||
	return content;
 | 
						kinc_file_reader_close(&file);
 | 
				
			||||||
}
 | 
						hl_blocking(false);
 | 
				
			||||||
 | 
						return content;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,265 +1,265 @@
 | 
				
			|||||||
#include <kinc/graphics4/graphics.h>
 | 
					#include <kinc/graphics4/graphics.h>
 | 
				
			||||||
#include <kinc/graphics4/pipeline.h>
 | 
					#include <kinc/graphics4/pipeline.h>
 | 
				
			||||||
#include <kinc/graphics4/shader.h>
 | 
					#include <kinc/graphics4/shader.h>
 | 
				
			||||||
#include <kinc/graphics4/vertexstructure.h>
 | 
					#include <kinc/graphics4/vertexstructure.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <hl.h>
 | 
					#include <hl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static kinc_g4_compare_mode_t convertCompareMode(int mode) {
 | 
					static kinc_g4_compare_mode_t convertCompareMode(int mode) {
 | 
				
			||||||
	switch (mode) {
 | 
						switch (mode) {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
		return KINC_G4_COMPARE_ALWAYS;
 | 
							return KINC_G4_COMPARE_ALWAYS;
 | 
				
			||||||
	case 1:
 | 
						case 1:
 | 
				
			||||||
		return KINC_G4_COMPARE_NEVER;
 | 
							return KINC_G4_COMPARE_NEVER;
 | 
				
			||||||
	case 2:
 | 
						case 2:
 | 
				
			||||||
		return KINC_G4_COMPARE_EQUAL;
 | 
							return KINC_G4_COMPARE_EQUAL;
 | 
				
			||||||
	case 3:
 | 
						case 3:
 | 
				
			||||||
		return KINC_G4_COMPARE_NOT_EQUAL;
 | 
							return KINC_G4_COMPARE_NOT_EQUAL;
 | 
				
			||||||
	case 4:
 | 
						case 4:
 | 
				
			||||||
		return KINC_G4_COMPARE_LESS;
 | 
							return KINC_G4_COMPARE_LESS;
 | 
				
			||||||
	case 5:
 | 
						case 5:
 | 
				
			||||||
		return KINC_G4_COMPARE_LESS_EQUAL;
 | 
							return KINC_G4_COMPARE_LESS_EQUAL;
 | 
				
			||||||
	case 6:
 | 
						case 6:
 | 
				
			||||||
		return KINC_G4_COMPARE_GREATER;
 | 
							return KINC_G4_COMPARE_GREATER;
 | 
				
			||||||
	case 7:
 | 
						case 7:
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return KINC_G4_COMPARE_GREATER_EQUAL;
 | 
							return KINC_G4_COMPARE_GREATER_EQUAL;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static kinc_g4_stencil_action_t convertStencilAction(int action) {
 | 
					static kinc_g4_stencil_action_t convertStencilAction(int action) {
 | 
				
			||||||
	switch (action) {
 | 
						switch (action) {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
		return KINC_G4_STENCIL_KEEP;
 | 
							return KINC_G4_STENCIL_KEEP;
 | 
				
			||||||
	case 1:
 | 
						case 1:
 | 
				
			||||||
		return KINC_G4_STENCIL_ZERO;
 | 
							return KINC_G4_STENCIL_ZERO;
 | 
				
			||||||
	case 2:
 | 
						case 2:
 | 
				
			||||||
		return KINC_G4_STENCIL_REPLACE;
 | 
							return KINC_G4_STENCIL_REPLACE;
 | 
				
			||||||
	case 3:
 | 
						case 3:
 | 
				
			||||||
		return KINC_G4_STENCIL_INCREMENT;
 | 
							return KINC_G4_STENCIL_INCREMENT;
 | 
				
			||||||
	case 4:
 | 
						case 4:
 | 
				
			||||||
		return KINC_G4_STENCIL_INCREMENT_WRAP;
 | 
							return KINC_G4_STENCIL_INCREMENT_WRAP;
 | 
				
			||||||
	case 5:
 | 
						case 5:
 | 
				
			||||||
		return KINC_G4_STENCIL_DECREMENT;
 | 
							return KINC_G4_STENCIL_DECREMENT;
 | 
				
			||||||
	case 6:
 | 
						case 6:
 | 
				
			||||||
		return KINC_G4_STENCIL_DECREMENT_WRAP;
 | 
							return KINC_G4_STENCIL_DECREMENT_WRAP;
 | 
				
			||||||
	case 7:
 | 
						case 7:
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return KINC_G4_STENCIL_INVERT;
 | 
							return KINC_G4_STENCIL_INVERT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static kinc_g4_render_target_format_t convertColorAttachment(int format) {
 | 
					static kinc_g4_render_target_format_t convertColorAttachment(int format) {
 | 
				
			||||||
	switch (format) {
 | 
						switch (format) {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
		return KINC_G4_RENDER_TARGET_FORMAT_32BIT;
 | 
							return KINC_G4_RENDER_TARGET_FORMAT_32BIT;
 | 
				
			||||||
	case 1:
 | 
						case 1:
 | 
				
			||||||
		return KINC_G4_RENDER_TARGET_FORMAT_8BIT_RED;
 | 
							return KINC_G4_RENDER_TARGET_FORMAT_8BIT_RED;
 | 
				
			||||||
	case 2:
 | 
						case 2:
 | 
				
			||||||
		return KINC_G4_RENDER_TARGET_FORMAT_128BIT_FLOAT;
 | 
							return KINC_G4_RENDER_TARGET_FORMAT_128BIT_FLOAT;
 | 
				
			||||||
	case 3:
 | 
						case 3:
 | 
				
			||||||
		return KINC_G4_RENDER_TARGET_FORMAT_16BIT_DEPTH;
 | 
							return KINC_G4_RENDER_TARGET_FORMAT_16BIT_DEPTH;
 | 
				
			||||||
	case 4:
 | 
						case 4:
 | 
				
			||||||
		return KINC_G4_RENDER_TARGET_FORMAT_64BIT_FLOAT;
 | 
							return KINC_G4_RENDER_TARGET_FORMAT_64BIT_FLOAT;
 | 
				
			||||||
	case 5:
 | 
						case 5:
 | 
				
			||||||
		return KINC_G4_RENDER_TARGET_FORMAT_32BIT_RED_FLOAT;
 | 
							return KINC_G4_RENDER_TARGET_FORMAT_32BIT_RED_FLOAT;
 | 
				
			||||||
	case 6:
 | 
						case 6:
 | 
				
			||||||
	default:
 | 
						default:
 | 
				
			||||||
		return KINC_G4_RENDER_TARGET_FORMAT_16BIT_RED_FLOAT;
 | 
							return KINC_G4_RENDER_TARGET_FORMAT_16BIT_RED_FLOAT;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_create_vertexshader(vbyte *data, int length) {
 | 
					vbyte *hl_kinc_create_vertexshader(vbyte *data, int length) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_VERTEX);
 | 
						kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_VERTEX);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_create_fragmentshader(vbyte *data, int length) {
 | 
					vbyte *hl_kinc_create_fragmentshader(vbyte *data, int length) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_FRAGMENT);
 | 
						kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_FRAGMENT);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_create_geometryshader(vbyte *data, int length) {
 | 
					vbyte *hl_kinc_create_geometryshader(vbyte *data, int length) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_GEOMETRY);
 | 
						kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_GEOMETRY);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_create_tesscontrolshader(vbyte *data, int length) {
 | 
					vbyte *hl_kinc_create_tesscontrolshader(vbyte *data, int length) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_TESSELLATION_CONTROL);
 | 
						kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_TESSELLATION_CONTROL);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_create_tessevalshader(vbyte *data, int length) {
 | 
					vbyte *hl_kinc_create_tessevalshader(vbyte *data, int length) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_TESSELLATION_EVALUATION);
 | 
						kinc_g4_shader_init(shader, data, length, KINC_G4_SHADER_TYPE_TESSELLATION_EVALUATION);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_vertexshader_from_source(vbyte *source) {
 | 
					vbyte *hl_kinc_vertexshader_from_source(vbyte *source) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_VERTEX);
 | 
						kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_VERTEX);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_fragmentshader_from_source(vbyte *source) {
 | 
					vbyte *hl_kinc_fragmentshader_from_source(vbyte *source) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_FRAGMENT);
 | 
						kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_FRAGMENT);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_geometryshader_from_source(vbyte *source) {
 | 
					vbyte *hl_kinc_geometryshader_from_source(vbyte *source) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_GEOMETRY);
 | 
						kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_GEOMETRY);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_tesscontrolshader_from_source(vbyte *source) {
 | 
					vbyte *hl_kinc_tesscontrolshader_from_source(vbyte *source) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_TESSELLATION_CONTROL);
 | 
						kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_TESSELLATION_CONTROL);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_tessevalshader_from_source(vbyte *source) {
 | 
					vbyte *hl_kinc_tessevalshader_from_source(vbyte *source) {
 | 
				
			||||||
	kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
						kinc_g4_shader_t *shader = (kinc_g4_shader_t *)malloc(sizeof(kinc_g4_shader_t));
 | 
				
			||||||
	kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_TESSELLATION_EVALUATION);
 | 
						kinc_g4_shader_init_from_source(shader, (char *)source, KINC_G4_SHADER_TYPE_TESSELLATION_EVALUATION);
 | 
				
			||||||
	return (vbyte *)shader;
 | 
						return (vbyte *)shader;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_create_pipeline() {
 | 
					vbyte *hl_kinc_create_pipeline() {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipeline = (kinc_g4_pipeline_t *)malloc(sizeof(kinc_g4_pipeline_t));
 | 
						kinc_g4_pipeline_t *pipeline = (kinc_g4_pipeline_t *)malloc(sizeof(kinc_g4_pipeline_t));
 | 
				
			||||||
	kinc_g4_pipeline_init(pipeline);
 | 
						kinc_g4_pipeline_init(pipeline);
 | 
				
			||||||
	return (vbyte *)pipeline;
 | 
						return (vbyte *)pipeline;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_delete_pipeline(vbyte *pipeline) {
 | 
					void hl_kinc_delete_pipeline(vbyte *pipeline) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	kinc_g4_pipeline_destroy(pipe);
 | 
						kinc_g4_pipeline_destroy(pipe);
 | 
				
			||||||
	free(pipe);
 | 
						free(pipe);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_pipeline_set_vertex_shader(vbyte *pipeline, vbyte *shader) {
 | 
					void hl_kinc_pipeline_set_vertex_shader(vbyte *pipeline, vbyte *shader) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
						kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
				
			||||||
	pipe->vertex_shader = sh;
 | 
						pipe->vertex_shader = sh;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_pipeline_set_fragment_shader(vbyte *pipeline, vbyte *shader) {
 | 
					void hl_kinc_pipeline_set_fragment_shader(vbyte *pipeline, vbyte *shader) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
						kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
				
			||||||
	pipe->fragment_shader = sh;
 | 
						pipe->fragment_shader = sh;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_pipeline_set_geometry_shader(vbyte *pipeline, vbyte *shader) {
 | 
					void hl_kinc_pipeline_set_geometry_shader(vbyte *pipeline, vbyte *shader) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
						kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
				
			||||||
	pipe->geometry_shader = sh;
 | 
						pipe->geometry_shader = sh;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_pipeline_set_tesscontrol_shader(vbyte *pipeline, vbyte *shader) {
 | 
					void hl_kinc_pipeline_set_tesscontrol_shader(vbyte *pipeline, vbyte *shader) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
						kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
				
			||||||
	pipe->tessellation_control_shader = sh;
 | 
						pipe->tessellation_control_shader = sh;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_pipeline_set_tesseval_shader(vbyte *pipeline, vbyte *shader) {
 | 
					void hl_kinc_pipeline_set_tesseval_shader(vbyte *pipeline, vbyte *shader) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
						kinc_g4_shader_t *sh = (kinc_g4_shader_t *)shader;
 | 
				
			||||||
	pipe->tessellation_evaluation_shader = sh;
 | 
						pipe->tessellation_evaluation_shader = sh;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_pipeline_compile(vbyte *pipeline, vbyte *structure0, vbyte *structure1, vbyte *structure2, vbyte *structure3) {
 | 
					void hl_kinc_pipeline_compile(vbyte *pipeline, vbyte *structure0, vbyte *structure1, vbyte *structure2, vbyte *structure3) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	pipe->input_layout[0] = (kinc_g4_vertex_structure_t *)structure0;
 | 
						pipe->input_layout[0] = (kinc_g4_vertex_structure_t *)structure0;
 | 
				
			||||||
	pipe->input_layout[1] = (kinc_g4_vertex_structure_t *)structure1;
 | 
						pipe->input_layout[1] = (kinc_g4_vertex_structure_t *)structure1;
 | 
				
			||||||
	pipe->input_layout[2] = (kinc_g4_vertex_structure_t *)structure2;
 | 
						pipe->input_layout[2] = (kinc_g4_vertex_structure_t *)structure2;
 | 
				
			||||||
	pipe->input_layout[3] = (kinc_g4_vertex_structure_t *)structure3;
 | 
						pipe->input_layout[3] = (kinc_g4_vertex_structure_t *)structure3;
 | 
				
			||||||
	pipe->input_layout[4] = NULL;
 | 
						pipe->input_layout[4] = NULL;
 | 
				
			||||||
	kinc_g4_pipeline_compile(pipe);
 | 
						kinc_g4_pipeline_compile(pipe);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_pipeline_set_states(vbyte *pipeline, int cullMode, int depthMode, int stencilFrontMode, int stencilFrontBothPass, int stencilFrontDepthFail,
 | 
					void hl_kinc_pipeline_set_states(vbyte *pipeline, int cullMode, int depthMode, int stencilFrontMode, int stencilFrontBothPass, int stencilFrontDepthFail,
 | 
				
			||||||
                                 int stencilFrontFail, int stencilBackMode, int stencilBackBothPass, int stencilBackDepthFail, int stencilBackFail,
 | 
					                                 int stencilFrontFail, int stencilBackMode, int stencilBackBothPass, int stencilBackDepthFail, int stencilBackFail,
 | 
				
			||||||
                                 int blendSource, int blendDestination, int alphaBlendSource, int alphaBlendDestination, bool depthWrite,
 | 
					                                 int blendSource, int blendDestination, int alphaBlendSource, int alphaBlendDestination, bool depthWrite,
 | 
				
			||||||
                                 int stencilReferenceValue, int stencilReadMask, int stencilWriteMask, bool colorWriteMaskRed, bool colorWriteMaskGreen,
 | 
					                                 int stencilReferenceValue, int stencilReadMask, int stencilWriteMask, bool colorWriteMaskRed, bool colorWriteMaskGreen,
 | 
				
			||||||
                                 bool colorWriteMaskBlue, bool colorWriteMaskAlpha, int colorAttachmentCount, int colorAttachment0, int colorAttachment1,
 | 
					                                 bool colorWriteMaskBlue, bool colorWriteMaskAlpha, int colorAttachmentCount, int colorAttachment0, int colorAttachment1,
 | 
				
			||||||
                                 int colorAttachment2, int colorAttachment3, int colorAttachment4, int colorAttachment5, int colorAttachment6,
 | 
					                                 int colorAttachment2, int colorAttachment3, int colorAttachment4, int colorAttachment5, int colorAttachment6,
 | 
				
			||||||
                                 int colorAttachment7, int depthAttachmentBits, int stencilAttachmentBits, bool conservativeRasterization) {
 | 
					                                 int colorAttachment7, int depthAttachmentBits, int stencilAttachmentBits, bool conservativeRasterization) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	switch (cullMode) {
 | 
						switch (cullMode) {
 | 
				
			||||||
	case 0:
 | 
						case 0:
 | 
				
			||||||
		pipe->cull_mode = KINC_G4_CULL_CLOCKWISE;
 | 
							pipe->cull_mode = KINC_G4_CULL_CLOCKWISE;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 1:
 | 
						case 1:
 | 
				
			||||||
		pipe->cull_mode = KINC_G4_CULL_COUNTER_CLOCKWISE;
 | 
							pipe->cull_mode = KINC_G4_CULL_COUNTER_CLOCKWISE;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	case 2:
 | 
						case 2:
 | 
				
			||||||
		pipe->cull_mode = KINC_G4_CULL_NOTHING;
 | 
							pipe->cull_mode = KINC_G4_CULL_NOTHING;
 | 
				
			||||||
		break;
 | 
							break;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe->depth_mode = convertCompareMode(depthMode);
 | 
						pipe->depth_mode = convertCompareMode(depthMode);
 | 
				
			||||||
	pipe->depth_write = depthWrite;
 | 
						pipe->depth_write = depthWrite;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe->stencil_front_mode = convertCompareMode(stencilFrontMode);
 | 
						pipe->stencil_front_mode = convertCompareMode(stencilFrontMode);
 | 
				
			||||||
	pipe->stencil_front_both_pass = convertStencilAction(stencilFrontBothPass);
 | 
						pipe->stencil_front_both_pass = convertStencilAction(stencilFrontBothPass);
 | 
				
			||||||
	pipe->stencil_front_depth_fail = convertStencilAction(stencilFrontDepthFail);
 | 
						pipe->stencil_front_depth_fail = convertStencilAction(stencilFrontDepthFail);
 | 
				
			||||||
	pipe->stencil_front_fail = convertStencilAction(stencilFrontFail);
 | 
						pipe->stencil_front_fail = convertStencilAction(stencilFrontFail);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe->stencil_back_mode = convertCompareMode(stencilBackMode);
 | 
						pipe->stencil_back_mode = convertCompareMode(stencilBackMode);
 | 
				
			||||||
	pipe->stencil_back_both_pass = convertStencilAction(stencilBackBothPass);
 | 
						pipe->stencil_back_both_pass = convertStencilAction(stencilBackBothPass);
 | 
				
			||||||
	pipe->stencil_back_depth_fail = convertStencilAction(stencilBackDepthFail);
 | 
						pipe->stencil_back_depth_fail = convertStencilAction(stencilBackDepthFail);
 | 
				
			||||||
	pipe->stencil_back_fail = convertStencilAction(stencilBackFail);
 | 
						pipe->stencil_back_fail = convertStencilAction(stencilBackFail);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe->stencil_reference_value = stencilReferenceValue;
 | 
						pipe->stencil_reference_value = stencilReferenceValue;
 | 
				
			||||||
	pipe->stencil_read_mask = stencilReadMask;
 | 
						pipe->stencil_read_mask = stencilReadMask;
 | 
				
			||||||
	pipe->stencil_write_mask = stencilWriteMask;
 | 
						pipe->stencil_write_mask = stencilWriteMask;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe->blend_source = (kinc_g4_blending_factor_t)blendSource;
 | 
						pipe->blend_source = (kinc_g4_blending_factor_t)blendSource;
 | 
				
			||||||
	pipe->blend_destination = (kinc_g4_blending_factor_t)blendDestination;
 | 
						pipe->blend_destination = (kinc_g4_blending_factor_t)blendDestination;
 | 
				
			||||||
	pipe->alpha_blend_source = (kinc_g4_blending_factor_t)alphaBlendSource;
 | 
						pipe->alpha_blend_source = (kinc_g4_blending_factor_t)alphaBlendSource;
 | 
				
			||||||
	pipe->alpha_blend_destination = (kinc_g4_blending_factor_t)alphaBlendDestination;
 | 
						pipe->alpha_blend_destination = (kinc_g4_blending_factor_t)alphaBlendDestination;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe->color_write_mask_red[0] = colorWriteMaskRed;
 | 
						pipe->color_write_mask_red[0] = colorWriteMaskRed;
 | 
				
			||||||
	pipe->color_write_mask_green[0] = colorWriteMaskGreen;
 | 
						pipe->color_write_mask_green[0] = colorWriteMaskGreen;
 | 
				
			||||||
	pipe->color_write_mask_blue[0] = colorWriteMaskBlue;
 | 
						pipe->color_write_mask_blue[0] = colorWriteMaskBlue;
 | 
				
			||||||
	pipe->color_write_mask_alpha[0] = colorWriteMaskAlpha;
 | 
						pipe->color_write_mask_alpha[0] = colorWriteMaskAlpha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe->color_attachment_count = colorAttachmentCount;
 | 
						pipe->color_attachment_count = colorAttachmentCount;
 | 
				
			||||||
	pipe->color_attachment[0] = convertColorAttachment(colorAttachment0);
 | 
						pipe->color_attachment[0] = convertColorAttachment(colorAttachment0);
 | 
				
			||||||
	pipe->color_attachment[1] = convertColorAttachment(colorAttachment1);
 | 
						pipe->color_attachment[1] = convertColorAttachment(colorAttachment1);
 | 
				
			||||||
	pipe->color_attachment[2] = convertColorAttachment(colorAttachment2);
 | 
						pipe->color_attachment[2] = convertColorAttachment(colorAttachment2);
 | 
				
			||||||
	pipe->color_attachment[3] = convertColorAttachment(colorAttachment3);
 | 
						pipe->color_attachment[3] = convertColorAttachment(colorAttachment3);
 | 
				
			||||||
	pipe->color_attachment[4] = convertColorAttachment(colorAttachment4);
 | 
						pipe->color_attachment[4] = convertColorAttachment(colorAttachment4);
 | 
				
			||||||
	pipe->color_attachment[5] = convertColorAttachment(colorAttachment5);
 | 
						pipe->color_attachment[5] = convertColorAttachment(colorAttachment5);
 | 
				
			||||||
	pipe->color_attachment[6] = convertColorAttachment(colorAttachment6);
 | 
						pipe->color_attachment[6] = convertColorAttachment(colorAttachment6);
 | 
				
			||||||
	pipe->color_attachment[7] = convertColorAttachment(colorAttachment7);
 | 
						pipe->color_attachment[7] = convertColorAttachment(colorAttachment7);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe->depth_attachment_bits = depthAttachmentBits;
 | 
						pipe->depth_attachment_bits = depthAttachmentBits;
 | 
				
			||||||
	pipe->stencil_attachment_bits = stencilAttachmentBits;
 | 
						pipe->stencil_attachment_bits = stencilAttachmentBits;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	pipe->conservative_rasterization = conservativeRasterization;
 | 
						pipe->conservative_rasterization = conservativeRasterization;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_pipeline_set(vbyte *pipeline) {
 | 
					void hl_kinc_pipeline_set(vbyte *pipeline) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	kinc_g4_set_pipeline(pipe);
 | 
						kinc_g4_set_pipeline(pipe);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_pipeline_get_constantlocation(vbyte *pipeline, vbyte *name) {
 | 
					vbyte *hl_kinc_pipeline_get_constantlocation(vbyte *pipeline, vbyte *name) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)malloc(sizeof(kinc_g4_constant_location_t));
 | 
						kinc_g4_constant_location_t *location = (kinc_g4_constant_location_t *)malloc(sizeof(kinc_g4_constant_location_t));
 | 
				
			||||||
	*location = kinc_g4_pipeline_get_constant_location(pipe, (char *)name);
 | 
						*location = kinc_g4_pipeline_get_constant_location(pipe, (char *)name);
 | 
				
			||||||
	return (vbyte *)location;
 | 
						return (vbyte *)location;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_pipeline_get_textureunit(vbyte *pipeline, vbyte *name) {
 | 
					vbyte *hl_kinc_pipeline_get_textureunit(vbyte *pipeline, vbyte *name) {
 | 
				
			||||||
	kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
						kinc_g4_pipeline_t *pipe = (kinc_g4_pipeline_t *)pipeline;
 | 
				
			||||||
	kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)malloc(sizeof(kinc_g4_texture_unit_t));
 | 
						kinc_g4_texture_unit_t *unit = (kinc_g4_texture_unit_t *)malloc(sizeof(kinc_g4_texture_unit_t));
 | 
				
			||||||
	*unit = kinc_g4_pipeline_get_texture_unit(pipe, (char *)name);
 | 
						*unit = kinc_g4_pipeline_get_texture_unit(pipe, (char *)name);
 | 
				
			||||||
	return (vbyte *)unit;
 | 
						return (vbyte *)unit;
 | 
				
			||||||
}
 | 
					} 
 | 
				
			||||||
@ -1,201 +1,201 @@
 | 
				
			|||||||
#include <kinc/input/acceleration.h>
 | 
					#include <kinc/input/acceleration.h>
 | 
				
			||||||
#include <kinc/input/gamepad.h>
 | 
					#include <kinc/input/gamepad.h>
 | 
				
			||||||
#include <kinc/input/keyboard.h>
 | 
					#include <kinc/input/keyboard.h>
 | 
				
			||||||
#include <kinc/input/mouse.h>
 | 
					#include <kinc/input/mouse.h>
 | 
				
			||||||
#include <kinc/input/pen.h>
 | 
					#include <kinc/input/pen.h>
 | 
				
			||||||
#include <kinc/input/rotation.h>
 | 
					#include <kinc/input/rotation.h>
 | 
				
			||||||
#include <kinc/input/surface.h>
 | 
					#include <kinc/input/surface.h>
 | 
				
			||||||
#include <kinc/log.h>
 | 
					#include <kinc/log.h>
 | 
				
			||||||
#include <kinc/system.h>
 | 
					#include <kinc/system.h>
 | 
				
			||||||
#include <kinc/video.h>
 | 
					#include <kinc/video.h>
 | 
				
			||||||
#include <kinc/window.h>
 | 
					#include <kinc/window.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include <hl.h>
 | 
					#include <hl.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_log(vbyte *v) {
 | 
					void hl_kinc_log(vbyte *v) {
 | 
				
			||||||
	kinc_log(KINC_LOG_LEVEL_INFO, (char *)v);
 | 
						kinc_log(KINC_LOG_LEVEL_INFO, (char *)v);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
double hl_kinc_get_time(void) {
 | 
					double hl_kinc_get_time(void) {
 | 
				
			||||||
	return kinc_time();
 | 
						return kinc_time();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int hl_kinc_get_window_width(int window) {
 | 
					int hl_kinc_get_window_width(int window) {
 | 
				
			||||||
	return kinc_window_width(window);
 | 
						return kinc_window_width(window);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int hl_kinc_get_window_height(int window) {
 | 
					int hl_kinc_get_window_height(int window) {
 | 
				
			||||||
	return kinc_window_height(window);
 | 
						return kinc_window_height(window);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_get_system_id(void) {
 | 
					vbyte *hl_kinc_get_system_id(void) {
 | 
				
			||||||
	return (vbyte *)kinc_system_id();
 | 
						return (vbyte *)kinc_system_id();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_vibrate(int ms) {
 | 
					void hl_kinc_vibrate(int ms) {
 | 
				
			||||||
	kinc_vibrate(ms);
 | 
						kinc_vibrate(ms);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_get_language(void) {
 | 
					vbyte *hl_kinc_get_language(void) {
 | 
				
			||||||
	return (vbyte *)kinc_language();
 | 
						return (vbyte *)kinc_language();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_request_shutdown(void) {
 | 
					void hl_kinc_request_shutdown(void) {
 | 
				
			||||||
	kinc_stop();
 | 
						kinc_stop();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_mouse_lock(int windowId) {
 | 
					void hl_kinc_mouse_lock(int windowId) {
 | 
				
			||||||
	kinc_mouse_lock(windowId);
 | 
						kinc_mouse_lock(windowId);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_mouse_unlock(void) {
 | 
					void hl_kinc_mouse_unlock(void) {
 | 
				
			||||||
	kinc_mouse_unlock();
 | 
						kinc_mouse_unlock();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool hl_kinc_can_lock_mouse(void) {
 | 
					bool hl_kinc_can_lock_mouse(void) {
 | 
				
			||||||
	return kinc_mouse_can_lock();
 | 
						return kinc_mouse_can_lock();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool hl_kinc_is_mouse_locked(void) {
 | 
					bool hl_kinc_is_mouse_locked(void) {
 | 
				
			||||||
	return kinc_mouse_is_locked();
 | 
						return kinc_mouse_is_locked();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_show_mouse(bool show) {
 | 
					void hl_kinc_show_mouse(bool show) {
 | 
				
			||||||
	if (show) {
 | 
						if (show) {
 | 
				
			||||||
		kinc_mouse_show();
 | 
							kinc_mouse_show();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	else {
 | 
						else {
 | 
				
			||||||
		kinc_mouse_hide();
 | 
							kinc_mouse_hide();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool hl_kinc_system_is_fullscreen(void) {
 | 
					bool hl_kinc_system_is_fullscreen(void) {
 | 
				
			||||||
	return false; // kinc_is_fullscreen();
 | 
						return false; // kinc_is_fullscreen();
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_system_request_fullscreen(void) {
 | 
					void hl_kinc_system_request_fullscreen(void) {
 | 
				
			||||||
	// kinc_change_resolution(display_width(), display_height(), true);
 | 
						// kinc_change_resolution(display_width(), display_height(), true);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_system_exit_fullscreen(int previousWidth, int previousHeight) {
 | 
					void hl_kinc_system_exit_fullscreen(int previousWidth, int previousHeight) {
 | 
				
			||||||
	// kinc_change_resolution(previousWidth, previousHeight, false);
 | 
						// kinc_change_resolution(previousWidth, previousHeight, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_system_change_resolution(int width, int height) {
 | 
					void hl_kinc_system_change_resolution(int width, int height) {
 | 
				
			||||||
	// kinc_change_resolution(width, height, false);
 | 
						// kinc_change_resolution(width, height, false);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_system_set_keepscreenon(bool on) {
 | 
					void hl_kinc_system_set_keepscreenon(bool on) {
 | 
				
			||||||
	kinc_set_keep_screen_on(on);
 | 
						kinc_set_keep_screen_on(on);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_system_load_url(vbyte *url) {
 | 
					void hl_kinc_system_load_url(vbyte *url) {
 | 
				
			||||||
	kinc_load_url((char *)url);
 | 
						kinc_load_url((char *)url);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_get_gamepad_id(int index) {
 | 
					vbyte *hl_kinc_get_gamepad_id(int index) {
 | 
				
			||||||
	return (vbyte*)kinc_gamepad_product_name(index);
 | 
						return (vbyte *)kinc_gamepad_product_name(index);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vbyte *hl_kinc_get_gamepad_vendor(int index) {
 | 
					vbyte *hl_kinc_get_gamepad_vendor(int index) {
 | 
				
			||||||
	return (vbyte*)kinc_gamepad_vendor(index);
 | 
						return (vbyte *)kinc_gamepad_vendor(index);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool hl_kinc_gamepad_connected(int index) {
 | 
					bool hl_kinc_gamepad_connected(int index) {
 | 
				
			||||||
	return kinc_gamepad_connected(index);
 | 
						return kinc_gamepad_connected(index);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*FN_KEY_DOWN)(int, void *);
 | 
					typedef void (*FN_KEY_DOWN)(int, void *);
 | 
				
			||||||
typedef void (*FN_KEY_UP)(int, void *);
 | 
					typedef void (*FN_KEY_UP)(int, void *);
 | 
				
			||||||
typedef void (*FN_KEY_PRESS)(unsigned int, void *);
 | 
					typedef void (*FN_KEY_PRESS)(unsigned int, void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_register_keyboard(vclosure *keyDown, vclosure *keyUp, vclosure *keyPress) {
 | 
					void hl_kinc_register_keyboard(vclosure *keyDown, vclosure *keyUp, vclosure *keyPress) {
 | 
				
			||||||
	kinc_keyboard_set_key_down_callback(*((FN_KEY_DOWN *)(&keyDown->fun)), NULL);
 | 
						kinc_keyboard_set_key_down_callback(*((FN_KEY_DOWN *)(&keyDown->fun)), NULL);
 | 
				
			||||||
	kinc_keyboard_set_key_up_callback(*((FN_KEY_UP *)(&keyUp->fun)), NULL);
 | 
						kinc_keyboard_set_key_up_callback(*((FN_KEY_UP *)(&keyUp->fun)), NULL);
 | 
				
			||||||
	kinc_keyboard_set_key_press_callback(*((FN_KEY_PRESS *)(&keyPress->fun)), NULL);
 | 
						kinc_keyboard_set_key_press_callback(*((FN_KEY_PRESS *)(&keyPress->fun)), NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*FN_MOUSE_DOWN)(int, int, int, int, void *);
 | 
					typedef void (*FN_MOUSE_DOWN)(int, int, int, int, void *);
 | 
				
			||||||
typedef void (*FN_MOUSE_UP)(int, int, int, int, void *);
 | 
					typedef void (*FN_MOUSE_UP)(int, int, int, int, void *);
 | 
				
			||||||
typedef void (*FN_MOUSE_MOVE)(int, int, int, int, int, void *);
 | 
					typedef void (*FN_MOUSE_MOVE)(int, int, int, int, int, void *);
 | 
				
			||||||
typedef void (*FN_MOUSE_WHEEL)(int, int, void *);
 | 
					typedef void (*FN_MOUSE_WHEEL)(int, int, void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_register_mouse(vclosure *mouseDown, vclosure *mouseUp, vclosure *mouseMove, vclosure *mouseWheel) {
 | 
					void hl_kinc_register_mouse(vclosure *mouseDown, vclosure *mouseUp, vclosure *mouseMove, vclosure *mouseWheel) {
 | 
				
			||||||
	kinc_mouse_set_press_callback(*((FN_MOUSE_DOWN *)(&mouseDown->fun)), NULL);
 | 
						kinc_mouse_set_press_callback(*((FN_MOUSE_DOWN *)(&mouseDown->fun)), NULL);
 | 
				
			||||||
	kinc_mouse_set_release_callback(*((FN_MOUSE_UP *)(&mouseUp->fun)), NULL);
 | 
						kinc_mouse_set_release_callback(*((FN_MOUSE_UP *)(&mouseUp->fun)), NULL);
 | 
				
			||||||
	kinc_mouse_set_move_callback(*((FN_MOUSE_MOVE *)(&mouseMove->fun)), NULL);
 | 
						kinc_mouse_set_move_callback(*((FN_MOUSE_MOVE *)(&mouseMove->fun)), NULL);
 | 
				
			||||||
	kinc_mouse_set_scroll_callback(*((FN_MOUSE_WHEEL *)(&mouseWheel->fun)), NULL);
 | 
						kinc_mouse_set_scroll_callback(*((FN_MOUSE_WHEEL *)(&mouseWheel->fun)), NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*FN_PEN_DOWN)(int, int, int, float);
 | 
					typedef void (*FN_PEN_DOWN)(int, int, int, float);
 | 
				
			||||||
typedef void (*FN_PEN_UP)(int, int, int, float);
 | 
					typedef void (*FN_PEN_UP)(int, int, int, float);
 | 
				
			||||||
typedef void (*FN_PEN_MOVE)(int, int, int, float);
 | 
					typedef void (*FN_PEN_MOVE)(int, int, int, float);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_register_pen(vclosure *penDown, vclosure *penUp, vclosure *penMove) {
 | 
					void hl_kinc_register_pen(vclosure *penDown, vclosure *penUp, vclosure *penMove) {
 | 
				
			||||||
	kinc_pen_set_press_callback(*((FN_PEN_DOWN *)(&penDown->fun)));
 | 
						kinc_pen_set_press_callback(*((FN_PEN_DOWN *)(&penDown->fun)));
 | 
				
			||||||
	kinc_pen_set_release_callback(*((FN_PEN_UP *)(&penUp->fun)));
 | 
						kinc_pen_set_release_callback(*((FN_PEN_UP *)(&penUp->fun)));
 | 
				
			||||||
	kinc_pen_set_move_callback(*((FN_PEN_MOVE *)(&penMove->fun)));
 | 
						kinc_pen_set_move_callback(*((FN_PEN_MOVE *)(&penMove->fun)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*FN_GAMEPAD_AXIS)(int, int, float);
 | 
					typedef void (*FN_GAMEPAD_AXIS)(int, int, float, void *);
 | 
				
			||||||
typedef void (*FN_GAMEPAD_BUTTON)(int, int, float);
 | 
					typedef void (*FN_GAMEPAD_BUTTON)(int, int, float, void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_register_gamepad(vclosure *gamepadAxis, vclosure *gamepadButton) {
 | 
					void hl_kinc_register_gamepad(vclosure *gamepadAxis, vclosure *gamepadButton) {
 | 
				
			||||||
	kinc_gamepad_set_axis_callback(*((FN_GAMEPAD_AXIS *)(&gamepadAxis->fun)));
 | 
						kinc_gamepad_set_axis_callback(*((FN_GAMEPAD_AXIS *)(&gamepadAxis->fun)), NULL);
 | 
				
			||||||
	kinc_gamepad_set_button_callback(*((FN_GAMEPAD_BUTTON *)(&gamepadButton->fun)));
 | 
						kinc_gamepad_set_button_callback(*((FN_GAMEPAD_BUTTON *)(&gamepadButton->fun)), NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*FN_TOUCH_START)(int, int, int);
 | 
					typedef void (*FN_TOUCH_START)(int, int, int);
 | 
				
			||||||
typedef void (*FN_TOUCH_END)(int, int, int);
 | 
					typedef void (*FN_TOUCH_END)(int, int, int);
 | 
				
			||||||
typedef void (*FN_TOUCH_MOVE)(int, int, int);
 | 
					typedef void (*FN_TOUCH_MOVE)(int, int, int);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_register_surface(vclosure *touchStart, vclosure *touchEnd, vclosure *touchMove) {
 | 
					void hl_kinc_register_surface(vclosure *touchStart, vclosure *touchEnd, vclosure *touchMove) {
 | 
				
			||||||
	kinc_surface_set_touch_start_callback(*((FN_TOUCH_START *)(&touchStart->fun)));
 | 
						kinc_surface_set_touch_start_callback(*((FN_TOUCH_START *)(&touchStart->fun)));
 | 
				
			||||||
	kinc_surface_set_touch_end_callback(*((FN_TOUCH_END *)(&touchEnd->fun)));
 | 
						kinc_surface_set_touch_end_callback(*((FN_TOUCH_END *)(&touchEnd->fun)));
 | 
				
			||||||
	kinc_surface_set_move_callback(*((FN_TOUCH_MOVE *)(&touchMove->fun)));
 | 
						kinc_surface_set_move_callback(*((FN_TOUCH_MOVE *)(&touchMove->fun)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*FN_SENSOR_ACCELEROMETER)(float, float, float);
 | 
					typedef void (*FN_SENSOR_ACCELEROMETER)(float, float, float);
 | 
				
			||||||
typedef void (*FN_SENSOR_GYROSCOPE)(float, float, float);
 | 
					typedef void (*FN_SENSOR_GYROSCOPE)(float, float, float);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_register_sensor(vclosure *accelerometerChanged, vclosure *gyroscopeChanged) {
 | 
					void hl_kinc_register_sensor(vclosure *accelerometerChanged, vclosure *gyroscopeChanged) {
 | 
				
			||||||
	kinc_acceleration_set_callback(*((FN_SENSOR_ACCELEROMETER *)(&accelerometerChanged->fun)));
 | 
						kinc_acceleration_set_callback(*((FN_SENSOR_ACCELEROMETER *)(&accelerometerChanged->fun)));
 | 
				
			||||||
	kinc_rotation_set_callback(*((FN_SENSOR_GYROSCOPE *)(&gyroscopeChanged->fun)));
 | 
						kinc_rotation_set_callback(*((FN_SENSOR_GYROSCOPE *)(&gyroscopeChanged->fun)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// typedef void(*FN_CB_ORIENTATION)(int);
 | 
					// typedef void(*FN_CB_ORIENTATION)(int);
 | 
				
			||||||
typedef void (*FN_CB_FOREGROUND)(void *);
 | 
					typedef void (*FN_CB_FOREGROUND)(void *);
 | 
				
			||||||
typedef void (*FN_CB_RESUME)(void *);
 | 
					typedef void (*FN_CB_RESUME)(void *);
 | 
				
			||||||
typedef void (*FN_CB_PAUSE)(void *);
 | 
					typedef void (*FN_CB_PAUSE)(void *);
 | 
				
			||||||
typedef void (*FN_CB_BACKGROUND)(void *);
 | 
					typedef void (*FN_CB_BACKGROUND)(void *);
 | 
				
			||||||
typedef void (*FN_CB_SHUTDOWN)(void *);
 | 
					typedef void (*FN_CB_SHUTDOWN)(void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_register_callbacks(vclosure *foreground, vclosure *resume, vclosure *pause, vclosure *background, vclosure *shutdown) {
 | 
					void hl_kinc_register_callbacks(vclosure *foreground, vclosure *resume, vclosure *pause, vclosure *background, vclosure *shutdown) {
 | 
				
			||||||
	// kinc_set_orientation_callback(orientation);
 | 
						// kinc_set_orientation_callback(orientation);
 | 
				
			||||||
	kinc_set_foreground_callback(*((FN_CB_FOREGROUND *)(&foreground->fun)), NULL);
 | 
						kinc_set_foreground_callback(*((FN_CB_FOREGROUND *)(&foreground->fun)), NULL);
 | 
				
			||||||
	kinc_set_resume_callback(*((FN_CB_RESUME *)(&resume->fun)), NULL);
 | 
						kinc_set_resume_callback(*((FN_CB_RESUME *)(&resume->fun)), NULL);
 | 
				
			||||||
	kinc_set_pause_callback(*((FN_CB_PAUSE *)(&pause->fun)), NULL);
 | 
						kinc_set_pause_callback(*((FN_CB_PAUSE *)(&pause->fun)), NULL);
 | 
				
			||||||
	kinc_set_background_callback(*((FN_CB_BACKGROUND *)(&background->fun)), NULL);
 | 
						kinc_set_background_callback(*((FN_CB_BACKGROUND *)(&background->fun)), NULL);
 | 
				
			||||||
	kinc_set_shutdown_callback(*((FN_CB_SHUTDOWN *)(&shutdown->fun)), NULL);
 | 
						kinc_set_shutdown_callback(*((FN_CB_SHUTDOWN *)(&shutdown->fun)), NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef void (*FN_CB_DROPFILES)(wchar_t *);
 | 
					typedef void (*FN_CB_DROPFILES)(wchar_t *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_register_dropfiles(vclosure *dropFiles) {
 | 
					void hl_kinc_register_dropfiles(vclosure *dropFiles) {
 | 
				
			||||||
	// todo: string convert
 | 
						// todo: string convert
 | 
				
			||||||
	// kinc_set_drop_files_callback(*((FN_CB_DROPFILES*)(&dropFiles->fun)));
 | 
						// kinc_set_drop_files_callback(*((FN_CB_DROPFILES*)(&dropFiles->fun)));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
typedef char *(*FN_CB_COPY)(void *);
 | 
					typedef char *(*FN_CB_COPY)(void *);
 | 
				
			||||||
typedef char *(*FN_CB_CUT)(void *);
 | 
					typedef char *(*FN_CB_CUT)(void *);
 | 
				
			||||||
typedef void (*FN_CB_PASTE)(char *, void *);
 | 
					typedef void (*FN_CB_PASTE)(char *, void *);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void hl_kinc_register_copycutpaste(vclosure *copy, vclosure *cut, vclosure *paste) {
 | 
					void hl_kinc_register_copycutpaste(vclosure *copy, vclosure *cut, vclosure *paste) {
 | 
				
			||||||
	kinc_set_copy_callback(*((FN_CB_COPY *)(©->fun)), NULL);
 | 
						kinc_set_copy_callback(*((FN_CB_COPY *)(©->fun)), NULL);
 | 
				
			||||||
	kinc_set_cut_callback(*((FN_CB_CUT *)(&cut->fun)), NULL);
 | 
						kinc_set_cut_callback(*((FN_CB_CUT *)(&cut->fun)), NULL);
 | 
				
			||||||
	kinc_set_paste_callback(*((FN_CB_PASTE *)(&paste->fun)), NULL);
 | 
						kinc_set_paste_callback(*((FN_CB_PASTE *)(&paste->fun)), NULL);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const char *hl_kinc_video_format(void) {
 | 
					const char *hl_kinc_video_format(void) {
 | 
				
			||||||
	return kinc_video_formats()[0];
 | 
						return kinc_video_formats()[0];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -80,6 +80,7 @@ extern class Krom {
 | 
				
			|||||||
	static function unloadImage(image: kha.Image): Void;
 | 
						static function unloadImage(image: kha.Image): Void;
 | 
				
			||||||
	static function loadSound(file: String): Dynamic;
 | 
						static function loadSound(file: String): Dynamic;
 | 
				
			||||||
	static function writeAudioBuffer(buffer: js.lib.ArrayBuffer, samples: Int): Void;
 | 
						static function writeAudioBuffer(buffer: js.lib.ArrayBuffer, samples: Int): Void;
 | 
				
			||||||
 | 
						static function getSamplesPerSecond(): Int;
 | 
				
			||||||
	static function loadBlob(file: String): js.lib.ArrayBuffer;
 | 
						static function loadBlob(file: String): js.lib.ArrayBuffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function init(title: String, width: Int, height: Int, samplesPerPixel: Int, vSync: Bool, windowMode: Int, windowFeatures: Int, kromApi: Int): Void;
 | 
						static function init(title: String, width: Int, height: Int, samplesPerPixel: Int, vSync: Bool, windowMode: Int, windowFeatures: Int, kromApi: Int): Void;
 | 
				
			||||||
@ -115,6 +116,7 @@ extern class Krom {
 | 
				
			|||||||
	static function screenDpi(): Int;
 | 
						static function screenDpi(): Int;
 | 
				
			||||||
	static function systemId(): String;
 | 
						static function systemId(): String;
 | 
				
			||||||
	static function requestShutdown(): Void;
 | 
						static function requestShutdown(): Void;
 | 
				
			||||||
 | 
						static function displayFrequency(): Int;
 | 
				
			||||||
	static function displayCount(): Int;
 | 
						static function displayCount(): Int;
 | 
				
			||||||
	static function displayWidth(index: Int): Int;
 | 
						static function displayWidth(index: Int): Int;
 | 
				
			||||||
	static function displayHeight(index: Int): Int;
 | 
						static function displayHeight(index: Int): Int;
 | 
				
			||||||
 | 
				
			|||||||
@ -79,7 +79,7 @@ class Display {
 | 
				
			|||||||
	public var frequency(get, never): Int;
 | 
						public var frequency(get, never): Int;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function get_frequency(): Int {
 | 
						function get_frequency(): Int {
 | 
				
			||||||
		return 60;
 | 
							return Krom.displayFrequency();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public var pixelsPerInch(get, never): Int;
 | 
						public var pixelsPerInch(get, never): Int;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,343 +1,344 @@
 | 
				
			|||||||
package kha;
 | 
					package kha;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import kha.graphics4.TextureFormat;
 | 
					import kha.graphics4.TextureFormat;
 | 
				
			||||||
import kha.input.Gamepad;
 | 
					import kha.input.Gamepad;
 | 
				
			||||||
import kha.input.Keyboard;
 | 
					import kha.input.Keyboard;
 | 
				
			||||||
import kha.input.Mouse;
 | 
					import kha.input.Mouse;
 | 
				
			||||||
import kha.input.MouseImpl;
 | 
					import kha.input.MouseImpl;
 | 
				
			||||||
import kha.input.Pen;
 | 
					import kha.input.Pen;
 | 
				
			||||||
import kha.input.Surface;
 | 
					import kha.input.Surface;
 | 
				
			||||||
import kha.System;
 | 
					import kha.System;
 | 
				
			||||||
import haxe.ds.Vector;
 | 
					import haxe.ds.Vector;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class SystemImpl {
 | 
					class SystemImpl {
 | 
				
			||||||
	static var start: Float;
 | 
						static var start: Float;
 | 
				
			||||||
	static var framebuffer: Framebuffer;
 | 
						static var framebuffer: Framebuffer;
 | 
				
			||||||
	static var keyboard: Keyboard;
 | 
						static var keyboard: Keyboard;
 | 
				
			||||||
	static var mouse: Mouse;
 | 
						static var mouse: Mouse;
 | 
				
			||||||
	static var pen: Pen;
 | 
						static var pen: Pen;
 | 
				
			||||||
	static var maxGamepads: Int = 4;
 | 
						static var maxGamepads: Int = 4;
 | 
				
			||||||
	static var gamepads: Array<Gamepad>;
 | 
						static var gamepads: Array<Gamepad>;
 | 
				
			||||||
	static var mouseLockListeners: Array<Void->Void> = [];
 | 
						static var mouseLockListeners: Array<Void->Void> = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function renderCallback(): Void {
 | 
						static function renderCallback(): Void {
 | 
				
			||||||
		Scheduler.executeFrame();
 | 
							Scheduler.executeFrame();
 | 
				
			||||||
		System.render([framebuffer]);
 | 
							System.render([framebuffer]);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function dropFilesCallback(filePath: String): Void {
 | 
						static function dropFilesCallback(filePath: String): Void {
 | 
				
			||||||
		System.dropFiles(filePath);
 | 
							System.dropFiles(filePath);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function copyCallback(): String {
 | 
						static function copyCallback(): String {
 | 
				
			||||||
		if (System.copyListener != null) {
 | 
							if (System.copyListener != null) {
 | 
				
			||||||
			return System.copyListener();
 | 
								return System.copyListener();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			return null;
 | 
								return null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function cutCallback(): String {
 | 
						static function cutCallback(): String {
 | 
				
			||||||
		if (System.cutListener != null) {
 | 
							if (System.cutListener != null) {
 | 
				
			||||||
			return System.cutListener();
 | 
								return System.cutListener();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			return null;
 | 
								return null;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function pasteCallback(data: String): Void {
 | 
						static function pasteCallback(data: String): Void {
 | 
				
			||||||
		if (System.pasteListener != null) {
 | 
							if (System.pasteListener != null) {
 | 
				
			||||||
			System.pasteListener(data);
 | 
								System.pasteListener(data);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function foregroundCallback(): Void {
 | 
						static function foregroundCallback(): Void {
 | 
				
			||||||
		System.foreground();
 | 
							System.foreground();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function resumeCallback(): Void {
 | 
						static function resumeCallback(): Void {
 | 
				
			||||||
		System.resume();
 | 
							System.resume();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function pauseCallback(): Void {
 | 
						static function pauseCallback(): Void {
 | 
				
			||||||
		System.pause();
 | 
							System.pause();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function backgroundCallback(): Void {
 | 
						static function backgroundCallback(): Void {
 | 
				
			||||||
		System.background();
 | 
							System.background();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function shutdownCallback(): Void {
 | 
						static function shutdownCallback(): Void {
 | 
				
			||||||
		System.shutdown();
 | 
							System.shutdown();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function keyboardDownCallback(code: Int): Void {
 | 
						static function keyboardDownCallback(code: Int): Void {
 | 
				
			||||||
		keyboard.sendDownEvent(cast code);
 | 
							keyboard.sendDownEvent(cast code);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function keyboardUpCallback(code: Int): Void {
 | 
						static function keyboardUpCallback(code: Int): Void {
 | 
				
			||||||
		keyboard.sendUpEvent(cast code);
 | 
							keyboard.sendUpEvent(cast code);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function keyboardPressCallback(charCode: Int): Void {
 | 
						static function keyboardPressCallback(charCode: Int): Void {
 | 
				
			||||||
		keyboard.sendPressEvent(String.fromCharCode(charCode));
 | 
							keyboard.sendPressEvent(String.fromCharCode(charCode));
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function mouseDownCallback(button: Int, x: Int, y: Int): Void {
 | 
						static function mouseDownCallback(button: Int, x: Int, y: Int): Void {
 | 
				
			||||||
		mouse.sendDownEvent(0, button, x, y);
 | 
							mouse.sendDownEvent(0, button, x, y);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function mouseUpCallback(button: Int, x: Int, y: Int): Void {
 | 
						static function mouseUpCallback(button: Int, x: Int, y: Int): Void {
 | 
				
			||||||
		mouse.sendUpEvent(0, button, x, y);
 | 
							mouse.sendUpEvent(0, button, x, y);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function mouseMoveCallback(x: Int, y: Int, mx: Int, my: Int): Void {
 | 
						static function mouseMoveCallback(x: Int, y: Int, mx: Int, my: Int): Void {
 | 
				
			||||||
		mouse.sendMoveEvent(0, x, y, mx, my);
 | 
							mouse.sendMoveEvent(0, x, y, mx, my);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function mouseWheelCallback(delta: Int): Void {
 | 
						static function mouseWheelCallback(delta: Int): Void {
 | 
				
			||||||
		mouse.sendWheelEvent(0, delta);
 | 
							mouse.sendWheelEvent(0, delta);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function penDownCallback(x: Int, y: Int, pressure: Float): Void {
 | 
						static function penDownCallback(x: Int, y: Int, pressure: Float): Void {
 | 
				
			||||||
		pen.sendDownEvent(0, x, y, pressure);
 | 
							pen.sendDownEvent(0, x, y, pressure);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function penUpCallback(x: Int, y: Int, pressure: Float): Void {
 | 
						static function penUpCallback(x: Int, y: Int, pressure: Float): Void {
 | 
				
			||||||
		pen.sendUpEvent(0, x, y, pressure);
 | 
							pen.sendUpEvent(0, x, y, pressure);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function penMoveCallback(x: Int, y: Int, pressure: Float): Void {
 | 
						static function penMoveCallback(x: Int, y: Int, pressure: Float): Void {
 | 
				
			||||||
		pen.sendMoveEvent(0, x, y, pressure);
 | 
							pen.sendMoveEvent(0, x, y, pressure);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function gamepadAxisCallback(gamepad: Int, axis: Int, value: Float): Void {
 | 
						static function gamepadAxisCallback(gamepad: Int, axis: Int, value: Float): Void {
 | 
				
			||||||
		gamepads[gamepad].sendAxisEvent(axis, value);
 | 
							gamepads[gamepad].sendAxisEvent(axis, value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function gamepadButtonCallback(gamepad: Int, button: Int, value: Float): Void {
 | 
						static function gamepadButtonCallback(gamepad: Int, button: Int, value: Float): Void {
 | 
				
			||||||
		gamepads[gamepad].sendButtonEvent(button, value);
 | 
							gamepads[gamepad].sendButtonEvent(button, value);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	static function audioCallback(samples: Int): Void {
 | 
						static function audioCallback(samples: Int): Void {
 | 
				
			||||||
		kha.audio2.Audio._callCallback(samples);
 | 
							kha.audio2.Audio._callCallback(samples);
 | 
				
			||||||
		var buffer = @:privateAccess kha.audio2.Audio.buffer;
 | 
							var buffer = @:privateAccess kha.audio2.Audio.buffer;
 | 
				
			||||||
		Krom.writeAudioBuffer(buffer.data.buffer, samples);
 | 
							Krom.writeAudioBuffer(buffer.data.buffer, samples);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static function init(options: SystemOptions, callback: Window->Void): Void {
 | 
						public static function init(options: SystemOptions, callback: Window->Void): Void {
 | 
				
			||||||
		Krom.init(options.title, options.width, options.height, options.framebuffer.samplesPerPixel, options.framebuffer.verticalSync,
 | 
							Krom.init(options.title, options.width, options.height, options.framebuffer.samplesPerPixel, options.framebuffer.verticalSync,
 | 
				
			||||||
			cast options.window.mode, options.window.windowFeatures, Krom.KROM_API);
 | 
								cast options.window.mode, options.window.windowFeatures, Krom.KROM_API);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		start = Krom.getTime();
 | 
							start = Krom.getTime();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		haxe.Log.trace = function(v: Dynamic, ?infos: haxe.PosInfos) {
 | 
							haxe.Log.trace = function(v: Dynamic, ?infos: haxe.PosInfos) {
 | 
				
			||||||
			var message = haxe.Log.formatOutput(v, infos);
 | 
								var message = haxe.Log.formatOutput(v, infos);
 | 
				
			||||||
			Krom.log(message);
 | 
								Krom.log(message);
 | 
				
			||||||
		};
 | 
							};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		new Window(0);
 | 
							new Window(0);
 | 
				
			||||||
		Scheduler.init();
 | 
							Scheduler.init();
 | 
				
			||||||
		Shaders.init();
 | 
							Shaders.init();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var g4 = new kha.krom.Graphics();
 | 
							var g4 = new kha.krom.Graphics();
 | 
				
			||||||
		framebuffer = new Framebuffer(0, null, null, g4);
 | 
							framebuffer = new Framebuffer(0, null, null, g4);
 | 
				
			||||||
		framebuffer.init(new kha.graphics2.Graphics1(framebuffer), new kha.graphics4.Graphics2(framebuffer), g4);
 | 
							framebuffer.init(new kha.graphics2.Graphics1(framebuffer), new kha.graphics4.Graphics2(framebuffer), g4);
 | 
				
			||||||
		Krom.setCallback(renderCallback);
 | 
							Krom.setCallback(renderCallback);
 | 
				
			||||||
		Krom.setDropFilesCallback(dropFilesCallback);
 | 
							Krom.setDropFilesCallback(dropFilesCallback);
 | 
				
			||||||
		Krom.setCutCopyPasteCallback(cutCallback, copyCallback, pasteCallback);
 | 
							Krom.setCutCopyPasteCallback(cutCallback, copyCallback, pasteCallback);
 | 
				
			||||||
		Krom.setApplicationStateCallback(foregroundCallback, resumeCallback, pauseCallback, backgroundCallback, shutdownCallback);
 | 
							Krom.setApplicationStateCallback(foregroundCallback, resumeCallback, pauseCallback, backgroundCallback, shutdownCallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		keyboard = new Keyboard();
 | 
							keyboard = new Keyboard();
 | 
				
			||||||
		mouse = new MouseImpl();
 | 
							mouse = new MouseImpl();
 | 
				
			||||||
		pen = new Pen();
 | 
							pen = new Pen();
 | 
				
			||||||
		gamepads = new Array<Gamepad>();
 | 
							gamepads = new Array<Gamepad>();
 | 
				
			||||||
		for (i in 0...maxGamepads) {
 | 
							for (i in 0...maxGamepads) {
 | 
				
			||||||
			gamepads[i] = new Gamepad(i);
 | 
								gamepads[i] = new Gamepad(i);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		Krom.setKeyboardDownCallback(keyboardDownCallback);
 | 
							Krom.setKeyboardDownCallback(keyboardDownCallback);
 | 
				
			||||||
		Krom.setKeyboardUpCallback(keyboardUpCallback);
 | 
							Krom.setKeyboardUpCallback(keyboardUpCallback);
 | 
				
			||||||
		Krom.setKeyboardPressCallback(keyboardPressCallback);
 | 
							Krom.setKeyboardPressCallback(keyboardPressCallback);
 | 
				
			||||||
		Krom.setMouseDownCallback(mouseDownCallback);
 | 
							Krom.setMouseDownCallback(mouseDownCallback);
 | 
				
			||||||
		Krom.setMouseUpCallback(mouseUpCallback);
 | 
							Krom.setMouseUpCallback(mouseUpCallback);
 | 
				
			||||||
		Krom.setMouseMoveCallback(mouseMoveCallback);
 | 
							Krom.setMouseMoveCallback(mouseMoveCallback);
 | 
				
			||||||
		Krom.setMouseWheelCallback(mouseWheelCallback);
 | 
							Krom.setMouseWheelCallback(mouseWheelCallback);
 | 
				
			||||||
		Krom.setPenDownCallback(penDownCallback);
 | 
							Krom.setPenDownCallback(penDownCallback);
 | 
				
			||||||
		Krom.setPenUpCallback(penUpCallback);
 | 
							Krom.setPenUpCallback(penUpCallback);
 | 
				
			||||||
		Krom.setPenMoveCallback(penMoveCallback);
 | 
							Krom.setPenMoveCallback(penMoveCallback);
 | 
				
			||||||
		Krom.setGamepadAxisCallback(gamepadAxisCallback);
 | 
							Krom.setGamepadAxisCallback(gamepadAxisCallback);
 | 
				
			||||||
		Krom.setGamepadButtonCallback(gamepadButtonCallback);
 | 
							Krom.setGamepadButtonCallback(gamepadButtonCallback);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		kha.audio2.Audio._init();
 | 
							kha.audio2.Audio.samplesPerSecond = Krom.getSamplesPerSecond();
 | 
				
			||||||
		kha.audio1.Audio._init();
 | 
							kha.audio1.Audio._init();
 | 
				
			||||||
		Krom.setAudioCallback(audioCallback);
 | 
							kha.audio2.Audio._init();
 | 
				
			||||||
 | 
							Krom.setAudioCallback(audioCallback);
 | 
				
			||||||
		Scheduler.start();
 | 
					
 | 
				
			||||||
 | 
							Scheduler.start();
 | 
				
			||||||
		callback(Window.get(0));
 | 
					
 | 
				
			||||||
	}
 | 
							callback(Window.get(0));
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function initEx(title: String, options: Array<WindowOptions>, windowCallback: Int->Void, callback: Void->Void): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function initEx(title: String, options: Array<WindowOptions>, windowCallback: Int->Void, callback: Void->Void): Void {}
 | 
				
			||||||
	static function translateWindowMode(value: Null<WindowMode>): Int {
 | 
					
 | 
				
			||||||
		if (value == null) {
 | 
						static function translateWindowMode(value: Null<WindowMode>): Int {
 | 
				
			||||||
			return 0;
 | 
							if (value == null) {
 | 
				
			||||||
		}
 | 
								return 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		return switch (value) {
 | 
					
 | 
				
			||||||
			case Windowed: 0;
 | 
							return switch (value) {
 | 
				
			||||||
			case Fullscreen: 1;
 | 
								case Windowed: 0;
 | 
				
			||||||
			case ExclusiveFullscreen: 2;
 | 
								case Fullscreen: 1;
 | 
				
			||||||
		}
 | 
								case ExclusiveFullscreen: 2;
 | 
				
			||||||
	}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getScreenRotation(): ScreenRotation {
 | 
					
 | 
				
			||||||
		return ScreenRotation.RotationNone;
 | 
						public static function getScreenRotation(): ScreenRotation {
 | 
				
			||||||
	}
 | 
							return ScreenRotation.RotationNone;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getTime(): Float {
 | 
					
 | 
				
			||||||
		return Krom.getTime() - start;
 | 
						public static function getTime(): Float {
 | 
				
			||||||
	}
 | 
							return Krom.getTime() - start;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getVsync(): Bool {
 | 
					
 | 
				
			||||||
		return true;
 | 
						public static function getVsync(): Bool {
 | 
				
			||||||
	}
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getRefreshRate(): Int {
 | 
					
 | 
				
			||||||
		return 60;
 | 
						public static function getRefreshRate(): Int {
 | 
				
			||||||
	}
 | 
							return Krom.displayFrequency();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getSystemId(): String {
 | 
					
 | 
				
			||||||
		return Krom.systemId();
 | 
						public static function getSystemId(): String {
 | 
				
			||||||
	}
 | 
							return Krom.systemId();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function vibrate(ms: Int): Void {
 | 
					
 | 
				
			||||||
		// TODO: Implement
 | 
						public static function vibrate(ms: Int): Void {
 | 
				
			||||||
	}
 | 
							// TODO: Implement
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getLanguage(): String {
 | 
					
 | 
				
			||||||
		return "en"; // TODO: Implement
 | 
						public static function getLanguage(): String {
 | 
				
			||||||
	}
 | 
							return "en"; // TODO: Implement
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function requestShutdown(): Bool {
 | 
					
 | 
				
			||||||
		Krom.requestShutdown();
 | 
						public static function requestShutdown(): Bool {
 | 
				
			||||||
		return true;
 | 
							Krom.requestShutdown();
 | 
				
			||||||
	}
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getMouse(num: Int): Mouse {
 | 
					
 | 
				
			||||||
		return mouse;
 | 
						public static function getMouse(num: Int): Mouse {
 | 
				
			||||||
	}
 | 
							return mouse;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getPen(num: Int): Pen {
 | 
					
 | 
				
			||||||
		return pen;
 | 
						public static function getPen(num: Int): Pen {
 | 
				
			||||||
	}
 | 
							return pen;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getKeyboard(num: Int): Keyboard {
 | 
					
 | 
				
			||||||
		return keyboard;
 | 
						public static function getKeyboard(num: Int): Keyboard {
 | 
				
			||||||
	}
 | 
							return keyboard;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function lockMouse(): Void {
 | 
					
 | 
				
			||||||
		if (!isMouseLocked()) {
 | 
						public static function lockMouse(): Void {
 | 
				
			||||||
			Krom.lockMouse();
 | 
							if (!isMouseLocked()) {
 | 
				
			||||||
			for (listener in mouseLockListeners) {
 | 
								Krom.lockMouse();
 | 
				
			||||||
				listener();
 | 
								for (listener in mouseLockListeners) {
 | 
				
			||||||
			}
 | 
									listener();
 | 
				
			||||||
		}
 | 
								}
 | 
				
			||||||
	}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function unlockMouse(): Void {
 | 
					
 | 
				
			||||||
		if (isMouseLocked()) {
 | 
						public static function unlockMouse(): Void {
 | 
				
			||||||
			Krom.unlockMouse();
 | 
							if (isMouseLocked()) {
 | 
				
			||||||
			for (listener in mouseLockListeners) {
 | 
								Krom.unlockMouse();
 | 
				
			||||||
				listener();
 | 
								for (listener in mouseLockListeners) {
 | 
				
			||||||
			}
 | 
									listener();
 | 
				
			||||||
		}
 | 
								}
 | 
				
			||||||
	}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function canLockMouse(): Bool {
 | 
					
 | 
				
			||||||
		return Krom.canLockMouse();
 | 
						public static function canLockMouse(): Bool {
 | 
				
			||||||
	}
 | 
							return Krom.canLockMouse();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function isMouseLocked(): Bool {
 | 
					
 | 
				
			||||||
		return Krom.isMouseLocked();
 | 
						public static function isMouseLocked(): Bool {
 | 
				
			||||||
	}
 | 
							return Krom.isMouseLocked();
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function notifyOfMouseLockChange(func: Void->Void, error: Void->Void): Void {
 | 
					
 | 
				
			||||||
		if (canLockMouse() && func != null) {
 | 
						public static function notifyOfMouseLockChange(func: Void->Void, error: Void->Void): Void {
 | 
				
			||||||
			mouseLockListeners.push(func);
 | 
							if (canLockMouse() && func != null) {
 | 
				
			||||||
		}
 | 
								mouseLockListeners.push(func);
 | 
				
			||||||
	}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function removeFromMouseLockChange(func: Void->Void, error: Void->Void): Void {
 | 
					
 | 
				
			||||||
		if (canLockMouse() && func != null) {
 | 
						public static function removeFromMouseLockChange(func: Void->Void, error: Void->Void): Void {
 | 
				
			||||||
			mouseLockListeners.remove(func);
 | 
							if (canLockMouse() && func != null) {
 | 
				
			||||||
		}
 | 
								mouseLockListeners.remove(func);
 | 
				
			||||||
	}
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function hideSystemCursor(): Void {
 | 
					
 | 
				
			||||||
		Krom.showMouse(false);
 | 
						public static function hideSystemCursor(): Void {
 | 
				
			||||||
	}
 | 
							Krom.showMouse(false);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function showSystemCursor(): Void {
 | 
					
 | 
				
			||||||
		Krom.showMouse(true);
 | 
						public static function showSystemCursor(): Void {
 | 
				
			||||||
	}
 | 
							Krom.showMouse(true);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	static function unload(): Void {}
 | 
					
 | 
				
			||||||
 | 
						static function unload(): Void {}
 | 
				
			||||||
	public static function canSwitchFullscreen(): Bool {
 | 
					
 | 
				
			||||||
		return false;
 | 
						public static function canSwitchFullscreen(): Bool {
 | 
				
			||||||
	}
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function isFullscreen(): Bool {
 | 
					
 | 
				
			||||||
		return false;
 | 
						public static function isFullscreen(): Bool {
 | 
				
			||||||
	}
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function requestFullscreen(): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function requestFullscreen(): Void {}
 | 
				
			||||||
	public static function exitFullscreen(): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function exitFullscreen(): Void {}
 | 
				
			||||||
	public static function notifyOfFullscreenChange(func: Void->Void, error: Void->Void): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function notifyOfFullscreenChange(func: Void->Void, error: Void->Void): Void {}
 | 
				
			||||||
	public static function removeFromFullscreenChange(func: Void->Void, error: Void->Void): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function removeFromFullscreenChange(func: Void->Void, error: Void->Void): Void {}
 | 
				
			||||||
	public static function changeResolution(width: Int, height: Int): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function changeResolution(width: Int, height: Int): Void {}
 | 
				
			||||||
	public static function setKeepScreenOn(on: Bool): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function setKeepScreenOn(on: Bool): Void {}
 | 
				
			||||||
	public static function loadUrl(url: String): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function loadUrl(url: String): Void {}
 | 
				
			||||||
	public static function getGamepadId(index: Int): String {
 | 
					
 | 
				
			||||||
		return "unknown";
 | 
						public static function getGamepadId(index: Int): String {
 | 
				
			||||||
	}
 | 
							return "unknown";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function getGamepadVendor(index: Int): String {
 | 
					
 | 
				
			||||||
		return "unknown";
 | 
						public static function getGamepadVendor(index: Int): String {
 | 
				
			||||||
	}
 | 
							return "unknown";
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function setGamepadRumble(index: Int, leftAmount: Float, rightAmount: Float): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function setGamepadRumble(index: Int, leftAmount: Float, rightAmount: Float): Void {}
 | 
				
			||||||
	public static function safeZone(): Float {
 | 
					
 | 
				
			||||||
		return 1.0;
 | 
						public static function safeZone(): Float {
 | 
				
			||||||
	}
 | 
							return 1.0;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function login(): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function login(): Void {}
 | 
				
			||||||
	public static function automaticSafeZone(): Bool {
 | 
					
 | 
				
			||||||
		return true;
 | 
						public static function automaticSafeZone(): Bool {
 | 
				
			||||||
	}
 | 
							return true;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function setSafeZone(value: Float): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function setSafeZone(value: Float): Void {}
 | 
				
			||||||
	public static function unlockAchievement(id: Int): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function unlockAchievement(id: Int): Void {}
 | 
				
			||||||
	public static function waitingForLogin(): Bool {
 | 
					
 | 
				
			||||||
		return false;
 | 
						public static function waitingForLogin(): Bool {
 | 
				
			||||||
	}
 | 
							return false;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	public static function disallowUserChange(): Void {}
 | 
					
 | 
				
			||||||
 | 
						public static function disallowUserChange(): Void {}
 | 
				
			||||||
	public static function allowUserChange(): Void {}
 | 
					
 | 
				
			||||||
}
 | 
						public static function allowUserChange(): Void {}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,57 +1,56 @@
 | 
				
			|||||||
package kha.audio2;
 | 
					package kha.audio2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import kha.Sound;
 | 
					import kha.Sound;
 | 
				
			||||||
import kha.internal.IntBox;
 | 
					import kha.internal.IntBox;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class Audio {
 | 
					class Audio {
 | 
				
			||||||
	public static var disableGcInteractions = false;
 | 
						public static var disableGcInteractions = false;
 | 
				
			||||||
	static var intBox: IntBox = new IntBox(0);
 | 
						static var intBox: IntBox = new IntBox(0);
 | 
				
			||||||
	static var buffer: Buffer;
 | 
						static var buffer: Buffer;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public static function _init() {
 | 
						public static function _init() {
 | 
				
			||||||
		var bufferSize = 1024 * 2;
 | 
							var bufferSize = 1024 * 2;
 | 
				
			||||||
		buffer = new Buffer(bufferSize * 4, 2, 44100);
 | 
							buffer = new Buffer(bufferSize * 4, 2, samplesPerSecond);
 | 
				
			||||||
		Audio.samplesPerSecond = 44100;
 | 
						}
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
 | 
						public static function _callCallback(samples: Int): Void {
 | 
				
			||||||
	public static function _callCallback(samples: Int): Void {
 | 
							if (buffer == null)
 | 
				
			||||||
		if (buffer == null)
 | 
								return;
 | 
				
			||||||
			return;
 | 
							if (audioCallback != null) {
 | 
				
			||||||
		if (audioCallback != null) {
 | 
								intBox.value = samples;
 | 
				
			||||||
			intBox.value = samples;
 | 
								audioCallback(intBox, buffer);
 | 
				
			||||||
			audioCallback(intBox, buffer);
 | 
							}
 | 
				
			||||||
		}
 | 
							else {
 | 
				
			||||||
		else {
 | 
								for (i in 0...samples) {
 | 
				
			||||||
			for (i in 0...samples) {
 | 
									buffer.data.set(buffer.writeLocation, 0);
 | 
				
			||||||
				buffer.data.set(buffer.writeLocation, 0);
 | 
									buffer.writeLocation += 1;
 | 
				
			||||||
				buffer.writeLocation += 1;
 | 
									if (buffer.writeLocation >= buffer.size) {
 | 
				
			||||||
				if (buffer.writeLocation >= buffer.size) {
 | 
										buffer.writeLocation = 0;
 | 
				
			||||||
					buffer.writeLocation = 0;
 | 
									}
 | 
				
			||||||
				}
 | 
								}
 | 
				
			||||||
			}
 | 
							}
 | 
				
			||||||
		}
 | 
						}
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
 | 
						public static function _readSample(): FastFloat {
 | 
				
			||||||
	public static function _readSample(): Float {
 | 
							if (buffer == null)
 | 
				
			||||||
		if (buffer == null)
 | 
								return 0;
 | 
				
			||||||
			return 0;
 | 
							var value = buffer.data.get(buffer.readLocation);
 | 
				
			||||||
		var value = buffer.data.get(buffer.readLocation);
 | 
							++buffer.readLocation;
 | 
				
			||||||
		buffer.readLocation += 1;
 | 
							if (buffer.readLocation >= buffer.size) {
 | 
				
			||||||
		if (buffer.readLocation >= buffer.size) {
 | 
								buffer.readLocation = 0;
 | 
				
			||||||
			buffer.readLocation = 0;
 | 
							}
 | 
				
			||||||
		}
 | 
							return value;
 | 
				
			||||||
		return value;
 | 
						}
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
 | 
						public static var samplesPerSecond: Int;
 | 
				
			||||||
	public static var samplesPerSecond: Int;
 | 
					
 | 
				
			||||||
 | 
						public static var audioCallback: IntBox->Buffer->Void;
 | 
				
			||||||
	public static var audioCallback: IntBox->Buffer->Void;
 | 
					
 | 
				
			||||||
 | 
						public static function play(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
 | 
				
			||||||
	public static function play(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
 | 
							return null;
 | 
				
			||||||
		return null;
 | 
						}
 | 
				
			||||||
	}
 | 
					
 | 
				
			||||||
 | 
						public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
 | 
				
			||||||
	public static function stream(sound: Sound, loop: Bool = false): kha.audio1.AudioChannel {
 | 
							return null;
 | 
				
			||||||
		return null;
 | 
						}
 | 
				
			||||||
	}
 | 
					}
 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
				
			|||||||
@ -59,7 +59,7 @@ class Graphics implements kha.graphics4.Graphics {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function refreshRate(): Int {
 | 
						public function refreshRate(): Int {
 | 
				
			||||||
		return 60;
 | 
							return Krom.displayFrequency();
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function clear(?color: Color, ?depth: Float, ?stencil: Int): Void {
 | 
						public function clear(?color: Color, ?depth: Float, ?stencil: Int): Void {
 | 
				
			||||||
 | 
				
			|||||||
@ -34,22 +34,46 @@ void copySample(void *buffer) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int playback_callback(snd_pcm_sframes_t nframes) {
 | 
					int playback_callback(snd_pcm_sframes_t nframes) {
 | 
				
			||||||
	int err = 0;
 | 
					    int err = 0; 
 | 
				
			||||||
	if (kinc_a2_internal_callback(&a2_buffer, nframes)) {
 | 
					    if (kinc_a2_internal_callback(&a2_buffer, nframes)) {
 | 
				
			||||||
		int ni = 0;
 | 
					        int ni = 0;
 | 
				
			||||||
		while (ni < nframes) {
 | 
					        while (ni < nframes) {
 | 
				
			||||||
			int i = 0;
 | 
					            int i = 0;
 | 
				
			||||||
			for (; ni < nframes && i < 4096 * 2; ++i, ++ni) {
 | 
					            for (; ni < nframes && i < 4096; ++i, ++ni) {
 | 
				
			||||||
				copySample(&buf[i * 2]);
 | 
					                copySample(&buf[i * 2]);
 | 
				
			||||||
			}
 | 
					            }
 | 
				
			||||||
			int err2;
 | 
					            int err2 = snd_pcm_writei(playback_handle, buf, i);
 | 
				
			||||||
			if ((err2 = snd_pcm_writei(playback_handle, buf, i)) < 0) {
 | 
					            if (err2 < 0) {
 | 
				
			||||||
				fprintf(stderr, "write failed (%s)\n", snd_strerror(err2));
 | 
					                fprintf(stderr, "ALSA write failed in playback_callback: %s\n", snd_strerror(err2));
 | 
				
			||||||
			}
 | 
					                return err2;
 | 
				
			||||||
			err += err2;
 | 
					            }
 | 
				
			||||||
		}
 | 
					            if (err2 < i) {
 | 
				
			||||||
	}
 | 
					                fprintf(stderr, "ALSA short write in playback_callback: wrote %d of %d frames\n", err2, i);
 | 
				
			||||||
	return err;
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        err = nframes;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    else {
 | 
				
			||||||
 | 
					        // Write silence data to prevent recovery
 | 
				
			||||||
 | 
					        if (nframes > 4096) {
 | 
				
			||||||
 | 
					             fprintf(stderr, "Warning: ALSA requested %ld frames for silence, exceeding local buffer size %d. Clamping.\n", nframes, 4096);
 | 
				
			||||||
 | 
					             nframes = 4096; 
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        memset(buf, 0, nframes * 4);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        int err2 = snd_pcm_writei(playback_handle, buf, nframes);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (err2 < 0) {
 | 
				
			||||||
 | 
					            fprintf(stderr, "ALSA silence write failed in playback_callback: %s\n", snd_strerror(err2));
 | 
				
			||||||
 | 
					            err = err2;
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (err2 < nframes) {
 | 
				
			||||||
 | 
					                fprintf(stderr, "ALSA short silence write in playback_callback: wrote %d of %d frames\n", err2, (int)nframes);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            err = err2;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return err;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
bool tryToRecover(snd_pcm_t *handle, int errorCode) {
 | 
					bool tryToRecover(snd_pcm_t *handle, int errorCode) {
 | 
				
			||||||
 | 
				
			|||||||
@ -140,4 +140,4 @@ void kinc_internal_gamepad_trigger_button(int gamepad, int button, float value)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifdef __cplusplus
 | 
					#ifdef __cplusplus
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
| 
		 Before Width: | Height: | Size: 417 KiB After Width: | Height: | Size: 281 KiB  | 
							
								
								
									
										
											BIN
										
									
								
								Krom/Krom.exe
									
									
									
									
									
								
							
							
						
						
							
								
								
									
										
											BIN
										
									
								
								Krom/Krom_opengl.exe
									
									
									
									
									
										Normal file
									
								
							
							
						
						
							
								
								
									
										14
									
								
								README.md
									
									
									
									
									
								
							
							
						
						@ -6,22 +6,12 @@ Welcome to Leenkx!
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
<br>
 | 
					<br>
 | 
				
			||||||
- <a style="color:#2AE0E0;" class="text primary primary-text" href="https://leenkx.com/files/LeenkxSDK3_RC.zip">LeenkxSDKV3.6 lts</a>
 | 
					- Run your own private p2p torrent socket changing Leenkx javascript file directly in /lnxsdk/lib/leenkx_tools/lnxjs/Leenkx.js or by configuring the OPTS map in the create Leenkx node.
 | 
				
			||||||
<br>
 | 
					 | 
				
			||||||
- <a style="color:#2AE0E0;" class="text primary primary-text" href="https://leenkx.com/files/lx/Leenkx.js">Leenkx.js</a>
 | 
					 | 
				
			||||||
<br>
 | 
					 | 
				
			||||||
- Run your own private p2p torrent socket changing Leenkx javascript file directly in /lnxsdk/lib/leenkx_tools/lxjs/Leenkx.js or by configuring the OPTS map in the create Leenkx node.
 | 
					 | 
				
			||||||
<br> 
 | 
					<br> 
 | 
				
			||||||
- All works are open source ZLIB / MIT and any compatible licence that  guarantee the softwares freedom from my additions to the previous maintainers 
 | 
					- LNXJS Works as a standalone library
 | 
				
			||||||
<br>
 | 
					 | 
				
			||||||
- LxJS Works as a standalone library
 | 
					 | 
				
			||||||
<br>
 | 
					<br>
 | 
				
			||||||
- The SDK is not ready for production, use for educational purposes. Help the team by reaching out at Leenkx.com!
 | 
					- The SDK is not ready for production, use for educational purposes. Help the team by reaching out at Leenkx.com!
 | 
				
			||||||
<br>
 | 
					<br>
 | 
				
			||||||
- This build is based on QuantumCoder's whole new core animation system packed with new features! Timmodrians Aura library is also built into this build when audio is enabled! 
 | 
					 | 
				
			||||||
<br>
 | 
					 | 
				
			||||||
- The SDK is still undergoing many changes so working on large projects is not recommended. 
 | 
					 | 
				
			||||||
<br>
 | 
					 | 
				
			||||||
- Special thanks to all contributors from the following projects!
 | 
					- Special thanks to all contributors from the following projects!
 | 
				
			||||||
<br>
 | 
					<br>
 | 
				
			||||||
* https://github.com/armory3d/armory/graphs/contributors<br>
 | 
					* https://github.com/armory3d/armory/graphs/contributors<br>
 | 
				
			||||||
 | 
				
			|||||||
@ -310,9 +310,9 @@ class LeenkxAddonPreferences(AddonPreferences):
 | 
				
			|||||||
        layout.label(text="Welcome to Leenkx!")
 | 
					        layout.label(text="Welcome to Leenkx!")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Compare version Blender and Leenkx (major, minor)
 | 
					        # Compare version Blender and Leenkx (major, minor)
 | 
				
			||||||
        if bpy.app.version[0] != 3 or bpy.app.version[1] != 6:
 | 
					        if bpy.app.version[:2] not in [(4, 4), (4, 2), (3, 6), (3, 3)]:
 | 
				
			||||||
            box = layout.box().column()
 | 
					            box = layout.box().column()
 | 
				
			||||||
            box.label(text="Warning: For Leenkx to work correctly, you need Blender 3.6 LTS.")
 | 
					            box.label(text="Warning: For Leenkx to work correctly, use a Blender LTS version")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        layout.prop(self, "sdk_path")
 | 
					        layout.prop(self, "sdk_path")
 | 
				
			||||||
        sdk_path = get_sdk_path(context)
 | 
					        sdk_path = get_sdk_path(context)
 | 
				
			||||||
@ -914,7 +914,10 @@ def restart_leenkx(context):
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
@persistent
 | 
					@persistent
 | 
				
			||||||
def on_load_post(context):
 | 
					def on_load_post(context):
 | 
				
			||||||
    restart_leenkx(bpy.context)  # context is None, use bpy.context instead
 | 
					    if bpy.context is not None:
 | 
				
			||||||
 | 
					        restart_leenkx(bpy.context)  # context is None, use bpy.context instead
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        bpy.app.timers.register(lambda: restart_leenkx(bpy.context), first_interval=0.1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def on_register_post():
 | 
					def on_register_post():
 | 
				
			||||||
 | 
				
			|||||||
@ -475,7 +475,11 @@ fragColor.rgb = min(fragColor.rgb, 65504 * 0.5);
 | 
				
			|||||||
			} else {
 | 
								} else {
 | 
				
			||||||
				fragColor.rgb = mix(midLumColor, maxLumColor, luminance);
 | 
									fragColor.rgb = mix(midLumColor, maxLumColor, luminance);
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
 | 
							} else if (PPComp4.x == 9){
 | 
				
			||||||
 | 
								fragColor.rgb = tonemapAgXSimple(fragColor.rgb);
 | 
				
			||||||
 | 
								fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
 | 
				
			||||||
 | 
							} else if (PPComp4.x == 10){
 | 
				
			||||||
 | 
								fragColor.rgb = tonemapAgXFull(fragColor.rgb);
 | 
				
			||||||
		} else {
 | 
							} else {
 | 
				
			||||||
			fragColor.rgb = vec3(0,1,0); //ERROR
 | 
								fragColor.rgb = vec3(0,1,0); //ERROR
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
@ -498,6 +502,13 @@ fragColor.rgb = min(fragColor.rgb, 65504 * 0.5);
 | 
				
			|||||||
		fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
 | 
							fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
 | 
				
			||||||
		fragColor.rgb = clamp(fragColor.rgb, 0.0, 2.2);
 | 
							fragColor.rgb = clamp(fragColor.rgb, 0.0, 2.2);
 | 
				
			||||||
	#endif
 | 
						#endif
 | 
				
			||||||
 | 
						#ifdef _CToneAgXSimple
 | 
				
			||||||
 | 
							fragColor.rgb = tonemapAgXSimple(fragColor.rgb);
 | 
				
			||||||
 | 
							fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
 | 
						#ifdef _CToneAgXFull
 | 
				
			||||||
 | 
							fragColor.rgb = tonemapAgXFull(fragColor.rgb);
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
	#ifdef _CToneNone
 | 
						#ifdef _CToneNone
 | 
				
			||||||
		fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
 | 
							fragColor.rgb = pow(fragColor.rgb, vec3(1.0 / 2.2)); // To gamma
 | 
				
			||||||
	#endif
 | 
						#endif
 | 
				
			||||||
@ -614,4 +625,37 @@ fragColor.rgb = min(fragColor.rgb, 65504 * 0.5);
 | 
				
			|||||||
#ifdef _CLUT
 | 
					#ifdef _CLUT
 | 
				
			||||||
	fragColor = LUTlookup(fragColor, lutTexture);
 | 
						fragColor = LUTlookup(fragColor, lutTexture);
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _CDitheringBlueNoise
 | 
				
			||||||
 | 
						const float ditherStrength = ditherStrengthValue / 255.0;
 | 
				
			||||||
 | 
						float noise = ditherBlueNoiseStyle(gl_FragCoord.xy);
 | 
				
			||||||
 | 
						float noiseOffset = (noise - 0.5) * ditherStrength;
 | 
				
			||||||
 | 
						fragColor.rgb += noiseOffset;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _CDitheringWhiteNoise
 | 
				
			||||||
 | 
						const float ditherStrength = ditherStrengthValue / 255.0;
 | 
				
			||||||
 | 
						float noise = ditherWhiteNoise(gl_FragCoord.xy);
 | 
				
			||||||
 | 
						float noiseOffset = (noise - 0.5) * ditherStrength;
 | 
				
			||||||
 | 
						fragColor.rgb += noiseOffset;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _CDitheringOrderedBayer4x4
 | 
				
			||||||
 | 
						const float ditherStrength = ditherStrengthValue / 255.0;
 | 
				
			||||||
 | 
						float noise = ditherOrderedBayer4x4(ivec2(gl_FragCoord.xy));
 | 
				
			||||||
 | 
						float noiseOffset = (noise - 0.5) * ditherStrength;
 | 
				
			||||||
 | 
						fragColor.rgb += noiseOffset;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#ifdef _CDitheringOrderedBayer8x8
 | 
				
			||||||
 | 
						const float ditherStrength = ditherStrengthValue / 255.0;
 | 
				
			||||||
 | 
						float noise = ditherOrderedBayer8x8(ivec2(gl_FragCoord.xy));
 | 
				
			||||||
 | 
						float noiseOffset = (noise - 0.5) * ditherStrength;
 | 
				
			||||||
 | 
						fragColor.rgb += noiseOffset;
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						//fragColor.rgb = clamp(fragColor.rgb, 0.0, 1.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,7 @@ uniform sampler2D gbuffer0;
 | 
				
			|||||||
uniform sampler2D gbuffer1;
 | 
					uniform sampler2D gbuffer1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _gbuffer2
 | 
					#ifdef _gbuffer2
 | 
				
			||||||
	uniform sampler2D gbuffer2;
 | 
						//!uniform sampler2D gbuffer2;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef _EmissionShaded
 | 
					#ifdef _EmissionShaded
 | 
				
			||||||
	uniform sampler2D gbufferEmission;
 | 
						uniform sampler2D gbufferEmission;
 | 
				
			||||||
@ -286,7 +286,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifdef _VoxelGI
 | 
					#ifdef _VoxelGI
 | 
				
			||||||
	vec4 indirect_diffuse = textureLod(voxels_diffuse, texCoord, 0.0);
 | 
						vec4 indirect_diffuse = textureLod(voxels_diffuse, texCoord, 0.0);
 | 
				
			||||||
	fragColor.rgb = (indirect_diffuse.rgb * albedo + envl.rgb * (1.0 - indirect_diffuse.a)) * voxelgiDiff;
 | 
						fragColor.rgb = (indirect_diffuse.rgb + envl.rgb * (1.0 - indirect_diffuse.a)) * albedo * voxelgiDiff;
 | 
				
			||||||
	if(roughness < 1.0 && occspec.y > 0.0)
 | 
						if(roughness < 1.0 && occspec.y > 0.0)
 | 
				
			||||||
		fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl;
 | 
							fragColor.rgb += textureLod(voxels_specular, texCoord, 0.0).rgb * occspec.y * voxelgiRefl;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
@ -380,7 +380,7 @@ void main() {
 | 
				
			|||||||
	#endif
 | 
						#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#ifdef _VoxelShadow
 | 
						#ifdef _VoxelShadow
 | 
				
			||||||
	svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
 | 
						svisibility *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, sunDir, clipmaps, gl_FragCoord.xy, g2.rg).r) * voxelgiShad;
 | 
				
			||||||
	#endif
 | 
						#endif
 | 
				
			||||||
	
 | 
						
 | 
				
			||||||
	#ifdef _SSRS
 | 
						#ifdef _SSRS
 | 
				
			||||||
 | 
				
			|||||||
@ -92,7 +92,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	vec3 viewNormal = V3 * n;
 | 
						vec3 viewNormal = V3 * n;
 | 
				
			||||||
	vec3 viewPos = getPosView(viewRay, d, cameraProj);
 | 
						vec3 viewPos = getPosView(viewRay, d, cameraProj);
 | 
				
			||||||
	vec3 reflected = reflect(viewPos, viewNormal);
 | 
						vec3 reflected = reflect(normalize(viewPos), viewNormal);
 | 
				
			||||||
	hitCoord = viewPos;
 | 
						hitCoord = viewPos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#ifdef _CPostprocess
 | 
						#ifdef _CPostprocess
 | 
				
			||||||
 | 
				
			|||||||
@ -57,14 +57,17 @@ vec4 binarySearch(vec3 dir) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vec4 rayCast(vec3 dir) {
 | 
					vec4 rayCast(vec3 dir) {
 | 
				
			||||||
	float ddepth;
 | 
					    float ddepth;
 | 
				
			||||||
	dir *= ss_refractionRayStep;
 | 
					    dir *= ss_refractionRayStep;
 | 
				
			||||||
	for (int i = 0; i < maxSteps; i++) {
 | 
					    for (int i = 0; i < maxSteps; i++) {
 | 
				
			||||||
		hitCoord += dir;
 | 
					        hitCoord += dir;
 | 
				
			||||||
		ddepth = getDeltaDepth(hitCoord);
 | 
					        ddepth = getDeltaDepth(hitCoord);
 | 
				
			||||||
		if (ddepth > 0.0) return binarySearch(dir);
 | 
					        if (ddepth > 0.0)
 | 
				
			||||||
	}
 | 
					            return binarySearch(dir);
 | 
				
			||||||
	return vec4(texCoord, 0.0, 1.0);
 | 
					    }
 | 
				
			||||||
 | 
					    // No hit — fallback to projecting the ray to UV space
 | 
				
			||||||
 | 
					    vec2 fallbackUV = getProjectedCoord(hitCoord);
 | 
				
			||||||
 | 
					    return vec4(fallbackUV, 0.0, 0.5); // We set .w lower to indicate fallback
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void main() {
 | 
					void main() {
 | 
				
			||||||
@ -74,7 +77,7 @@ void main() {
 | 
				
			|||||||
    float ior = gr.x;
 | 
					    float ior = gr.x;
 | 
				
			||||||
    float opac = gr.y;
 | 
					    float opac = gr.y;
 | 
				
			||||||
    float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
 | 
					    float d = textureLod(gbufferD, texCoord, 0.0).r * 2.0 - 1.0;
 | 
				
			||||||
    if (d == 0.0 || d == 1.0 || opac == 1.0 || ior == 1.0) {
 | 
					    if (d == 0.0 || opac == 1.0 || ior == 1.0) {
 | 
				
			||||||
        fragColor.rgb = textureLod(tex1, texCoord, 0.0).rgb;
 | 
					        fragColor.rgb = textureLod(tex1, texCoord, 0.0).rgb;
 | 
				
			||||||
        return;
 | 
					        return;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -86,7 +89,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    vec3 viewNormal = V3 * n;
 | 
					    vec3 viewNormal = V3 * n;
 | 
				
			||||||
    vec3 viewPos = getPosView(viewRay, d, cameraProj);
 | 
					    vec3 viewPos = getPosView(viewRay, d, cameraProj);
 | 
				
			||||||
    vec3 refracted = refract(viewPos, viewNormal, 1.0 / ior);
 | 
					    vec3 refracted = refract(normalize(viewPos), viewNormal, 1.0 / ior);
 | 
				
			||||||
    hitCoord = viewPos;
 | 
					    hitCoord = viewPos;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    vec3 dir = refracted * (1.0 - rand(texCoord) * ss_refractionJitter * roughness) * 2.0;
 | 
					    vec3 dir = refracted * (1.0 - rand(texCoord) * ss_refractionJitter * roughness) * 2.0;
 | 
				
			||||||
 | 
				
			|||||||
@ -166,7 +166,7 @@ vec4 traceDiffuse(const vec3 origin, const vec3 normal, const sampler3D voxels,
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 viewDir, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
 | 
					vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 viewDir, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
 | 
				
			||||||
	vec3 specularDir = reflect(-viewDir, normal);
 | 
						vec3 specularDir = reflect(normalize(-viewDir), normal);
 | 
				
			||||||
	vec3 P = origin + specularDir * ((BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5)) * voxelgiStep;
 | 
						vec3 P = origin + specularDir * ((BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5)) * voxelgiStep;
 | 
				
			||||||
	vec4 amount = traceCone(voxels, voxelsSDF, P, normal, specularDir, 0, true, roughness, voxelgiStep, clipmaps);
 | 
						vec4 amount = traceCone(voxels, voxelsSDF, P, normal, specularDir, 0, true, roughness, voxelgiStep, clipmaps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -176,9 +176,9 @@ vec4 traceSpecular(const vec3 origin, const vec3 normal, const sampler3D voxels,
 | 
				
			|||||||
	return amount * voxelgiOcc;
 | 
						return amount * voxelgiOcc;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vec4 traceRefraction(const vec3 origin, const vec3 normal, sampler3D voxels, sampler3D voxelsSDF, const vec3 viewDir, const float ior, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
 | 
					vec4 traceRefraction(const vec3 origin, const vec3 normal, sampler3D voxels, sampler3D voxelsSDF, const vec3 viewDir, const float ior, const float roughness, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity, const float opacity) {
 | 
				
			||||||
 	const float transmittance = 1.0;
 | 
					 	const float transmittance = 1.0 - opacity;
 | 
				
			||||||
 	vec3 refractionDir = refract(-viewDir, normal, 1.0 / ior);
 | 
					 	vec3 refractionDir = refract(normalize(-viewDir), normal, 1.0 / ior);
 | 
				
			||||||
 	vec3 P = origin + refractionDir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep;
 | 
					 	vec3 P = origin + refractionDir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep;
 | 
				
			||||||
	vec4 amount =  transmittance * traceCone(voxels, voxelsSDF, P, normal, refractionDir, 0, true, roughness, voxelgiStep, clipmaps);
 | 
						vec4 amount =  transmittance * traceCone(voxels, voxelsSDF, P, normal, refractionDir, 0, true, roughness, voxelgiStep, clipmaps);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -328,8 +328,8 @@ float traceConeShadow(const sampler3D voxels, const sampler3D voxelsSDF, const v
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
float traceShadow(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 dir, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel) {
 | 
					float traceShadow(const vec3 origin, const vec3 normal, const sampler3D voxels, const sampler3D voxelsSDF, const vec3 dir, const float clipmaps[voxelgiClipmapCount * 10], const vec2 pixel, const vec2 velocity) {
 | 
				
			||||||
 	vec3 P = origin + dir * (BayerMatrix8[int(pixel.x) % 8][int(pixel.y) % 8] - 0.5) * voxelgiStep;
 | 
					 	vec3 P = origin + dir * (BayerMatrix8[int(pixel.x + velocity.x) % 8][int(pixel.y + velocity.y) % 8] - 0.5) * voxelgiStep;
 | 
				
			||||||
	float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, DIFFUSE_CONE_APERTURE, voxelgiStep, clipmaps);
 | 
						float amount = traceConeShadow(voxels, voxelsSDF, P, normal, dir, DIFFUSE_CONE_APERTURE, voxelgiStep, clipmaps);
 | 
				
			||||||
	amount = clamp(amount, 0.0, 1.0);
 | 
						amount = clamp(amount, 0.0, 1.0);
 | 
				
			||||||
	return amount * voxelgiOcc;
 | 
						return amount * voxelgiOcc;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,239 +1,242 @@
 | 
				
			|||||||
#ifndef _LIGHT_GLSL_
 | 
					#ifndef _LIGHT_GLSL_
 | 
				
			||||||
#define _LIGHT_GLSL_
 | 
					#define _LIGHT_GLSL_
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "compiled.inc"
 | 
					#include "compiled.inc"
 | 
				
			||||||
#include "std/brdf.glsl"
 | 
					#include "std/brdf.glsl"
 | 
				
			||||||
#include "std/math.glsl"
 | 
					#include "std/math.glsl"
 | 
				
			||||||
#ifdef _ShadowMap
 | 
					#ifdef _ShadowMap
 | 
				
			||||||
#include "std/shadows.glsl"
 | 
					#include "std/shadows.glsl"
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#ifdef _VoxelShadow
 | 
					#ifdef _VoxelShadow
 | 
				
			||||||
#include "std/conetrace.glsl"
 | 
					#include "std/conetrace.glsl"
 | 
				
			||||||
//!uniform sampler2D voxels_shadows;
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#ifdef _gbuffer2
 | 
				
			||||||
#ifdef _LTC
 | 
					uniform sampler2D gbuffer2;
 | 
				
			||||||
#include "std/ltc.glsl"
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#ifdef _LTC
 | 
				
			||||||
#ifdef _LightIES
 | 
					#include "std/ltc.glsl"
 | 
				
			||||||
#include "std/ies.glsl"
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#ifdef _LightIES
 | 
				
			||||||
#ifdef _SSRS
 | 
					#include "std/ies.glsl"
 | 
				
			||||||
#include "std/ssrs.glsl"
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#ifdef _SSRS
 | 
				
			||||||
#ifdef _Spot
 | 
					#include "std/ssrs.glsl"
 | 
				
			||||||
#include "std/light_common.glsl"
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#ifdef _Spot
 | 
				
			||||||
 | 
					#include "std/light_common.glsl"
 | 
				
			||||||
#ifdef _ShadowMap
 | 
					#endif
 | 
				
			||||||
	#ifdef _SinglePoint
 | 
					
 | 
				
			||||||
		#ifdef _Spot
 | 
					#ifdef _ShadowMap
 | 
				
			||||||
			#ifndef _LTC
 | 
						#ifdef _SinglePoint
 | 
				
			||||||
				uniform sampler2DShadow shadowMapSpot[1];
 | 
							#ifdef _Spot
 | 
				
			||||||
				uniform sampler2D shadowMapSpotTransparent[1];
 | 
								#ifndef _LTC
 | 
				
			||||||
				uniform mat4 LWVPSpot[1];
 | 
									uniform sampler2DShadow shadowMapSpot[1];
 | 
				
			||||||
			#endif
 | 
									uniform sampler2D shadowMapSpotTransparent[1];
 | 
				
			||||||
		#else
 | 
									uniform mat4 LWVPSpot[1];
 | 
				
			||||||
			uniform samplerCubeShadow shadowMapPoint[1];
 | 
								#endif
 | 
				
			||||||
			uniform samplerCube shadowMapPointTransparent[1];
 | 
							#else
 | 
				
			||||||
			uniform vec2 lightProj;
 | 
								uniform samplerCubeShadow shadowMapPoint[1];
 | 
				
			||||||
		#endif
 | 
								uniform samplerCube shadowMapPointTransparent[1];
 | 
				
			||||||
	#endif
 | 
								uniform vec2 lightProj;
 | 
				
			||||||
	#ifdef _Clusters
 | 
							#endif
 | 
				
			||||||
		#ifdef _SingleAtlas
 | 
						#endif
 | 
				
			||||||
		//!uniform sampler2DShadow shadowMapAtlas;
 | 
						#ifdef _Clusters
 | 
				
			||||||
		//!uniform sampler2D shadowMapAtlasTransparent;
 | 
							#ifdef _SingleAtlas
 | 
				
			||||||
		#endif
 | 
							//!uniform sampler2DShadow shadowMapAtlas;
 | 
				
			||||||
		uniform vec2 lightProj;
 | 
							//!uniform sampler2D shadowMapAtlasTransparent;
 | 
				
			||||||
		#ifdef _ShadowMapAtlas
 | 
							#endif
 | 
				
			||||||
		#ifndef _SingleAtlas
 | 
							uniform vec2 lightProj;
 | 
				
			||||||
		uniform sampler2DShadow shadowMapAtlasPoint;
 | 
							#ifdef _ShadowMapAtlas
 | 
				
			||||||
		uniform sampler2D shadowMapAtlasPointTransparent;
 | 
							#ifndef _SingleAtlas
 | 
				
			||||||
		#endif
 | 
							uniform sampler2DShadow shadowMapAtlasPoint;
 | 
				
			||||||
		#else
 | 
							uniform sampler2D shadowMapAtlasPointTransparent;
 | 
				
			||||||
		uniform samplerCubeShadow shadowMapPoint[4];
 | 
							#endif
 | 
				
			||||||
		uniform samplerCube shadowMapPointTransparent[4];
 | 
							#else
 | 
				
			||||||
		#endif
 | 
							uniform samplerCubeShadow shadowMapPoint[4];
 | 
				
			||||||
		#ifdef _Spot
 | 
							uniform samplerCube shadowMapPointTransparent[4];
 | 
				
			||||||
			#ifdef _ShadowMapAtlas
 | 
							#endif
 | 
				
			||||||
			#ifndef _SingleAtlas
 | 
							#ifdef _Spot
 | 
				
			||||||
			uniform sampler2DShadow shadowMapAtlasSpot;
 | 
								#ifdef _ShadowMapAtlas
 | 
				
			||||||
			uniform sampler2D shadowMapAtlasSpotTransparent;
 | 
								#ifndef _SingleAtlas
 | 
				
			||||||
			#endif
 | 
								uniform sampler2DShadow shadowMapAtlasSpot;
 | 
				
			||||||
			#else
 | 
								uniform sampler2D shadowMapAtlasSpotTransparent;
 | 
				
			||||||
			uniform sampler2DShadow shadowMapSpot[4];
 | 
								#endif
 | 
				
			||||||
			uniform sampler2D shadowMapSpotTransparent[4];
 | 
								#else
 | 
				
			||||||
			#endif
 | 
								uniform sampler2DShadow shadowMapSpot[4];
 | 
				
			||||||
			uniform mat4 LWVPSpotArray[maxLightsCluster];
 | 
								uniform sampler2D shadowMapSpotTransparent[4];
 | 
				
			||||||
		#endif
 | 
								#endif
 | 
				
			||||||
	#endif
 | 
								uniform mat4 LWVPSpotArray[maxLightsCluster];
 | 
				
			||||||
#endif
 | 
							#endif
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
#ifdef _LTC
 | 
					#endif
 | 
				
			||||||
uniform vec3 lightArea0;
 | 
					
 | 
				
			||||||
uniform vec3 lightArea1;
 | 
					#ifdef _LTC
 | 
				
			||||||
uniform vec3 lightArea2;
 | 
					uniform vec3 lightArea0;
 | 
				
			||||||
uniform vec3 lightArea3;
 | 
					uniform vec3 lightArea1;
 | 
				
			||||||
uniform sampler2D sltcMat;
 | 
					uniform vec3 lightArea2;
 | 
				
			||||||
uniform sampler2D sltcMag;
 | 
					uniform vec3 lightArea3;
 | 
				
			||||||
#ifdef _ShadowMap
 | 
					uniform sampler2D sltcMat;
 | 
				
			||||||
#ifndef _Spot
 | 
					uniform sampler2D sltcMag;
 | 
				
			||||||
	#ifdef _SinglePoint
 | 
					#ifdef _ShadowMap
 | 
				
			||||||
		uniform sampler2DShadow shadowMapSpot[1];
 | 
					#ifndef _Spot
 | 
				
			||||||
		uniform sampler2D shadowMapSpotTransparent[1];
 | 
						#ifdef _SinglePoint
 | 
				
			||||||
		uniform mat4 LWVPSpot[1];
 | 
							uniform sampler2DShadow shadowMapSpot[1];
 | 
				
			||||||
	#endif
 | 
							uniform sampler2D shadowMapSpotTransparent[1];
 | 
				
			||||||
	#ifdef _Clusters
 | 
							uniform mat4 LWVPSpot[1];
 | 
				
			||||||
		uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
 | 
						#endif
 | 
				
			||||||
		uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
 | 
						#ifdef _Clusters
 | 
				
			||||||
		uniform mat4 LWVPSpotArray[maxLightsCluster];
 | 
							uniform sampler2DShadow shadowMapSpot[maxLightsCluster];
 | 
				
			||||||
	#endif
 | 
							uniform sampler2D shadowMapSpotTransparent[maxLightsCluster];
 | 
				
			||||||
	#endif
 | 
							uniform mat4 LWVPSpotArray[maxLightsCluster];
 | 
				
			||||||
#endif
 | 
						#endif
 | 
				
			||||||
#endif
 | 
						#endif
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
 | 
					#endif
 | 
				
			||||||
	const vec3 albedo, const float rough, const float spec, const vec3 f0
 | 
					
 | 
				
			||||||
	#ifdef _ShadowMap
 | 
					vec3 sampleLight(const vec3 p, const vec3 n, const vec3 v, const float dotNV, const vec3 lp, const vec3 lightCol,
 | 
				
			||||||
		, int index, float bias, bool receiveShadow, bool transparent
 | 
						const vec3 albedo, const float rough, const float spec, const vec3 f0
 | 
				
			||||||
	#endif
 | 
						#ifdef _ShadowMap
 | 
				
			||||||
	#ifdef _Spot
 | 
							, int index, float bias, bool receiveShadow, bool transparent
 | 
				
			||||||
		, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
 | 
						#endif
 | 
				
			||||||
	#endif
 | 
						#ifdef _Spot
 | 
				
			||||||
	#ifdef _VoxelShadow
 | 
							, const bool isSpot, const float spotSize, float spotBlend, vec3 spotDir, vec2 scale, vec3 right
 | 
				
			||||||
		, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount]
 | 
						#endif
 | 
				
			||||||
	#endif
 | 
						#ifdef _VoxelShadow
 | 
				
			||||||
	#ifdef _MicroShadowing
 | 
							, sampler3D voxels, sampler3D voxelsSDF, float clipmaps[10 * voxelgiClipmapCount]
 | 
				
			||||||
		, float occ
 | 
						#endif
 | 
				
			||||||
	#endif
 | 
						#ifdef _MicroShadowing
 | 
				
			||||||
	#ifdef _SSRS
 | 
							, float occ
 | 
				
			||||||
		, sampler2D gbufferD, mat4 invVP, vec3 eye
 | 
						#endif
 | 
				
			||||||
	#endif
 | 
						#ifdef _SSRS
 | 
				
			||||||
	) {
 | 
							, sampler2D gbufferD, mat4 invVP, vec3 eye
 | 
				
			||||||
	vec3 ld = lp - p;
 | 
						#endif
 | 
				
			||||||
	vec3 l = normalize(ld);
 | 
						) {
 | 
				
			||||||
	vec3 h = normalize(v + l);
 | 
						vec3 ld = lp - p;
 | 
				
			||||||
	float dotNH = max(0.0, dot(n, h));
 | 
						vec3 l = normalize(ld);
 | 
				
			||||||
	float dotVH = max(0.0, dot(v, h));
 | 
						vec3 h = normalize(v + l);
 | 
				
			||||||
	float dotNL = max(0.0, dot(n, l));
 | 
						float dotNH = max(0.0, dot(n, h));
 | 
				
			||||||
 | 
						float dotVH = max(0.0, dot(v, h));
 | 
				
			||||||
	#ifdef _LTC
 | 
						float dotNL = max(0.0, dot(n, l));
 | 
				
			||||||
	float theta = acos(dotNV);
 | 
					
 | 
				
			||||||
	vec2 tuv = vec2(rough, theta / (0.5 * PI));
 | 
						#ifdef _LTC
 | 
				
			||||||
	tuv = tuv * LUT_SCALE + LUT_BIAS;
 | 
						float theta = acos(dotNV);
 | 
				
			||||||
	vec4 t = textureLod(sltcMat, tuv, 0.0);
 | 
						vec2 tuv = vec2(rough, theta / (0.5 * PI));
 | 
				
			||||||
	mat3 invM = mat3(
 | 
						tuv = tuv * LUT_SCALE + LUT_BIAS;
 | 
				
			||||||
		vec3(1.0, 0.0, t.y),
 | 
						vec4 t = textureLod(sltcMat, tuv, 0.0);
 | 
				
			||||||
		vec3(0.0, t.z, 0.0),
 | 
						mat3 invM = mat3(
 | 
				
			||||||
		vec3(t.w, 0.0, t.x));
 | 
							vec3(1.0, 0.0, t.y),
 | 
				
			||||||
	float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
 | 
							vec3(0.0, t.z, 0.0),
 | 
				
			||||||
	ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
 | 
							vec3(t.w, 0.0, t.x));
 | 
				
			||||||
	float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
 | 
						float ltcspec = ltcEvaluate(n, v, dotNV, p, invM, lightArea0, lightArea1, lightArea2, lightArea3);
 | 
				
			||||||
	vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
 | 
						ltcspec *= textureLod(sltcMag, tuv, 0.0).a;
 | 
				
			||||||
	#else
 | 
						float ltcdiff = ltcEvaluate(n, v, dotNV, p, mat3(1.0), lightArea0, lightArea1, lightArea2, lightArea3);
 | 
				
			||||||
	vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
 | 
						vec3 direct = albedo * ltcdiff + ltcspec * spec * 0.05;
 | 
				
			||||||
				  specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
 | 
						#else
 | 
				
			||||||
	#endif
 | 
						vec3 direct = lambertDiffuseBRDF(albedo, dotNL) +
 | 
				
			||||||
 | 
									  specularBRDF(f0, rough, dotNL, dotNH, dotNV, dotVH) * spec;
 | 
				
			||||||
	direct *= attenuate(distance(p, lp));
 | 
						#endif
 | 
				
			||||||
	direct *= lightCol;
 | 
					
 | 
				
			||||||
 | 
						direct *= attenuate(distance(p, lp));
 | 
				
			||||||
	#ifdef _MicroShadowing
 | 
						direct *= lightCol;
 | 
				
			||||||
	direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
 | 
					
 | 
				
			||||||
	#endif
 | 
						#ifdef _MicroShadowing
 | 
				
			||||||
 | 
						direct *= clamp(dotNL + 2.0 * occ * occ - 1.0, 0.0, 1.0);
 | 
				
			||||||
	#ifdef _SSRS
 | 
						#endif
 | 
				
			||||||
	direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
 | 
					
 | 
				
			||||||
	#endif
 | 
						#ifdef _SSRS
 | 
				
			||||||
 | 
						direct *= traceShadowSS(l, p, gbufferD, invVP, eye);
 | 
				
			||||||
	#ifdef _VoxelShadow
 | 
						#endif
 | 
				
			||||||
	direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, l, clipmaps, gl_FragCoord.xy).r) * voxelgiShad;
 | 
					
 | 
				
			||||||
	#endif
 | 
						#ifdef _VoxelShadow
 | 
				
			||||||
 | 
						vec4 g2 = textureLod(gbuffer2, gl_FragCoord.xy, 0.0);
 | 
				
			||||||
	#ifdef _LTC
 | 
						direct *= (1.0 - traceShadow(p, n, voxels, voxelsSDF, l, clipmaps, gl_FragCoord.xy, g2.rg).r) * voxelgiShad;
 | 
				
			||||||
	#ifdef _ShadowMap
 | 
						#endif
 | 
				
			||||||
		if (receiveShadow) {
 | 
					
 | 
				
			||||||
			#ifdef _SinglePoint
 | 
						#ifdef _LTC
 | 
				
			||||||
			vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
 | 
						#ifdef _ShadowMap
 | 
				
			||||||
			direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
 | 
							if (receiveShadow) {
 | 
				
			||||||
			#endif
 | 
								#ifdef _SinglePoint
 | 
				
			||||||
			#ifdef _Clusters
 | 
								vec4 lPos = LWVPSpotArray[0] * vec4(p + n * bias * 10, 1.0);
 | 
				
			||||||
			vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
 | 
								direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
			if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
 | 
								#endif
 | 
				
			||||||
			else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
 | 
								#ifdef _Clusters
 | 
				
			||||||
			else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
 | 
								vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
 | 
				
			||||||
			else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
 | 
								if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
			#endif
 | 
								else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
		}
 | 
								else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
	#endif
 | 
								else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
	return direct;
 | 
								#endif
 | 
				
			||||||
	#endif
 | 
							}
 | 
				
			||||||
 | 
						#endif
 | 
				
			||||||
	#ifdef _Spot
 | 
						return direct;
 | 
				
			||||||
	if (isSpot) {
 | 
						#endif
 | 
				
			||||||
		direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
 | 
					
 | 
				
			||||||
 | 
						#ifdef _Spot
 | 
				
			||||||
		#ifdef _ShadowMap
 | 
						if (isSpot) {
 | 
				
			||||||
			if (receiveShadow) {
 | 
							direct *= spotlightMask(l, spotDir, right, scale, spotSize, spotBlend);
 | 
				
			||||||
				#ifdef _SinglePoint
 | 
					
 | 
				
			||||||
				vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
 | 
							#ifdef _ShadowMap
 | 
				
			||||||
				direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
 | 
								if (receiveShadow) {
 | 
				
			||||||
				#endif
 | 
									#ifdef _SinglePoint
 | 
				
			||||||
				#ifdef _Clusters
 | 
									vec4 lPos = LWVPSpot[0] * vec4(p + n * bias * 10, 1.0);
 | 
				
			||||||
					vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
 | 
									direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
					#ifdef _ShadowMapAtlas
 | 
									#endif
 | 
				
			||||||
						direct *= shadowTest(
 | 
									#ifdef _Clusters
 | 
				
			||||||
							#ifndef _SingleAtlas
 | 
										vec4 lPos = LWVPSpotArray[index] * vec4(p + n * bias * 10, 1.0);
 | 
				
			||||||
							shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
 | 
										#ifdef _ShadowMapAtlas
 | 
				
			||||||
							#else
 | 
											direct *= shadowTest(
 | 
				
			||||||
							shadowMapAtlas, shadowMapAtlasTransparent
 | 
												#ifndef _SingleAtlas
 | 
				
			||||||
							#endif
 | 
												shadowMapAtlasSpot, shadowMapAtlasSpotTransparent
 | 
				
			||||||
							, lPos.xyz / lPos.w, bias, transparent
 | 
												#else
 | 
				
			||||||
						);
 | 
												shadowMapAtlas, shadowMapAtlasTransparent
 | 
				
			||||||
					#else
 | 
												#endif
 | 
				
			||||||
							 if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
 | 
												, lPos.xyz / lPos.w, bias, transparent
 | 
				
			||||||
						else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
 | 
											);
 | 
				
			||||||
						else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
 | 
										#else
 | 
				
			||||||
						else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
 | 
												 if (index == 0) direct *= shadowTest(shadowMapSpot[0], shadowMapSpotTransparent[0], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
					#endif
 | 
											else if (index == 1) direct *= shadowTest(shadowMapSpot[1], shadowMapSpotTransparent[1], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
				#endif
 | 
											else if (index == 2) direct *= shadowTest(shadowMapSpot[2], shadowMapSpotTransparent[2], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
			}
 | 
											else if (index == 3) direct *= shadowTest(shadowMapSpot[3], shadowMapSpotTransparent[3], lPos.xyz / lPos.w, bias, transparent);
 | 
				
			||||||
		#endif
 | 
										#endif
 | 
				
			||||||
		return direct;
 | 
									#endif
 | 
				
			||||||
	}
 | 
								}
 | 
				
			||||||
	#endif
 | 
							#endif
 | 
				
			||||||
 | 
							return direct;
 | 
				
			||||||
	#ifdef _LightIES
 | 
						}
 | 
				
			||||||
	direct *= iesAttenuation(-l);
 | 
						#endif
 | 
				
			||||||
	#endif
 | 
					
 | 
				
			||||||
 | 
						#ifdef _LightIES
 | 
				
			||||||
	#ifdef _ShadowMap
 | 
						direct *= iesAttenuation(-l);
 | 
				
			||||||
		if (receiveShadow) {
 | 
						#endif
 | 
				
			||||||
			#ifdef _SinglePoint
 | 
					
 | 
				
			||||||
			#ifndef _Spot
 | 
						#ifdef _ShadowMap
 | 
				
			||||||
			direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
 | 
							if (receiveShadow) {
 | 
				
			||||||
			#endif
 | 
								#ifdef _SinglePoint
 | 
				
			||||||
			#endif
 | 
								#ifndef _Spot
 | 
				
			||||||
			#ifdef _Clusters
 | 
								direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
 | 
				
			||||||
				#ifdef _ShadowMapAtlas
 | 
								#endif
 | 
				
			||||||
				direct *= PCFFakeCube(
 | 
								#endif
 | 
				
			||||||
					#ifndef _SingleAtlas
 | 
								#ifdef _Clusters
 | 
				
			||||||
					shadowMapAtlasPoint, shadowMapAtlasPointTransparent
 | 
									#ifdef _ShadowMapAtlas
 | 
				
			||||||
					#else
 | 
									direct *= PCFFakeCube(
 | 
				
			||||||
					shadowMapAtlas, shadowMapAtlasTransparent
 | 
										#ifndef _SingleAtlas
 | 
				
			||||||
					#endif
 | 
										shadowMapAtlasPoint, shadowMapAtlasPointTransparent
 | 
				
			||||||
					, ld, -l, bias, lightProj, n, index, transparent
 | 
										#else
 | 
				
			||||||
				);
 | 
										shadowMapAtlas, shadowMapAtlasTransparent
 | 
				
			||||||
				#else
 | 
										#endif
 | 
				
			||||||
					 if (index == 0) direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
 | 
										, ld, -l, bias, lightProj, n, index, transparent
 | 
				
			||||||
				else if (index == 1) direct *= PCFCube(shadowMapPoint[1], shadowMapPointTransparent[1], ld, -l, bias, lightProj, n, transparent);
 | 
									);
 | 
				
			||||||
				else if (index == 2) direct *= PCFCube(shadowMapPoint[2], shadowMapPointTransparent[2], ld, -l, bias, lightProj, n, transparent);
 | 
									#else
 | 
				
			||||||
				else if (index == 3) direct *= PCFCube(shadowMapPoint[3], shadowMapPointTransparent[3], ld, -l, bias, lightProj, n, transparent);
 | 
										 if (index == 0) direct *= PCFCube(shadowMapPoint[0], shadowMapPointTransparent[0], ld, -l, bias, lightProj, n, transparent);
 | 
				
			||||||
				#endif
 | 
									else if (index == 1) direct *= PCFCube(shadowMapPoint[1], shadowMapPointTransparent[1], ld, -l, bias, lightProj, n, transparent);
 | 
				
			||||||
			#endif
 | 
									else if (index == 2) direct *= PCFCube(shadowMapPoint[2], shadowMapPointTransparent[2], ld, -l, bias, lightProj, n, transparent);
 | 
				
			||||||
		}
 | 
									else if (index == 3) direct *= PCFCube(shadowMapPoint[3], shadowMapPointTransparent[3], ld, -l, bias, lightProj, n, transparent);
 | 
				
			||||||
	#endif
 | 
									#endif
 | 
				
			||||||
 | 
								#endif
 | 
				
			||||||
	return direct;
 | 
							}
 | 
				
			||||||
}
 | 
						#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#endif
 | 
						return direct;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#endif
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,3 @@
 | 
				
			|||||||
 | 
					 | 
				
			||||||
vec3 uncharted2Tonemap(const vec3 x) {
 | 
					vec3 uncharted2Tonemap(const vec3 x) {
 | 
				
			||||||
	const float A = 0.15;
 | 
						const float A = 0.15;
 | 
				
			||||||
	const float B = 0.50;
 | 
						const float B = 0.50;
 | 
				
			||||||
@ -36,3 +35,106 @@ vec3 acesFilm(const vec3 x) {
 | 
				
			|||||||
vec3 tonemapReinhard(const vec3 color) {
 | 
					vec3 tonemapReinhard(const vec3 color) {
 | 
				
			||||||
	return color / (color + vec3(1.0));
 | 
						return color / (color + vec3(1.0));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Blender AgX Implementation 
 | 
				
			||||||
 | 
					// Troy Sobotka https://github.com/sobotka/AgX
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AGX Simple
 | 
				
			||||||
 | 
					vec3 tonemapAgXSimple(vec3 x) {
 | 
				
			||||||
 | 
						// TODO CORRECT AND OPTIMIZE
 | 
				
			||||||
 | 
					    x = max(x, vec3(0.0));
 | 
				
			||||||
 | 
					    float exposure = 0.6;
 | 
				
			||||||
 | 
					    x *= exposure;
 | 
				
			||||||
 | 
					    const vec3 AgX_A = vec3(0.92, 0.92, 0.72);
 | 
				
			||||||
 | 
					    const vec3 AgX_B = vec3(0.24, 0.24, 0.36);
 | 
				
			||||||
 | 
					    const vec3 AgX_C = vec3(0.92, 0.92, 0.72);
 | 
				
			||||||
 | 
					    const vec3 AgX_D = vec3(0.24, 0.24, 0.36);
 | 
				
			||||||
 | 
					    const vec3 AgX_E = vec3(0.08, 0.08, 0.12);
 | 
				
			||||||
 | 
					    const vec3 AgX_F = vec3(0.0);
 | 
				
			||||||
 | 
					    vec3 result = (x * (AgX_A * x + AgX_B)) / (x * (AgX_C * x + AgX_D) + AgX_E) + AgX_F;
 | 
				
			||||||
 | 
					    float luma = dot(result, vec3(0.2126, 0.7152, 0.0722));
 | 
				
			||||||
 | 
					    result = mix(vec3(luma), result, 0.6);
 | 
				
			||||||
 | 
					    return clamp(result, vec3(0.0), vec3(1.0));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AGX Full Contrast Approx
 | 
				
			||||||
 | 
					vec3 agxDefaultContrastApprox(vec3 x) {
 | 
				
			||||||
 | 
					    vec3 x2 = x * x;
 | 
				
			||||||
 | 
					    vec3 x4 = x2 * x2;
 | 
				
			||||||
 | 
					    return + 15.5     * x4 * x2
 | 
				
			||||||
 | 
					           - 40.14    * x4 * x
 | 
				
			||||||
 | 
					           + 31.96    * x4
 | 
				
			||||||
 | 
					           - 6.868    * x2 * x
 | 
				
			||||||
 | 
					           + 0.4298   * x2
 | 
				
			||||||
 | 
					           + 0.1191   * x
 | 
				
			||||||
 | 
					           - 0.00232;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					// AGX Full Look
 | 
				
			||||||
 | 
					vec3 agxLook(vec3 x, float strength) {
 | 
				
			||||||
 | 
					    const vec3 slope = vec3(1.0);
 | 
				
			||||||
 | 
					    const vec3 power = vec3(1.35);
 | 
				
			||||||
 | 
					    const vec3 sat = vec3(1.4);
 | 
				
			||||||
 | 
					    vec3 lw = vec3(0.2126, 0.7152, 0.0722);
 | 
				
			||||||
 | 
					    float luma = dot(x, lw);
 | 
				
			||||||
 | 
					    return pow(x * slope, power) * sat - (pow(luma * slope, power) * (sat - 1.0));
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// AGX Full
 | 
				
			||||||
 | 
					vec3 tonemapAgXFull(vec3 x) {
 | 
				
			||||||
 | 
					    // x *= 2.0 * (1.0/0.8); // Brightness scale to match Blender's default
 | 
				
			||||||
 | 
					    x = clamp(x, 0.0, 65504.0);
 | 
				
			||||||
 | 
					    x = log2(x + 1.0);
 | 
				
			||||||
 | 
					    x = agxDefaultContrastApprox(clamp(x * 0.5 - 10.5, -12.0, 12.0));    
 | 
				
			||||||
 | 
					    x = mix(x, agxLook(x, 0.5), 0.5);
 | 
				
			||||||
 | 
					    x = clamp(x, 0.0, 1.0);
 | 
				
			||||||
 | 
					    return pow(x, vec3(1.0/2.2)); 
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Interleaved Gradient Noise (Pseudo-random, AKA Blue Noise style)
 | 
				
			||||||
 | 
					// Based on http://momentsingraphics.de/BlueNoise.html
 | 
				
			||||||
 | 
					float ditherBlueNoiseStyle(vec2 p) {
 | 
				
			||||||
 | 
					    return fract(sin(dot(p.xy, vec2(12.9898, 78.233))) * 43758.5453123);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// White Noise Dithering
 | 
				
			||||||
 | 
					float ditherWhiteNoise(vec2 p) {
 | 
				
			||||||
 | 
					    return fract(sin(dot(p, vec2(12.9898, 4.1414))) * 43758.5453);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Ordered Dithering (4x4 Bayer Matrix)
 | 
				
			||||||
 | 
					float ditherOrderedBayer4x4(ivec2 p) {
 | 
				
			||||||
 | 
					    const float bayer[16] = float[16](
 | 
				
			||||||
 | 
					         0.0,  8.0,  2.0, 10.0,
 | 
				
			||||||
 | 
					        12.0,  4.0, 14.0,  6.0,
 | 
				
			||||||
 | 
					         3.0, 11.0,  1.0,  9.0,
 | 
				
			||||||
 | 
					        15.0,  7.0, 13.0,  5.0
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    int index = (p.x % 4) * 4 + (p.y % 4);
 | 
				
			||||||
 | 
					    return bayer[index] / 16.0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Ordered Dithering (8x8 Bayer Matrix)
 | 
				
			||||||
 | 
					float ditherOrderedBayer8x8(ivec2 p) {
 | 
				
			||||||
 | 
					    const float bayer8x8[64] = float[64](
 | 
				
			||||||
 | 
					         0.0, 32.0,  8.0, 40.0,  2.0, 34.0, 10.0, 42.0,
 | 
				
			||||||
 | 
					        48.0, 16.0, 56.0, 24.0, 50.0, 18.0, 58.0, 26.0,
 | 
				
			||||||
 | 
					        12.0, 44.0,  4.0, 36.0, 14.0, 46.0,  6.0, 38.0,
 | 
				
			||||||
 | 
					        60.0, 28.0, 52.0, 20.0, 62.0, 30.0, 54.0, 22.0,
 | 
				
			||||||
 | 
					         3.0, 35.0, 11.0, 43.0,  1.0, 33.0,  9.0, 41.0,
 | 
				
			||||||
 | 
					        51.0, 19.0, 59.0, 27.0, 49.0, 17.0, 57.0, 25.0,
 | 
				
			||||||
 | 
					        15.0, 47.0,  7.0, 39.0, 13.0, 45.0,  5.0, 37.0,
 | 
				
			||||||
 | 
					        63.0, 31.0, 55.0, 23.0, 61.0, 29.0, 53.0, 21.0
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    int index = (p.x % 8) * 8 + (p.y % 8);
 | 
				
			||||||
 | 
					    return bayer8x8[index] / 64.0;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//vec3 applyDither(vec3 color, vec2 screenCoord) {
 | 
				
			||||||
 | 
					//    float quantizationLevels = 255.0;
 | 
				
			||||||
 | 
					//    float noise = randomDither(screenCoord);
 | 
				
			||||||
 | 
					//    float noiseOffset = (noise - 0.5) / quantizationLevels;
 | 
				
			||||||
 | 
					//    vec3 ditheredColor = color + noiseOffset;
 | 
				
			||||||
 | 
					//    return clamp(ditheredColor, 0.0, 1.0);
 | 
				
			||||||
 | 
					//}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,6 +33,7 @@ uniform layout(r32ui) uimage3D voxelsLight;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#ifdef _ShadowMap
 | 
					#ifdef _ShadowMap
 | 
				
			||||||
uniform sampler2DShadow shadowMap;
 | 
					uniform sampler2DShadow shadowMap;
 | 
				
			||||||
 | 
					uniform sampler2D shadowMapTransparent;
 | 
				
			||||||
uniform sampler2DShadow shadowMapSpot;
 | 
					uniform sampler2DShadow shadowMapSpot;
 | 
				
			||||||
#ifdef _ShadowMapAtlas
 | 
					#ifdef _ShadowMapAtlas
 | 
				
			||||||
uniform sampler2DShadow shadowMapPoint;
 | 
					uniform sampler2DShadow shadowMapPoint;
 | 
				
			||||||
@ -86,53 +87,51 @@ float lpToDepth(vec3 lp, const vec2 lightProj) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
void main() {
 | 
					void main() {
 | 
				
			||||||
	int res = voxelgiResolution.x;
 | 
						int res = voxelgiResolution.x;
 | 
				
			||||||
 | 
						for (int i = 0; i < 6; i++) {
 | 
				
			||||||
 | 
							ivec3 dst = ivec3(gl_GlobalInvocationID.xyz);
 | 
				
			||||||
 | 
							vec3 P = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution;
 | 
				
			||||||
 | 
							P = P * 2.0 - 1.0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ivec3 dst = ivec3(gl_GlobalInvocationID.xyz);
 | 
							float visibility;
 | 
				
			||||||
	dst.y += clipmapLevel * res;
 | 
							vec3 lp = lightPos - P;
 | 
				
			||||||
 | 
							vec3 l;
 | 
				
			||||||
	vec3 P = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution;
 | 
							if (lightType == 0) { l = lightDir; visibility = 1.0; }
 | 
				
			||||||
	P = P * 2.0 - 1.0;
 | 
							else { l = normalize(lp); visibility = attenuate(distance(P, lightPos)); }
 | 
				
			||||||
	P *= clipmaps[int(clipmapLevel * 10)];
 | 
					 | 
				
			||||||
	P *= voxelgiResolution;
 | 
					 | 
				
			||||||
	P += vec3(clipmaps[int(clipmapLevel * 10 + 4)], clipmaps[int(clipmapLevel * 10 + 5)], clipmaps[int(clipmapLevel * 10 + 6)]);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	vec3 visibility;
 | 
					 | 
				
			||||||
	vec3 lp = lightPos - P;
 | 
					 | 
				
			||||||
	vec3 l;
 | 
					 | 
				
			||||||
	if (lightType == 0) { l = lightDir; visibility = vec3(1.0); }
 | 
					 | 
				
			||||||
	else { l = normalize(lp); visibility = vec3(attenuate(distance(P, lightPos))); }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
#ifdef _ShadowMap
 | 
					#ifdef _ShadowMap
 | 
				
			||||||
	if (lightShadow == 1) {
 | 
							if (lightShadow == 1) {
 | 
				
			||||||
		vec4 lightPosition = LVP * vec4(P, 1.0);
 | 
								vec4 lightPosition = LVP * vec4(P, 1.0);
 | 
				
			||||||
		vec3 lPos = lightPosition.xyz / lightPosition.w;
 | 
								vec3 lPos = lightPosition.xyz / lightPosition.w;
 | 
				
			||||||
		visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).rrr;
 | 
								visibility = texture(shadowMap, vec3(lPos.xy, lPos.z - shadowsBias)).r;
 | 
				
			||||||
	}
 | 
							}
 | 
				
			||||||
	else if (lightShadow == 2) {
 | 
							else if (lightShadow == 2) {
 | 
				
			||||||
		vec4 lightPosition = LVP * vec4(P, 1.0);
 | 
								vec4 lightPosition = LVP * vec4(P, 1.0);
 | 
				
			||||||
		vec3 lPos = lightPosition.xyz / lightPosition.w;
 | 
								vec3 lPos = lightPosition.xyz / lightPosition.w;
 | 
				
			||||||
		visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
 | 
								visibility *= texture(shadowMapSpot, vec3(lPos.xy, lPos.z - shadowsBias)).r;
 | 
				
			||||||
	}
 | 
							}
 | 
				
			||||||
	else if (lightShadow == 3) {
 | 
							else if (lightShadow == 3) {
 | 
				
			||||||
		#ifdef _ShadowMapAtlas
 | 
								#ifdef _ShadowMapAtlas
 | 
				
			||||||
		int faceIndex = 0;
 | 
								int faceIndex = 0;
 | 
				
			||||||
		const int lightIndex = index * 6;
 | 
								const int lightIndex = index * 6;
 | 
				
			||||||
		const vec2 uv = sampleCube(-l, faceIndex);
 | 
								const vec2 uv = sampleCube(-l, faceIndex);
 | 
				
			||||||
		vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
 | 
								vec4 pointLightTile = pointLightDataArray[lightIndex + faceIndex]; // x: tile X offset, y: tile Y offset, z: tile size relative to atlas
 | 
				
			||||||
		vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
 | 
								vec2 uvtiled = pointLightTile.z * uv + pointLightTile.xy;
 | 
				
			||||||
		#ifdef _FlipY
 | 
								#ifdef _FlipY
 | 
				
			||||||
		uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
 | 
								uvtiled.y = 1.0 - uvtiled.y; // invert Y coordinates for direct3d coordinate system
 | 
				
			||||||
		#endif
 | 
								#endif
 | 
				
			||||||
		visibility *= texture(shadowMapPoint, vec3(uvtiled, lpToDepth(lp, lightProj) - shadowsBias)).r;
 | 
								visibility *= texture(shadowMapPoint, vec3(uvtiled, lpToDepth(lp, lightProj) - shadowsBias)).r;
 | 
				
			||||||
		#else
 | 
								#else
 | 
				
			||||||
		visibility *= texture(shadowMapPoint, vec4(-l, lpToDepth(lp, lightProj) - shadowsBias)).r;
 | 
								visibility *= texture(shadowMapPoint, vec4(-l, lpToDepth(lp, lightProj) - shadowsBias)).r;
 | 
				
			||||||
		#endif
 | 
								#endif
 | 
				
			||||||
	}
 | 
							}
 | 
				
			||||||
#endif
 | 
						#endif
 | 
				
			||||||
 | 
							vec3 uvw_light = (P - vec3(clipmaps[int(clipmapLevel * 10 + 4)], clipmaps[int(clipmapLevel * 10 + 5)], clipmaps[int(clipmapLevel * 10 + 6)])) / (float(clipmaps[int(clipmapLevel * 10)]) * voxelgiResolution);
 | 
				
			||||||
 | 
							uvw_light = (uvw_light * 0.5 + 0.5);
 | 
				
			||||||
 | 
							if (any(notEqual(uvw_light, clamp(uvw_light, 0.0, 1.0)))) return;
 | 
				
			||||||
 | 
							vec3 writecoords_light = floor(uvw_light * voxelgiResolution);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vec3 light = visibility * lightColor;
 | 
							imageAtomicMax(voxelsLight, ivec3(writecoords_light), uint(visibility * lightColor.r * 255));
 | 
				
			||||||
 | 
							imageAtomicMax(voxelsLight, ivec3(writecoords_light) + ivec3(0, 0, voxelgiResolution.x), uint(visibility * lightColor.g * 255));
 | 
				
			||||||
	imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, 0), uint(light.r * 255));
 | 
							imageAtomicMax(voxelsLight, ivec3(writecoords_light) + ivec3(0, 0, voxelgiResolution.x * 2), uint(visibility * lightColor.b * 255));
 | 
				
			||||||
	imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x), uint(light.g * 255));
 | 
						}
 | 
				
			||||||
	imageAtomicAdd(voxelsLight, dst + ivec3(0, 0, voxelgiResolution.x * 2), uint(light.b * 255));
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
 | 
				
			|||||||
uniform sampler3D voxels;
 | 
					uniform sampler3D voxels;
 | 
				
			||||||
uniform sampler2D gbufferD;
 | 
					uniform sampler2D gbufferD;
 | 
				
			||||||
uniform sampler2D gbuffer0;
 | 
					uniform sampler2D gbuffer0;
 | 
				
			||||||
uniform layout(r8) image2D voxels_ao;
 | 
					uniform layout(r16) image2D voxels_ao;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uniform float clipmaps[voxelgiClipmapCount * 10];
 | 
					uniform float clipmaps[voxelgiClipmapCount * 10];
 | 
				
			||||||
uniform mat4 InvVP;
 | 
					uniform mat4 InvVP;
 | 
				
			||||||
 | 
				
			|||||||
@ -33,7 +33,7 @@ layout (local_size_x = 8, local_size_y = 8, local_size_z = 1) in;
 | 
				
			|||||||
uniform sampler3D voxels;
 | 
					uniform sampler3D voxels;
 | 
				
			||||||
uniform sampler2D gbufferD;
 | 
					uniform sampler2D gbufferD;
 | 
				
			||||||
uniform sampler2D gbuffer0;
 | 
					uniform sampler2D gbuffer0;
 | 
				
			||||||
uniform layout(rgba8) image2D voxels_diffuse;
 | 
					uniform layout(rgba16) image2D voxels_diffuse;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uniform float clipmaps[voxelgiClipmapCount * 10];
 | 
					uniform float clipmaps[voxelgiClipmapCount * 10];
 | 
				
			||||||
uniform mat4 InvVP;
 | 
					uniform mat4 InvVP;
 | 
				
			||||||
@ -46,7 +46,7 @@ void main() {
 | 
				
			|||||||
	const vec2 pixel = gl_GlobalInvocationID.xy;
 | 
						const vec2 pixel = gl_GlobalInvocationID.xy;
 | 
				
			||||||
	vec2 uv = (pixel + 0.5) / postprocess_resolution;
 | 
						vec2 uv = (pixel + 0.5) / postprocess_resolution;
 | 
				
			||||||
	#ifdef _InvY
 | 
						#ifdef _InvY
 | 
				
			||||||
	uv.y = 1.0 - uv.y
 | 
						uv.y = 1.0 - uv.y;
 | 
				
			||||||
	#endif
 | 
						#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
 | 
						float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
 | 
				
			||||||
 | 
				
			|||||||
@ -34,7 +34,7 @@ uniform sampler2D gbufferD;
 | 
				
			|||||||
uniform sampler2D gbuffer0;
 | 
					uniform sampler2D gbuffer0;
 | 
				
			||||||
uniform sampler3D voxels;
 | 
					uniform sampler3D voxels;
 | 
				
			||||||
uniform sampler3D voxelsSDF;
 | 
					uniform sampler3D voxelsSDF;
 | 
				
			||||||
uniform layout(rgba8) image2D voxels_specular;
 | 
					uniform layout(rgba16) image2D voxels_specular;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uniform float clipmaps[voxelgiClipmapCount * 10];
 | 
					uniform float clipmaps[voxelgiClipmapCount * 10];
 | 
				
			||||||
uniform mat4 InvVP;
 | 
					uniform mat4 InvVP;
 | 
				
			||||||
@ -48,7 +48,7 @@ void main() {
 | 
				
			|||||||
	const vec2 pixel = gl_GlobalInvocationID.xy;
 | 
						const vec2 pixel = gl_GlobalInvocationID.xy;
 | 
				
			||||||
	vec2 uv = (pixel + 0.5) / postprocess_resolution;
 | 
						vec2 uv = (pixel + 0.5) / postprocess_resolution;
 | 
				
			||||||
	#ifdef _InvY
 | 
						#ifdef _InvY
 | 
				
			||||||
	uv.y = 1.0 - uv.y
 | 
						uv.y = 1.0 - uv.y;
 | 
				
			||||||
	#endif
 | 
						#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
 | 
						float depth = textureLod(gbufferD, uv, 0.0).r * 2.0 - 1.0;
 | 
				
			||||||
@ -71,7 +71,7 @@ void main() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	vec2 velocity = -textureLod(sveloc, uv, 0.0).rg;
 | 
						vec2 velocity = -textureLod(sveloc, uv, 0.0).rg;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z, clipmaps, pixel, velocity).rgb;
 | 
						vec3 color = traceSpecular(P, n, voxels, voxelsSDF, normalize(eye - P), g0.z * g0.z, clipmaps, pixel, velocity).rgb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	imageStore(voxels_specular, ivec2(pixel), vec4(color, 1.0));
 | 
						imageStore(voxels_specular, ivec2(pixel), vec4(color, 1.0));
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -23,8 +23,8 @@ THE SOFTWARE.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#include "compiled.inc"
 | 
					#include "compiled.inc"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uniform layout(r16) image3D input_sdf;
 | 
					uniform layout(r8) image3D input_sdf;
 | 
				
			||||||
uniform layout(r16) image3D output_sdf;
 | 
					uniform layout(r8) image3D output_sdf;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
uniform float jump_size;
 | 
					uniform float jump_size;
 | 
				
			||||||
uniform int clipmapLevel;
 | 
					uniform int clipmapLevel;
 | 
				
			||||||
 | 
				
			|||||||
@ -46,15 +46,15 @@ uniform layout(r32ui) uimage3D voxels;
 | 
				
			|||||||
uniform layout(r32ui) uimage3D voxelsLight;
 | 
					uniform layout(r32ui) uimage3D voxelsLight;
 | 
				
			||||||
uniform layout(rgba8) image3D voxelsB;
 | 
					uniform layout(rgba8) image3D voxelsB;
 | 
				
			||||||
uniform layout(rgba8) image3D voxelsOut;
 | 
					uniform layout(rgba8) image3D voxelsOut;
 | 
				
			||||||
uniform layout(r16) image3D SDF;
 | 
					uniform layout(r8) image3D SDF;
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
#ifdef _VoxelAOvar
 | 
					#ifdef _VoxelAOvar
 | 
				
			||||||
#ifdef _VoxelShadow
 | 
					#ifdef _VoxelShadow
 | 
				
			||||||
uniform layout(r16) image3D SDF;
 | 
					uniform layout(r8) image3D SDF;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
uniform layout(r32ui) uimage3D voxels;
 | 
					uniform layout(r32ui) uimage3D voxels;
 | 
				
			||||||
uniform layout(r16) image3D voxelsB;
 | 
					uniform layout(r8) image3D voxelsB;
 | 
				
			||||||
uniform layout(r16) image3D voxelsOut;
 | 
					uniform layout(r8) image3D voxelsOut;
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -80,7 +80,6 @@ void main() {
 | 
				
			|||||||
	light.r = float(imageLoad(voxelsLight, src)) / 255;
 | 
						light.r = float(imageLoad(voxelsLight, src)) / 255;
 | 
				
			||||||
	light.g = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x))) / 255;
 | 
						light.g = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x))) / 255;
 | 
				
			||||||
	light.b = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
 | 
						light.b = float(imageLoad(voxelsLight, src + ivec3(0, 0, voxelgiResolution.x * 2))) / 255;
 | 
				
			||||||
	light /= 3;
 | 
					 | 
				
			||||||
	#endif
 | 
						#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	for (int i = 0; i < 6 + DIFFUSE_CONE_COUNT; i++)
 | 
						for (int i = 0; i < 6 + DIFFUSE_CONE_COUNT; i++)
 | 
				
			||||||
@ -125,7 +124,7 @@ void main() {
 | 
				
			|||||||
			envl.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 10))) / 255;
 | 
								envl.g = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 10))) / 255;
 | 
				
			||||||
			envl.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255;
 | 
								envl.b = float(imageLoad(voxels, src + ivec3(0, 0, voxelgiResolution.x * 11))) / 255;
 | 
				
			||||||
			envl /= 3;
 | 
								envl /= 3;
 | 
				
			||||||
			envl *= 100;
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			//clipmap to world
 | 
								//clipmap to world
 | 
				
			||||||
			vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
 | 
								vec3 wposition = (gl_GlobalInvocationID.xyz + 0.5) / voxelgiResolution.x;
 | 
				
			||||||
@ -137,7 +136,7 @@ void main() {
 | 
				
			|||||||
			radiance = basecol;
 | 
								radiance = basecol;
 | 
				
			||||||
			vec4 trace = traceDiffuse(wposition, wnormal, voxelsSampler, clipmaps);
 | 
								vec4 trace = traceDiffuse(wposition, wnormal, voxelsSampler, clipmaps);
 | 
				
			||||||
			vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a);
 | 
								vec3 indirect = trace.rgb + envl.rgb * (1.0 - trace.a);
 | 
				
			||||||
			radiance.rgb *= light + indirect;
 | 
								radiance.rgb *= light / PI + indirect;
 | 
				
			||||||
			radiance.rgb += emission.rgb;
 | 
								radiance.rgb += emission.rgb;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			#else
 | 
								#else
 | 
				
			||||||
 | 
				
			|||||||
@ -75,16 +75,17 @@ vec4 binarySearch(vec3 dir) {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
vec4 rayCast(vec3 dir) {
 | 
					vec4 rayCast(vec3 dir) {
 | 
				
			||||||
	#ifdef _CPostprocess
 | 
					    float ddepth;
 | 
				
			||||||
		dir *= PPComp9.x;
 | 
					    dir *= ss_refractionRayStep;
 | 
				
			||||||
	#else
 | 
					    for (int i = 0; i < maxSteps; i++) {
 | 
				
			||||||
		dir *= ssrRayStep;
 | 
					        hitCoord += dir;
 | 
				
			||||||
	#endif
 | 
					        ddepth = getDeltaDepth(hitCoord);
 | 
				
			||||||
	for (int i = 0; i < maxSteps; i++) {
 | 
					        if (ddepth > 0.0)
 | 
				
			||||||
		hitCoord += dir;
 | 
					            return binarySearch(dir);
 | 
				
			||||||
		if (getDeltaDepth(hitCoord) > 0.0) return binarySearch(dir);
 | 
					    }
 | 
				
			||||||
	}
 | 
					    // No hit — fallback to projecting the ray to UV space
 | 
				
			||||||
	return vec4(0.0);
 | 
					    vec2 fallbackUV = getProjectedCoord(hitCoord);
 | 
				
			||||||
 | 
					    return vec4(fallbackUV, 0.0, 0.5); // We set .w lower to indicate fallback
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
#endif //SSR
 | 
					#endif //SSR
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -66,12 +66,32 @@ class Quat {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public inline function fromAxisAngle(axis: Vec4, angle: FastFloat): Quat {
 | 
						public inline function fromAxisAngle(axis: Vec4, angle: FastFloat): Quat {
 | 
				
			||||||
		var s: FastFloat = Math.sin(angle * 0.5);
 | 
							//var s: FastFloat = Math.sin(angle * 0.5);
 | 
				
			||||||
		x = axis.x * s;
 | 
							//x = axis.x * s;
 | 
				
			||||||
		y = axis.y * s;
 | 
							//y = axis.y * s;
 | 
				
			||||||
		z = axis.z * s;
 | 
							//z = axis.z * s;
 | 
				
			||||||
		w = Math.cos(angle * 0.5);
 | 
							//w = Math.cos(angle * 0.5);
 | 
				
			||||||
		return normalize();
 | 
							//return normalize();
 | 
				
			||||||
 | 
							// Normalize the axis vector first
 | 
				
			||||||
 | 
							var axisLen = Math.sqrt(axis.x * axis.x + axis.y * axis.y + axis.z * axis.z);
 | 
				
			||||||
 | 
							if (axisLen > 0.00001) {
 | 
				
			||||||
 | 
								var aL = 1.0 / axisLen;
 | 
				
			||||||
 | 
								var nX = axis.x * aL;
 | 
				
			||||||
 | 
								var nY = axis.y * aL;
 | 
				
			||||||
 | 
								var nZ = axis.z * aL;
 | 
				
			||||||
 | 
								var halfAngle = angle * 0.5;
 | 
				
			||||||
 | 
								var s: FastFloat = Math.sin(halfAngle);
 | 
				
			||||||
 | 
								x = nX * s;
 | 
				
			||||||
 | 
								y = nY * s;
 | 
				
			||||||
 | 
								z = nZ * s;
 | 
				
			||||||
 | 
								w = Math.cos(halfAngle);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								x = 0.0;
 | 
				
			||||||
 | 
								y = 0.0;
 | 
				
			||||||
 | 
								z = 0.0;
 | 
				
			||||||
 | 
								w = 1.0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return this;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public inline function toAxisAngle(axis: Vec4): FastFloat {
 | 
						public inline function toAxisAngle(axis: Vec4): FastFloat {
 | 
				
			||||||
@ -379,17 +399,33 @@ class Quat {
 | 
				
			|||||||
		@return	This quaternion.
 | 
							@return	This quaternion.
 | 
				
			||||||
	**/
 | 
						**/
 | 
				
			||||||
	public inline function fromEulerOrdered(e: Vec4, order: String): Quat {
 | 
						public inline function fromEulerOrdered(e: Vec4, order: String): Quat {
 | 
				
			||||||
		var c1 = Math.cos(e.x / 2);
 | 
							
 | 
				
			||||||
		var c2 = Math.cos(e.y / 2);
 | 
							var mappedAngles = new Vec4();
 | 
				
			||||||
		var c3 = Math.cos(e.z / 2);
 | 
							switch (order) {
 | 
				
			||||||
		var s1 = Math.sin(e.x / 2);
 | 
								case "XYZ":
 | 
				
			||||||
		var s2 = Math.sin(e.y / 2);
 | 
									mappedAngles.set(e.x, e.y, e.z);
 | 
				
			||||||
		var s3 = Math.sin(e.z / 2);
 | 
								case "XZY":
 | 
				
			||||||
 | 
									mappedAngles.set(e.x, e.z, e.y);
 | 
				
			||||||
 | 
								case "YXZ": 
 | 
				
			||||||
 | 
									mappedAngles.set(e.y, e.x, e.z);
 | 
				
			||||||
 | 
								case "YZX": 
 | 
				
			||||||
 | 
									mappedAngles.set(e.y, e.z, e.x);
 | 
				
			||||||
 | 
								case "ZXY": 
 | 
				
			||||||
 | 
									mappedAngles.set(e.z, e.x, e.y);
 | 
				
			||||||
 | 
								case "ZYX": 
 | 
				
			||||||
 | 
									mappedAngles.set(e.z, e.y, e.x);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							var c1 = Math.cos(mappedAngles.x / 2);
 | 
				
			||||||
 | 
							var c2 = Math.cos(mappedAngles.y / 2);
 | 
				
			||||||
 | 
							var c3 = Math.cos(mappedAngles.z / 2);
 | 
				
			||||||
 | 
							var s1 = Math.sin(mappedAngles.x / 2);
 | 
				
			||||||
 | 
							var s2 = Math.sin(mappedAngles.y / 2);
 | 
				
			||||||
 | 
							var s3 = Math.sin(mappedAngles.z / 2);
 | 
				
			||||||
		var qx = new Quat(s1, 0, 0, c1);
 | 
							var qx = new Quat(s1, 0, 0, c1);
 | 
				
			||||||
		var qy = new Quat(0, s2, 0, c2);
 | 
							var qy = new Quat(0, s2, 0, c2);
 | 
				
			||||||
		var qz = new Quat(0, 0, s3, c3);
 | 
							var qz = new Quat(0, 0, s3, c3);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Original multiplication sequence (implements reverse of 'order')
 | 
				
			||||||
		if (order.charAt(2) == 'X')
 | 
							if (order.charAt(2) == 'X')
 | 
				
			||||||
			this.setFrom(qx);
 | 
								this.setFrom(qx);
 | 
				
			||||||
		else if (order.charAt(2) == 'Y')
 | 
							else if (order.charAt(2) == 'Y')
 | 
				
			||||||
@ -409,6 +445,12 @@ class Quat {
 | 
				
			|||||||
		else
 | 
							else
 | 
				
			||||||
			this.mult(qz);
 | 
								this.mult(qz);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// TO DO quick fix somethings wrong..
 | 
				
			||||||
 | 
							this.x = -this.x;
 | 
				
			||||||
 | 
							this.y = -this.y;
 | 
				
			||||||
 | 
							this.z = -this.z;
 | 
				
			||||||
 | 
							this.w = -this.w;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		return this;
 | 
							return this;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -411,12 +411,23 @@ class ActionSampler {
 | 
				
			|||||||
	 */
 | 
						 */
 | 
				
			||||||
	public inline function setBoneAction(actionData: Array<TObj>) {
 | 
						public inline function setBoneAction(actionData: Array<TObj>) {
 | 
				
			||||||
		this.actionData = actionData;
 | 
							this.actionData = actionData;
 | 
				
			||||||
		this.totalFrames = actionData[0].anim.tracks[0].frames.length;
 | 
							if (actionData != null && actionData.length > 0 && actionData[0] != null && actionData[0].anim != null) {
 | 
				
			||||||
		if(actionData[0].anim.root_motion_pos) this.rootMotionPos = true;
 | 
								if (actionData[0].anim.tracks != null && actionData[0].anim.tracks.length > 0) {
 | 
				
			||||||
		if(actionData[0].anim.root_motion_rot) this.rootMotionRot = true;
 | 
									this.totalFrames = actionData[0].anim.tracks[0].frames.length;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								else {
 | 
				
			||||||
 | 
									this.totalFrames = 0;
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if(actionData[0].anim.root_motion_pos) this.rootMotionPos = true;
 | 
				
			||||||
 | 
								if(actionData[0].anim.root_motion_rot) this.rootMotionRot = true;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							else {
 | 
				
			||||||
 | 
								this.totalFrames = 0;
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
		actionDataInit = true;
 | 
							actionDataInit = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
	 * Cache raw object data for object animation.
 | 
						 * Cache raw object data for object animation.
 | 
				
			||||||
	 * @param actionData Raw object data.
 | 
						 * @param actionData Raw object data.
 | 
				
			||||||
 | 
				
			|||||||
@ -51,6 +51,7 @@ class ParticleSystem {
 | 
				
			|||||||
		seed = pref.seed;
 | 
							seed = pref.seed;
 | 
				
			||||||
		particles = [];
 | 
							particles = [];
 | 
				
			||||||
		ready = false;
 | 
							ready = false;
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		Data.getParticle(sceneName, pref.particle, function(b: ParticleData) {
 | 
							Data.getParticle(sceneName, pref.particle, function(b: ParticleData) {
 | 
				
			||||||
			data = b;
 | 
								data = b;
 | 
				
			||||||
			r = data.raw;
 | 
								r = data.raw;
 | 
				
			||||||
@ -70,7 +71,13 @@ class ParticleSystem {
 | 
				
			|||||||
			lifetime = r.lifetime / frameRate;
 | 
								lifetime = r.lifetime / frameRate;
 | 
				
			||||||
			animtime = (r.frame_end - r.frame_start) / frameRate;
 | 
								animtime = (r.frame_end - r.frame_start) / frameRate;
 | 
				
			||||||
			spawnRate = ((r.frame_end - r.frame_start) / r.count) / frameRate;
 | 
								spawnRate = ((r.frame_end - r.frame_start) / r.count) / frameRate;
 | 
				
			||||||
			for (i in 0...r.count) particles.push(new Particle(i));
 | 
					
 | 
				
			||||||
 | 
								for (i in 0...r.count) {
 | 
				
			||||||
 | 
									var particle = new Particle(i);
 | 
				
			||||||
 | 
									particle.sr = 1 - Math.random() * r.size_random;
 | 
				
			||||||
 | 
									particles.push(particle);
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			ready = true;
 | 
								ready = true;
 | 
				
			||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -108,7 +115,7 @@ class ParticleSystem {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// Animate
 | 
							// Animate
 | 
				
			||||||
		time += Time.realDelta * speed;
 | 
							time += Time.delta * speed;
 | 
				
			||||||
		lap = Std.int(time / animtime);
 | 
							lap = Std.int(time / animtime);
 | 
				
			||||||
		lapTime = time - lap * animtime;
 | 
							lapTime = time - lap * animtime;
 | 
				
			||||||
		count = Std.int(lapTime / spawnRate);
 | 
							count = Std.int(lapTime / spawnRate);
 | 
				
			||||||
@ -143,7 +150,7 @@ class ParticleSystem {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function setupGeomGpu(object: MeshObject, owner: MeshObject) {
 | 
						function setupGeomGpu(object: MeshObject, owner: MeshObject) {
 | 
				
			||||||
		var instancedData = new Float32Array(particles.length * 3);
 | 
							var instancedData = new Float32Array(particles.length * 6);
 | 
				
			||||||
		var i = 0;
 | 
							var i = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var normFactor = 1 / 32767; // pa.values are not normalized
 | 
							var normFactor = 1 / 32767; // pa.values are not normalized
 | 
				
			||||||
@ -162,6 +169,10 @@ class ParticleSystem {
 | 
				
			|||||||
					instancedData.set(i, pa.values[j * pa.size    ] * normFactor * scaleFactor.x); i++;
 | 
										instancedData.set(i, pa.values[j * pa.size    ] * normFactor * scaleFactor.x); i++;
 | 
				
			||||||
					instancedData.set(i, pa.values[j * pa.size + 1] * normFactor * scaleFactor.y); i++;
 | 
										instancedData.set(i, pa.values[j * pa.size + 1] * normFactor * scaleFactor.y); i++;
 | 
				
			||||||
					instancedData.set(i, pa.values[j * pa.size + 2] * normFactor * scaleFactor.z); i++;
 | 
										instancedData.set(i, pa.values[j * pa.size + 2] * normFactor * scaleFactor.z); i++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										instancedData.set(i, p.sr); i++;
 | 
				
			||||||
 | 
										instancedData.set(i, p.sr); i++;
 | 
				
			||||||
 | 
										instancedData.set(i, p.sr); i++;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case 1: // Face
 | 
								case 1: // Face
 | 
				
			||||||
@ -185,6 +196,10 @@ class ParticleSystem {
 | 
				
			|||||||
					instancedData.set(i, pos.x * normFactor * scaleFactor.x); i++;
 | 
										instancedData.set(i, pos.x * normFactor * scaleFactor.x); i++;
 | 
				
			||||||
					instancedData.set(i, pos.y * normFactor * scaleFactor.y); i++;
 | 
										instancedData.set(i, pos.y * normFactor * scaleFactor.y); i++;
 | 
				
			||||||
					instancedData.set(i, pos.z * normFactor * scaleFactor.z); i++;
 | 
										instancedData.set(i, pos.z * normFactor * scaleFactor.z); i++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										instancedData.set(i, p.sr); i++;
 | 
				
			||||||
 | 
										instancedData.set(i, p.sr); i++;
 | 
				
			||||||
 | 
										instancedData.set(i, p.sr); i++;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case 2: // Volume
 | 
								case 2: // Volume
 | 
				
			||||||
@ -195,9 +210,13 @@ class ParticleSystem {
 | 
				
			|||||||
					instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.x); i++;
 | 
										instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.x); i++;
 | 
				
			||||||
					instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.y); i++;
 | 
										instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.y); i++;
 | 
				
			||||||
					instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.z); i++;
 | 
										instancedData.set(i, (Math.random() * 2.0 - 1.0) * scaleFactorVolume.z); i++;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										instancedData.set(i, p.sr); i++;
 | 
				
			||||||
 | 
										instancedData.set(i, p.sr); i++;
 | 
				
			||||||
 | 
										instancedData.set(i, p.sr); i++;
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		object.data.geom.setupInstanced(instancedData, 1, Usage.StaticUsage);
 | 
							object.data.geom.setupInstanced(instancedData, 3, Usage.StaticUsage);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function fhash(n: Int): Float {
 | 
						function fhash(n: Int): Float {
 | 
				
			||||||
@ -236,9 +255,10 @@ class ParticleSystem {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
class Particle {
 | 
					class Particle {
 | 
				
			||||||
	public var i: Int;
 | 
						public var i: Int;
 | 
				
			||||||
	public var x = 0.0;
 | 
						public var px = 0.0;
 | 
				
			||||||
	public var y = 0.0;
 | 
						public var py = 0.0;
 | 
				
			||||||
	public var z = 0.0;
 | 
						public var pz = 0.0;
 | 
				
			||||||
 | 
						public var sr = 1.0; // Size random
 | 
				
			||||||
	public var cameraDistance: Float;
 | 
						public var cameraDistance: Float;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(i: Int) {
 | 
						public function new(i: Int) {
 | 
				
			||||||
 | 
				
			|||||||
@ -160,6 +160,7 @@ class LnxPack {
 | 
				
			|||||||
			case "anim": TAnimation;
 | 
								case "anim": TAnimation;
 | 
				
			||||||
			case "tracks": TTrack;
 | 
								case "tracks": TTrack;
 | 
				
			||||||
			case "morph_target": TMorphTarget;
 | 
								case "morph_target": TMorphTarget;
 | 
				
			||||||
 | 
								case "vertex_groups": TVertex_groups;
 | 
				
			||||||
			case _: TSceneFormat;
 | 
								case _: TSceneFormat;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -2,9 +2,11 @@ package leenkx.logicnode;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import iron.object.Object;
 | 
					import iron.object.Object;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if lnx_physics
 | 
					#if lnx_bullet
 | 
				
			||||||
import leenkx.trait.physics.PhysicsConstraint;
 | 
					import leenkx.trait.physics.PhysicsConstraint;
 | 
				
			||||||
import leenkx.trait.physics.bullet.PhysicsConstraint.ConstraintType;
 | 
					import leenkx.trait.physics.bullet.PhysicsConstraint.ConstraintType;
 | 
				
			||||||
 | 
					#elseif lnx_oimo
 | 
				
			||||||
 | 
					// TODO
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AddPhysicsConstraintNode extends LogicNode {
 | 
					class AddPhysicsConstraintNode extends LogicNode {
 | 
				
			||||||
@ -25,7 +27,7 @@ class AddPhysicsConstraintNode extends LogicNode {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if (pivotObject == null || rb1 == null || rb2 == null) return;
 | 
							if (pivotObject == null || rb1 == null || rb2 == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if lnx_physics
 | 
					#if lnx_bullet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var disableCollisions: Bool = inputs[4].get();
 | 
							var disableCollisions: Bool = inputs[4].get();
 | 
				
			||||||
		var breakable: Bool = inputs[5].get();
 | 
							var breakable: Bool = inputs[5].get();
 | 
				
			||||||
@ -108,6 +110,8 @@ class AddPhysicsConstraintNode extends LogicNode {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			pivotObject.addTrait(con);
 | 
								pivotObject.addTrait(con);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					#elseif lnx_oimo
 | 
				
			||||||
 | 
					// TODO
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
		runOutput(0);
 | 
							runOutput(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -4,7 +4,7 @@ import iron.object.Object;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if lnx_physics
 | 
					#if lnx_physics
 | 
				
			||||||
import leenkx.trait.physics.RigidBody;
 | 
					import leenkx.trait.physics.RigidBody;
 | 
				
			||||||
import leenkx.trait.physics.bullet.RigidBody.Shape;
 | 
					import leenkx.trait.physics.RigidBody.Shape;
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -21,7 +21,7 @@ class ApplyForceNode extends LogicNode {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if lnx_physics
 | 
					#if lnx_physics
 | 
				
			||||||
		var rb: RigidBody = object.getTrait(RigidBody);
 | 
							var rb: RigidBody = object.getTrait(RigidBody);
 | 
				
			||||||
 | 
							if (rb == null) return;
 | 
				
			||||||
		!local ? rb.applyForce(force) : rb.applyForce(object.transform.worldVecToOrientation(force));
 | 
							!local ? rb.applyForce(force) : rb.applyForce(object.transform.worldVecToOrientation(force));
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										26
									
								
								leenkx/Sources/leenkx/logicnode/ArrayIndexListNode.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,26 @@
 | 
				
			|||||||
 | 
					package leenkx.logicnode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ArrayIndexListNode extends LogicNode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public function new(tree: LogicTree) {
 | 
				
			||||||
 | 
							super(tree);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						override function get(from: Int): Dynamic {
 | 
				
			||||||
 | 
							var array: Array<Dynamic> = inputs[0].get();
 | 
				
			||||||
 | 
							array = array.map(item -> Std.string(item));
 | 
				
			||||||
 | 
							var value: Dynamic = inputs[1].get();
 | 
				
			||||||
 | 
							var from: Int = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var arrayList: Array<Int> = [];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var index: Int = array.indexOf(Std.string(value), from);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							while(index != -1){
 | 
				
			||||||
 | 
								arrayList.push(index);
 | 
				
			||||||
 | 
								index = array.indexOf(Std.string(value), index+1);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							return arrayList;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package leenkx.logicnode;
 | 
					package leenkx.logicnode;
 | 
				
			||||||
import aura.Aura;
 | 
					import aura.Aura;
 | 
				
			||||||
import aura.Types;
 | 
					import aura.Types;
 | 
				
			||||||
import aura.types.HRTFData;
 | 
					import aura.types.HRTF;
 | 
				
			||||||
import aura.dsp.panner.HRTFPanner;
 | 
					import aura.dsp.panner.HRTFPanner;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class AudioHRTFPannerNode extends LogicNode {
 | 
					class AudioHRTFPannerNode extends LogicNode {
 | 
				
			||||||
 | 
				
			|||||||
@ -26,10 +26,9 @@ class GetBoneTransformNode extends LogicNode {
 | 
				
			|||||||
		// Get bone in armature
 | 
							// Get bone in armature
 | 
				
			||||||
		var bone = anim.getBone(boneName);
 | 
							var bone = anim.getBone(boneName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //return anim.getAbsWorldMat(bone);
 | 
							return anim.getAbsWorldMat(anim.skeletonMats, bone);
 | 
				
			||||||
		return anim.getAbsMat(bone).clone().multmat(object.transform.world);
 | 
					        //return anim.getAbsMat(bone).clone().multmat(object.transform.world);
 | 
				
			||||||
		//return anim.getAbsWorldMat(bone);
 | 
							
 | 
				
			||||||
 | 
					 | 
				
			||||||
        #else
 | 
					        #else
 | 
				
			||||||
        return null;
 | 
					        return null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package leenkx.logicnode;
 | 
					package leenkx.logicnode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if lnx_physics
 | 
					#if lnx_physics
 | 
				
			||||||
import leenkx.trait.physics.bullet.PhysicsWorld;
 | 
					import leenkx.trait.physics.PhysicsWorld;
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
import leenkx.trait.navigation.Navigation;
 | 
					import leenkx.trait.navigation.Navigation;
 | 
				
			||||||
import iron.object.Object;
 | 
					import iron.object.Object;
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package leenkx.logicnode;
 | 
					package leenkx.logicnode;
 | 
				
			||||||
 | 
					#if lnx_audio
 | 
				
			||||||
import iron.object.SpeakerObject;
 | 
					import iron.object.SpeakerObject;
 | 
				
			||||||
 | 
					#end
 | 
				
			||||||
class PauseSoundNode extends LogicNode {
 | 
					class PauseSoundNode extends LogicNode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(tree: LogicTree) {
 | 
						public function new(tree: LogicTree) {
 | 
				
			||||||
@ -9,9 +9,11 @@ class PauseSoundNode extends LogicNode {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	override function run(from: Int) {
 | 
						override function run(from: Int) {
 | 
				
			||||||
 | 
							#if lnx_audio
 | 
				
			||||||
		var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
							var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
				
			||||||
		if (object == null) return;
 | 
							if (object == null) return;
 | 
				
			||||||
		object.pause();
 | 
							object.pause();
 | 
				
			||||||
 | 
							#end
 | 
				
			||||||
		runOutput(0);
 | 
							runOutput(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package leenkx.logicnode;
 | 
					package leenkx.logicnode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if lnx_physics
 | 
					#if lnx_physics
 | 
				
			||||||
import leenkx.trait.physics.bullet.PhysicsConstraint.ConstraintAxis;
 | 
					import leenkx.trait.physics.PhysicsConstraint.ConstraintAxis;
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PhysicsConstraintNode extends LogicNode {
 | 
					class PhysicsConstraintNode extends LogicNode {
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package leenkx.logicnode;
 | 
					package leenkx.logicnode;
 | 
				
			||||||
 | 
					#if lnx_audio
 | 
				
			||||||
import iron.object.SpeakerObject;
 | 
					import iron.object.SpeakerObject;
 | 
				
			||||||
 | 
					#end
 | 
				
			||||||
class PlaySoundNode extends LogicNode {
 | 
					class PlaySoundNode extends LogicNode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(tree: LogicTree) {
 | 
						public function new(tree: LogicTree) {
 | 
				
			||||||
@ -9,9 +9,11 @@ class PlaySoundNode extends LogicNode {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	override function run(from: Int) {
 | 
						override function run(from: Int) {
 | 
				
			||||||
 | 
							#if lnx_audio
 | 
				
			||||||
		var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
							var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
				
			||||||
		if (object == null) return;
 | 
							if (object == null) return;
 | 
				
			||||||
		object.play();
 | 
							object.play();
 | 
				
			||||||
 | 
							#end
 | 
				
			||||||
		runOutput(0);
 | 
							runOutput(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -16,15 +16,16 @@ class PlaySoundRawNode extends LogicNode {
 | 
				
			|||||||
	public var property5: Bool;
 | 
						public var property5: Bool;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public var property6: String;
 | 
						public var property6: String;
 | 
				
			||||||
 | 
						#if lnx_audio
 | 
				
			||||||
	var sound: kha.Sound = null;
 | 
						var sound: kha.Sound = null;
 | 
				
			||||||
	var channel: kha.audio1.AudioChannel = null;
 | 
						var channel: kha.audio1.AudioChannel = null;
 | 
				
			||||||
 | 
						#end
 | 
				
			||||||
	public function new(tree: LogicTree) {
 | 
						public function new(tree: LogicTree) {
 | 
				
			||||||
		super(tree);
 | 
							super(tree);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	override function run(from: Int) {
 | 
						override function run(from: Int) {
 | 
				
			||||||
 | 
							#if lnx_audio
 | 
				
			||||||
		switch (from) {
 | 
							switch (from) {
 | 
				
			||||||
			case Play:
 | 
								case Play:
 | 
				
			||||||
				if (property6 == 'Sound' ? sound == null : true) {
 | 
									if (property6 == 'Sound' ? sound == null : true) {
 | 
				
			||||||
@ -63,6 +64,10 @@ class PlaySoundRawNode extends LogicNode {
 | 
				
			|||||||
			case UpdateVolume:
 | 
								case UpdateVolume:
 | 
				
			||||||
				if (channel != null) channel.volume = inputs[4].get();
 | 
									if (channel != null) channel.volume = inputs[4].get();
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							#end
 | 
				
			||||||
 | 
							#if !lnx_audio
 | 
				
			||||||
 | 
								runOutput(0);
 | 
				
			||||||
 | 
							#end
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function onUpdate() {
 | 
						function onUpdate() {
 | 
				
			||||||
 | 
				
			|||||||
@ -37,6 +37,7 @@ class RotationNode extends LogicNode {
 | 
				
			|||||||
				value.y = vect.y;
 | 
									value.y = vect.y;
 | 
				
			||||||
				value.z = vect.z;
 | 
									value.z = vect.z;
 | 
				
			||||||
				value.w = inputs[1].get();
 | 
									value.w = inputs[1].get();
 | 
				
			||||||
 | 
									value.normalize();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			case "AxisAngle":
 | 
								case "AxisAngle":
 | 
				
			||||||
				var vec: Vec4 = inputs[0].get();
 | 
									var vec: Vec4 = inputs[0].get();
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										37
									
								
								leenkx/Sources/leenkx/logicnode/SetBoneTransformNode.hx
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,37 @@
 | 
				
			|||||||
 | 
					package leenkx.logicnode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import iron.object.Object;
 | 
				
			||||||
 | 
					#if lnx_skin
 | 
				
			||||||
 | 
					import iron.object.BoneAnimation;
 | 
				
			||||||
 | 
					#end
 | 
				
			||||||
 | 
					import iron.math.Mat4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SetBoneTransformNode extends LogicNode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public function new(tree: LogicTree) {
 | 
				
			||||||
 | 
							super(tree);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						override function run(from: Int) {
 | 
				
			||||||
 | 
							#if lnx_skin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var object: Object = inputs[1].get();
 | 
				
			||||||
 | 
							if (object == null) return;
 | 
				
			||||||
 | 
					                var transform = inputs[3].get();
 | 
				
			||||||
 | 
					                if (transform == null) return;
 | 
				
			||||||
 | 
					                var boneName: String = inputs[2].get();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							var anim = object.animation != null ? cast(object.animation, BoneAnimation) : null;
 | 
				
			||||||
 | 
							if (anim == null) anim = object.getBoneAnimation(object.uid);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// Get bone in armature
 | 
				
			||||||
 | 
							var bone = anim.getBone(boneName);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							anim.setBoneMatFromWorldMat(anim.skeletonMats, transform, bone);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							runOutput(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        #end
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -17,7 +17,7 @@ class SetParentBoneNode extends LogicNode {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
		if (object == null || parent == null) return;
 | 
							if (object == null || parent == null) return;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		object.setParent(parent, false, false);
 | 
							object.setParent(parent, inputs[4].get(), inputs[5].get());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var banim = object.getBoneAnimation(object.parent.uid);
 | 
							var banim = object.getBoneAnimation(object.parent.uid);
 | 
				
			||||||
		banim.addBoneChild(bone, object);
 | 
							banim.addBoneChild(bone, object);
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package leenkx.logicnode;
 | 
					package leenkx.logicnode;
 | 
				
			||||||
 | 
					#if lnx_audio
 | 
				
			||||||
import iron.object.SpeakerObject;
 | 
					import iron.object.SpeakerObject;
 | 
				
			||||||
 | 
					#end
 | 
				
			||||||
class SetSoundNode extends LogicNode {
 | 
					class SetSoundNode extends LogicNode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(tree: LogicTree) {
 | 
						public function new(tree: LogicTree) {
 | 
				
			||||||
@ -9,10 +9,12 @@ class SetSoundNode extends LogicNode {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	override function run(from: Int) {
 | 
						override function run(from: Int) {
 | 
				
			||||||
 | 
							#if lnx_audio
 | 
				
			||||||
		var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
							var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
				
			||||||
		var sound: String = inputs[2].get(); 
 | 
							var sound: String = inputs[2].get(); 
 | 
				
			||||||
		if (object == null || sound == null) return;
 | 
							if (object == null || sound == null) return;
 | 
				
			||||||
		object.setSound(sound);
 | 
							object.setSound(sound);
 | 
				
			||||||
 | 
							#end
 | 
				
			||||||
		runOutput(0);
 | 
							runOutput(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package leenkx.logicnode;
 | 
					package leenkx.logicnode;
 | 
				
			||||||
 | 
					#if lnx_audio
 | 
				
			||||||
import iron.object.SpeakerObject;
 | 
					import iron.object.SpeakerObject;
 | 
				
			||||||
 | 
					#end
 | 
				
			||||||
class SetVolumeSoundNode extends LogicNode {
 | 
					class SetVolumeSoundNode extends LogicNode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(tree: LogicTree) {
 | 
						public function new(tree: LogicTree) {
 | 
				
			||||||
@ -9,9 +9,11 @@ class SetVolumeSoundNode extends LogicNode {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	override function run(from: Int) {
 | 
						override function run(from: Int) {
 | 
				
			||||||
 | 
							#if lnx_audio
 | 
				
			||||||
		var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
							var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
				
			||||||
		if (object == null) return;
 | 
							if (object == null) return;
 | 
				
			||||||
		object.setVolume(inputs[2].get());
 | 
							object.setVolume(inputs[2].get());
 | 
				
			||||||
 | 
							#end
 | 
				
			||||||
		runOutput(0);
 | 
							runOutput(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,7 +1,7 @@
 | 
				
			|||||||
package leenkx.logicnode;
 | 
					package leenkx.logicnode;
 | 
				
			||||||
 | 
					#if lnx_audio
 | 
				
			||||||
import iron.object.SpeakerObject;
 | 
					import iron.object.SpeakerObject;
 | 
				
			||||||
 | 
					#end
 | 
				
			||||||
class StopSoundNode extends LogicNode {
 | 
					class StopSoundNode extends LogicNode {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(tree: LogicTree) {
 | 
						public function new(tree: LogicTree) {
 | 
				
			||||||
@ -9,9 +9,11 @@ class StopSoundNode extends LogicNode {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	override function run(from: Int) {
 | 
						override function run(from: Int) {
 | 
				
			||||||
 | 
							#if lnx_audio
 | 
				
			||||||
		var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
							var object: SpeakerObject = cast(inputs[1].get(), SpeakerObject);
 | 
				
			||||||
		if (object == null) return;
 | 
							if (object == null) return;
 | 
				
			||||||
		object.stop();
 | 
							object.stop();
 | 
				
			||||||
 | 
							#end
 | 
				
			||||||
		runOutput(0);
 | 
							runOutput(0);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,7 +18,7 @@ class TransformNode extends LogicNode {
 | 
				
			|||||||
	override function get(from: Int): Dynamic {
 | 
						override function get(from: Int): Dynamic {
 | 
				
			||||||
		var loc: Vec4 = inputs[0].get();
 | 
							var loc: Vec4 = inputs[0].get();
 | 
				
			||||||
		var rot: Quat = new Quat().setFrom(inputs[1].get());
 | 
							var rot: Quat = new Quat().setFrom(inputs[1].get());
 | 
				
			||||||
		rot.normalize();
 | 
							//rot.normalize();
 | 
				
			||||||
		var scale: Vec4 = inputs[2].get();
 | 
							var scale: Vec4 = inputs[2].get();
 | 
				
			||||||
		if (loc == null && rot == null && scale == null) return this.value;
 | 
							if (loc == null && rot == null && scale == null) return this.value;
 | 
				
			||||||
		if (loc == null || rot == null || scale == null) return null;
 | 
							if (loc == null || rot == null || scale == null) return null;
 | 
				
			||||||
 | 
				
			|||||||
@ -77,6 +77,9 @@ class Inc {
 | 
				
			|||||||
	#if (rp_voxels == "Voxel GI")
 | 
						#if (rp_voxels == "Voxel GI")
 | 
				
			||||||
	static var voxel_sh5:kha.compute.Shader = null;
 | 
						static var voxel_sh5:kha.compute.Shader = null;
 | 
				
			||||||
	static var voxel_ta5:kha.compute.TextureUnit;
 | 
						static var voxel_ta5:kha.compute.TextureUnit;
 | 
				
			||||||
 | 
						static var voxel_te5:kha.compute.TextureUnit;
 | 
				
			||||||
 | 
						static var voxel_tf5:kha.compute.TextureUnit;
 | 
				
			||||||
 | 
						static var voxel_tg5:kha.compute.TextureUnit;
 | 
				
			||||||
	static var voxel_ca5:kha.compute.ConstantLocation;
 | 
						static var voxel_ca5:kha.compute.ConstantLocation;
 | 
				
			||||||
	static var voxel_cb5:kha.compute.ConstantLocation;
 | 
						static var voxel_cb5:kha.compute.ConstantLocation;
 | 
				
			||||||
	static var voxel_cc5:kha.compute.ConstantLocation;
 | 
						static var voxel_cc5:kha.compute.ConstantLocation;
 | 
				
			||||||
@ -677,7 +680,7 @@ class Inc {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		else {
 | 
							else {
 | 
				
			||||||
			if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") {
 | 
								if (t.name == "voxelsSDF" || t.name == "voxelsSDFtmp") {
 | 
				
			||||||
				t.format = "R16";
 | 
									t.format = "R8";
 | 
				
			||||||
				t.width = res;
 | 
									t.width = res;
 | 
				
			||||||
				t.height = res * Main.voxelgiClipmapCount;
 | 
									t.height = res * Main.voxelgiClipmapCount;
 | 
				
			||||||
				t.depth = res;
 | 
									t.depth = res;
 | 
				
			||||||
@ -686,7 +689,7 @@ class Inc {
 | 
				
			|||||||
				#if (rp_voxels == "Voxel AO")
 | 
									#if (rp_voxels == "Voxel AO")
 | 
				
			||||||
				{
 | 
									{
 | 
				
			||||||
					if (t.name == "voxelsOut" || t.name == "voxelsOutB") {
 | 
										if (t.name == "voxelsOut" || t.name == "voxelsOutB") {
 | 
				
			||||||
						t.format = "R16";
 | 
											t.format = "R8";
 | 
				
			||||||
						t.width = res * (6 + 16);
 | 
											t.width = res * (6 + 16);
 | 
				
			||||||
						t.height = res * Main.voxelgiClipmapCount;
 | 
											t.height = res * Main.voxelgiClipmapCount;
 | 
				
			||||||
						t.depth = res;
 | 
											t.depth = res;
 | 
				
			||||||
@ -892,7 +895,9 @@ class Inc {
 | 
				
			|||||||
		{
 | 
							{
 | 
				
			||||||
			voxel_sh5 = path.getComputeShader("voxel_light");
 | 
								voxel_sh5 = path.getComputeShader("voxel_light");
 | 
				
			||||||
			voxel_ta5 = voxel_sh5.getTextureUnit("voxelsLight");
 | 
								voxel_ta5 = voxel_sh5.getTextureUnit("voxelsLight");
 | 
				
			||||||
 | 
								voxel_te5 = voxel_sh5.getTextureUnit("voxels");
 | 
				
			||||||
 | 
								voxel_tf5 = voxel_sh5.getTextureUnit("voxelsSampler");
 | 
				
			||||||
 | 
								voxel_tg5 = voxel_sh5.getTextureUnit("voxelsSDFSampler");
 | 
				
			||||||
	 		voxel_ca5 = voxel_sh5.getConstantLocation("clipmaps");
 | 
						 		voxel_ca5 = voxel_sh5.getConstantLocation("clipmaps");
 | 
				
			||||||
			voxel_cb5 = voxel_sh5.getConstantLocation("clipmapLevel");
 | 
								voxel_cb5 = voxel_sh5.getConstantLocation("clipmapLevel");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1288,7 +1293,9 @@ class Inc {
 | 
				
			|||||||
	 		kha.compute.Compute.setShader(voxel_sh5);
 | 
						 		kha.compute.Compute.setShader(voxel_sh5);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			kha.compute.Compute.setTexture(voxel_ta5, rts.get("voxelsLight").image, kha.compute.Access.Write);
 | 
								kha.compute.Compute.setTexture(voxel_ta5, rts.get("voxelsLight").image, kha.compute.Access.Write);
 | 
				
			||||||
 | 
								kha.compute.Compute.setTexture(voxel_te5, rts.get("voxels").image, kha.compute.Access.Read);
 | 
				
			||||||
 | 
								kha.compute.Compute.setSampledTexture(voxel_tf5, rts.get("voxelsOut").image);
 | 
				
			||||||
 | 
								kha.compute.Compute.setSampledTexture(voxel_tg5, rts.get("voxelsSDF").image);
 | 
				
			||||||
			var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
 | 
								var fa:Float32Array = new Float32Array(Main.voxelgiClipmapCount * 10);
 | 
				
			||||||
			for (i in 0...Main.voxelgiClipmapCount) {
 | 
								for (i in 0...Main.voxelgiClipmapCount) {
 | 
				
			||||||
				fa[i * 10] = clipmaps[i].voxelSize;
 | 
									fa[i * 10] = clipmaps[i].voxelSize;
 | 
				
			||||||
 | 
				
			|||||||
@ -368,7 +368,7 @@ class RenderPathDeferred {
 | 
				
			|||||||
			t.scale = Inc.getSuperSampling();
 | 
								t.scale = Inc.getSuperSampling();
 | 
				
			||||||
			path.createRenderTarget(t);
 | 
								path.createRenderTarget(t);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			// holds background depth
 | 
								// holds background color
 | 
				
			||||||
			var t = new RenderTargetRaw();
 | 
								var t = new RenderTargetRaw();
 | 
				
			||||||
			t.name = "refr";
 | 
								t.name = "refr";
 | 
				
			||||||
			t.width = 0;
 | 
								t.width = 0;
 | 
				
			||||||
@ -473,6 +473,13 @@ class RenderPathDeferred {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		#end
 | 
							#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							#if rp_ssrefr
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								path.setTarget("gbuffer_refraction");
 | 
				
			||||||
 | 
								path.clearTarget(0xffffff00);
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		RenderPathCreator.setTargetMeshes();
 | 
							RenderPathCreator.setTargetMeshes();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#if rp_dynres
 | 
							#if rp_dynres
 | 
				
			||||||
@ -837,7 +844,7 @@ class RenderPathDeferred {
 | 
				
			|||||||
				{
 | 
									{
 | 
				
			||||||
					path.bindTarget("voxelsOut", "voxels");
 | 
										path.bindTarget("voxelsOut", "voxels");
 | 
				
			||||||
					path.bindTarget("voxelsSDF", "voxelsSDF");
 | 
										path.bindTarget("voxelsSDF", "voxelsSDF");
 | 
				
			||||||
					path.bindTarget("gbuffer2", "sveloc");
 | 
										path.bindTarget("gbuffer2", "gbuffer2");
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				#end
 | 
									#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -522,6 +522,17 @@ class RenderPathForward {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
					path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
 | 
										path.setTarget("lbuffer0", ["lbuffer1", "gbuffer_refraction"]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
										#if rp_shadowmap
 | 
				
			||||||
 | 
										{
 | 
				
			||||||
 | 
											#if lnx_shadowmap_atlas
 | 
				
			||||||
 | 
											Inc.bindShadowMapAtlas();
 | 
				
			||||||
 | 
											#else
 | 
				
			||||||
 | 
											Inc.bindShadowMap();
 | 
				
			||||||
 | 
											#end
 | 
				
			||||||
 | 
										}
 | 
				
			||||||
 | 
										#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
					#if (rp_voxels != "Off")
 | 
										#if (rp_voxels != "Off")
 | 
				
			||||||
					path.bindTarget("voxelsOut", "voxels");
 | 
										path.bindTarget("voxelsOut", "voxels");
 | 
				
			||||||
					path.bindTarget("voxelsSDF", "voxelsSDF");
 | 
										path.bindTarget("voxelsSDF", "voxelsSDF");
 | 
				
			||||||
 | 
				
			|||||||
@ -41,7 +41,11 @@ class Starter {
 | 
				
			|||||||
			try {
 | 
								try {
 | 
				
			||||||
			#end
 | 
								#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window: kha.Window) {
 | 
								kha.System.start({title: Main.projectName, width: c.window_w, height: c.window_h, window: {
 | 
				
			||||||
 | 
								#if lnx_render_viewport
 | 
				
			||||||
 | 
								visible: false,
 | 
				
			||||||
 | 
								#end
 | 
				
			||||||
 | 
								mode: windowMode, windowFeatures: windowFeatures}, framebuffer: {samplesPerPixel: c.window_msaa, verticalSync: c.window_vsync}}, function(window: kha.Window) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
				iron.App.init(function() {
 | 
									iron.App.init(function() {
 | 
				
			||||||
					#if lnx_loadscreen
 | 
										#if lnx_loadscreen
 | 
				
			||||||
 | 
				
			|||||||
@ -10,6 +10,10 @@ class KinematicCharacterController extends iron.Trait { public function new() {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	typedef KinematicCharacterController = leenkx.trait.physics.bullet.KinematicCharacterController;
 | 
						typedef KinematicCharacterController = leenkx.trait.physics.bullet.KinematicCharacterController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						typedef KinematicCharacterController = leenkx.trait.physics.oimo.KinematicCharacterController;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#end
 | 
						#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
 | 
				
			|||||||
@ -3,17 +3,16 @@ package leenkx.trait.physics;
 | 
				
			|||||||
#if (!lnx_physics)
 | 
					#if (!lnx_physics)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class PhysicsConstraint extends iron.Trait { public function new() { super(); } }
 | 
					class PhysicsConstraint extends iron.Trait { public function new() { super(); } }
 | 
				
			||||||
 | 
					@:enum abstract ConstraintAxis(Int) from Int to Int { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#if lnx_bullet
 | 
						#if lnx_bullet
 | 
				
			||||||
 | 
					 | 
				
			||||||
	typedef PhysicsConstraint = leenkx.trait.physics.bullet.PhysicsConstraint;
 | 
						typedef PhysicsConstraint = leenkx.trait.physics.bullet.PhysicsConstraint;
 | 
				
			||||||
 | 
						typedef ConstraintAxis = leenkx.trait.physics.bullet.PhysicsConstraint.ConstraintAxis;
 | 
				
			||||||
	#else
 | 
						#else
 | 
				
			||||||
 | 
					 | 
				
			||||||
	typedef PhysicsConstraint = leenkx.trait.physics.oimo.PhysicsConstraint;
 | 
						typedef PhysicsConstraint = leenkx.trait.physics.oimo.PhysicsConstraint;
 | 
				
			||||||
 | 
						typedef ConstraintAxis = leenkx.trait.physics.oimo.PhysicsConstraint.ConstraintAxis;
 | 
				
			||||||
	#end
 | 
						#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
 | 
				
			|||||||
@ -2,6 +2,7 @@ package leenkx.trait.physics;
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#if (!lnx_physics)
 | 
					#if (!lnx_physics)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class Hit { }
 | 
				
			||||||
class PhysicsWorld extends iron.Trait { public function new() { super(); } }
 | 
					class PhysicsWorld extends iron.Trait { public function new() { super(); } }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
@ -9,11 +10,11 @@ class PhysicsWorld extends iron.Trait { public function new() { super(); } }
 | 
				
			|||||||
	#if lnx_bullet
 | 
						#if lnx_bullet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	typedef PhysicsWorld = leenkx.trait.physics.bullet.PhysicsWorld;
 | 
						typedef PhysicsWorld = leenkx.trait.physics.bullet.PhysicsWorld;
 | 
				
			||||||
 | 
						typedef Hit = leenkx.trait.physics.bullet.PhysicsWorld.Hit;
 | 
				
			||||||
	#else
 | 
						#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	typedef PhysicsWorld = leenkx.trait.physics.oimo.PhysicsWorld;
 | 
						typedef PhysicsWorld = leenkx.trait.physics.oimo.PhysicsWorld;
 | 
				
			||||||
 | 
						typedef Hit = leenkx.trait.physics.oimo.PhysicsWorld.Hit;
 | 
				
			||||||
	#end
 | 
						#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
 | 
				
			|||||||
@ -3,17 +3,20 @@ package leenkx.trait.physics;
 | 
				
			|||||||
#if (!lnx_physics)
 | 
					#if (!lnx_physics)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class RigidBody extends iron.Trait { public function new() { super(); } }
 | 
					class RigidBody extends iron.Trait { public function new() { super(); } }
 | 
				
			||||||
 | 
					@:enum abstract Shape(Int) from Int to Int { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#else
 | 
					#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#if lnx_bullet
 | 
						#if lnx_bullet
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	typedef RigidBody = leenkx.trait.physics.bullet.RigidBody;
 | 
						typedef RigidBody = leenkx.trait.physics.bullet.RigidBody;
 | 
				
			||||||
 | 
						typedef Shape = leenkx.trait.physics.bullet.RigidBody.Shape;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	#else
 | 
						#else
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	typedef RigidBody = leenkx.trait.physics.oimo.RigidBody;
 | 
						typedef RigidBody = leenkx.trait.physics.oimo.RigidBody;
 | 
				
			||||||
 | 
						typedef Shape = leenkx.trait.physics.oimo.RigidBody.Shape;
 | 
				
			||||||
 | 
						
 | 
				
			||||||
	#end
 | 
						#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
 | 
				
			|||||||
@ -1,5 +1,8 @@
 | 
				
			|||||||
package leenkx.trait.physics.bullet;
 | 
					package leenkx.trait.physics.bullet;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#if lnx_bullet
 | 
				
			||||||
 | 
					import leenkx.trait.physics.bullet.PhysicsWorld.DebugDrawMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import bullet.Bt.Vector3;
 | 
					import bullet.Bt.Vector3;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import kha.FastFloat;
 | 
					import kha.FastFloat;
 | 
				
			||||||
@ -18,15 +21,21 @@ class DebugDrawHelper {
 | 
				
			|||||||
	static inline var contactPointNormalColor = 0xffffffff;
 | 
						static inline var contactPointNormalColor = 0xffffffff;
 | 
				
			||||||
	static inline var contactPointDrawLifetime = true;
 | 
						static inline var contactPointDrawLifetime = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						final rayCastColor: Vec4 = new Vec4(0.0, 1.0, 0.0);
 | 
				
			||||||
 | 
						final rayCastHitColor: Vec4 = new Vec4(1.0, 0.0, 0.0);
 | 
				
			||||||
 | 
						final rayCastHitPointColor: Vec4 = new Vec4(1.0, 1.0, 0.0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	final physicsWorld: PhysicsWorld;
 | 
						final physicsWorld: PhysicsWorld;
 | 
				
			||||||
	final lines: Array<LineData> = [];
 | 
						final lines: Array<LineData> = [];
 | 
				
			||||||
	final texts: Array<TextData> = [];
 | 
						final texts: Array<TextData> = [];
 | 
				
			||||||
	var font: kha.Font = null;
 | 
						var font: kha.Font = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var debugMode: PhysicsWorld.DebugDrawMode = NoDebug;
 | 
						var rayCasts:Array<TRayCastData> = [];
 | 
				
			||||||
 | 
						var debugDrawMode: DebugDrawMode = NoDebug;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(physicsWorld: PhysicsWorld) {
 | 
						public function new(physicsWorld: PhysicsWorld, debugDrawMode: DebugDrawMode) {
 | 
				
			||||||
		this.physicsWorld = physicsWorld;
 | 
							this.physicsWorld = physicsWorld;
 | 
				
			||||||
 | 
							this.debugDrawMode = debugDrawMode;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#if lnx_ui
 | 
							#if lnx_ui
 | 
				
			||||||
		iron.data.Data.getFont(Canvas.defaultFontName, function(defaultFont: kha.Font) {
 | 
							iron.data.Data.getFont(Canvas.defaultFontName, function(defaultFont: kha.Font) {
 | 
				
			||||||
@ -35,6 +44,11 @@ class DebugDrawHelper {
 | 
				
			|||||||
		#end
 | 
							#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		iron.App.notifyOnRender2D(onRender);
 | 
							iron.App.notifyOnRender2D(onRender);
 | 
				
			||||||
 | 
							if (debugDrawMode & DrawRayCast != 0) {
 | 
				
			||||||
 | 
								iron.App.notifyOnUpdate(function () {
 | 
				
			||||||
 | 
									rayCasts.resize(0);
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function drawLine(from: bullet.Bt.Vector3, to: bullet.Bt.Vector3, color: bullet.Bt.Vector3) {
 | 
						public function drawLine(from: bullet.Bt.Vector3, to: bullet.Bt.Vector3, color: bullet.Bt.Vector3) {
 | 
				
			||||||
@ -49,9 +63,10 @@ class DebugDrawHelper {
 | 
				
			|||||||
		final fromScreenSpace = worldToScreenFast(new Vec4(from.x(), from.y(), from.z(), 1.0));
 | 
							final fromScreenSpace = worldToScreenFast(new Vec4(from.x(), from.y(), from.z(), 1.0));
 | 
				
			||||||
		final toScreenSpace = worldToScreenFast(new Vec4(to.x(), to.y(), to.z(), 1.0));
 | 
							final toScreenSpace = worldToScreenFast(new Vec4(to.x(), to.y(), to.z(), 1.0));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		// For now don't draw lines if any point is outside of clip space z,
 | 
					 | 
				
			||||||
		// investigate how to clamp lines to clip space borders
 | 
							// investigate how to clamp lines to clip space borders
 | 
				
			||||||
		if (fromScreenSpace.w == 1 && toScreenSpace.w == 1) {
 | 
							// If at least one point is within the Z clip space (w==1), attempt to draw.
 | 
				
			||||||
 | 
							// Note: This is not full clipping, line may still go off screen sides.
 | 
				
			||||||
 | 
							if (fromScreenSpace.w == 1 || toScreenSpace.w == 1) {
 | 
				
			||||||
			lines.push({
 | 
								lines.push({
 | 
				
			||||||
				fromX: fromScreenSpace.x,
 | 
									fromX: fromScreenSpace.x,
 | 
				
			||||||
				fromY: fromScreenSpace.y,
 | 
									fromY: fromScreenSpace.y,
 | 
				
			||||||
@ -112,6 +127,61 @@ class DebugDrawHelper {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public function rayCast(rayCastData:TRayCastData) {
 | 
				
			||||||
 | 
							rayCasts.push(rayCastData);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function drawRayCast(f: Vec4, t: Vec4, hit: Bool) {
 | 
				
			||||||
 | 
							final from = worldToScreenFast(f.clone());
 | 
				
			||||||
 | 
							final to = worldToScreenFast(t.clone());
 | 
				
			||||||
 | 
							var c: kha.Color;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (from.w == 1 && to.w == 1) {
 | 
				
			||||||
 | 
								if (hit) c = kha.Color.fromFloats(rayCastHitColor.x, rayCastHitColor.y, rayCastHitColor.z);
 | 
				
			||||||
 | 
								else c = kha.Color.fromFloats(rayCastColor.x, rayCastColor.y, rayCastColor.z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								lines.push({
 | 
				
			||||||
 | 
									fromX: from.x,
 | 
				
			||||||
 | 
									fromY: from.y,
 | 
				
			||||||
 | 
									toX: to.x,
 | 
				
			||||||
 | 
									toY: to.y,
 | 
				
			||||||
 | 
									color: c
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						function drawHitPoint(hp: Vec4) {
 | 
				
			||||||
 | 
							final hitPoint = worldToScreenFast(hp.clone());
 | 
				
			||||||
 | 
							final c = kha.Color.fromFloats(rayCastHitPointColor.x, rayCastHitPointColor.y, rayCastHitPointColor.z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (hitPoint.w == 1) {
 | 
				
			||||||
 | 
								lines.push({
 | 
				
			||||||
 | 
									fromX: hitPoint.x - contactPointSizePx,
 | 
				
			||||||
 | 
									fromY: hitPoint.y - contactPointSizePx,
 | 
				
			||||||
 | 
									toX: hitPoint.x + contactPointSizePx,
 | 
				
			||||||
 | 
									toY: hitPoint.y + contactPointSizePx,
 | 
				
			||||||
 | 
									color: c
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								lines.push({
 | 
				
			||||||
 | 
									fromX: hitPoint.x - contactPointSizePx,
 | 
				
			||||||
 | 
									fromY: hitPoint.y + contactPointSizePx,
 | 
				
			||||||
 | 
									toX: hitPoint.x + contactPointSizePx,
 | 
				
			||||||
 | 
									toY: hitPoint.y - contactPointSizePx,
 | 
				
			||||||
 | 
									color: c
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
								if (font != null) {
 | 
				
			||||||
 | 
									texts.push({
 | 
				
			||||||
 | 
										x: hitPoint.x,
 | 
				
			||||||
 | 
										y: hitPoint.y,
 | 
				
			||||||
 | 
										color: c,
 | 
				
			||||||
 | 
										text: 'RAYCAST HIT'
 | 
				
			||||||
 | 
									});
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function reportErrorWarning(warningString: bullet.Bt.BulletString) {
 | 
						public function reportErrorWarning(warningString: bullet.Bt.BulletString) {
 | 
				
			||||||
		trace(warningString.toHaxeString().trim());
 | 
							trace(warningString.toHaxeString().trim());
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -135,13 +205,13 @@ class DebugDrawHelper {
 | 
				
			|||||||
		});
 | 
							});
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function setDebugMode(debugMode: PhysicsWorld.DebugDrawMode) {
 | 
						public function setDebugMode(debugDrawMode: DebugDrawMode) {
 | 
				
			||||||
		this.debugMode = debugMode;
 | 
							this.debugDrawMode = debugDrawMode;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function getDebugMode(): PhysicsWorld.DebugDrawMode {
 | 
						public function getDebugMode(): DebugDrawMode {
 | 
				
			||||||
		#if js
 | 
							#if js
 | 
				
			||||||
			return debugMode;
 | 
								return debugDrawMode;
 | 
				
			||||||
		#elseif hl
 | 
							#elseif hl
 | 
				
			||||||
			return physicsWorld.getDebugDrawMode();
 | 
								return physicsWorld.getDebugDrawMode();
 | 
				
			||||||
		#else
 | 
							#else
 | 
				
			||||||
@ -161,6 +231,7 @@ class DebugDrawHelper {
 | 
				
			|||||||
		// before some user-specific physics update, which would result in a
 | 
							// before some user-specific physics update, which would result in a
 | 
				
			||||||
		// one-frame drawing delay... Ideally we would ensure that debugDrawWorld()
 | 
							// one-frame drawing delay... Ideally we would ensure that debugDrawWorld()
 | 
				
			||||||
		// is called when all other (late) update callbacks are already executed...
 | 
							// is called when all other (late) update callbacks are already executed...
 | 
				
			||||||
 | 
							
 | 
				
			||||||
		physicsWorld.world.debugDrawWorld();
 | 
							physicsWorld.world.debugDrawWorld();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		g.opacity = 1.0;
 | 
							g.opacity = 1.0;
 | 
				
			||||||
@ -180,6 +251,17 @@ class DebugDrawHelper {
 | 
				
			|||||||
			}
 | 
								}
 | 
				
			||||||
			texts.resize(0);
 | 
								texts.resize(0);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							
 | 
				
			||||||
 | 
							if (debugDrawMode & DrawRayCast != 0) {
 | 
				
			||||||
 | 
								for (rayCastData in rayCasts) {
 | 
				
			||||||
 | 
									if (rayCastData.hasHit) {
 | 
				
			||||||
 | 
										drawRayCast(rayCastData.from, rayCastData.hitPoint, true);
 | 
				
			||||||
 | 
										drawHitPoint(rayCastData.hitPoint);
 | 
				
			||||||
 | 
									} else {
 | 
				
			||||||
 | 
										drawRayCast(rayCastData.from, rayCastData.to, false);
 | 
				
			||||||
 | 
									}
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/**
 | 
				
			||||||
@ -222,3 +304,14 @@ class TextData {
 | 
				
			|||||||
	public var color: kha.Color;
 | 
						public var color: kha.Color;
 | 
				
			||||||
	public var text: String;
 | 
						public var text: String;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@:structInit
 | 
				
			||||||
 | 
					typedef TRayCastData = {
 | 
				
			||||||
 | 
						var from: Vec4;
 | 
				
			||||||
 | 
						var to: Vec4;
 | 
				
			||||||
 | 
						var hasHit: Bool;
 | 
				
			||||||
 | 
						@:optional var hitPoint: Vec4;
 | 
				
			||||||
 | 
						@:optional var hitNormal: Vec4;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#end
 | 
				
			||||||
@ -85,6 +85,22 @@ class PhysicsWorld extends Trait {
 | 
				
			|||||||
	public static var physTime = 0.0;
 | 
						public static var physTime = 0.0;
 | 
				
			||||||
	#end
 | 
						#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static function getSolverInfo(world:bullet.Bt.DynamicsWorld):Dynamic {
 | 
				
			||||||
 | 
							return Reflect.callMethod(world, Reflect.field(world, "getSolverInfo"), []);
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						public static function setSolverIterations(world:bullet.Bt.DynamicsWorld, iterations:Int):Void {
 | 
				
			||||||
 | 
							var solverInfo = getSolverInfo(world);
 | 
				
			||||||
 | 
							if (solverInfo != null) {
 | 
				
			||||||
 | 
								Reflect.setField(solverInfo, "m_numIterations", iterations);
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								trace("Warning: Could not access solver info. Solver iterations not applied.");
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function new(timeScale = 1.0, maxSteps = 10, solverIterations = 10, debugDrawMode: DebugDrawMode = NoDebug) {
 | 
						public function new(timeScale = 1.0, maxSteps = 10, solverIterations = 10, debugDrawMode: DebugDrawMode = NoDebug) {
 | 
				
			||||||
		super();
 | 
							super();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -164,7 +180,8 @@ class PhysicsWorld extends Trait {
 | 
				
			|||||||
#else
 | 
					#else
 | 
				
			||||||
		world = new bullet.Bt.DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
 | 
							world = new bullet.Bt.DiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
 | 
				
			||||||
#end
 | 
					#end
 | 
				
			||||||
 | 
							// TO DO: Set the solver iterations from Blender's rigid body world
 | 
				
			||||||
 | 
							// setSolverIterations(world, solverIterations);
 | 
				
			||||||
		setGravity(gravity);
 | 
							setGravity(gravity);
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -378,6 +395,7 @@ class PhysicsWorld extends Trait {
 | 
				
			|||||||
		rayTo.setValue(to.x, to.y, to.z);
 | 
							rayTo.setValue(to.x, to.y, to.z);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		var rayCallback = new bullet.Bt.ClosestRayResultCallback(rayFrom, rayTo);
 | 
							var rayCallback = new bullet.Bt.ClosestRayResultCallback(rayFrom, rayTo);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#if js
 | 
							#if js
 | 
				
			||||||
		rayCallback.set_m_collisionFilterGroup(group);
 | 
							rayCallback.set_m_collisionFilterGroup(group);
 | 
				
			||||||
		rayCallback.set_m_collisionFilterMask(mask);
 | 
							rayCallback.set_m_collisionFilterMask(mask);
 | 
				
			||||||
@ -387,6 +405,7 @@ class PhysicsWorld extends Trait {
 | 
				
			|||||||
		#end
 | 
							#end
 | 
				
			||||||
		var worldDyn: bullet.Bt.DynamicsWorld = world;
 | 
							var worldDyn: bullet.Bt.DynamicsWorld = world;
 | 
				
			||||||
		var worldCol: bullet.Bt.CollisionWorld = worldDyn;
 | 
							var worldCol: bullet.Bt.CollisionWorld = worldDyn;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		worldCol.rayTest(rayFrom, rayTo, rayCallback);
 | 
							worldCol.rayTest(rayFrom, rayTo, rayCallback);
 | 
				
			||||||
		var rb: RigidBody = null;
 | 
							var rb: RigidBody = null;
 | 
				
			||||||
		var hitInfo: Hit = null;
 | 
							var hitInfo: Hit = null;
 | 
				
			||||||
@ -412,6 +431,16 @@ class PhysicsWorld extends Trait {
 | 
				
			|||||||
			#end
 | 
								#end
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							if (getDebugDrawMode() & DrawRayCast != 0) {
 | 
				
			||||||
 | 
								debugDrawHelper.rayCast({
 | 
				
			||||||
 | 
									from: from,
 | 
				
			||||||
 | 
									to: to,
 | 
				
			||||||
 | 
									hasHit: rc.hasHit(),
 | 
				
			||||||
 | 
									hitPoint: hitPointWorld,
 | 
				
			||||||
 | 
									hitNormal: hitNormalWorld
 | 
				
			||||||
 | 
								});
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#if js
 | 
							#if js
 | 
				
			||||||
		bullet.Bt.Ammo.destroy(rayCallback);
 | 
							bullet.Bt.Ammo.destroy(rayCallback);
 | 
				
			||||||
		#else
 | 
							#else
 | 
				
			||||||
@ -493,7 +522,7 @@ class PhysicsWorld extends Trait {
 | 
				
			|||||||
			if (debugDrawMode == NoDebug) {
 | 
								if (debugDrawMode == NoDebug) {
 | 
				
			||||||
				return;
 | 
									return;
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			initDebugDrawing();
 | 
								initDebugDrawing(debugDrawMode);
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#if js
 | 
							#if js
 | 
				
			||||||
@ -517,8 +546,8 @@ class PhysicsWorld extends Trait {
 | 
				
			|||||||
		#end
 | 
							#end
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	function initDebugDrawing() {
 | 
						function initDebugDrawing(debugDrawMode: DebugDrawMode) {
 | 
				
			||||||
		debugDrawHelper = new DebugDrawHelper(this);
 | 
							debugDrawHelper = new DebugDrawHelper(this, debugDrawMode);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
		#if js
 | 
							#if js
 | 
				
			||||||
			final drawer = new bullet.Bt.DebugDrawer();
 | 
								final drawer = new bullet.Bt.DebugDrawer();
 | 
				
			||||||
@ -644,10 +673,7 @@ enum abstract DebugDrawMode(Int) from Int to Int {
 | 
				
			|||||||
	// We could use it in the future to toggle depth testing for lines, i.e. draw actual 3D lines if not set and Kha's g2 lines if set.
 | 
						// We could use it in the future to toggle depth testing for lines, i.e. draw actual 3D lines if not set and Kha's g2 lines if set.
 | 
				
			||||||
	var FastWireframe = 1 << 13;
 | 
						var FastWireframe = 1 << 13;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	/**
 | 
						/** Draw the normal vectors of the triangles of the physics collider meshes. **/
 | 
				
			||||||
		Draw the normal vectors of the triangles of the physics collider meshes.
 | 
					 | 
				
			||||||
		This only works for `Mesh` collision shapes.
 | 
					 | 
				
			||||||
	**/
 | 
					 | 
				
			||||||
	// Outside of Leenkx this works for a few more collision shapes
 | 
						// Outside of Leenkx this works for a few more collision shapes
 | 
				
			||||||
	var DrawNormals = 1 << 14;
 | 
						var DrawNormals = 1 << 14;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -657,6 +683,8 @@ enum abstract DebugDrawMode(Int) from Int to Int {
 | 
				
			|||||||
	 **/
 | 
						 **/
 | 
				
			||||||
	var DrawFrames = 1 << 15;
 | 
						var DrawFrames = 1 << 15;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						var DrawRayCast = 1 << 16;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	@:op(~A) public inline function bitwiseNegate(): DebugDrawMode {
 | 
						@:op(~A) public inline function bitwiseNegate(): DebugDrawMode {
 | 
				
			||||||
		return ~this;
 | 
							return ~this;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,8 +1,5 @@
 | 
				
			|||||||
package zui;
 | 
					package zui;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Immediate Mode UI Library
 | 
					 | 
				
			||||||
// https://github.com/leenkx3d/zui
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
import kha.input.Mouse;
 | 
					import kha.input.Mouse;
 | 
				
			||||||
import kha.input.Pen;
 | 
					import kha.input.Pen;
 | 
				
			||||||
import kha.input.Surface;
 | 
					import kha.input.Surface;
 | 
				
			||||||
@ -255,7 +252,7 @@ class Zui {
 | 
				
			|||||||
		Mouse.get().notifyWindowed(ops.khaWindowId, onMouseDown, onMouseUp, onMouseMove, onMouseWheel);
 | 
							Mouse.get().notifyWindowed(ops.khaWindowId, onMouseDown, onMouseUp, onMouseMove, onMouseWheel);
 | 
				
			||||||
		if (Pen.get() != null) Pen.get().notify(onPenDown, onPenUp, onPenMove);
 | 
							if (Pen.get() != null) Pen.get().notify(onPenDown, onPenUp, onPenMove);
 | 
				
			||||||
		Keyboard.get().notify(onKeyDown, onKeyUp, onKeyPress);
 | 
							Keyboard.get().notify(onKeyDown, onKeyUp, onKeyPress);
 | 
				
			||||||
		#if (kha_android || kha_ios)
 | 
							#if (kha_android || kha_ios || kha_html5 || kha_debug_html5)
 | 
				
			||||||
		if (Surface.get() != null) Surface.get().notify(onTouchDown, onTouchUp, onTouchMove);
 | 
							if (Surface.get() != null) Surface.get().notify(onTouchDown, onTouchUp, onTouchMove);
 | 
				
			||||||
		#end
 | 
							#end
 | 
				
			||||||
		// Reset mouse delta on foreground
 | 
							// Reset mouse delta on foreground
 | 
				
			||||||
@ -268,7 +265,7 @@ class Zui {
 | 
				
			|||||||
		Mouse.get().removeWindowed(ops.khaWindowId, onMouseDown, onMouseUp, onMouseMove, onMouseWheel);
 | 
							Mouse.get().removeWindowed(ops.khaWindowId, onMouseDown, onMouseUp, onMouseMove, onMouseWheel);
 | 
				
			||||||
		if (Pen.get() != null) Pen.get().remove(onPenDown, onPenUp, onPenMove);
 | 
							if (Pen.get() != null) Pen.get().remove(onPenDown, onPenUp, onPenMove);
 | 
				
			||||||
		Keyboard.get().remove(onKeyDown, onKeyUp, onKeyPress);
 | 
							Keyboard.get().remove(onKeyDown, onKeyUp, onKeyPress);
 | 
				
			||||||
		#if (kha_android || kha_ios)
 | 
							#if (kha_android || kha_ios || kha_html5 || kha_debug_html5)
 | 
				
			||||||
		if (Surface.get() != null) Surface.get().remove(onTouchDown, onTouchUp, onTouchMove);
 | 
							if (Surface.get() != null) Surface.get().remove(onTouchDown, onTouchUp, onTouchMove);
 | 
				
			||||||
		#end
 | 
							#end
 | 
				
			||||||
		endInput();
 | 
							endInput();
 | 
				
			||||||
@ -1760,7 +1757,7 @@ class Zui {
 | 
				
			|||||||
		button == 0 ? inputStarted = true : inputStartedR = true;
 | 
							button == 0 ? inputStarted = true : inputStartedR = true;
 | 
				
			||||||
		button == 0 ? inputDown = true : inputDownR = true;
 | 
							button == 0 ? inputDown = true : inputDownR = true;
 | 
				
			||||||
		inputStartedTime = kha.Scheduler.time();
 | 
							inputStartedTime = kha.Scheduler.time();
 | 
				
			||||||
		#if (kha_android || kha_ios)
 | 
							#if (kha_android || kha_ios || kha_html5 || kha_debug_html5)
 | 
				
			||||||
		setInputPosition(x, y);
 | 
							setInputPosition(x, y);
 | 
				
			||||||
		#end
 | 
							#end
 | 
				
			||||||
		inputStartedX = x;
 | 
							inputStartedX = x;
 | 
				
			||||||
@ -1787,7 +1784,7 @@ class Zui {
 | 
				
			|||||||
			button == 0 ? inputReleased = true : inputReleasedR = true;
 | 
								button == 0 ? inputReleased = true : inputReleasedR = true;
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		button == 0 ? inputDown = false : inputDownR = false;
 | 
							button == 0 ? inputDown = false : inputDownR = false;
 | 
				
			||||||
		#if (kha_android || kha_ios)
 | 
							#if (kha_android || kha_ios || kha_html5 || kha_debug_html5)
 | 
				
			||||||
		setInputPosition(x, y);
 | 
							setInputPosition(x, y);
 | 
				
			||||||
		#end
 | 
							#end
 | 
				
			||||||
		deselectText();
 | 
							deselectText();
 | 
				
			||||||
@ -1811,7 +1808,7 @@ class Zui {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function onPenDown(x: Int, y: Int, pressure: Float) {
 | 
						public function onPenDown(x: Int, y: Int, pressure: Float) {
 | 
				
			||||||
		#if (kha_android || kha_ios)
 | 
							#if (kha_android || kha_ios || kha_html5 || kha_debug_html5)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
		#end
 | 
							#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1819,7 +1816,7 @@ class Zui {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function onPenUp(x: Int, y: Int, pressure: Float) {
 | 
						public function onPenUp(x: Int, y: Int, pressure: Float) {
 | 
				
			||||||
		#if (kha_android || kha_ios)
 | 
							#if (kha_android || kha_ios || kha_html5 || kha_debug_html5)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
		#end
 | 
							#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1829,7 +1826,7 @@ class Zui {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	public function onPenMove(x: Int, y: Int, pressure: Float) {
 | 
						public function onPenMove(x: Int, y: Int, pressure: Float) {
 | 
				
			||||||
		#if (kha_android || kha_ios)
 | 
							#if (kha_android || kha_ios || kha_html5 || kha_debug_html5)
 | 
				
			||||||
		return;
 | 
							return;
 | 
				
			||||||
		#end
 | 
							#end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1889,7 +1886,7 @@ class Zui {
 | 
				
			|||||||
		isKeyPressed = true;
 | 
							isKeyPressed = true;
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	#if (kha_android || kha_ios)
 | 
						#if (kha_android || kha_ios || kha_html5 || kha_debug_html5)
 | 
				
			||||||
	public function onTouchDown(index: Int, x: Int, y: Int) {
 | 
						public function onTouchDown(index: Int, x: Int, y: Int) {
 | 
				
			||||||
		// Reset movement delta on touch start
 | 
							// Reset movement delta on touch start
 | 
				
			||||||
		if (index == 0) {
 | 
							if (index == 0) {
 | 
				
			||||||
 | 
				
			|||||||
@ -324,6 +324,20 @@ class LeenkxExporter:
 | 
				
			|||||||
    def export_object_transform(self, bobject: bpy.types.Object, o):
 | 
					    def export_object_transform(self, bobject: bpy.types.Object, o):
 | 
				
			||||||
        wrd = bpy.data.worlds['Lnx']
 | 
					        wrd = bpy.data.worlds['Lnx']
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # HACK: In Blender 4.2.x, each camera must be selected to ensure its matrix is correctly assigned
 | 
				
			||||||
 | 
					        if bpy.app.version >= (4, 2, 0) and bobject.type == 'CAMERA' and bobject.users_scene:
 | 
				
			||||||
 | 
					            current_scene = bpy.context.window.scene
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bpy.context.window.scene = bobject.users_scene[0]
 | 
				
			||||||
 | 
					            bpy.context.view_layer.update()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bobject.select_set(True)
 | 
				
			||||||
 | 
					            bpy.context.view_layer.update()
 | 
				
			||||||
 | 
					            bobject.select_set(False)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					            bpy.context.window.scene = current_scene
 | 
				
			||||||
 | 
					            bpy.context.view_layer.update()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        # Static transform
 | 
					        # Static transform
 | 
				
			||||||
        o['transform'] = {'values': LeenkxExporter.write_matrix(bobject.matrix_local)}
 | 
					        o['transform'] = {'values': LeenkxExporter.write_matrix(bobject.matrix_local)}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -1001,7 +1015,8 @@ class LeenkxExporter:
 | 
				
			|||||||
                    action = actions.get('leenkxpose')
 | 
					                    action = actions.get('leenkxpose')
 | 
				
			||||||
                    if action is None:
 | 
					                    if action is None:
 | 
				
			||||||
                        action = actions.new(name='leenkxpose')
 | 
					                        action = actions.new(name='leenkxpose')
 | 
				
			||||||
 | 
					                    adata.action = action
 | 
				
			||||||
 | 
					                    
 | 
				
			||||||
                # Export actions
 | 
					                # Export actions
 | 
				
			||||||
                export_actions = [action]
 | 
					                export_actions = [action]
 | 
				
			||||||
                # hasattr - armature modifier may reference non-parent
 | 
					                # hasattr - armature modifier may reference non-parent
 | 
				
			||||||
@ -1551,8 +1566,7 @@ class LeenkxExporter:
 | 
				
			|||||||
                        log.error(e.message)
 | 
					                        log.error(e.message)
 | 
				
			||||||
                    else:
 | 
					                    else:
 | 
				
			||||||
                        # Assume it was caused because of encountering n-gons
 | 
					                        # Assume it was caused because of encountering n-gons
 | 
				
			||||||
                        log.error(f"""object {bobject.name} contains n-gons in its mesh, so it's impossible to compute tanget space for normal mapping.
 | 
					                        log.error(f"""object {bobject.name} contains n-gons in its mesh, so it's impossible to compute tanget space for normal mapping. Make sure the mesh only has tris/quads.""")
 | 
				
			||||||
Make sure the mesh only has tris/quads.""")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
                tangdata = np.empty(num_verts * 3, dtype='<f4')
 | 
					                tangdata = np.empty(num_verts * 3, dtype='<f4')
 | 
				
			||||||
        if has_col:
 | 
					        if has_col:
 | 
				
			||||||
@ -3025,14 +3039,15 @@ Make sure the mesh only has tris/quads.""")
 | 
				
			|||||||
            if rbw is not None and rbw.enabled:
 | 
					            if rbw is not None and rbw.enabled:
 | 
				
			||||||
                out_trait['parameters'] = [str(rbw.time_scale), str(rbw.substeps_per_frame), str(rbw.solver_iterations)]
 | 
					                out_trait['parameters'] = [str(rbw.time_scale), str(rbw.substeps_per_frame), str(rbw.solver_iterations)]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                if phys_pkg == 'bullet':
 | 
					                if phys_pkg == 'bullet' or phys_pkg == 'oimo':
 | 
				
			||||||
                    debug_draw_mode = 1 if wrd.lnx_bullet_dbg_draw_wireframe else 0
 | 
					                    debug_draw_mode = 1 if wrd.lnx_physics_dbg_draw_wireframe else 0
 | 
				
			||||||
                    debug_draw_mode |= 2 if wrd.lnx_bullet_dbg_draw_aabb else 0
 | 
					                    debug_draw_mode |= 2 if wrd.lnx_physics_dbg_draw_aabb else 0
 | 
				
			||||||
                    debug_draw_mode |= 8 if wrd.lnx_bullet_dbg_draw_contact_points else 0
 | 
					                    debug_draw_mode |= 8 if wrd.lnx_physics_dbg_draw_contact_points else 0
 | 
				
			||||||
                    debug_draw_mode |= 2048 if wrd.lnx_bullet_dbg_draw_constraints else 0
 | 
					                    debug_draw_mode |= 2048 if wrd.lnx_physics_dbg_draw_constraints else 0
 | 
				
			||||||
                    debug_draw_mode |= 4096 if wrd.lnx_bullet_dbg_draw_constraint_limits else 0
 | 
					                    debug_draw_mode |= 4096 if wrd.lnx_physics_dbg_draw_constraint_limits else 0
 | 
				
			||||||
                    debug_draw_mode |= 16384 if wrd.lnx_bullet_dbg_draw_normals else 0
 | 
					                    debug_draw_mode |= 16384 if wrd.lnx_physics_dbg_draw_normals else 0
 | 
				
			||||||
                    debug_draw_mode |= 32768 if wrd.lnx_bullet_dbg_draw_axis_gizmo else 0
 | 
					                    debug_draw_mode |= 32768 if wrd.lnx_physics_dbg_draw_axis_gizmo else 0
 | 
				
			||||||
 | 
					                    debug_draw_mode |= 65536 if wrd.lnx_physics_dbg_draw_raycast else 0
 | 
				
			||||||
                    out_trait['parameters'].append(str(debug_draw_mode))
 | 
					                    out_trait['parameters'].append(str(debug_draw_mode))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            self.output['traits'].append(out_trait)
 | 
					            self.output['traits'].append(out_trait)
 | 
				
			||||||
 | 
				
			|||||||
@ -132,6 +132,7 @@ def always() -> float:
 | 
				
			|||||||
    return 0.5
 | 
					    return 0.5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def poll_threads() -> float:
 | 
					def poll_threads() -> float:
 | 
				
			||||||
    """Polls the thread callback queue and if a thread has finished, it
 | 
					    """Polls the thread callback queue and if a thread has finished, it
 | 
				
			||||||
    is joined with the main thread and the corresponding callback is
 | 
					    is joined with the main thread and the corresponding callback is
 | 
				
			||||||
@ -141,21 +142,27 @@ def poll_threads() -> float:
 | 
				
			|||||||
        thread, callback = make.thread_callback_queue.get(block=False)
 | 
					        thread, callback = make.thread_callback_queue.get(block=False)
 | 
				
			||||||
    except queue.Empty:
 | 
					    except queue.Empty:
 | 
				
			||||||
        return 0.25
 | 
					        return 0.25
 | 
				
			||||||
 | 
					    if thread.is_alive():
 | 
				
			||||||
    thread.join()
 | 
					        try:
 | 
				
			||||||
 | 
					            make.thread_callback_queue.put((thread, callback), block=False)
 | 
				
			||||||
    try:
 | 
					        except queue.Full:
 | 
				
			||||||
        callback()
 | 
					            return 0.5
 | 
				
			||||||
    except Exception as e:
 | 
					        return 0.1 
 | 
				
			||||||
        # If there is an exception, we can no longer return the time to
 | 
					    else:
 | 
				
			||||||
        # the next call to this polling function, so to keep it running
 | 
					        try:
 | 
				
			||||||
        # we re-register it and then raise the original exception.
 | 
					            thread.join()
 | 
				
			||||||
        bpy.app.timers.unregister(poll_threads)
 | 
					            callback()
 | 
				
			||||||
        bpy.app.timers.register(poll_threads, first_interval=0.01, persistent=True)
 | 
					        except Exception as e:
 | 
				
			||||||
        raise e
 | 
					            # If there is an exception, we can no longer return the time to
 | 
				
			||||||
 | 
					            # the next call to this polling function, so to keep it running
 | 
				
			||||||
    # Quickly check if another thread has finished
 | 
					            # we re-register it and then raise the original exception.
 | 
				
			||||||
    return 0.01
 | 
					            try:
 | 
				
			||||||
 | 
					                bpy.app.timers.unregister(poll_threads)
 | 
				
			||||||
 | 
					            except ValueError:
 | 
				
			||||||
 | 
					                pass
 | 
				
			||||||
 | 
					            bpy.app.timers.register(poll_threads, first_interval=0.01, persistent=True)
 | 
				
			||||||
 | 
					        # Quickly check if another thread has finished
 | 
				
			||||||
 | 
					        return 0.01
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
loaded_py_libraries: dict[str, types.ModuleType] = {}
 | 
					loaded_py_libraries: dict[str, types.ModuleType] = {}
 | 
				
			||||||
 | 
				
			|||||||
@ -7,48 +7,46 @@ if lnx.is_reload(__name__):
 | 
				
			|||||||
else:
 | 
					else:
 | 
				
			||||||
    lnx.enable_reload(__name__)
 | 
					    lnx.enable_reload(__name__)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
lnx.keymaps = []
 | 
					#lnx.keymaps = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
def register():
 | 
					def register():
 | 
				
			||||||
    wm = bpy.context.window_manager
 | 
					    wm = bpy.context.window_manager
 | 
				
			||||||
    addon_keyconfig = wm.keyconfigs.addon
 | 
					    keyconfig = wm.keyconfigs.user
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
    # Keyconfigs are not available in background mode. If the keyconfig
 | 
					    # Keyconfigs are not available in background mode. If the keyconfig
 | 
				
			||||||
    # was not found despite running _not_ in background mode, a warning
 | 
					    # was not found despite running _not_ in background mode, a warning
 | 
				
			||||||
    # is printed
 | 
					    # is printed
 | 
				
			||||||
    if addon_keyconfig is None:
 | 
					    if keyconfig is None:
 | 
				
			||||||
        if not bpy.app.background:
 | 
					        if not bpy.app.background:
 | 
				
			||||||
            log.warn("No keyconfig path found")
 | 
					            log.warn("No keyconfig path found")
 | 
				
			||||||
        return
 | 
					        return
 | 
				
			||||||
 | 
					    km = keyconfig.keymaps.get('Window')
 | 
				
			||||||
    km = addon_keyconfig.keymaps.new(name='Window', space_type='EMPTY', region_type="WINDOW")
 | 
					    if km is None:
 | 
				
			||||||
    km.keymap_items.new(props_ui.LeenkxPlayButton.bl_idname, type='F5', value='PRESS')
 | 
					        log.warn("Window keymaps not available")
 | 
				
			||||||
    km.keymap_items.new("tlm.build_lightmaps", type='F6', value='PRESS')
 | 
					        return
 | 
				
			||||||
    km.keymap_items.new("tlm.clean_lightmaps", type='F7', value='PRESS')
 | 
					    lnx_start = any(kmi.idname == props_ui.LeenkxPlayButton.bl_idname for kmi in km.keymap_items)
 | 
				
			||||||
    lnx.keymaps.append(km)
 | 
					    if not lnx_start:
 | 
				
			||||||
 | 
					        kmw = keyconfig.keymaps.new(name='Window', space_type='EMPTY', region_type="WINDOW")
 | 
				
			||||||
    km = addon_keyconfig.keymaps.new(name='Node Editor', space_type='NODE_EDITOR')
 | 
					        kmw.keymap_items.new(props_ui.LeenkxPlayButton.bl_idname, type='F5', value='PRESS')
 | 
				
			||||||
 | 
					        kmw.keymap_items.new('tlm.build_lightmaps', type='F6', value='PRESS')
 | 
				
			||||||
    # shift+G: Create a new node call group node
 | 
					        kmw.keymap_items.new('tlm.clean_lightmaps', type='F7', value='PRESS')
 | 
				
			||||||
    km.keymap_items.new('lnx.add_call_group_node', 'G', 'PRESS', shift=True)
 | 
					        kmn = keyconfig.keymaps.new(name='Node Editor', space_type='NODE_EDITOR')
 | 
				
			||||||
 | 
					        kmn.keymap_items.new('lnx.add_call_group_node', 'G', 'PRESS', shift=True)
 | 
				
			||||||
    # ctrl+G: make node group from selected
 | 
					        kmn.keymap_items.new('lnx.add_group_tree_from_selected', 'G', 'PRESS', ctrl=True)
 | 
				
			||||||
    km.keymap_items.new('lnx.add_group_tree_from_selected', 'G', 'PRESS', ctrl=True)
 | 
					        kmn.keymap_items.new('lnx.edit_group_tree', 'TAB', 'PRESS')
 | 
				
			||||||
 | 
					        kmn.keymap_items.new('node.tree_path_parent', 'TAB', 'PRESS', ctrl=True)
 | 
				
			||||||
    # TAB: enter node groups depending on selection
 | 
					        kmn.keymap_items.new('lnx.ungroup_group_tree', 'G', 'PRESS', alt=True)
 | 
				
			||||||
    km.keymap_items.new('lnx.edit_group_tree', 'TAB', 'PRESS')
 | 
					        
 | 
				
			||||||
 | 
					 | 
				
			||||||
    # ctrl+TAB: exit node groups depending on selectio
 | 
					 | 
				
			||||||
    km.keymap_items.new('node.tree_path_parent', 'TAB', 'PRESS', ctrl=True)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    # alt+G: ungroup node tree
 | 
					 | 
				
			||||||
    km.keymap_items.new('lnx.ungroup_group_tree', 'G', 'PRESS', alt=True)
 | 
					 | 
				
			||||||
    lnx.keymaps.append(km)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
def unregister():
 | 
					def unregister():
 | 
				
			||||||
    wm = bpy.context.window_manager
 | 
					    kmw = bpy.context.window_manager.keyconfigs.user.keymaps.get('Window')
 | 
				
			||||||
    for km in lnx.keymaps:
 | 
					    kmw.keymap_items.remove(kmw.keymap_items[props_ui.LeenkxPlayButton.bl_idname])
 | 
				
			||||||
        wm.keyconfigs.addon.keymaps.remove(km)
 | 
					    kmw.keymap_items.remove(kmw.keymap_items['tlm.build_lightmaps'])
 | 
				
			||||||
    del lnx.keymaps[:]
 | 
					    kmw.keymap_items.remove(kmw.keymap_items['tlm.clean_lightmaps'])
 | 
				
			||||||
 | 
					    kmn = bpy.context.window_manager.keyconfigs.user.keymaps.get('Node Editor')
 | 
				
			||||||
 | 
					    kmn.keymap_items.remove(kmn.keymap_items['lnx.add_call_group_node'])
 | 
				
			||||||
 | 
					    kmn.keymap_items.remove(kmn.keymap_items['lnx.add_group_tree_from_selected'])
 | 
				
			||||||
 | 
					    kmn.keymap_items.remove(kmn.keymap_items['lnx.edit_group_tree'])
 | 
				
			||||||
 | 
					    kmn.keymap_items.remove(kmn.keymap_items['node.tree_path_parent'])
 | 
				
			||||||
 | 
					    kmn.keymap_items.remove(kmn.keymap_items['lnx.ungroup_group_tree'])
 | 
				
			||||||
 | 
				
			|||||||
@ -5,7 +5,8 @@ class TLM_Logman:
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    _log = []
 | 
					    _log = []
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        super(TLM_Logman, self).__init__(*args, **kwargs)
 | 
				
			||||||
        print("Logger started Init")
 | 
					        print("Logger started Init")
 | 
				
			||||||
        self.append("Logger started.")
 | 
					        self.append("Logger started.")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -1,25 +1,25 @@
 | 
				
			|||||||
from lnx.logicnode.lnx_nodes import *
 | 
					from lnx.logicnode.lnx_nodes import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class BlendActionNode(LnxLogicTreeNode):
 | 
					class BlendActionNode(LnxLogicTreeNode):
 | 
				
			||||||
    """Interpolates between the two given actions."""
 | 
					    """Interpolates between the two given actions."""
 | 
				
			||||||
    bl_idname = 'LNBlendActionNode'
 | 
					    bl_idname = 'LNBlendActionNode'
 | 
				
			||||||
    bl_label = 'Blend Action'
 | 
					    bl_label = 'Blend Action'
 | 
				
			||||||
    lnx_version = 2
 | 
					    lnx_version = 2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
        self.add_input('LnxNodeSocketObject', 'Object')
 | 
					        self.add_input('LnxNodeSocketObject', 'Object')
 | 
				
			||||||
        self.add_input('LnxNodeSocketAnimTree', 'Action 1')
 | 
					        self.add_input('LnxNodeSocketAnimTree', 'Action 1')
 | 
				
			||||||
        self.add_input('LnxNodeSocketAnimTree', 'Action 2')
 | 
					        self.add_input('LnxNodeSocketAnimTree', 'Action 2')
 | 
				
			||||||
        self.add_input('ArmFactorSocket', 'Factor', default_value = 0.5)
 | 
					        self.add_input('LnxFactorSocket', 'Factor', default_value = 0.5)
 | 
				
			||||||
        self.add_input('LnxIntSocket', 'Bone Group', default_value = -1)
 | 
					        self.add_input('LnxIntSocket', 'Bone Group', default_value = -1)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.add_output('LnxNodeSocketAnimTree', 'Result')
 | 
					        self.add_output('LnxNodeSocketAnimTree', 'Result')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def get_replacement_node(self, node_tree: bpy.types.NodeTree):
 | 
					    def get_replacement_node(self, node_tree: bpy.types.NodeTree):
 | 
				
			||||||
        if self.lnx_version not in (0, 1):
 | 
					        if self.lnx_version not in (0, 1):
 | 
				
			||||||
            raise LookupError()
 | 
					            raise LookupError()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return NodeReplacement(
 | 
					        return NodeReplacement(
 | 
				
			||||||
            'LNBlendActionNode', self.lnx_version, 'LNBlendActionNode', 2,
 | 
					            'LNBlendActionNode', self.lnx_version, 'LNBlendActionNode', 2,
 | 
				
			||||||
            in_socket_mapping={}, out_socket_mapping={}
 | 
					            in_socket_mapping={}, out_socket_mapping={}
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
 | 
				
			|||||||
@ -90,7 +90,8 @@ class BlendSpaceNode(LnxLogicTreeNode):
 | 
				
			|||||||
    draw_handler_dict = {}
 | 
					    draw_handler_dict = {}
 | 
				
			||||||
    modal_handler_dict = {}
 | 
					    modal_handler_dict = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        super(BlendSpaceNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        array_nodes[str(id(self))] = self
 | 
					        array_nodes[str(id(self))] = self
 | 
				
			||||||
        if self.advanced_draw_run:
 | 
					        if self.advanced_draw_run:
 | 
				
			||||||
            self.add_advanced_draw()
 | 
					            self.add_advanced_draw()
 | 
				
			||||||
@ -112,8 +113,8 @@ class BlendSpaceNode(LnxLogicTreeNode):
 | 
				
			|||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
        self.add_input('LnxNodeSocketObject', 'Object')
 | 
					        self.add_input('LnxNodeSocketObject', 'Object')
 | 
				
			||||||
        self.add_input('LnxNodeSocketArray', 'Actions')
 | 
					        self.add_input('LnxNodeSocketArray', 'Actions')
 | 
				
			||||||
        self.add_input('ArmBlendSpaceSocket', 'Cursor X')
 | 
					        self.add_input('LnxBlendSpaceSocket', 'Cursor X')
 | 
				
			||||||
        self.add_input('ArmBlendSpaceSocket', 'Cursor Y')
 | 
					        self.add_input('LnxBlendSpaceSocket', 'Cursor Y')
 | 
				
			||||||
        self.add_output('LnxNodeSocketAnimTree', 'Out')
 | 
					        self.add_output('LnxNodeSocketAnimTree', 'Out')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def add_advanced_draw(self):
 | 
					    def add_advanced_draw(self):
 | 
				
			||||||
 | 
				
			|||||||
@ -45,7 +45,7 @@ class BoneIKNode(LnxLogicTreeNode):
 | 
				
			|||||||
        self.add_input('LnxBoolSocket', 'Enable Pole')
 | 
					        self.add_input('LnxBoolSocket', 'Enable Pole')
 | 
				
			||||||
        self.add_input('LnxVectorSocket', 'Pole Position')
 | 
					        self.add_input('LnxVectorSocket', 'Pole Position')
 | 
				
			||||||
        self.add_input('LnxFloatSocket', 'Roll Angle')
 | 
					        self.add_input('LnxFloatSocket', 'Roll Angle')
 | 
				
			||||||
        self.add_input('ArmFactorSocket', 'Influence', default_value = 1.0)
 | 
					        self.add_input('LnxFactorSocket', 'Influence', default_value = 1.0)
 | 
				
			||||||
        self.add_input('LnxIntSocket', 'Bone Group', default_value = 0)
 | 
					        self.add_input('LnxIntSocket', 'Bone Group', default_value = 0)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.add_output('LnxNodeSocketAnimTree', 'Result')
 | 
					        self.add_output('LnxNodeSocketAnimTree', 'Result')
 | 
				
			||||||
 | 
				
			|||||||
@ -8,8 +8,8 @@ class OneShotActionMultiNode(LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_version = 1
 | 
					    lnx_version = 1
 | 
				
			||||||
    min_inputs = 10
 | 
					    min_inputs = 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(OneShotActionMultiNode, self).__init__()
 | 
					        super(OneShotActionMultiNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        array_nodes[self.get_id_str()] = self
 | 
					        array_nodes[self.get_id_str()] = self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    property0: HaxeStringProperty('property0', name = 'Action ID', default = '')
 | 
					    property0: HaxeStringProperty('property0', name = 'Action ID', default = '')
 | 
				
			||||||
 | 
				
			|||||||
@ -0,0 +1,16 @@
 | 
				
			|||||||
 | 
					from lnx.logicnode.lnx_nodes import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class SetBoneTransformNode(LnxLogicTreeNode):
 | 
				
			||||||
 | 
					    """Sets the bones transform in world space."""
 | 
				
			||||||
 | 
					    bl_idname = 'LNSetBoneTransformNode'
 | 
				
			||||||
 | 
					    bl_label = 'Set Bone Transform'
 | 
				
			||||||
 | 
					    lnx_version = 1
 | 
				
			||||||
 | 
					    lnx_section = 'armature'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
					        self.add_input('LnxNodeSocketAction', 'In')
 | 
				
			||||||
 | 
					        self.add_input('LnxNodeSocketObject', 'Object')
 | 
				
			||||||
 | 
					        self.add_input('LnxStringSocket', 'Bone')
 | 
				
			||||||
 | 
					        self.add_input('LnxDynamicSocket', 'Transform')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.add_output('LnxNodeSocketAction', 'Out')
 | 
				
			||||||
@ -12,5 +12,7 @@ class SetParentBoneNode(LnxLogicTreeNode):
 | 
				
			|||||||
        self.add_input('LnxNodeSocketObject', 'Object')
 | 
					        self.add_input('LnxNodeSocketObject', 'Object')
 | 
				
			||||||
        self.add_input('LnxNodeSocketObject', 'Parent')
 | 
					        self.add_input('LnxNodeSocketObject', 'Parent')
 | 
				
			||||||
        self.add_input('LnxStringSocket', 'Bone', default_value='Bone')
 | 
					        self.add_input('LnxStringSocket', 'Bone', default_value='Bone')
 | 
				
			||||||
 | 
					        self.add_input('LnxBoolSocket', 'Set Inverse')
 | 
				
			||||||
 | 
					        self.add_input('LnxBoolSocket', 'Keep Transform')
 | 
				
			||||||
 | 
					              
 | 
				
			||||||
        self.add_output('LnxNodeSocketAction', 'Out')
 | 
					        self.add_output('LnxNodeSocketAction', 'Out')
 | 
				
			||||||
 | 
				
			|||||||
@ -7,8 +7,8 @@ class SwitchActionMultiNode(LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_version = 1
 | 
					    lnx_version = 1
 | 
				
			||||||
    min_inputs = 8
 | 
					    min_inputs = 8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(SwitchActionMultiNode, self).__init__()
 | 
					        super(SwitchActionMultiNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        array_nodes[self.get_id_str()] = self
 | 
					        array_nodes[self.get_id_str()] = self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -9,7 +9,8 @@ class ArrayNode(LnxLogicVariableNodeMixin, LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_section = 'variable'
 | 
					    lnx_section = 'variable'
 | 
				
			||||||
    min_inputs = 0
 | 
					    min_inputs = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        super(ArrayNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        self.register_id()
 | 
					        self.register_id()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -12,8 +12,8 @@ class ArrayAddNode(LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_version = 5
 | 
					    lnx_version = 5
 | 
				
			||||||
    min_inputs = 6
 | 
					    min_inputs = 6
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(ArrayAddNode, self).__init__()
 | 
					        super(ArrayAddNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        array_nodes[self.get_id_str()] = self
 | 
					        array_nodes[self.get_id_str()] = self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,8 @@ class BooleanArrayNode(LnxLogicVariableNodeMixin, LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_section = 'variable'
 | 
					    lnx_section = 'variable'
 | 
				
			||||||
    min_inputs = 0
 | 
					    min_inputs = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(BooleanArrayNode, self).__init__()
 | 
					        super(BooleanArrayNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        self.register_id()
 | 
					        self.register_id()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,8 @@ class ColorArrayNode(LnxLogicVariableNodeMixin, LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_section = 'variable'
 | 
					    lnx_section = 'variable'
 | 
				
			||||||
    min_inputs = 0
 | 
					    min_inputs = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(ColorArrayNode, self).__init__()
 | 
					        super(ColorArrayNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        self.register_id()
 | 
					        self.register_id()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,8 @@ class FloatArrayNode(LnxLogicVariableNodeMixin, LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_section = 'variable'
 | 
					    lnx_section = 'variable'
 | 
				
			||||||
    min_inputs = 0
 | 
					    min_inputs = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(FloatArrayNode, self).__init__()
 | 
					        super(FloatArrayNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        self.register_id()
 | 
					        self.register_id()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										13
									
								
								leenkx/blender/lnx/logicnode/array/LN_array_index_list.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					from lnx.logicnode.lnx_nodes import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					class ArrayIndexNode(LnxLogicTreeNode):
 | 
				
			||||||
 | 
					    """Returns the array index list of the given value as an array."""
 | 
				
			||||||
 | 
					    bl_idname = 'LNArrayIndexListNode'
 | 
				
			||||||
 | 
					    bl_label = 'Array Index List'
 | 
				
			||||||
 | 
					    lnx_version = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
					        self.add_input('LnxNodeSocketArray', 'Array')
 | 
				
			||||||
 | 
					        self.add_input('LnxDynamicSocket', 'Value')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        self.add_output('LnxNodeSocketArray', 'Array')
 | 
				
			||||||
@ -9,8 +9,8 @@ class IntegerArrayNode(LnxLogicVariableNodeMixin, LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_section = 'variable'
 | 
					    lnx_section = 'variable'
 | 
				
			||||||
    min_inputs = 0
 | 
					    min_inputs = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(IntegerArrayNode, self).__init__()
 | 
					        super(IntegerArrayNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        self.register_id()
 | 
					        self.register_id()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,8 @@ class ObjectArrayNode(LnxLogicVariableNodeMixin, LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_section = 'variable'
 | 
					    lnx_section = 'variable'
 | 
				
			||||||
    min_inputs = 0
 | 
					    min_inputs = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(ObjectArrayNode, self).__init__()
 | 
					        super(ObjectArrayNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        self.register_id()
 | 
					        self.register_id()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -8,7 +8,8 @@ class ArrayRemoveValueNode(LnxLogicTreeNode):
 | 
				
			|||||||
    bl_label = 'Array Remove by Value'
 | 
					    bl_label = 'Array Remove by Value'
 | 
				
			||||||
    lnx_version = 1
 | 
					    lnx_version = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    # def __init__(self):
 | 
					    # def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        # super(ArrayRemoveValueNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        # array_nodes[str(id(self))] = self
 | 
					        # array_nodes[str(id(self))] = self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,8 @@ class StringArrayNode(LnxLogicVariableNodeMixin, LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_section = 'variable'
 | 
					    lnx_section = 'variable'
 | 
				
			||||||
    min_inputs = 0
 | 
					    min_inputs = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(StringArrayNode, self).__init__()
 | 
					        super(StringArrayNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        self.register_id()
 | 
					        self.register_id()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -9,8 +9,9 @@ class VectorArrayNode(LnxLogicVariableNodeMixin, LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_section = 'variable'
 | 
					    lnx_section = 'variable'
 | 
				
			||||||
    min_inputs = 0
 | 
					    min_inputs = 0
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
        super(VectorArrayNode, self).__init__()
 | 
					        super(VectorArrayNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        self.register_id()
 | 
					        self.register_id()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def lnx_init(self, context):
 | 
					    def lnx_init(self, context):
 | 
				
			||||||
 | 
				
			|||||||
@ -35,4 +35,4 @@ class LoadUrlNode(LnxLogicTreeNode):
 | 
				
			|||||||
        if self.lnx_version not in (0, 1):
 | 
					        if self.lnx_version not in (0, 1):
 | 
				
			||||||
            raise LookupError()
 | 
					            raise LookupError()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return NodeReplacement.Identity(self)
 | 
					        return NodeReplacement.Identity(self)
 | 
				
			||||||
@ -9,7 +9,8 @@ class AddTorrentNode(LnxLogicTreeNode):
 | 
				
			|||||||
    lnx_category = 'Leenkx'
 | 
					    lnx_category = 'Leenkx'
 | 
				
			||||||
    lnx_version = 1
 | 
					    lnx_version = 1
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def __init__(self):
 | 
					    def __init__(self, *args, **kwargs):
 | 
				
			||||||
 | 
					        super(AddTorrentNode, self).__init__(*args, **kwargs)
 | 
				
			||||||
        array_nodes[str(id(self))] = self
 | 
					        array_nodes[str(id(self))] = self
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||