* new models_magicavoxel_loading example * Portable header-only file "magicavoxel_loader.h" for MagicaVoxel loader example. * models_magicavoxel_loading example added to CMakeLists.txt and Makefile * fix models_magicavoxel_loading example for linux. * * vox_loader into "src/external/vox_loader.h" * vox file support for "models.c" * updated example "models/models_magicavoxel_loading.c" * * Fix Vox_FreeArrays (removed memory leak) * * removed magicavoxel_loader.h * * Revert vs2019 solutionpull/1978/head
| @ -0,0 +1,153 @@ | |||
| /******************************************************************************************* | |||
| * | |||
| * raylib [models] example - magicavoxel loader and viewer | |||
| * | |||
| * This example has been created using raylib 3.8 (www.raylib.com) | |||
| * raylib is licensed under an unmodified zlib/libpng license (View raylib.h for details) | |||
| * | |||
| * Example contributed by Johann Nadalutti | |||
| * | |||
| * Copyright (c) 2021 Johann Nadalutti | |||
| * | |||
| ********************************************************************************************/ | |||
| #include "raylib.h" | |||
| #include "raymath.h" | |||
| #include <string.h> | |||
| // VOX Files to load and view | |||
| #define NUM_VOX_FILES 3 | |||
| const char* szVoxFiles[] = { | |||
| "resources/vox/chr_knight.vox", | |||
| "resources/vox/chr_sword.vox", | |||
| "resources/vox/monu9.vox" | |||
| }; | |||
| int main(void) | |||
| { | |||
| // Initialization | |||
| //-------------------------------------------------------------------------------------- | |||
| const int screenWidth = 800; | |||
| const int screenHeight = 450; | |||
| InitWindow(screenWidth, screenHeight, "raylib [models] example - magicavoxel loading"); | |||
| // Load MagicaVoxel files | |||
| Model models[NUM_VOX_FILES] = { 0 }; | |||
| for (int i = 0; i < NUM_VOX_FILES; i++) | |||
| { | |||
| // Load MagicaVoxel File and build model | |||
| double t0, t1; | |||
| t0 = GetTime() * 1000.0; | |||
| models[i] = LoadModel(szVoxFiles[i]); | |||
| t1 = GetTime() * 1000.0; | |||
| TraceLog(LOG_INFO, TextFormat("Vox <%s> loaded in %f ms", GetFileName(szVoxFiles[i]), t1 - t0)); | |||
| //Compute model matrix | |||
| BoundingBox bb = GetModelBoundingBox(models[i]); | |||
| Vector3 center; | |||
| center.x = -(((bb.max.x - bb.min.x) / 2)); | |||
| center.y = -(((bb.max.y - bb.min.y) / 2)); | |||
| center.z = -(((bb.max.z - bb.min.z) / 2)); | |||
| Matrix matP = MatrixTranslate(center.x, center.z, 0); | |||
| Matrix matR = MatrixRotateX(90 * DEG2RAD); | |||
| models[i].transform = MatrixMultiply(matP, matR); | |||
| } | |||
| // Define the camera to look into our 3d world | |||
| Camera camera = { { 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f, 0 }; | |||
| // Model drawing position | |||
| Vector3 position = { 0.0f, 0.0f, 0.0f }; | |||
| int currentModel = 0; | |||
| SetCameraMode(camera, CAMERA_ORBITAL); // Set a orbital camera mode | |||
| SetTargetFPS(60); // Set our game to run at 60 frames-per-second | |||
| //-------------------------------------------------------------------------------------- | |||
| // Main game loop | |||
| //-------------------------------------------------------------------------------------- | |||
| while (!WindowShouldClose()) // Detect window close button or ESC key | |||
| { | |||
| //-------------------------------------------------------------------------------------- | |||
| // Update | |||
| //---------------------------------------------------------------------------------- | |||
| UpdateCamera(&camera); // Update internal camera and our camera | |||
| if (IsMouseButtonPressed(MOUSE_BUTTON_LEFT)) | |||
| { | |||
| currentModel = (currentModel + 1) % NUM_VOX_FILES; // Cycle between models | |||
| } | |||
| if (IsKeyPressed(KEY_RIGHT)) | |||
| { | |||
| currentModel++; | |||
| if (currentModel >= NUM_VOX_FILES) currentModel = 0; | |||
| } | |||
| else if (IsKeyPressed(KEY_LEFT)) | |||
| { | |||
| currentModel--; | |||
| if (currentModel < 0) currentModel = NUM_VOX_FILES - 1; | |||
| } | |||
| //---------------------------------------------------------------------------------- | |||
| // Draw | |||
| //---------------------------------------------------------------------------------- | |||
| BeginDrawing(); | |||
| ClearBackground(RAYWHITE); | |||
| //Display model | |||
| BeginMode3D(camera); | |||
| Vector3 rotAxis = { 1,0,0 }; | |||
| Vector3 scale = { 1,1,1 }; | |||
| DrawModelEx(models[currentModel], position, rotAxis, 0, scale, WHITE); | |||
| //DrawModelWiresEx(models[currentModel], position, rotAxis, -90.0f, scale, BLACK); | |||
| DrawGrid(10, 1.0); | |||
| EndMode3D(); | |||
| //Display debug infos | |||
| DrawRectangle(30, 400, 310, 30, Fade(SKYBLUE, 0.5f)); | |||
| DrawRectangleLines(30, 400, 310, 30, Fade(DARKBLUE, 0.5f)); | |||
| DrawText("MOUSE LEFT BUTTON to CYCLE VOX MODELS", 40, 410, 10, BLUE); | |||
| DrawText(GetFileName(szVoxFiles[currentModel]), 100, 10, 20, DARKBLUE); | |||
| EndDrawing(); | |||
| //---------------------------------------------------------------------------------- | |||
| } | |||
| // De-Initialization | |||
| //-------------------------------------------------------------------------------------- | |||
| // Unload models data (GPU VRAM) | |||
| for (int i = 0; i < NUM_VOX_FILES; i++) UnloadModel(models[i]); | |||
| CloseWindow(); // Close window and OpenGL context | |||
| //-------------------------------------------------------------------------------------- | |||
| return 0; | |||
| } | |||
| @ -0,0 +1,387 @@ | |||
| <?xml version="1.0" encoding="utf-8"?> | |||
| <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> | |||
| <ItemGroup Label="ProjectConfigurations"> | |||
| <ProjectConfiguration Include="Debug.DLL|Win32"> | |||
| <Configuration>Debug.DLL</Configuration> | |||
| <Platform>Win32</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Debug.DLL|x64"> | |||
| <Configuration>Debug.DLL</Configuration> | |||
| <Platform>x64</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Debug|Win32"> | |||
| <Configuration>Debug</Configuration> | |||
| <Platform>Win32</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Debug|x64"> | |||
| <Configuration>Debug</Configuration> | |||
| <Platform>x64</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Release.DLL|Win32"> | |||
| <Configuration>Release.DLL</Configuration> | |||
| <Platform>Win32</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Release.DLL|x64"> | |||
| <Configuration>Release.DLL</Configuration> | |||
| <Platform>x64</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Release|Win32"> | |||
| <Configuration>Release</Configuration> | |||
| <Platform>Win32</Platform> | |||
| </ProjectConfiguration> | |||
| <ProjectConfiguration Include="Release|x64"> | |||
| <Configuration>Release</Configuration> | |||
| <Platform>x64</Platform> | |||
| </ProjectConfiguration> | |||
| </ItemGroup> | |||
| <PropertyGroup Label="Globals"> | |||
| <ProjectGuid>{2F1B955B-275E-4D8E-8864-06FEC44D7912}</ProjectGuid> | |||
| <Keyword>Win32Proj</Keyword> | |||
| <RootNamespace>models_mesh_magicavoxel_loading</RootNamespace> | |||
| <WindowsTargetPlatformVersion>10.0</WindowsTargetPlatformVersion> | |||
| <ProjectName>models_mesh_magicavoxel_loading</ProjectName> | |||
| </PropertyGroup> | |||
| <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" /> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration"> | |||
| <ConfigurationType>Application</ConfigurationType> | |||
| <UseDebugLibraries>true</UseDebugLibraries> | |||
| <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | |||
| <CharacterSet>Unicode</CharacterSet> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration"> | |||
| <ConfigurationType>Application</ConfigurationType> | |||
| <UseDebugLibraries>true</UseDebugLibraries> | |||
| <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | |||
| <CharacterSet>Unicode</CharacterSet> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="Configuration"> | |||
| <ConfigurationType>Application</ConfigurationType> | |||
| <UseDebugLibraries>true</UseDebugLibraries> | |||
| <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | |||
| <CharacterSet>Unicode</CharacterSet> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="Configuration"> | |||
| <ConfigurationType>Application</ConfigurationType> | |||
| <UseDebugLibraries>true</UseDebugLibraries> | |||
| <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | |||
| <CharacterSet>Unicode</CharacterSet> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration"> | |||
| <ConfigurationType>Application</ConfigurationType> | |||
| <UseDebugLibraries>false</UseDebugLibraries> | |||
| <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | |||
| <WholeProgramOptimization>true</WholeProgramOptimization> | |||
| <CharacterSet>Unicode</CharacterSet> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration"> | |||
| <ConfigurationType>Application</ConfigurationType> | |||
| <UseDebugLibraries>false</UseDebugLibraries> | |||
| <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | |||
| <WholeProgramOptimization>true</WholeProgramOptimization> | |||
| <CharacterSet>Unicode</CharacterSet> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="Configuration"> | |||
| <ConfigurationType>Application</ConfigurationType> | |||
| <UseDebugLibraries>false</UseDebugLibraries> | |||
| <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | |||
| <WholeProgramOptimization>true</WholeProgramOptimization> | |||
| <CharacterSet>Unicode</CharacterSet> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="Configuration"> | |||
| <ConfigurationType>Application</ConfigurationType> | |||
| <UseDebugLibraries>false</UseDebugLibraries> | |||
| <PlatformToolset>$(DefaultPlatformToolset)</PlatformToolset> | |||
| <WholeProgramOptimization>true</WholeProgramOptimization> | |||
| <CharacterSet>Unicode</CharacterSet> | |||
| </PropertyGroup> | |||
| <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" /> | |||
| <ImportGroup Label="ExtensionSettings"> | |||
| </ImportGroup> | |||
| <ImportGroup Label="Shared"> | |||
| </ImportGroup> | |||
| <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
| </ImportGroup> | |||
| <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets"> | |||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
| </ImportGroup> | |||
| <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'" Label="PropertySheets"> | |||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
| </ImportGroup> | |||
| <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'" Label="PropertySheets"> | |||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
| </ImportGroup> | |||
| <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
| </ImportGroup> | |||
| <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets"> | |||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
| </ImportGroup> | |||
| <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'" Label="PropertySheets"> | |||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
| </ImportGroup> | |||
| <ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'" Label="PropertySheets"> | |||
| <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" /> | |||
| </ImportGroup> | |||
| <PropertyGroup Label="UserMacros" /> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||
| <LinkIncremental>true</LinkIncremental> | |||
| <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> | |||
| <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||
| <LinkIncremental>true</LinkIncremental> | |||
| <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> | |||
| <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> | |||
| <LinkIncremental>true</LinkIncremental> | |||
| <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> | |||
| <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> | |||
| <LinkIncremental>true</LinkIncremental> | |||
| <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> | |||
| <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||
| <LinkIncremental>false</LinkIncremental> | |||
| <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> | |||
| <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||
| <LinkIncremental>false</LinkIncremental> | |||
| <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> | |||
| <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> | |||
| <LinkIncremental>false</LinkIncremental> | |||
| <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> | |||
| <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> | |||
| <LinkIncremental>false</LinkIncremental> | |||
| <OutDir>$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)\</OutDir> | |||
| <IntDir>$(SolutionDir)\build\$(ProjectName)\obj\$(Platform)\$(Configuration)\</IntDir> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> | |||
| <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> | |||
| <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> | |||
| <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> | |||
| <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||
| <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> | |||
| <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||
| <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> | |||
| <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> | |||
| <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> | |||
| <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||
| <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> | |||
| <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||
| <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> | |||
| <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | |||
| </PropertyGroup> | |||
| <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> | |||
| <LocalDebuggerWorkingDirectory>$(SolutionDir)..\..\examples\models</LocalDebuggerWorkingDirectory> | |||
| <DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor> | |||
| </PropertyGroup> | |||
| <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'"> | |||
| <ClCompile> | |||
| <PrecompiledHeader> | |||
| </PrecompiledHeader> | |||
| <WarningLevel>Level3</WarningLevel> | |||
| <Optimization>Disabled</Optimization> | |||
| <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||
| <CompileAs>CompileAsC</CompileAs> | |||
| <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
| </ClCompile> | |||
| <Link> | |||
| <SubSystem>Console</SubSystem> | |||
| <GenerateDebugInformation>true</GenerateDebugInformation> | |||
| <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> | |||
| <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> | |||
| </Link> | |||
| </ItemDefinitionGroup> | |||
| <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'"> | |||
| <ClCompile> | |||
| <PrecompiledHeader> | |||
| </PrecompiledHeader> | |||
| <WarningLevel>Level3</WarningLevel> | |||
| <Optimization>Disabled</Optimization> | |||
| <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||
| <CompileAs>CompileAsC</CompileAs> | |||
| <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
| <AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions> | |||
| </ClCompile> | |||
| <Link> | |||
| <SubSystem>Console</SubSystem> | |||
| <GenerateDebugInformation>true</GenerateDebugInformation> | |||
| <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> | |||
| <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> | |||
| </Link> | |||
| </ItemDefinitionGroup> | |||
| <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|Win32'"> | |||
| <ClCompile> | |||
| <PrecompiledHeader> | |||
| </PrecompiledHeader> | |||
| <WarningLevel>Level3</WarningLevel> | |||
| <Optimization>Disabled</Optimization> | |||
| <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||
| <CompileAs>CompileAsC</CompileAs> | |||
| <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
| </ClCompile> | |||
| <Link> | |||
| <SubSystem>Console</SubSystem> | |||
| <GenerateDebugInformation>true</GenerateDebugInformation> | |||
| <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> | |||
| <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> | |||
| </Link> | |||
| <PostBuildEvent> | |||
| <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> | |||
| <Message>Copy Debug DLL to output directory</Message> | |||
| </PostBuildEvent> | |||
| </ItemDefinitionGroup> | |||
| <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug.DLL|x64'"> | |||
| <ClCompile> | |||
| <PrecompiledHeader> | |||
| </PrecompiledHeader> | |||
| <WarningLevel>Level3</WarningLevel> | |||
| <Optimization>Disabled</Optimization> | |||
| <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;PLATFORM_DESKTOP;%(PreprocessorDefinitions)</PreprocessorDefinitions> | |||
| <CompileAs>CompileAsC</CompileAs> | |||
| <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
| </ClCompile> | |||
| <Link> | |||
| <SubSystem>Console</SubSystem> | |||
| <GenerateDebugInformation>true</GenerateDebugInformation> | |||
| <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> | |||
| <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> | |||
| </Link> | |||
| <PostBuildEvent> | |||
| <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> | |||
| <Message>Copy Debug DLL to output directory</Message> | |||
| </PostBuildEvent> | |||
| </ItemDefinitionGroup> | |||
| <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'"> | |||
| <ClCompile> | |||
| <WarningLevel>Level3</WarningLevel> | |||
| <PrecompiledHeader> | |||
| </PrecompiledHeader> | |||
| <Optimization>MaxSpeed</Optimization> | |||
| <FunctionLevelLinking>true</FunctionLevelLinking> | |||
| <IntrinsicFunctions>true</IntrinsicFunctions> | |||
| <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> | |||
| <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
| <CompileAs>CompileAsC</CompileAs> | |||
| <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> | |||
| </ClCompile> | |||
| <Link> | |||
| <SubSystem>Console</SubSystem> | |||
| <EnableCOMDATFolding>true</EnableCOMDATFolding> | |||
| <OptimizeReferences>true</OptimizeReferences> | |||
| <GenerateDebugInformation>true</GenerateDebugInformation> | |||
| <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> | |||
| <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> | |||
| </Link> | |||
| </ItemDefinitionGroup> | |||
| <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'"> | |||
| <ClCompile> | |||
| <WarningLevel>Level3</WarningLevel> | |||
| <PrecompiledHeader> | |||
| </PrecompiledHeader> | |||
| <Optimization>MaxSpeed</Optimization> | |||
| <FunctionLevelLinking>true</FunctionLevelLinking> | |||
| <IntrinsicFunctions>true</IntrinsicFunctions> | |||
| <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> | |||
| <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
| <CompileAs>CompileAsC</CompileAs> | |||
| <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> | |||
| </ClCompile> | |||
| <Link> | |||
| <SubSystem>Console</SubSystem> | |||
| <EnableCOMDATFolding>true</EnableCOMDATFolding> | |||
| <OptimizeReferences>true</OptimizeReferences> | |||
| <GenerateDebugInformation>true</GenerateDebugInformation> | |||
| <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> | |||
| <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> | |||
| </Link> | |||
| </ItemDefinitionGroup> | |||
| <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|Win32'"> | |||
| <ClCompile> | |||
| <WarningLevel>Level3</WarningLevel> | |||
| <PrecompiledHeader> | |||
| </PrecompiledHeader> | |||
| <Optimization>MaxSpeed</Optimization> | |||
| <FunctionLevelLinking>true</FunctionLevelLinking> | |||
| <IntrinsicFunctions>true</IntrinsicFunctions> | |||
| <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> | |||
| <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
| <CompileAs>CompileAsC</CompileAs> | |||
| <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> | |||
| </ClCompile> | |||
| <Link> | |||
| <SubSystem>Console</SubSystem> | |||
| <EnableCOMDATFolding>true</EnableCOMDATFolding> | |||
| <OptimizeReferences>true</OptimizeReferences> | |||
| <GenerateDebugInformation>true</GenerateDebugInformation> | |||
| <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> | |||
| <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> | |||
| </Link> | |||
| <PostBuildEvent> | |||
| <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> | |||
| </PostBuildEvent> | |||
| <PostBuildEvent> | |||
| <Message>Copy Release DLL to output directory</Message> | |||
| </PostBuildEvent> | |||
| </ItemDefinitionGroup> | |||
| <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release.DLL|x64'"> | |||
| <ClCompile> | |||
| <WarningLevel>Level3</WarningLevel> | |||
| <PrecompiledHeader> | |||
| </PrecompiledHeader> | |||
| <Optimization>MaxSpeed</Optimization> | |||
| <FunctionLevelLinking>true</FunctionLevelLinking> | |||
| <IntrinsicFunctions>true</IntrinsicFunctions> | |||
| <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions);PLATFORM_DESKTOP</PreprocessorDefinitions> | |||
| <AdditionalIncludeDirectories>$(SolutionDir)..\..\src;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> | |||
| <CompileAs>CompileAsC</CompileAs> | |||
| <RemoveUnreferencedCodeData>true</RemoveUnreferencedCodeData> | |||
| </ClCompile> | |||
| <Link> | |||
| <SubSystem>Console</SubSystem> | |||
| <EnableCOMDATFolding>true</EnableCOMDATFolding> | |||
| <OptimizeReferences>true</OptimizeReferences> | |||
| <GenerateDebugInformation>true</GenerateDebugInformation> | |||
| <AdditionalDependencies>raylib.lib;opengl32.lib;kernel32.lib;user32.lib;gdi32.lib;winmm.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;%(AdditionalDependencies)</AdditionalDependencies> | |||
| <AdditionalLibraryDirectories>$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\</AdditionalLibraryDirectories> | |||
| </Link> | |||
| <PostBuildEvent> | |||
| <Command>xcopy /y /d "$(SolutionDir)\build\raylib\bin\$(Platform)\$(Configuration)\raylib.dll" "$(SolutionDir)\build\$(ProjectName)\bin\$(Platform)\$(Configuration)"</Command> | |||
| </PostBuildEvent> | |||
| <PostBuildEvent> | |||
| <Message>Copy Release DLL to output directory</Message> | |||
| </PostBuildEvent> | |||
| </ItemDefinitionGroup> | |||
| <ItemGroup> | |||
| <ProjectReference Include="..\raylib\raylib.vcxproj"> | |||
| <Project>{e89d61ac-55de-4482-afd4-df7242ebc859}</Project> | |||
| </ProjectReference> | |||
| </ItemGroup> | |||
| <ItemGroup> | |||
| <ClCompile Include="..\..\..\examples\models\models_magicavoxel_loading.c" /> | |||
| </ItemGroup> | |||
| <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" /> | |||
| <ImportGroup Label="ExtensionTargets"> | |||
| </ImportGroup> | |||
| </Project> | |||
| @ -0,0 +1,771 @@ | |||
| /* | |||
| The MIT License (MIT) | |||
| Copyright (c) 2021 Johann Nadalutti. | |||
| Permission is hereby granted, free of charge, to any person obtaining a copy | |||
| of this software and associated documentation files (the "Software"), to deal | |||
| in the Software without restriction, including without limitation the rights | |||
| to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | |||
| copies of the Software, and to permit persons to whom the Software is | |||
| furnished to do so, subject to the following conditions: | |||
| The above copyright notice and this permission notice shall be included in | |||
| all copies or substantial portions of the Software. | |||
| THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | |||
| IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | |||
| FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | |||
| AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | |||
| LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | |||
| OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN | |||
| THE SOFTWARE. | |||
| vox_loader - v1.00 | |||
| no warranty implied; use at your own risk | |||
| Do this: | |||
| #define VOX_LOADER_INCLUDE__H | |||
| before you include this file in* one* C or C++ file to create the implementation. | |||
| // i.e. it should look like this: | |||
| #include ... | |||
| #include ... | |||
| #include ... | |||
| #define VOX_LOADER_INCLUDE__H | |||
| #include "magicavoxel_loader.h" | |||
| revision history: | |||
| 1.00 (2021-09-03) first released version | |||
| */ | |||
| #ifndef VOX_LOADER_H | |||
| #define VOX_LOADER_H | |||
| #include <string.h> | |||
| #ifdef __cplusplus | |||
| extern "C" { | |||
| #endif | |||
| #define VOX_SUCCESS (0) | |||
| #define VOX_ERROR_FILE_NOT_FOUND (-1) | |||
| #define VOX_ERROR_INVALID_FORMAT (-2) | |||
| #define VOX_ERROR_FILE_VERSION_TOO_OLD (-3) | |||
| typedef struct | |||
| { | |||
| int* array; | |||
| int used, size; | |||
| } ArrayInt; | |||
| typedef struct | |||
| { | |||
| Vector3* array; | |||
| int used, size; | |||
| } ArrayVector3; | |||
| typedef struct | |||
| { | |||
| Color* array; | |||
| int used, size; | |||
| } ArrayColor; | |||
| typedef struct | |||
| { | |||
| unsigned short* array; | |||
| int used, size; | |||
| } ArrayUShort; | |||
| // A chunk that contain voxels | |||
| typedef struct | |||
| { | |||
| unsigned char* m_array; //If Sparse != null | |||
| int arraySize; //Size for m_array in bytes (DEBUG ONLY) | |||
| } CubeChunk3D; | |||
| // Array for voxels | |||
| // Array is divised into chunks of CHUNKSIZE*CHUNKSIZE*CHUNKSIZE voxels size | |||
| typedef struct | |||
| { | |||
| //Array size in voxels | |||
| int sizeX; | |||
| int sizeY; | |||
| int sizeZ; | |||
| //Chunks size into array (array is divised into chunks) | |||
| int chunksSizeX; | |||
| int chunksSizeY; | |||
| int chunksSizeZ; | |||
| //Chunks array | |||
| CubeChunk3D* m_arrayChunks; | |||
| int arrayChunksSize; //Size for m_arrayChunks in bytes (DEBUG ONLY) | |||
| int ChunkFlattenOffset; | |||
| int chunksAllocated; | |||
| int chunksTotal; | |||
| //Arrays for mesh build | |||
| ArrayVector3 vertices; | |||
| ArrayUShort indices; | |||
| ArrayColor colors; | |||
| //Palette for voxels | |||
| Color palette[256]; | |||
| } VoxArray3D; | |||
| // Functions | |||
| extern int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray); | |||
| extern void Vox_FreeArrays(VoxArray3D* voxarray); | |||
| #ifdef __cplusplus | |||
| } | |||
| #endif | |||
| //// end header file ///////////////////////////////////////////////////// | |||
| #endif // VOX_LOADER_H | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| // Implementation | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| #ifdef VOX_LOADER_IMPLEMENTATION | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| // ArrayInt helper | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| void initArrayInt(ArrayInt* a, int initialSize) | |||
| { | |||
| a->array = MemAlloc(initialSize * sizeof(int)); | |||
| a->used = 0; | |||
| a->size = initialSize; | |||
| } | |||
| void insertArrayInt(ArrayInt* a, int element) | |||
| { | |||
| if (a->used == a->size) | |||
| { | |||
| a->size *= 2; | |||
| a->array = MemRealloc(a->array, a->size * sizeof(int)); | |||
| } | |||
| a->array[a->used++] = element; | |||
| } | |||
| void freeArrayInt(ArrayInt* a) | |||
| { | |||
| MemFree(a->array); | |||
| a->array = NULL; | |||
| a->used = a->size = 0; | |||
| } | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| // ArrayUShort helper | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| void initArrayUShort(ArrayUShort* a, int initialSize) | |||
| { | |||
| a->array = MemAlloc(initialSize * sizeof(unsigned short)); | |||
| a->used = 0; | |||
| a->size = initialSize; | |||
| } | |||
| void insertArrayUShort(ArrayUShort* a, unsigned short element) | |||
| { | |||
| if (a->used == a->size) | |||
| { | |||
| a->size *= 2; | |||
| a->array = MemRealloc(a->array, a->size * sizeof(unsigned short)); | |||
| } | |||
| a->array[a->used++] = element; | |||
| } | |||
| void freeArrayUShort(ArrayUShort* a) | |||
| { | |||
| MemFree(a->array); | |||
| a->array = NULL; | |||
| a->used = a->size = 0; | |||
| } | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| // ArrayVector3 helper | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| void initArrayVector3(ArrayVector3* a, int initialSize) | |||
| { | |||
| a->array = MemAlloc(initialSize * sizeof(Vector3)); | |||
| a->used = 0; | |||
| a->size = initialSize; | |||
| } | |||
| void insertArrayVector3(ArrayVector3* a, Vector3 element) | |||
| { | |||
| if (a->used == a->size) | |||
| { | |||
| a->size *= 2; | |||
| a->array = MemRealloc(a->array, a->size * sizeof(Vector3)); | |||
| } | |||
| a->array[a->used++] = element; | |||
| } | |||
| void freeArrayVector3(ArrayVector3* a) | |||
| { | |||
| MemFree(a->array); | |||
| a->array = NULL; | |||
| a->used = a->size = 0; | |||
| } | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| // ArrayColor helper | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| void initArrayColor(ArrayColor* a, int initialSize) | |||
| { | |||
| a->array = MemAlloc(initialSize * sizeof(Color)); | |||
| a->used = 0; | |||
| a->size = initialSize; | |||
| } | |||
| void insertArrayColor(ArrayColor* a, Color element) | |||
| { | |||
| if (a->used == a->size) | |||
| { | |||
| a->size *= 2; | |||
| a->array = MemRealloc(a->array, a->size * sizeof(Color)); | |||
| } | |||
| a->array[a->used++] = element; | |||
| } | |||
| void freeArrayColor(ArrayColor* a) | |||
| { | |||
| MemFree(a->array); | |||
| a->array = NULL; | |||
| a->used = a->size = 0; | |||
| } | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| // Vox Loader | |||
| ///////////////////////////////////////////////////////////////////////////////////////////// | |||
| #define CHUNKSIZE 16 // chunk size (CHUNKSIZE*CHUNKSIZE*CHUNKSIZE) in voxels | |||
| #define CHUNKSIZE_OPSHIFT 4 // 1<<4=16 -> Warning depend of CHUNKSIZE | |||
| #define CHUNK_FLATTENOFFSET_OPSHIFT 8 //Warning depend of CHUNKSIZE | |||
| // | |||
| // used right handed system and CCW face | |||
| // | |||
| // indexes for voxelcoords, per face orientation | |||
| // | |||
| //# Y | |||
| //# | | |||
| //# o----X | |||
| //# / | |||
| //# Z 2------------3 | |||
| //# /| /| | |||
| //# 6------------7 | | |||
| //# | | | | | |||
| //# |0 ----------|- 1 | |||
| //# |/ |/ | |||
| //# 4------------5 | |||
| // | |||
| // CCW | |||
| const int fv[6][4] = { | |||
| {0, 2, 6, 4 }, //-X | |||
| {5, 7, 3, 1 }, //+X | |||
| {0, 4, 5, 1 }, //-y | |||
| {6, 2, 3, 7 }, //+y | |||
| {1, 3, 2, 0 }, //-Z | |||
| {4, 6, 7, 5 } };//+Z | |||
| const Vector3 SolidVertex[] = { | |||
| {0, 0, 0}, //0 | |||
| {1, 0, 0}, //1 | |||
| {0, 1, 0}, //2 | |||
| {1, 1, 0}, //3 | |||
| {0, 0, 1}, //4 | |||
| {1, 0, 1}, //5 | |||
| {0, 1, 1}, //6 | |||
| {1, 1, 1} }; //7 | |||
| // Allocated VoxArray3D size | |||
| void Vox_AllocArray(VoxArray3D* voxarray, int _sx, int _sy, int _sz) | |||
| { | |||
| int sx = _sx + ((CHUNKSIZE - (_sx % CHUNKSIZE)) % CHUNKSIZE); | |||
| int sy = _sy + ((CHUNKSIZE - (_sy % CHUNKSIZE)) % CHUNKSIZE); | |||
| int sz = _sz + ((CHUNKSIZE - (_sz % CHUNKSIZE)) % CHUNKSIZE); | |||
| int chx = sx >> CHUNKSIZE_OPSHIFT; //Chunks Count in X | |||
| int chy = sy >> CHUNKSIZE_OPSHIFT; //Chunks Count in Y | |||
| int chz = sz >> CHUNKSIZE_OPSHIFT; //Chunks Count in Z | |||
| //VoxArray3D* parray = (VoxArray3D*)MemAlloc(sizeof(VoxArray3D)); | |||
| voxarray->sizeX = sx; | |||
| voxarray->sizeY = sy; | |||
| voxarray->sizeZ = sz; | |||
| voxarray->chunksSizeX = chx; | |||
| voxarray->chunksSizeY = chy; | |||
| voxarray->chunksSizeZ = chz; | |||
| voxarray->ChunkFlattenOffset = (chy * chz); //m_arrayChunks[(x * (sy*sz)) + (z * sy) + y] | |||
| //Alloc chunks array | |||
| int size = sizeof(CubeChunk3D) * chx * chy * chz; | |||
| voxarray->m_arrayChunks = MemAlloc(size); | |||
| voxarray->arrayChunksSize = size; | |||
| //Init chunks array | |||
| size = chx * chy * chz; | |||
| voxarray->chunksTotal = size; | |||
| voxarray->chunksAllocated = 0; | |||
| for (int i = 0; i < size; i++) | |||
| { | |||
| voxarray->m_arrayChunks[i].m_array = 0; | |||
| voxarray->m_arrayChunks[i].arraySize = 0; | |||
| } | |||
| return voxarray; | |||
| } | |||
| // Set voxel ID from its position into VoxArray3D | |||
| void Vox_SetVoxel(VoxArray3D* voxarray, int x, int y, int z, unsigned char id) | |||
| { | |||
| //Get chunk from array pos | |||
| int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE; | |||
| int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE; | |||
| int chZ = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE; | |||
| int offset = (chX * voxarray->ChunkFlattenOffset) + (chZ * voxarray->chunksSizeY) + chY; | |||
| //if (offset > voxarray->arrayChunksSize) | |||
| //{ | |||
| // TraceLog(LOG_ERROR, "Out of array"); | |||
| //} | |||
| CubeChunk3D* chunk = &voxarray->m_arrayChunks[offset]; | |||
| //Set Chunk | |||
| chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE); | |||
| chY = y - (chY << CHUNKSIZE_OPSHIFT); //y - (by * CHUNKSIZE); | |||
| chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //z - (bz * CHUNKSIZE); | |||
| if (chunk->m_array == 0) | |||
| { | |||
| int size = CHUNKSIZE * CHUNKSIZE * CHUNKSIZE; | |||
| chunk->m_array = MemAlloc(size); | |||
| chunk->arraySize = size; | |||
| //memset(chunk->m_array, 0, size); | |||
| voxarray->chunksAllocated++; | |||
| } | |||
| offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY; | |||
| //if (offset > chunk->arraySize) | |||
| //{ | |||
| // TraceLog(LOG_ERROR, "Out of array"); | |||
| //} | |||
| chunk->m_array[offset] = id; | |||
| } | |||
| // Get voxel ID from its position into VoxArray3D | |||
| unsigned char Vox_GetVoxel(VoxArray3D* voxarray, int x, int y, int z) | |||
| { | |||
| if (x < 0 || y < 0 || z < 0) | |||
| return 0; | |||
| if (x >= voxarray->sizeX || y >= voxarray->sizeY || z >= voxarray->sizeZ) | |||
| return 0; | |||
| //Get chunk from array pos | |||
| int chX = x >> CHUNKSIZE_OPSHIFT; //x / CHUNKSIZE; | |||
| int chY = y >> CHUNKSIZE_OPSHIFT; //y / CHUNKSIZE; | |||
| int chZ = z >> CHUNKSIZE_OPSHIFT; //z / CHUNKSIZE; | |||
| int offset = (chX * voxarray->ChunkFlattenOffset) + (chZ * voxarray->chunksSizeY) + chY; | |||
| //if (offset > voxarray->arrayChunksSize) | |||
| //{ | |||
| // TraceLog(LOG_ERROR, "Out of array"); | |||
| //} | |||
| CubeChunk3D* chunk = &voxarray->m_arrayChunks[offset]; | |||
| //Set Chunk | |||
| chX = x - (chX << CHUNKSIZE_OPSHIFT); //x - (bx * CHUNKSIZE); | |||
| chY = y - (chY << CHUNKSIZE_OPSHIFT); //y - (by * CHUNKSIZE); | |||
| chZ = z - (chZ << CHUNKSIZE_OPSHIFT); //z - (bz * CHUNKSIZE); | |||
| if (chunk->m_array == 0) | |||
| { | |||
| return 0; | |||
| } | |||
| offset = (chX << CHUNK_FLATTENOFFSET_OPSHIFT) + (chZ << CHUNKSIZE_OPSHIFT) + chY; | |||
| //if (offset > chunk->arraySize) | |||
| //{ | |||
| // TraceLog(LOG_ERROR, "Out of array"); | |||
| //} | |||
| return chunk->m_array[offset]; | |||
| } | |||
| // Calc visibles faces from a voxel position | |||
| unsigned char Vox_CalcFacesVisible(VoxArray3D* pvoxArray, int cx, int cy, int cz) | |||
| { | |||
| unsigned char idXm1 = Vox_GetVoxel(pvoxArray, cx - 1, cy, cz); | |||
| unsigned char idXp1 = Vox_GetVoxel(pvoxArray, cx + 1, cy, cz); | |||
| unsigned char idYm1 = Vox_GetVoxel(pvoxArray, cx, cy - 1, cz); | |||
| unsigned char idYp1 = Vox_GetVoxel(pvoxArray, cx, cy + 1, cz); | |||
| unsigned char idZm1 = Vox_GetVoxel(pvoxArray, cx, cy, cz - 1); | |||
| unsigned char idZp1 = Vox_GetVoxel(pvoxArray, cx, cy, cz + 1); | |||
| unsigned char byVFMask = 0; | |||
| //#-x | |||
| if (idXm1 == 0) | |||
| byVFMask |= (1 << 0); | |||
| //#+x | |||
| if (idXp1 == 0) | |||
| byVFMask |= (1 << 1); | |||
| //#-y | |||
| if (idYm1 == 0) | |||
| byVFMask |= (1 << 2); | |||
| //#+y | |||
| if (idYp1 == 0) | |||
| byVFMask |= (1 << 3); | |||
| //#-z | |||
| if (idZm1 == 0) | |||
| byVFMask |= (1 << 4); | |||
| //#+z | |||
| if (idZp1 == 0) | |||
| byVFMask |= (1 << 5); | |||
| return byVFMask; | |||
| } | |||
| // Get a vertex position from a voxel's corner | |||
| Vector3 Vox_GetVertexPosition(int _wcx, int _wcy, int _wcz, int _nNumVertex) | |||
| { | |||
| float scale = 0.25; | |||
| Vector3 vtx = SolidVertex[_nNumVertex]; | |||
| vtx.x = (vtx.x + _wcx) * scale; | |||
| vtx.y = (vtx.y + _wcy) * scale; | |||
| vtx.z = (vtx.z + _wcz) * scale; | |||
| return vtx; | |||
| } | |||
| // Build a voxel vertices/colors/indices | |||
| void Vox_Build_Voxel(VoxArray3D* pvoxArray, int x, int y, int z, int matID) | |||
| { | |||
| unsigned char byVFMask = Vox_CalcFacesVisible(pvoxArray, x, y, z); | |||
| if (byVFMask == 0) | |||
| return; | |||
| int i, j; | |||
| Vector3 vertComputed[8]; | |||
| int bVertexComputed[8]; | |||
| memset(vertComputed, 0, sizeof(vertComputed)); | |||
| memset(bVertexComputed, 0, sizeof(bVertexComputed)); | |||
| //For each Cube's faces | |||
| for (i = 0; i < 6; i++) // 6 faces | |||
| { | |||
| if ((byVFMask & (1 << i)) != 0) //If face is visible | |||
| { | |||
| for (j = 0; j < 4; j++) // 4 corners | |||
| { | |||
| int nNumVertex = fv[i][j]; //Face,Corner | |||
| if (bVertexComputed[nNumVertex] == 0) //if never calc | |||
| { | |||
| bVertexComputed[nNumVertex] = 1; | |||
| vertComputed[nNumVertex] = Vox_GetVertexPosition(x, y, z, nNumVertex); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| //Add face | |||
| for (i = 0; i < 6; i++)// 6 faces | |||
| { | |||
| if ((byVFMask & (1 << i)) == 0) | |||
| continue; //Face invisible | |||
| int v0 = fv[i][0]; //Face, Corner | |||
| int v1 = fv[i][1]; //Face, Corner | |||
| int v2 = fv[i][2]; //Face, Corner | |||
| int v3 = fv[i][3]; //Face, Corner | |||
| //Arrays | |||
| int idx = pvoxArray->vertices.used; | |||
| insertArrayVector3(&pvoxArray->vertices, vertComputed[v0]); | |||
| insertArrayVector3(&pvoxArray->vertices, vertComputed[v1]); | |||
| insertArrayVector3(&pvoxArray->vertices, vertComputed[v2]); | |||
| insertArrayVector3(&pvoxArray->vertices, vertComputed[v3]); | |||
| Color col = pvoxArray->palette[matID]; | |||
| insertArrayColor(&pvoxArray->colors, col); | |||
| insertArrayColor(&pvoxArray->colors, col); | |||
| insertArrayColor(&pvoxArray->colors, col); | |||
| insertArrayColor(&pvoxArray->colors, col); | |||
| //v0 - v1 - v2, v0 - v2 - v3 | |||
| insertArrayUShort(&pvoxArray->indices, idx + 0); | |||
| insertArrayUShort(&pvoxArray->indices, idx + 2); | |||
| insertArrayUShort(&pvoxArray->indices, idx + 1); | |||
| insertArrayUShort(&pvoxArray->indices, idx + 0); | |||
| insertArrayUShort(&pvoxArray->indices, idx + 3); | |||
| insertArrayUShort(&pvoxArray->indices, idx + 2); | |||
| } | |||
| } | |||
| // MagicaVoxel *.vox file format Loader | |||
| int Vox_LoadFileName(const char* pszfileName, VoxArray3D* voxarray) | |||
| { | |||
| ////////////////////////////////////////////////// | |||
| //Read VOX file | |||
| //4 bytes: magic number ('V' 'O' 'X' 'space' ) | |||
| //4 bytes: version number (current version is 150 ) | |||
| unsigned long signature; | |||
| unsigned long readed = 0; | |||
| unsigned char* fileData; | |||
| fileData = LoadFileData(pszfileName, &readed); | |||
| if (fileData == 0) | |||
| { | |||
| return VOX_ERROR_FILE_NOT_FOUND; | |||
| } | |||
| unsigned char* fileDataPtr = fileData; | |||
| unsigned char* endfileDataPtr = fileData + readed; | |||
| signature = *((unsigned long*)fileDataPtr); | |||
| fileDataPtr += sizeof(unsigned long); | |||
| if (signature != 0x20584F56) //56 4F 58 20 | |||
| { | |||
| //TraceLog(LOG_ERROR, "Not an MagicaVoxel File format"); | |||
| return VOX_ERROR_INVALID_FORMAT; | |||
| } | |||
| unsigned long version; | |||
| version = *((unsigned long*)fileDataPtr); | |||
| fileDataPtr += sizeof(unsigned long); | |||
| if (version < 150) | |||
| { | |||
| //TraceLog(LOG_ERROR, "MagicaVoxel version too old"); | |||
| return VOX_ERROR_FILE_VERSION_TOO_OLD; | |||
| } | |||
| // header | |||
| //4 bytes: chunk id | |||
| //4 bytes: size of chunk contents (n) | |||
| //4 bytes: total size of children chunks(m) | |||
| //// chunk content | |||
| //n bytes: chunk contents | |||
| //// children chunks : m bytes | |||
| //{ child chunk 0 } | |||
| //{ child chunk 1 } | |||
| unsigned long sizeX, sizeY, sizeZ; | |||
| sizeX = sizeY = sizeZ = 0; | |||
| unsigned long numVoxels = 0; | |||
| int offsetX, offsetY, offsetZ; | |||
| offsetX = offsetY = offsetZ = 0; | |||
| while (fileDataPtr < endfileDataPtr) | |||
| { | |||
| char szChunkName[5]; | |||
| memcpy(szChunkName, fileDataPtr, 4); | |||
| szChunkName[4] = 0; | |||
| fileDataPtr += 4; | |||
| unsigned long chunkSize = *((unsigned long*)fileDataPtr); | |||
| fileDataPtr += sizeof(unsigned long); | |||
| unsigned long chunkTotalChildSize = *((unsigned long*)fileDataPtr); | |||
| fileDataPtr += sizeof(unsigned long); | |||
| if (strcmp(szChunkName, "SIZE") == 0) | |||
| { | |||
| //(4 bytes x 3 : x, y, z ) | |||
| sizeX = *((unsigned long*)fileDataPtr); | |||
| fileDataPtr += sizeof(unsigned long); | |||
| sizeY = *((unsigned long*)fileDataPtr); | |||
| fileDataPtr += sizeof(unsigned long); | |||
| sizeZ = *((unsigned long*)fileDataPtr); | |||
| fileDataPtr += sizeof(unsigned long); | |||
| //Alloc vox array | |||
| Vox_AllocArray(voxarray, sizeX, sizeY, sizeZ); | |||
| } | |||
| else if (strcmp(szChunkName, "XYZI") == 0) | |||
| { | |||
| unsigned char vx, vy, vz, vi; | |||
| //(numVoxels : 4 bytes ) | |||
| //(each voxel: 1 byte x 4 : x, y, z, colorIndex ) x numVoxels | |||
| numVoxels = *((unsigned long*)fileDataPtr); | |||
| fileDataPtr += sizeof(unsigned long); | |||
| while (numVoxels > 0) | |||
| { | |||
| vx = *((unsigned char*)fileDataPtr++); | |||
| vy = *((unsigned char*)fileDataPtr++); | |||
| vz = *((unsigned char*)fileDataPtr++); | |||
| vi = *((unsigned char*)fileDataPtr++); | |||
| Vox_SetVoxel(voxarray, vx, vy, vz, vi); | |||
| numVoxels--; | |||
| } | |||
| } | |||
| else if (strcmp(szChunkName, "RGBA") == 0) | |||
| { | |||
| Color col; | |||
| //(each pixel: 1 byte x 4 : r, g, b, a ) x 256 | |||
| for (int i = 0; i < 256 - 1; i++) | |||
| { | |||
| col.r = *((unsigned char*)fileDataPtr++); | |||
| col.g = *((unsigned char*)fileDataPtr++); | |||
| col.b = *((unsigned char*)fileDataPtr++); | |||
| col.a = *((unsigned char*)fileDataPtr++); | |||
| voxarray->palette[i + 1] = col; | |||
| } | |||
| } | |||
| else | |||
| { | |||
| fileDataPtr += chunkSize; | |||
| } | |||
| } | |||
| //TraceLog(LOG_INFO, TextFormat("Vox Size : %dx%dx%d", sizeX, sizeY, sizeZ)); | |||
| //TraceLog(LOG_INFO, TextFormat("Vox Chunks Count : %d/%d", pvoxArray->chunksAllocated, pvoxArray->chunksTotal)); | |||
| ////////////////////////////////////////////////////////// | |||
| // Building Mesh | |||
| // TODO compute globals indices array | |||
| //TraceLog(LOG_INFO, TextFormat("Building VOX Mesh : %s", pszfileName)); | |||
| // Init Arrays | |||
| initArrayVector3(&voxarray->vertices, 3 * 1024); | |||
| initArrayUShort(&voxarray->indices, 3 * 1024); | |||
| initArrayColor(&voxarray->colors, 3 * 1024); | |||
| // Create vertices and indices buffers | |||
| int x, y, z; | |||
| for (x = 0; x <= voxarray->sizeX; x++) | |||
| { | |||
| for (z = 0; z <= voxarray->sizeZ; z++) | |||
| { | |||
| for (y = 0; y <= voxarray->sizeY; y++) | |||
| { | |||
| unsigned char matID = Vox_GetVoxel(voxarray, x, y, z); | |||
| if (matID != 0) | |||
| Vox_Build_Voxel(voxarray, x, y, z, matID); | |||
| } | |||
| } | |||
| } | |||
| return VOX_SUCCESS; | |||
| } | |||
| void Vox_FreeArrays(VoxArray3D* voxarray) | |||
| { | |||
| //Free chunks | |||
| if (voxarray->m_arrayChunks != 0) | |||
| { | |||
| for (int i = 0; i < voxarray->chunksTotal; i++) | |||
| { | |||
| CubeChunk3D* chunk = &voxarray->m_arrayChunks[i]; | |||
| if (chunk->m_array != 0) | |||
| { | |||
| chunk->arraySize = 0; | |||
| MemFree(chunk->m_array); | |||
| } | |||
| } | |||
| MemFree(voxarray->m_arrayChunks); | |||
| voxarray->m_arrayChunks = 0; | |||
| voxarray->arrayChunksSize = 0; | |||
| voxarray->chunksSizeX = voxarray->chunksSizeY = voxarray->chunksSizeZ = 0; | |||
| voxarray->chunksTotal = 0; | |||
| voxarray->chunksAllocated = 0; | |||
| voxarray->ChunkFlattenOffset = 0; | |||
| voxarray->sizeX = voxarray->sizeY = voxarray->sizeZ = 0; | |||
| } | |||
| //Free arrays | |||
| freeArrayVector3(&voxarray->vertices); | |||
| freeArrayUShort(&voxarray->indices); | |||
| freeArrayColor(&voxarray->colors); | |||
| } | |||
| #endif //VOX_LOADER_IMPLEMENTATION | |||