* 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 |