mirror of
https://github.com/aharabada/glitchy-engine-beef.git
synced 2026-09-05 21:01:52 +00:00
Compare commits
45
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
499ca0311c | ||
|
|
62c85e9e1f | ||
|
|
8296f1c5cd | ||
|
|
457b43352a | ||
|
|
cc7fb7311f | ||
|
|
5f27b8001a | ||
|
|
0cbb8a4966 | ||
|
|
79adc70f01 | ||
|
|
78ba016b03 | ||
|
|
3e55a1614a | ||
|
|
f0de874572 | ||
|
|
6e02a04a4f | ||
|
|
cd1562f372 | ||
|
|
e8505f6bdb | ||
|
|
66d66d3308 | ||
|
|
88b393157a | ||
|
|
28155ec92c | ||
|
|
1641bafd06 | ||
|
|
76bff3a6c1 | ||
|
|
a507eeb1cd | ||
|
|
77c45db122 | ||
|
|
e12fcaacff | ||
|
|
b31d43820a | ||
|
|
334c2c0366 | ||
|
|
bb520b43ec | ||
|
|
46693666aa | ||
|
|
9e1f648aa0 | ||
|
|
5f5da2ed35 | ||
|
|
fa2277cd99 | ||
|
|
54936d5744 | ||
|
|
04d69717a3 | ||
|
|
3becc1e25b | ||
|
|
e8e6207bc1 | ||
|
|
f4c5bf9c2d | ||
|
|
f4607a6210 | ||
|
|
6a59deb9e2 | ||
|
|
ac1817fe33 | ||
|
|
5855b13873 | ||
|
|
ef5e4ba64f | ||
|
|
4fd9a924a0 | ||
|
|
e60d74fccd | ||
|
|
5e5134a607 | ||
|
|
fd6826785a | ||
|
|
43bcf01299 | ||
|
|
0ee2f5fa9e |
@@ -5,3 +5,6 @@ build/
|
|||||||
recovery/
|
recovery/
|
||||||
vendor/directx
|
vendor/directx
|
||||||
imgui.ini
|
imgui.ini
|
||||||
|
GlitchyEditor/resources/scripts/ScriptCore.dll
|
||||||
|
GlitchyEditor/resources/scripts/ScriptCore.pdb
|
||||||
|
GlitchyEditor/settings.bon
|
||||||
|
|||||||
@@ -31,3 +31,6 @@
|
|||||||
[submodule "GlitchyEngine/vendor/Beef.Linq"]
|
[submodule "GlitchyEngine/vendor/Beef.Linq"]
|
||||||
path = GlitchyEngine/vendor/Beef.Linq
|
path = GlitchyEngine/vendor/Beef.Linq
|
||||||
url = https://github.com/aharabada/Beef.Linq.git
|
url = https://github.com/aharabada/Beef.Linq.git
|
||||||
|
[submodule "GlitchyEngine/vendor/NetHostBeef"]
|
||||||
|
path = GlitchyEngine/vendor/NetHostBeef
|
||||||
|
url = https://github.com/aharabada/NetHostBeef.git
|
||||||
|
|||||||
+2
-2
@@ -1,7 +1,7 @@
|
|||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}}
|
Projects = {Sandbox = {Path = "Sandbox"}, GlitchyEngine = {Path = "GlitchyEngine"}, GlitchLog = {Path = "GlitchLog"}, DirectX = {Path = "GlitchyEngine/vendor/directx/DirectX"}, LodePng = {Path = "vendor/lodepng-beef/lodepng-beef"}, FreeType = {Path = "GlitchyEngine/vendor/freetype"}, cgltf-beef = {Path = "GlitchyEngine/vendor/gltf/cgltf-beef"}, GlitchyEditor = {Path = "GlitchyEditor"}, msdfgen-beef = {Path = "GlitchyEngine/vendor/msdfgen/msdfgen-beef"}, ImGui = {Path = "GlitchyEngine/vendor/imgui/ImGui"}, ImGuiImplDX11 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplDX11"}, ImGuiImplWin32 = {Path = "GlitchyEngine/vendor/imgui/ImGuiImplWin32"}, ImGuizmo = {Path = "GlitchyEngine/vendor/imgui/ImGuizmo"}, GlitchyEngineHelper = {Path = "GlitchyEngineHelper"}, bon = {Path = "GlitchyEngine/vendor/bon"}, box2d-beef = {Path = "GlitchyEngine/vendor/box2D"}, "Beef.Linq" = {Path = "GlitchyEngine/vendor/Beef.Linq/src"}, ScriptCore = {Path = "ScriptCore"}, NetHostBeef = {Path = "GlitchyEngine/vendor/NetHostBeef/NetHostBeef"}}
|
||||||
Unlocked = ["corlib"]
|
Unlocked = ["corlib"]
|
||||||
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq"]}
|
WorkspaceFolders = {GlitchyEngine = ["GlitchyEngine", "GlitchLog", "GlitchyEngineHelper", "ScriptCore"], "GlitchyEngine/Dependencies" = ["cgltf-beef", "DirectX", "FreeType", "ImGui", "ImGuiImplDX11", "ImGuiImplWin32", "ImGuizmo", "LodePng", "msdfgen-beef", "bon", "box2d-beef", "Beef.Linq", "NetHostBeef"]}
|
||||||
|
|
||||||
[Workspace]
|
[Workspace]
|
||||||
StartupProject = "GlitchyEditor"
|
StartupProject = "GlitchyEditor"
|
||||||
|
|||||||
@@ -5,3 +5,6 @@ Dependencies = {corlib = "*", GlitchLog = "*", GlitchyEngine = "*"}
|
|||||||
Name = "GlitchyEditor"
|
Name = "GlitchyEditor"
|
||||||
TargetType = "BeefGUIApplication"
|
TargetType = "BeefGUIApplication"
|
||||||
StartupObject = "GlitchyEngine.Program"
|
StartupObject = "GlitchyEngine.Program"
|
||||||
|
|
||||||
|
[Configs.Debug.Win64]
|
||||||
|
DebugCommandArguments = "\"content\\Scenes\\physics2D.scene\""
|
||||||
|
|||||||
@@ -0,0 +1,398 @@
|
|||||||
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
##
|
||||||
|
## Get latest from https://github.com/github/gitignore/blob/main/VisualStudio.gitignore
|
||||||
|
|
||||||
|
# User-specific files
|
||||||
|
*.rsuser
|
||||||
|
*.suo
|
||||||
|
*.user
|
||||||
|
*.userosscache
|
||||||
|
*.sln.docstates
|
||||||
|
|
||||||
|
# User-specific files (MonoDevelop/Xamarin Studio)
|
||||||
|
*.userprefs
|
||||||
|
|
||||||
|
# Mono auto generated files
|
||||||
|
mono_crash.*
|
||||||
|
|
||||||
|
# Build results
|
||||||
|
[Dd]ebug/
|
||||||
|
[Dd]ebugPublic/
|
||||||
|
[Rr]elease/
|
||||||
|
[Rr]eleases/
|
||||||
|
x64/
|
||||||
|
x86/
|
||||||
|
[Ww][Ii][Nn]32/
|
||||||
|
[Aa][Rr][Mm]/
|
||||||
|
[Aa][Rr][Mm]64/
|
||||||
|
bld/
|
||||||
|
[Bb]in/
|
||||||
|
[Oo]bj/
|
||||||
|
[Ll]og/
|
||||||
|
[Ll]ogs/
|
||||||
|
|
||||||
|
# Visual Studio 2015/2017 cache/options directory
|
||||||
|
.vs/
|
||||||
|
# Uncomment if you have tasks that create the project's static files in wwwroot
|
||||||
|
#wwwroot/
|
||||||
|
|
||||||
|
# Visual Studio 2017 auto generated files
|
||||||
|
Generated\ Files/
|
||||||
|
|
||||||
|
# MSTest test Results
|
||||||
|
[Tt]est[Rr]esult*/
|
||||||
|
[Bb]uild[Ll]og.*
|
||||||
|
|
||||||
|
# NUnit
|
||||||
|
*.VisualState.xml
|
||||||
|
TestResult.xml
|
||||||
|
nunit-*.xml
|
||||||
|
|
||||||
|
# Build Results of an ATL Project
|
||||||
|
[Dd]ebugPS/
|
||||||
|
[Rr]eleasePS/
|
||||||
|
dlldata.c
|
||||||
|
|
||||||
|
# Benchmark Results
|
||||||
|
BenchmarkDotNet.Artifacts/
|
||||||
|
|
||||||
|
# .NET Core
|
||||||
|
project.lock.json
|
||||||
|
project.fragment.lock.json
|
||||||
|
artifacts/
|
||||||
|
|
||||||
|
# ASP.NET Scaffolding
|
||||||
|
ScaffoldingReadMe.txt
|
||||||
|
|
||||||
|
# StyleCop
|
||||||
|
StyleCopReport.xml
|
||||||
|
|
||||||
|
# Files built by Visual Studio
|
||||||
|
*_i.c
|
||||||
|
*_p.c
|
||||||
|
*_h.h
|
||||||
|
*.ilk
|
||||||
|
*.meta
|
||||||
|
*.obj
|
||||||
|
*.iobj
|
||||||
|
*.pch
|
||||||
|
*.pdb
|
||||||
|
*.ipdb
|
||||||
|
*.pgc
|
||||||
|
*.pgd
|
||||||
|
*.rsp
|
||||||
|
*.sbr
|
||||||
|
*.tlb
|
||||||
|
*.tli
|
||||||
|
*.tlh
|
||||||
|
*.tmp
|
||||||
|
*.tmp_proj
|
||||||
|
*_wpftmp.csproj
|
||||||
|
*.log
|
||||||
|
*.tlog
|
||||||
|
*.vspscc
|
||||||
|
*.vssscc
|
||||||
|
.builds
|
||||||
|
*.pidb
|
||||||
|
*.svclog
|
||||||
|
*.scc
|
||||||
|
|
||||||
|
# Chutzpah Test files
|
||||||
|
_Chutzpah*
|
||||||
|
|
||||||
|
# Visual C++ cache files
|
||||||
|
ipch/
|
||||||
|
*.aps
|
||||||
|
*.ncb
|
||||||
|
*.opendb
|
||||||
|
*.opensdf
|
||||||
|
*.sdf
|
||||||
|
*.cachefile
|
||||||
|
*.VC.db
|
||||||
|
*.VC.VC.opendb
|
||||||
|
|
||||||
|
# Visual Studio profiler
|
||||||
|
*.psess
|
||||||
|
*.vsp
|
||||||
|
*.vspx
|
||||||
|
*.sap
|
||||||
|
|
||||||
|
# Visual Studio Trace Files
|
||||||
|
*.e2e
|
||||||
|
|
||||||
|
# TFS 2012 Local Workspace
|
||||||
|
$tf/
|
||||||
|
|
||||||
|
# Guidance Automation Toolkit
|
||||||
|
*.gpState
|
||||||
|
|
||||||
|
# ReSharper is a .NET coding add-in
|
||||||
|
_ReSharper*/
|
||||||
|
*.[Rr]e[Ss]harper
|
||||||
|
*.DotSettings.user
|
||||||
|
|
||||||
|
# TeamCity is a build add-in
|
||||||
|
_TeamCity*
|
||||||
|
|
||||||
|
# DotCover is a Code Coverage Tool
|
||||||
|
*.dotCover
|
||||||
|
|
||||||
|
# AxoCover is a Code Coverage Tool
|
||||||
|
.axoCover/*
|
||||||
|
!.axoCover/settings.json
|
||||||
|
|
||||||
|
# Coverlet is a free, cross platform Code Coverage Tool
|
||||||
|
coverage*.json
|
||||||
|
coverage*.xml
|
||||||
|
coverage*.info
|
||||||
|
|
||||||
|
# Visual Studio code coverage results
|
||||||
|
*.coverage
|
||||||
|
*.coveragexml
|
||||||
|
|
||||||
|
# NCrunch
|
||||||
|
_NCrunch_*
|
||||||
|
.*crunch*.local.xml
|
||||||
|
nCrunchTemp_*
|
||||||
|
|
||||||
|
# MightyMoose
|
||||||
|
*.mm.*
|
||||||
|
AutoTest.Net/
|
||||||
|
|
||||||
|
# Web workbench (sass)
|
||||||
|
.sass-cache/
|
||||||
|
|
||||||
|
# Installshield output folder
|
||||||
|
[Ee]xpress/
|
||||||
|
|
||||||
|
# DocProject is a documentation generator add-in
|
||||||
|
DocProject/buildhelp/
|
||||||
|
DocProject/Help/*.HxT
|
||||||
|
DocProject/Help/*.HxC
|
||||||
|
DocProject/Help/*.hhc
|
||||||
|
DocProject/Help/*.hhk
|
||||||
|
DocProject/Help/*.hhp
|
||||||
|
DocProject/Help/Html2
|
||||||
|
DocProject/Help/html
|
||||||
|
|
||||||
|
# Click-Once directory
|
||||||
|
publish/
|
||||||
|
|
||||||
|
# Publish Web Output
|
||||||
|
*.[Pp]ublish.xml
|
||||||
|
*.azurePubxml
|
||||||
|
# Note: Comment the next line if you want to checkin your web deploy settings,
|
||||||
|
# but database connection strings (with potential passwords) will be unencrypted
|
||||||
|
*.pubxml
|
||||||
|
*.publishproj
|
||||||
|
|
||||||
|
# Microsoft Azure Web App publish settings. Comment the next line if you want to
|
||||||
|
# checkin your Azure Web App publish settings, but sensitive information contained
|
||||||
|
# in these scripts will be unencrypted
|
||||||
|
PublishScripts/
|
||||||
|
|
||||||
|
# NuGet Packages
|
||||||
|
*.nupkg
|
||||||
|
# NuGet Symbol Packages
|
||||||
|
*.snupkg
|
||||||
|
# The packages folder can be ignored because of Package Restore
|
||||||
|
**/[Pp]ackages/*
|
||||||
|
# except build/, which is used as an MSBuild target.
|
||||||
|
!**/[Pp]ackages/build/
|
||||||
|
# Uncomment if necessary however generally it will be regenerated when needed
|
||||||
|
#!**/[Pp]ackages/repositories.config
|
||||||
|
# NuGet v3's project.json files produces more ignorable files
|
||||||
|
*.nuget.props
|
||||||
|
*.nuget.targets
|
||||||
|
|
||||||
|
# Microsoft Azure Build Output
|
||||||
|
csx/
|
||||||
|
*.build.csdef
|
||||||
|
|
||||||
|
# Microsoft Azure Emulator
|
||||||
|
ecf/
|
||||||
|
rcf/
|
||||||
|
|
||||||
|
# Windows Store app package directories and files
|
||||||
|
AppPackages/
|
||||||
|
BundleArtifacts/
|
||||||
|
Package.StoreAssociation.xml
|
||||||
|
_pkginfo.txt
|
||||||
|
*.appx
|
||||||
|
*.appxbundle
|
||||||
|
*.appxupload
|
||||||
|
|
||||||
|
# Visual Studio cache files
|
||||||
|
# files ending in .cache can be ignored
|
||||||
|
*.[Cc]ache
|
||||||
|
# but keep track of directories ending in .cache
|
||||||
|
!?*.[Cc]ache/
|
||||||
|
|
||||||
|
# Others
|
||||||
|
ClientBin/
|
||||||
|
~$*
|
||||||
|
*~
|
||||||
|
*.dbmdl
|
||||||
|
*.dbproj.schemaview
|
||||||
|
*.jfm
|
||||||
|
*.pfx
|
||||||
|
*.publishsettings
|
||||||
|
orleans.codegen.cs
|
||||||
|
|
||||||
|
# Including strong name files can present a security risk
|
||||||
|
# (https://github.com/github/gitignore/pull/2483#issue-259490424)
|
||||||
|
#*.snk
|
||||||
|
|
||||||
|
# Since there are multiple workflows, uncomment next line to ignore bower_components
|
||||||
|
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
|
||||||
|
#bower_components/
|
||||||
|
|
||||||
|
# RIA/Silverlight projects
|
||||||
|
Generated_Code/
|
||||||
|
|
||||||
|
# Backup & report files from converting an old project file
|
||||||
|
# to a newer Visual Studio version. Backup files are not needed,
|
||||||
|
# because we have git ;-)
|
||||||
|
_UpgradeReport_Files/
|
||||||
|
Backup*/
|
||||||
|
UpgradeLog*.XML
|
||||||
|
UpgradeLog*.htm
|
||||||
|
ServiceFabricBackup/
|
||||||
|
*.rptproj.bak
|
||||||
|
|
||||||
|
# SQL Server files
|
||||||
|
*.mdf
|
||||||
|
*.ldf
|
||||||
|
*.ndf
|
||||||
|
|
||||||
|
# Business Intelligence projects
|
||||||
|
*.rdl.data
|
||||||
|
*.bim.layout
|
||||||
|
*.bim_*.settings
|
||||||
|
*.rptproj.rsuser
|
||||||
|
*- [Bb]ackup.rdl
|
||||||
|
*- [Bb]ackup ([0-9]).rdl
|
||||||
|
*- [Bb]ackup ([0-9][0-9]).rdl
|
||||||
|
|
||||||
|
# Microsoft Fakes
|
||||||
|
FakesAssemblies/
|
||||||
|
|
||||||
|
# GhostDoc plugin setting file
|
||||||
|
*.GhostDoc.xml
|
||||||
|
|
||||||
|
# Node.js Tools for Visual Studio
|
||||||
|
.ntvs_analysis.dat
|
||||||
|
node_modules/
|
||||||
|
|
||||||
|
# Visual Studio 6 build log
|
||||||
|
*.plg
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace options file
|
||||||
|
*.opt
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
|
||||||
|
*.vbw
|
||||||
|
|
||||||
|
# Visual Studio 6 auto-generated project file (contains which files were open etc.)
|
||||||
|
*.vbp
|
||||||
|
|
||||||
|
# Visual Studio 6 workspace and project file (working project files containing files to include in project)
|
||||||
|
*.dsw
|
||||||
|
*.dsp
|
||||||
|
|
||||||
|
# Visual Studio 6 technical files
|
||||||
|
*.ncb
|
||||||
|
*.aps
|
||||||
|
|
||||||
|
# Visual Studio LightSwitch build output
|
||||||
|
**/*.HTMLClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/GeneratedArtifacts
|
||||||
|
**/*.DesktopClient/ModelManifest.xml
|
||||||
|
**/*.Server/GeneratedArtifacts
|
||||||
|
**/*.Server/ModelManifest.xml
|
||||||
|
_Pvt_Extensions
|
||||||
|
|
||||||
|
# Paket dependency manager
|
||||||
|
.paket/paket.exe
|
||||||
|
paket-files/
|
||||||
|
|
||||||
|
# FAKE - F# Make
|
||||||
|
.fake/
|
||||||
|
|
||||||
|
# CodeRush personal settings
|
||||||
|
.cr/personal
|
||||||
|
|
||||||
|
# Python Tools for Visual Studio (PTVS)
|
||||||
|
__pycache__/
|
||||||
|
*.pyc
|
||||||
|
|
||||||
|
# Cake - Uncomment if you are using it
|
||||||
|
# tools/**
|
||||||
|
# !tools/packages.config
|
||||||
|
|
||||||
|
# Tabs Studio
|
||||||
|
*.tss
|
||||||
|
|
||||||
|
# Telerik's JustMock configuration file
|
||||||
|
*.jmconfig
|
||||||
|
|
||||||
|
# BizTalk build output
|
||||||
|
*.btp.cs
|
||||||
|
*.btm.cs
|
||||||
|
*.odx.cs
|
||||||
|
*.xsd.cs
|
||||||
|
|
||||||
|
# OpenCover UI analysis results
|
||||||
|
OpenCover/
|
||||||
|
|
||||||
|
# Azure Stream Analytics local run output
|
||||||
|
ASALocalRun/
|
||||||
|
|
||||||
|
# MSBuild Binary and Structured Log
|
||||||
|
*.binlog
|
||||||
|
|
||||||
|
# NVidia Nsight GPU debugger configuration file
|
||||||
|
*.nvuser
|
||||||
|
|
||||||
|
# MFractors (Xamarin productivity tool) working folder
|
||||||
|
.mfractor/
|
||||||
|
|
||||||
|
# Local History for Visual Studio
|
||||||
|
.localhistory/
|
||||||
|
|
||||||
|
# Visual Studio History (VSHistory) files
|
||||||
|
.vshistory/
|
||||||
|
|
||||||
|
# BeatPulse healthcheck temp database
|
||||||
|
healthchecksdb
|
||||||
|
|
||||||
|
# Backup folder for Package Reference Convert tool in Visual Studio 2017
|
||||||
|
MigrationBackup/
|
||||||
|
|
||||||
|
# Ionide (cross platform F# VS Code tools) working folder
|
||||||
|
.ionide/
|
||||||
|
|
||||||
|
# Fody - auto-generated XML schema
|
||||||
|
FodyWeavers.xsd
|
||||||
|
|
||||||
|
# VS Code files for those working on multiple tools
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
*.code-workspace
|
||||||
|
|
||||||
|
# Local History for Visual Studio Code
|
||||||
|
.history/
|
||||||
|
|
||||||
|
# Windows Installer files from build outputs
|
||||||
|
*.cab
|
||||||
|
*.msi
|
||||||
|
*.msix
|
||||||
|
*.msm
|
||||||
|
*.msp
|
||||||
|
|
||||||
|
# JetBrains Rider
|
||||||
|
*.sln.iml
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using GlitchyEngine;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
|
||||||
|
using static GlitchyEngine.Math.Math;
|
||||||
|
|
||||||
|
namespace Sandbox;
|
||||||
|
public class Camera : Entity
|
||||||
|
{
|
||||||
|
public float DistanceFromPlayer = 5.0f;
|
||||||
|
|
||||||
|
public float DontFollowRadius = 3.0f;
|
||||||
|
|
||||||
|
void OnCreate()
|
||||||
|
{
|
||||||
|
Log.Info("Camera Create");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void OnUpdate(float deltaTime)
|
||||||
|
{
|
||||||
|
Log.Info($"Camera Update {deltaTime}");
|
||||||
|
|
||||||
|
//Entity player = FindEntityWithName("Player");
|
||||||
|
|
||||||
|
//if (player != null)
|
||||||
|
//{
|
||||||
|
// float2 playerPosition = player.Transform.Translation.XY;
|
||||||
|
|
||||||
|
// float2 cameraPosition = Transform.Translation.XY;
|
||||||
|
|
||||||
|
// float2 distanceVector = playerPosition - cameraPosition;
|
||||||
|
|
||||||
|
// float distance = length(distanceVector);
|
||||||
|
|
||||||
|
// float2 neededMovement = float2.Zero;
|
||||||
|
|
||||||
|
// if (distance > DontFollowRadius)
|
||||||
|
// {
|
||||||
|
// neededMovement = distanceVector - (distanceVector / distance) * DontFollowRadius;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// Transform.Translation = new float3(cameraPosition + neededMovement, DistanceFromPlayer);
|
||||||
|
//}
|
||||||
|
//else
|
||||||
|
//{
|
||||||
|
// Log.Error("Player not found!");
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,126 @@
|
|||||||
|
using System;
|
||||||
|
using GlitchyEngine;
|
||||||
|
using GlitchyEngine.Editor;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
|
||||||
|
using static GlitchyEngine.Math.Math;
|
||||||
|
|
||||||
|
namespace Sandbox
|
||||||
|
{
|
||||||
|
|
||||||
|
public enum MyEnum
|
||||||
|
{
|
||||||
|
Yes,
|
||||||
|
No,
|
||||||
|
Maybe
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct MyStruct
|
||||||
|
{
|
||||||
|
public float TheFloat;
|
||||||
|
public float2 TheVector;
|
||||||
|
public MyEnum TheEnum;
|
||||||
|
}
|
||||||
|
|
||||||
|
class MyTestEntity : Entity
|
||||||
|
{
|
||||||
|
//[ShowInEditor]
|
||||||
|
RigidBody2D _rigidBody;
|
||||||
|
|
||||||
|
public bool Bo;
|
||||||
|
|
||||||
|
public byte By;
|
||||||
|
public ushort Us;
|
||||||
|
public uint Ui;
|
||||||
|
public ulong Ul;
|
||||||
|
|
||||||
|
public sbyte Sb;
|
||||||
|
public short Sh;
|
||||||
|
public int In;
|
||||||
|
public long Lo;
|
||||||
|
|
||||||
|
public float Fl;
|
||||||
|
public double Do;
|
||||||
|
public float2 V2;
|
||||||
|
public float3 V3;
|
||||||
|
public float4 V4;
|
||||||
|
|
||||||
|
public Entity TheEntity;
|
||||||
|
|
||||||
|
public float JumpForce = 2000;
|
||||||
|
[ShowInEditor] float MoveForce = 1000;
|
||||||
|
[ShowInEditor] private int MyNumber = 1337;
|
||||||
|
[ShowInEditor] public double MyDouble = 1000.0f;
|
||||||
|
|
||||||
|
public MyStruct AStruct;
|
||||||
|
|
||||||
|
public Camera Camera;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called after the script component was created. (The entity might not be fully created yet)
|
||||||
|
/// </summary>
|
||||||
|
void OnCreate()
|
||||||
|
{
|
||||||
|
Log.Info($"Create! {UUID}");
|
||||||
|
|
||||||
|
Log.Info($"Jump Force: {JumpForce}");
|
||||||
|
|
||||||
|
//_rigidBody ??= GetComponent<RigidBody2D>() ?? AddComponent<RigidBody2D>();
|
||||||
|
|
||||||
|
//Camera = FindEntityWithName("Camera").As<Camera>();
|
||||||
|
|
||||||
|
//if (Camera == null)
|
||||||
|
//{
|
||||||
|
// Log.Error("Camera not found.");
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called every frame.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="deltaTime"></param>
|
||||||
|
void OnUpdate(float deltaTime)
|
||||||
|
{
|
||||||
|
Log.Info($"On update: {deltaTime}");
|
||||||
|
|
||||||
|
//float2 force = float2.Zero;
|
||||||
|
|
||||||
|
//if (Input.IsKeyPressed(Key.A))
|
||||||
|
//{
|
||||||
|
// force.X -= MoveForce * deltaTime;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (Input.IsKeyPressed(Key.D))
|
||||||
|
//{
|
||||||
|
// force.X += MoveForce * deltaTime;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//if (Input.IsKeyPressed(Key.Q))
|
||||||
|
// Camera.DistanceFromPlayer -= deltaTime;
|
||||||
|
|
||||||
|
//if (Input.IsKeyPressed(Key.E))
|
||||||
|
// Camera.DistanceFromPlayer += deltaTime;
|
||||||
|
|
||||||
|
//if (Input.IsKeyPressing(Key.Space))
|
||||||
|
//{
|
||||||
|
// force.Y += JumpForce;
|
||||||
|
//}
|
||||||
|
|
||||||
|
//_rigidBody.ApplyForceToCenter(force);
|
||||||
|
|
||||||
|
//if (Input.IsMouseButtonReleasing(MouseButton.MiddleButton))
|
||||||
|
//{
|
||||||
|
// Log.Info($"Ouha! {MyNumber}");
|
||||||
|
// Physics2D.Gravity *= new float2(1, -1);
|
||||||
|
//}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Called before the component is being destroyed.
|
||||||
|
/// </summary>
|
||||||
|
void OnDestroy()
|
||||||
|
{
|
||||||
|
Log.Trace("Destroy");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"Start Editor": {
|
||||||
|
"commandName": "Executable",
|
||||||
|
"executablePath": "D:\\Development\\Projects\\Beef\\GlitchyEngine\\build\\Debug_Win64\\GlitchyEditor\\GlitchyEditor.exe",
|
||||||
|
"commandLineArgs": "\"content\\Scenes\\physics2D.scene\"",
|
||||||
|
"workingDirectory": "D:\\Development\\Projects\\Beef\\GlitchyEngine\\GlitchyEditor",
|
||||||
|
"nativeDebugging": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,57 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||||
|
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
|
||||||
|
<PropertyGroup>
|
||||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
|
||||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
|
||||||
|
<ProjectGuid>{7A70819C-5317-402A-8553-95C5A001E370}</ProjectGuid>
|
||||||
|
<OutputType>Library</OutputType>
|
||||||
|
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||||
|
<RootNamespace>Sandbox</RootNamespace>
|
||||||
|
<AssemblyName>Sandbox</AssemblyName>
|
||||||
|
<TargetFrameworkVersion>v4.7.2</TargetFrameworkVersion>
|
||||||
|
<FileAlignment>512</FileAlignment>
|
||||||
|
<Deterministic>true</Deterministic>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||||
|
<DebugSymbols>true</DebugSymbols>
|
||||||
|
<DebugType>full</DebugType>
|
||||||
|
<Optimize>false</Optimize>
|
||||||
|
<OutputPath>bin\</OutputPath>
|
||||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<LangVersion>default</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||||
|
<DebugType>pdbonly</DebugType>
|
||||||
|
<Optimize>true</Optimize>
|
||||||
|
<OutputPath>bin\</OutputPath>
|
||||||
|
<DefineConstants>TRACE</DefineConstants>
|
||||||
|
<ErrorReport>prompt</ErrorReport>
|
||||||
|
<WarningLevel>4</WarningLevel>
|
||||||
|
<LangVersion>default</LangVersion>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Core" />
|
||||||
|
<Reference Include="System.Xml.Linq" />
|
||||||
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="System.Data" />
|
||||||
|
<Reference Include="System.Net.Http" />
|
||||||
|
<Reference Include="System.Xml" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<Compile Include="Camera.cs" />
|
||||||
|
<Compile Include="MyTestEntity.cs" />
|
||||||
|
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\..\ScriptCore\ScriptCore.csproj">
|
||||||
|
<Project>{6222c226-fc78-498c-80ba-5cf10ac9123c}</Project>
|
||||||
|
<Name>ScriptCore</Name>
|
||||||
|
</ProjectReference>
|
||||||
|
</ItemGroup>
|
||||||
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,16 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net7.0</TargetFramework>
|
||||||
|
<LangVersion>latest</LangVersion>
|
||||||
|
<OutputPath>bin</OutputPath>
|
||||||
|
<EmitCompilerGeneratedFiles>true</EmitCompilerGeneratedFiles>
|
||||||
|
|
||||||
|
<GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
|
||||||
|
<EnableDynamicLoading>true</EnableDynamicLoading>
|
||||||
|
<AppendTargetFrameworkToOutputPath>false</AppendTargetFrameworkToOutputPath>
|
||||||
|
</PropertyGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\..\..\..\ScriptCore\ScriptCore.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
|
||||||
|
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||||
|
# Visual Studio Version 17
|
||||||
|
VisualStudioVersion = 17.4.33205.214
|
||||||
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sandbox", "Sandbox.csproj", "{7A70819C-5317-402A-8553-95C5A001E370}"
|
||||||
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ScriptCore", "..\..\..\..\ScriptCore\ScriptCore.csproj", "{6222C226-FC78-498C-80BA-5CF10AC9123C}"
|
||||||
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ScriptCoreGenerator", "..\..\..\..\ScriptCoreGenerator\ScriptCoreGenerator.csproj", "{5D662996-1E1E-4170-A08A-B26CDB63A0DE}"
|
||||||
|
EndProject
|
||||||
|
Global
|
||||||
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
Release|Any CPU = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||||
|
{7A70819C-5317-402A-8553-95C5A001E370}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{7A70819C-5317-402A-8553-95C5A001E370}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{7A70819C-5317-402A-8553-95C5A001E370}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{7A70819C-5317-402A-8553-95C5A001E370}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{6222C226-FC78-498C-80BA-5CF10AC9123C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{6222C226-FC78-498C-80BA-5CF10AC9123C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{6222C226-FC78-498C-80BA-5CF10AC9123C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{6222C226-FC78-498C-80BA-5CF10AC9123C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{5D662996-1E1E-4170-A08A-B26CDB63A0DE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{5D662996-1E1E-4170-A08A-B26CDB63A0DE}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{5D662996-1E1E-4170-A08A-B26CDB63A0DE}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{5D662996-1E1E-4170-A08A-B26CDB63A0DE}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
|
HideSolutionNode = FALSE
|
||||||
|
EndGlobalSection
|
||||||
|
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||||
|
SolutionGuid = {B5D43D8D-D80B-41AA-BE40-1DC507D87148}
|
||||||
|
EndGlobalSection
|
||||||
|
EndGlobal
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
|
using GlitchyEngine;
|
||||||
|
|
||||||
|
namespace Sandbox;
|
||||||
|
|
||||||
|
public static class TestClass
|
||||||
|
{
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
public static void TestFunction()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Hello from the second Assembly!");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InternalTest()
|
||||||
|
{
|
||||||
|
Console.WriteLine("Ja, ich existiere in der Tat");
|
||||||
|
|
||||||
|
Log.Info("Yeah!");
|
||||||
|
//Console.WriteLine("Und nun bin ich anders");
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int Test(IntPtr arg, int sizeofArg)
|
||||||
|
{
|
||||||
|
Console.WriteLine($"YUPPYPLASDPASDOIUZASD");
|
||||||
|
return 7;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@
|
|||||||
},
|
},
|
||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = 0,
|
X = -0.72789681,
|
||||||
Y = 2,
|
Y = 2,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
@@ -71,8 +71,8 @@
|
|||||||
SpriteRendererComponent = {
|
SpriteRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
R = 1,
|
R = 1,
|
||||||
G = 0.941886365,
|
G = 0.941886961,
|
||||||
B = 0.401484847,
|
B = 0.401484549,
|
||||||
A = 1
|
A = 1
|
||||||
},
|
},
|
||||||
Sprite = "",
|
Sprite = "",
|
||||||
@@ -162,14 +162,20 @@
|
|||||||
OrthographicHeight = 10,
|
OrthographicHeight = 10,
|
||||||
OrthographicNearPlane = 0,
|
OrthographicNearPlane = 0,
|
||||||
OrthographicFarPlane = 10,
|
OrthographicFarPlane = 10,
|
||||||
AspectRatio = 3.22169805,
|
AspectRatio = 0.884925187,
|
||||||
FixedAspectRatio = false
|
FixedAspectRatio = false
|
||||||
}
|
},
|
||||||
|
ScriptComponent = {
|
||||||
|
ScriptClass = "Sandbox.Camera",
|
||||||
|
Fields = [
|
||||||
|
DistanceFromPlayer = (Float)-7,
|
||||||
|
DontFollowRadius = (Float)3
|
||||||
|
] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Id = 15710354273720487680,
|
Id = 15710354273720487680,
|
||||||
NameComponent = {
|
NameComponent = {
|
||||||
Name = "Circle"
|
Name = "Player"
|
||||||
},
|
},
|
||||||
CircleRendererComponent = {
|
CircleRendererComponent = {
|
||||||
Color = {
|
Color = {
|
||||||
@@ -189,8 +195,8 @@
|
|||||||
},
|
},
|
||||||
TransformComponent = {
|
TransformComponent = {
|
||||||
Position = {
|
Position = {
|
||||||
X = -0.12120308,
|
X = -0.121203184,
|
||||||
Y = 0.660160363,
|
Y = 0.660160959,
|
||||||
Z = 0
|
Z = 0
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
@@ -224,7 +230,42 @@
|
|||||||
Friction = 0.5,
|
Friction = 0.5,
|
||||||
Restitution = 0,
|
Restitution = 0,
|
||||||
RestitutionThreshold = 0.5
|
RestitutionThreshold = 0.5
|
||||||
}
|
},
|
||||||
|
ScriptComponent = {
|
||||||
|
ScriptClass = "Sandbox.MyTestEntity",
|
||||||
|
Fields = [
|
||||||
|
Bo = (Bool)false,
|
||||||
|
By = (Byte)0,
|
||||||
|
Us = (UShort)57,
|
||||||
|
Ui = (UInt)54,
|
||||||
|
Ul = (ULong)53,
|
||||||
|
Sb = (SByte)-128,
|
||||||
|
Sh = (Short)95,
|
||||||
|
In = (Int)-149,
|
||||||
|
Lo = (Long)82,
|
||||||
|
Fl = (Float)-98.122963,
|
||||||
|
Do = (Double)118,
|
||||||
|
V2 = (float2){
|
||||||
|
X = 11,
|
||||||
|
Y = 12
|
||||||
|
},
|
||||||
|
V3 = (float3){
|
||||||
|
X = 13,
|
||||||
|
Y = 14,
|
||||||
|
Z = 15
|
||||||
|
},
|
||||||
|
V4 = (float4){
|
||||||
|
X = 14,
|
||||||
|
Y = 17,
|
||||||
|
Z = 18,
|
||||||
|
W = 19
|
||||||
|
},
|
||||||
|
TheEntity = (Entity)0,
|
||||||
|
JumpForce = (Float)200,
|
||||||
|
MoveForce = (Float)148,
|
||||||
|
MyNumber = (Int)22,
|
||||||
|
MyDouble = (Double)23
|
||||||
|
] }
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Id = 935640822766280888,
|
Id = 935640822766280888,
|
||||||
@@ -249,9 +290,9 @@
|
|||||||
Z = 1
|
Z = 1
|
||||||
},
|
},
|
||||||
EditorEulerRotation = {
|
EditorEulerRotation = {
|
||||||
X = 1.0908947,
|
X = 1.09089541,
|
||||||
Y = -0.340793997,
|
Y = -0.340793997,
|
||||||
Z = 0.160857916
|
Z = 0.160857871
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
LightComponent = {
|
LightComponent = {
|
||||||
@@ -260,7 +301,7 @@
|
|||||||
Color = {
|
Color = {
|
||||||
R = 0.985467017,
|
R = 0.985467017,
|
||||||
G = 1,
|
G = 1,
|
||||||
B = 0.569978654
|
B = 0.569978058
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -273,7 +314,7 @@
|
|||||||
Position = {
|
Position = {
|
||||||
X = 0,
|
X = 0,
|
||||||
Y = 0,
|
Y = 0,
|
||||||
Z = -1.47202551
|
Z = 2.56930423
|
||||||
},
|
},
|
||||||
Rotation = {
|
Rotation = {
|
||||||
X = 0,
|
X = 0,
|
||||||
@@ -298,6 +339,192 @@
|
|||||||
MeshRendererComponent = {
|
MeshRendererComponent = {
|
||||||
Material = "Textures/TestMaterial.mat"
|
Material = "Textures/TestMaterial.mat"
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id = 2241063100006479259,
|
||||||
|
NameComponent = {
|
||||||
|
Name = "Floor 2"
|
||||||
|
},
|
||||||
|
SpriteRendererComponent = {
|
||||||
|
Color = {
|
||||||
|
R = 0.425658971,
|
||||||
|
G = 0.855207562,
|
||||||
|
B = 0.0558161102,
|
||||||
|
A = 1
|
||||||
|
},
|
||||||
|
Sprite = "",
|
||||||
|
UvTransform = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Z = 1,
|
||||||
|
W = 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TransformComponent = {
|
||||||
|
Position = {
|
||||||
|
X = 6.74610233,
|
||||||
|
Y = -2.03225899,
|
||||||
|
Z = 0
|
||||||
|
},
|
||||||
|
Rotation = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Z = -0.331792623,
|
||||||
|
W = 0.943352342
|
||||||
|
},
|
||||||
|
Scale = {
|
||||||
|
X = 5.29557419,
|
||||||
|
Y = 1,
|
||||||
|
Z = 1
|
||||||
|
},
|
||||||
|
EditorEulerRotation = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Z = -0.676406503
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Rigidbody2D = {
|
||||||
|
BodyType = .Static,
|
||||||
|
FixedRotation = false
|
||||||
|
},
|
||||||
|
BoxCollider2D = {
|
||||||
|
Offset = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0
|
||||||
|
},
|
||||||
|
Size = {
|
||||||
|
X = 0.5,
|
||||||
|
Y = 0.5
|
||||||
|
},
|
||||||
|
Density = 1,
|
||||||
|
Friction = 0.5,
|
||||||
|
Restitution = 0,
|
||||||
|
RestitutionThreshold = 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id = 5126705881069187728,
|
||||||
|
NameComponent = {
|
||||||
|
Name = "Floor 3"
|
||||||
|
},
|
||||||
|
SpriteRendererComponent = {
|
||||||
|
Color = {
|
||||||
|
R = 0.666116953,
|
||||||
|
G = 0.0600316115,
|
||||||
|
B = 1,
|
||||||
|
A = 1
|
||||||
|
},
|
||||||
|
Sprite = "",
|
||||||
|
UvTransform = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Z = 1,
|
||||||
|
W = 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TransformComponent = {
|
||||||
|
Position = {
|
||||||
|
X = 15.2321301,
|
||||||
|
Y = -1.98709249,
|
||||||
|
Z = 0
|
||||||
|
},
|
||||||
|
Rotation = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Z = 0.134986058,
|
||||||
|
W = 0.990847468
|
||||||
|
},
|
||||||
|
Scale = {
|
||||||
|
X = 13.9764566,
|
||||||
|
Y = 1,
|
||||||
|
Z = 1
|
||||||
|
},
|
||||||
|
EditorEulerRotation = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Z = 0.270798802
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Rigidbody2D = {
|
||||||
|
BodyType = .Static,
|
||||||
|
FixedRotation = false
|
||||||
|
},
|
||||||
|
BoxCollider2D = {
|
||||||
|
Offset = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0
|
||||||
|
},
|
||||||
|
Size = {
|
||||||
|
X = 0.5,
|
||||||
|
Y = 0.5
|
||||||
|
},
|
||||||
|
Density = 1,
|
||||||
|
Friction = 0.5,
|
||||||
|
Restitution = 0.800000012,
|
||||||
|
RestitutionThreshold = 0.5
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Id = 6861260438693901700,
|
||||||
|
NameComponent = {
|
||||||
|
Name = "Floor 4"
|
||||||
|
},
|
||||||
|
SpriteRendererComponent = {
|
||||||
|
Color = {
|
||||||
|
R = 0.176544324,
|
||||||
|
G = 0.666713238,
|
||||||
|
B = 0.687030852,
|
||||||
|
A = 1
|
||||||
|
},
|
||||||
|
Sprite = "",
|
||||||
|
UvTransform = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Z = 1,
|
||||||
|
W = 1
|
||||||
|
}
|
||||||
|
},
|
||||||
|
TransformComponent = {
|
||||||
|
Position = {
|
||||||
|
X = -6.27842855,
|
||||||
|
Y = 2.62550211,
|
||||||
|
Z = 0
|
||||||
|
},
|
||||||
|
Rotation = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Z = 0.187087834,
|
||||||
|
W = 0.982343197
|
||||||
|
},
|
||||||
|
Scale = {
|
||||||
|
X = 0.999999523,
|
||||||
|
Y = 6.49634314,
|
||||||
|
Z = 1
|
||||||
|
},
|
||||||
|
EditorEulerRotation = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0,
|
||||||
|
Z = 0.376393586
|
||||||
|
}
|
||||||
|
},
|
||||||
|
Rigidbody2D = {
|
||||||
|
BodyType = .Static,
|
||||||
|
FixedRotation = false
|
||||||
|
},
|
||||||
|
BoxCollider2D = {
|
||||||
|
Offset = {
|
||||||
|
X = 0,
|
||||||
|
Y = 0
|
||||||
|
},
|
||||||
|
Size = {
|
||||||
|
X = 0.5,
|
||||||
|
Y = 0.5
|
||||||
|
},
|
||||||
|
Density = 1,
|
||||||
|
Friction = 0.5,
|
||||||
|
Restitution = 0.899999976,
|
||||||
|
RestitutionThreshold = 0.5
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
#pragma EngineBuffer[ Name = "SceneConstants"; Binding = "Scene" ]
|
||||||
|
cbuffer SceneConstants : register(b0)
|
||||||
|
{
|
||||||
|
float4x4 ViewProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma EngineBuffer[ Name = "ObjectConstants"; Binding = "Object" ]
|
||||||
|
cbuffer ObjectConstants : register(b1)
|
||||||
|
{
|
||||||
|
float4x4 Transform;
|
||||||
|
/**
|
||||||
|
* \brief Inverted and transposed transform matrix.
|
||||||
|
* \remarks This matrix is used in order to correctly transform normal vectors.
|
||||||
|
*/
|
||||||
|
float4x3 Transform_InvT;
|
||||||
|
#ifdef OutputEntityId
|
||||||
|
uint EntityId;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Pixel Shader output for lit surfaces.
|
||||||
|
*/
|
||||||
|
struct PS_OUT_Lit
|
||||||
|
{
|
||||||
|
/** RGB: Albedo A: Transparency */
|
||||||
|
float4 Albedo : SV_TARGET0;
|
||||||
|
/** RG: TextureNormal.XY | BA: GeoNrm.XY */
|
||||||
|
float4 Normal : SV_TARGET1;
|
||||||
|
/** R: GeoNrm.Z | GBA: GeoTan.XYZ */
|
||||||
|
float4 Tangent : SV_TARGET2;
|
||||||
|
/** RGB: world position XYZ | A: 1.0 */
|
||||||
|
float4 Position : SV_TARGET3;
|
||||||
|
/** RGB: emissive light and color | A: unused */
|
||||||
|
float4 Emissive : SV_TARGET4;
|
||||||
|
/** R: Metallicity | G: Roughness | B: Ambient | A: Unused */
|
||||||
|
float4 Material : SV_TARGET5;
|
||||||
|
#ifdef OutputEntityId
|
||||||
|
/** Needed for editor picking. Simply pass through the EntityId. */
|
||||||
|
uint EntityId : SV_TARGET6;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* \brief Pixel Shader output for unlit surfaces.
|
||||||
|
*/
|
||||||
|
struct PS_OUT_Unlit
|
||||||
|
{
|
||||||
|
/** RGB: Color A: Transparency */
|
||||||
|
float4 Color : SV_TARGET0;
|
||||||
|
/** RGB: emissive light and color | A: unused */
|
||||||
|
float4 Emissive : SV_TARGET1;
|
||||||
|
/** RGB: world position XYZ | A: 1.0 */
|
||||||
|
float4 Position : SV_TARGET2;
|
||||||
|
|
||||||
|
#ifdef OutputEntityId
|
||||||
|
uint EntityId : SV_TARGET5;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
AssetLoader = "EffectAssetLoader",
|
||||||
|
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}/* No reflection data for GlitchyEditor.Assets.EffectAssetLoaderConfig. Add [BonTarget] or force it */
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
Texture2DArray Texture : register(t0);
|
||||||
|
SamplerState Sampler : register(s0);
|
||||||
|
|
||||||
|
Texture2DArray<int4> IntTexture : register(t1);
|
||||||
|
SamplerState IntSampler : register(s1);
|
||||||
|
|
||||||
|
Texture2DArray<uint4> UIntTexture : register(t2);
|
||||||
|
SamplerState UIntSampler : register(s2);
|
||||||
|
|
||||||
|
#define SWIZZLE_NONE 0
|
||||||
|
#define SWIZZLE_R 1
|
||||||
|
#define SWIZZLE_G 2
|
||||||
|
#define SWIZZLE_B 3
|
||||||
|
#define SWIZZLE_A 4
|
||||||
|
|
||||||
|
cbuffer Constants
|
||||||
|
{
|
||||||
|
float ColorOffset = 0.5;
|
||||||
|
float AlphaOffset = 0.0;
|
||||||
|
float ColorScale = 0.5;
|
||||||
|
float AlphaScale = 1.0;
|
||||||
|
|
||||||
|
float MipLevel = 0.0;
|
||||||
|
float ArraySlice = 0.0;
|
||||||
|
|
||||||
|
// 0: Float | 1: Int | 2: Uint
|
||||||
|
int Mode = 0;
|
||||||
|
|
||||||
|
int4 Swizzle = int4(SWIZZLE_R, SWIZZLE_G, SWIZZLE_B, SWIZZLE_A);
|
||||||
|
|
||||||
|
float2 Texels;
|
||||||
|
|
||||||
|
float4x4 WorldViewProjection;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct VS_Input
|
||||||
|
{
|
||||||
|
float2 Position : POSITION;
|
||||||
|
float2 Texcoord : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct PS_Input
|
||||||
|
{
|
||||||
|
float4 Position : SV_Position;
|
||||||
|
float2 Texcoord : TEXCOORD0;
|
||||||
|
};
|
||||||
|
|
||||||
|
PS_Input VS(VS_Input input)
|
||||||
|
{
|
||||||
|
PS_Input output;
|
||||||
|
|
||||||
|
output.Position = mul(WorldViewProjection, float4(input.Position, 0.0f, 1.0f));
|
||||||
|
output.Texcoord = input.Texcoord;
|
||||||
|
|
||||||
|
return output;
|
||||||
|
}
|
||||||
|
|
||||||
|
void SwizzleColor(int swizzleMode, float4 colorToSwizzle, inout float output)
|
||||||
|
{
|
||||||
|
switch (swizzleMode)
|
||||||
|
{
|
||||||
|
case SWIZZLE_R:
|
||||||
|
output = colorToSwizzle.r;
|
||||||
|
break;
|
||||||
|
case SWIZZLE_G:
|
||||||
|
output = colorToSwizzle.g;
|
||||||
|
break;
|
||||||
|
case SWIZZLE_B:
|
||||||
|
output = colorToSwizzle.b;
|
||||||
|
break;
|
||||||
|
case SWIZZLE_A:
|
||||||
|
output = colorToSwizzle.a;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 PS(PS_Input input) : SV_Target0
|
||||||
|
{
|
||||||
|
float4 outputColor;
|
||||||
|
|
||||||
|
if (Mode == 0)
|
||||||
|
{
|
||||||
|
//float4 color = Texture.SampleLevel(Sampler, float3(input.Texcoord, ArraySlice), MipLevel);
|
||||||
|
// Quasi next neighbor
|
||||||
|
float4 color = Texture.Load(int4(input.Texcoord * Texels, ArraySlice, MipLevel));
|
||||||
|
outputColor = float4(ColorOffset.xxx, AlphaOffset) + color * float4(ColorScale.xxx, AlphaScale);
|
||||||
|
}
|
||||||
|
else if (Mode == 1)
|
||||||
|
{
|
||||||
|
int4 color = IntTexture.Load(int4(input.Texcoord * Texels, ArraySlice, MipLevel));
|
||||||
|
outputColor = float4(ColorOffset.xxx, AlphaOffset) + color * float4(ColorScale.xxx, AlphaScale);
|
||||||
|
}
|
||||||
|
else if (Mode == 2)
|
||||||
|
{
|
||||||
|
uint4 color = UIntTexture.Load(int4(input.Texcoord * Texels, ArraySlice, MipLevel));
|
||||||
|
outputColor = float4(ColorOffset.xxx, AlphaOffset) + color * float4(ColorScale.xxx, AlphaScale);
|
||||||
|
}
|
||||||
|
|
||||||
|
float4 swizzledOutput = float4(0, 0, 0, 1);
|
||||||
|
|
||||||
|
SwizzleColor(Swizzle.r, outputColor, swizzledOutput.r);
|
||||||
|
SwizzleColor(Swizzle.g, outputColor, swizzledOutput.g);
|
||||||
|
SwizzleColor(Swizzle.b, outputColor, swizzledOutput.b);
|
||||||
|
SwizzleColor(Swizzle.a, outputColor, swizzledOutput.a);
|
||||||
|
|
||||||
|
return swizzledOutput;
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma Effect[VS=VS; PS=PS]
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
{
|
||||||
|
AssetLoader = "EffectAssetLoader",
|
||||||
|
Config = (GlitchyEditor.Assets.EffectAssetLoaderConfig){}/* No reflection data for GlitchyEditor.Assets.EffectAssetLoaderConfig. Add [BonTarget] or force it */
|
||||||
|
}
|
||||||
@@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
#include "ShaderHelpers.hlsl"
|
#include "ShaderHelpers.hlsl"
|
||||||
|
|
||||||
|
#include "GlitchyEngine.hlsl"
|
||||||
|
|
||||||
Texture2D AlbedoTexture : register(t0);
|
Texture2D AlbedoTexture : register(t0);
|
||||||
SamplerState AlbedoSampler : register(s0);
|
SamplerState AlbedoSampler : register(s0);
|
||||||
|
|
||||||
@@ -14,28 +16,11 @@ SamplerState MetallicSampler : register(s2);
|
|||||||
Texture2D<float> RoughnessTexture : register(t3);
|
Texture2D<float> RoughnessTexture : register(t3);
|
||||||
SamplerState RoughnessSampler : register(s3);
|
SamplerState RoughnessSampler : register(s3);
|
||||||
|
|
||||||
// Texture2D<float> AmbientTexture : register(t4);
|
Texture2D<float3> EmissiveTexture : register(t4);
|
||||||
// SamplerState AmbientSampler : register(s4);
|
SamplerState EmissiveSampler : register(s4);
|
||||||
|
|
||||||
#pragma EngineBuffer[ Name = "SceneConstants"; Binding = "Scene" ]
|
// Texture2D<float> AmbientTexture : register(t5);
|
||||||
cbuffer SceneConstants : register(b0)
|
// SamplerState AmbientSampler : register(s5);
|
||||||
{
|
|
||||||
float4x4 ViewProjection;
|
|
||||||
}
|
|
||||||
|
|
||||||
#pragma EngineBuffer[ Name = "ObjectConstants"; Binding = "Object" ]
|
|
||||||
cbuffer ObjectConstants : register(b1)
|
|
||||||
{
|
|
||||||
float4x4 Transform;
|
|
||||||
/**
|
|
||||||
* \brief Inverted and transposed transform matrix.
|
|
||||||
* \remarks This matrix is used in order to correctly transform normal vectors.
|
|
||||||
*/
|
|
||||||
float4x3 Transform_InvT;
|
|
||||||
#ifdef OutputEntityId
|
|
||||||
uint EntityId;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
cbuffer MaterialConstants : register(b2)
|
cbuffer MaterialConstants : register(b2)
|
||||||
{
|
{
|
||||||
@@ -44,9 +29,12 @@ cbuffer MaterialConstants : register(b2)
|
|||||||
#pragma EditorVariable[ Name = "NormalScaling"; Preview = "Normal Scaling" ]
|
#pragma EditorVariable[ Name = "NormalScaling"; Preview = "Normal Scaling" ]
|
||||||
float2 NormalScaling = float2(1.0, 1.0);
|
float2 NormalScaling = float2(1.0, 1.0);
|
||||||
#pragma EditorVariable[ Name = "MetallicFactor"; Preview = "Metallic Factor"; Min = 0.0f; Max = 1.0f ]
|
#pragma EditorVariable[ Name = "MetallicFactor"; Preview = "Metallic Factor"; Min = 0.0f; Max = 1.0f ]
|
||||||
float MetallicFactor = 1.0;
|
float MetallicFactor = 0.0;
|
||||||
#pragma EditorVariable[ Name = "RoughnessFactor"; Preview = "Rougness Factor"; Min = 0.0f; Max = 1.0f ]
|
#pragma EditorVariable[ Name = "RoughnessFactor"; Preview = "Rougness Factor"; Min = 0.0f; Max = 1.0f ]
|
||||||
float RoughnessFactor = 1.0;
|
float RoughnessFactor = 0.6;
|
||||||
|
#pragma EditorVariable[ Name = "EmissiveColor"; Preview = "Emissive Factor"; Type="ColorHDR" ]
|
||||||
|
float3 EmissiveColor = float3(0.0, 0.0, 0.0);
|
||||||
|
// # pra gma Editor Variable[ Name = "AmbientFactor"; Preview = "Ambient Factor" ]
|
||||||
// float AmbientFactor = 1.0;
|
// float AmbientFactor = 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -59,7 +47,7 @@ struct VS_IN
|
|||||||
float2 TexCoord : TEXCOORD;
|
float2 TexCoord : TEXCOORD;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct PS_IN
|
typedef struct PS_IN
|
||||||
{
|
{
|
||||||
float4 Position : SV_POSITION;
|
float4 Position : SV_POSITION;
|
||||||
float3 WorldPosition : WORLDPOSITION;
|
float3 WorldPosition : WORLDPOSITION;
|
||||||
@@ -70,11 +58,11 @@ struct PS_IN
|
|||||||
#ifdef OutputEntityId
|
#ifdef OutputEntityId
|
||||||
nointerpolation uint EntityId : ENTITYID;
|
nointerpolation uint EntityId : ENTITYID;
|
||||||
#endif
|
#endif
|
||||||
};
|
} VS_OUT;
|
||||||
|
|
||||||
PS_IN VS(VS_IN input)
|
VS_OUT VS(VS_IN input)
|
||||||
{
|
{
|
||||||
PS_IN output;
|
VS_OUT output;
|
||||||
|
|
||||||
float4 worldPosition = mul(Transform, float4(input.Position, 1));
|
float4 worldPosition = mul(Transform, float4(input.Position, 1));
|
||||||
|
|
||||||
@@ -92,22 +80,22 @@ PS_IN VS(VS_IN input)
|
|||||||
return output;
|
return output;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct PS_OUT
|
//struct PS_OUT
|
||||||
{
|
//{
|
||||||
float4 Albedo : SV_TARGET0;
|
// float4 Albedo : SV_TARGET0;
|
||||||
// RG: TextureNormal.XY BA: GeoNrm.XY
|
// // RG: TextureNormal.XY BA: GeoNrm.XY
|
||||||
float4 Normal : SV_TARGET1;
|
// float4 Normal : SV_TARGET1;
|
||||||
// R: GeoNrm.Z GBA: GeoTan.XYZ
|
// // R: GeoNrm.Z GBA: GeoTan.XYZ
|
||||||
float4 Tangent : SV_TARGET2;
|
// float4 Tangent : SV_TARGET2;
|
||||||
float4 Position : SV_TARGET3;
|
// float4 Position : SV_TARGET3;
|
||||||
// R: Metallicity G: Roughness B: Ambient
|
// // R: Metallicity G: Roughness B: Ambient
|
||||||
float4 Material : SV_TARGET4;
|
// float4 Material : SV_TARGET4;
|
||||||
#ifdef OutputEntityId
|
//#ifdef OutputEntityId
|
||||||
uint EntityId : SV_TARGET5;
|
// uint EntityId : SV_TARGET5;
|
||||||
#endif
|
//#endif
|
||||||
};
|
//};
|
||||||
|
|
||||||
PS_OUT PS(PS_IN input)
|
PS_OUT_Lit PS(PS_IN input)
|
||||||
{
|
{
|
||||||
// Build tangent space
|
// Build tangent space
|
||||||
float3 normal = normalize(input.Normal);
|
float3 normal = normalize(input.Normal);
|
||||||
@@ -124,6 +112,9 @@ PS_OUT PS(PS_IN input)
|
|||||||
float texMetallic = MetallicTexture.Sample(MetallicSampler, input.TexCoord);
|
float texMetallic = MetallicTexture.Sample(MetallicSampler, input.TexCoord);
|
||||||
float texRoughness = RoughnessTexture.Sample(RoughnessSampler, input.TexCoord);
|
float texRoughness = RoughnessTexture.Sample(RoughnessSampler, input.TexCoord);
|
||||||
|
|
||||||
|
|
||||||
|
float3 texEmissive = EmissiveTexture.Sample(EmissiveSampler, input.TexCoord);
|
||||||
|
|
||||||
//float3 objectNormal = mul(tangentTransform, texNormal);
|
//float3 objectNormal = mul(tangentTransform, texNormal);
|
||||||
//float3 worldNormal = mul(objectNormal, (float3x3)Transform);
|
//float3 worldNormal = mul(objectNormal, (float3x3)Transform);
|
||||||
|
|
||||||
@@ -131,6 +122,7 @@ PS_OUT PS(PS_IN input)
|
|||||||
float3 finalNormal = ScaleNormal(texNormal, NormalScaling);
|
float3 finalNormal = ScaleNormal(texNormal, NormalScaling);
|
||||||
float finalMetallic = texMetallic * MetallicFactor;
|
float finalMetallic = texMetallic * MetallicFactor;
|
||||||
float finalRoughness = texRoughness * RoughnessFactor;
|
float finalRoughness = texRoughness * RoughnessFactor;
|
||||||
|
float3 finalEmissive = texEmissive * EmissiveColor;
|
||||||
|
|
||||||
/////////////TODO: REMOVEME
|
/////////////TODO: REMOVEME
|
||||||
|
|
||||||
@@ -141,12 +133,13 @@ PS_OUT PS(PS_IN input)
|
|||||||
|
|
||||||
/////////////TODO: END_REMOVEME
|
/////////////TODO: END_REMOVEME
|
||||||
|
|
||||||
PS_OUT output;
|
PS_OUT_Lit output;
|
||||||
output.Albedo = finalAlbedo;
|
output.Albedo = finalAlbedo;
|
||||||
//output.Normal = float4(objectNormal, 1.0);
|
//output.Normal = float4(objectNormal, 1.0);
|
||||||
output.Normal = float4(finalNormal.xy, normal.xy);
|
output.Normal = float4(finalNormal.xy, normal.xy);
|
||||||
output.Tangent = float4(normal.z, tangent.xyz);
|
output.Tangent = float4(normal.z, tangent.xyz);
|
||||||
output.Position = float4(input.WorldPosition, 1.0);
|
output.Position = float4(input.WorldPosition, 1.0);
|
||||||
|
output.Emissive = float4(finalEmissive, 0.0);
|
||||||
output.Material = float4(finalMetallic, finalRoughness, 1.0, 0);
|
output.Material = float4(finalMetallic, finalRoughness, 1.0, 0);
|
||||||
|
|
||||||
#ifdef OutputEntityId
|
#ifdef OutputEntityId
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ Texture2D GBuffer_Albedo : register(t0);
|
|||||||
Texture2D GBuffer_Normal : register(t1);
|
Texture2D GBuffer_Normal : register(t1);
|
||||||
Texture2D GBuffer_Tangent : register(t2);
|
Texture2D GBuffer_Tangent : register(t2);
|
||||||
Texture2D GBuffer_Position : register(t3);
|
Texture2D GBuffer_Position : register(t3);
|
||||||
Texture2D GBuffer_Material : register(t4);
|
Texture2D GBuffer_Emissive : register(t4);
|
||||||
|
Texture2D GBuffer_Material : register(t5);
|
||||||
|
|
||||||
cbuffer Constants
|
cbuffer Constants
|
||||||
{
|
{
|
||||||
@@ -59,6 +60,7 @@ float4 PS(PS_IN input) : SV_TARGET
|
|||||||
float4 rawNormal = GBuffer_Normal.Sample(Sampler, input.TexCoord);
|
float4 rawNormal = GBuffer_Normal.Sample(Sampler, input.TexCoord);
|
||||||
float4 rawTangent = GBuffer_Tangent.Sample(Sampler, input.TexCoord);
|
float4 rawTangent = GBuffer_Tangent.Sample(Sampler, input.TexCoord);
|
||||||
float4 rawPosition = GBuffer_Position.Sample(Sampler, input.TexCoord);
|
float4 rawPosition = GBuffer_Position.Sample(Sampler, input.TexCoord);
|
||||||
|
float4 rawEmissive = GBuffer_Emissive.Sample(Sampler, input.TexCoord);
|
||||||
float4 rawMaterial = GBuffer_Material.Sample(Sampler, input.TexCoord);
|
float4 rawMaterial = GBuffer_Material.Sample(Sampler, input.TexCoord);
|
||||||
|
|
||||||
// Extract data from GBuffer
|
// Extract data from GBuffer
|
||||||
@@ -108,7 +110,7 @@ float4 PS(PS_IN input) : SV_TARGET
|
|||||||
|
|
||||||
float3 luminanceColor = LightColor * Illuminance;
|
float3 luminanceColor = LightColor * Illuminance;
|
||||||
|
|
||||||
float3 final = (kd * diffuse + specular) * luminanceColor * n_dot_l;
|
float3 final = (kd * diffuse + specular) * luminanceColor * n_dot_l + rawEmissive;
|
||||||
|
|
||||||
#if OUTPUT == Inspect_NormalDistribution
|
#if OUTPUT == Inspect_NormalDistribution
|
||||||
final = max(final - 10000000, nrmDist.xxx);
|
final = max(final - 10000000, nrmDist.xxx);
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
@@ -1,20 +1,16 @@
|
|||||||
{
|
{
|
||||||
AssetLoader = "EditorTextureAssetLoader",
|
AssetLoader = "EditorTextureAssetLoader",
|
||||||
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
||||||
_generateMipMaps = false,
|
|
||||||
_isSrgb = false,
|
|
||||||
_samplerStateDescription = {
|
_samplerStateDescription = {
|
||||||
MinFilter = .Linear,
|
MinFilter = .Anisotropic,
|
||||||
MagFilter = .Linear,
|
MagFilter = .Anisotropic,
|
||||||
MipFilter = .Linear,
|
MipFilter = .Anisotropic,
|
||||||
FilterMode = .Default,
|
|
||||||
ComparisonFunction = .Never,
|
ComparisonFunction = .Never,
|
||||||
AddressModeU = .Wrap,
|
AddressModeU = .Wrap,
|
||||||
AddressModeV = .Wrap,
|
AddressModeV = .Wrap,
|
||||||
AddressModeW = .Clamp,
|
AddressModeW = .Clamp,
|
||||||
MipLODBias = 0,
|
MipMinLOD = -Infinity,
|
||||||
MipMinLOD = -3.40282347e+38,
|
MipMaxLOD = Infinity,
|
||||||
MipMaxLOD = 3.40282347e+38,
|
|
||||||
MaxAnisotropy = 1,
|
MaxAnisotropy = 1,
|
||||||
BorderColor = {
|
BorderColor = {
|
||||||
R = 1,
|
R = 1,
|
||||||
|
|||||||
@@ -1,10 +1,11 @@
|
|||||||
{
|
{
|
||||||
Effect = "Shaders\\myEffect.hlsl",
|
Effect = "Shaders/myEffect.hlsl",
|
||||||
Textures = [
|
Textures = [
|
||||||
"AlbedoTexture": "Textures\\TestMat\\rustediron2_albedo.png",
|
"AlbedoTexture": "Textures/TestMat/rustediron2_albedo.png",
|
||||||
"NormalTexture": "Textures\\TestMat\\rustediron2_normal.png",
|
"NormalTexture": "Textures/TestMat/rustediron2_normal.png",
|
||||||
"MetallicTexture": "Textures\\TestMat\\rustediron2_metallic.png",
|
"MetallicTexture": "Textures/TestMat/rustediron2_metallic.png",
|
||||||
"RoughnessTexture": "Textures\\TestMat\\rustediron2_roughness.png"
|
"RoughnessTexture": "Textures/TestMat/rustediron2_roughness.png",
|
||||||
|
"EmissiveTexture": "Textures/rocket.png"
|
||||||
],
|
],
|
||||||
Variables = [
|
Variables = [
|
||||||
"AlbedoColor": .ColorRGBA{
|
"AlbedoColor": .ColorRGBA{
|
||||||
@@ -26,6 +27,13 @@
|
|||||||
},
|
},
|
||||||
"RoughnessFactor": .Float{
|
"RoughnessFactor": .Float{
|
||||||
Value = 1
|
Value = 1
|
||||||
|
},
|
||||||
|
"EmissiveColor": .ColorRGB{
|
||||||
|
Value = {
|
||||||
|
R = 1,
|
||||||
|
G = 0,
|
||||||
|
B = 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Binary file not shown.
@@ -0,0 +1,24 @@
|
|||||||
|
{
|
||||||
|
AssetLoader = "EditorTextureAssetLoader",
|
||||||
|
Config = (GlitchyEditor.Assets.EditorTextureAssetLoaderConfig){
|
||||||
|
_isSrgb = true,
|
||||||
|
_samplerStateDescription = {
|
||||||
|
MinFilter = .Linear,
|
||||||
|
MagFilter = .Linear,
|
||||||
|
MipFilter = .Linear,
|
||||||
|
ComparisonFunction = .Never,
|
||||||
|
AddressModeU = .Clamp,
|
||||||
|
AddressModeV = .Clamp,
|
||||||
|
AddressModeW = .Clamp,
|
||||||
|
MipMinLOD = -Infinity,
|
||||||
|
MipMaxLOD = Infinity,
|
||||||
|
MaxAnisotropy = 1,
|
||||||
|
BorderColor = {
|
||||||
|
R = 1,
|
||||||
|
G = 1,
|
||||||
|
B = 1,
|
||||||
|
A = 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
4.5/
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Install mono and copy the folder `lib/mono/4.5` here!
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"runtimeTarget": {
|
||||||
|
"name": ".NETCoreApp,Version=v7.0",
|
||||||
|
"signature": ""
|
||||||
|
},
|
||||||
|
"compilationOptions": {},
|
||||||
|
"targets": {
|
||||||
|
".NETCoreApp,Version=v7.0": {
|
||||||
|
"ScriptCore/1.0.0": {
|
||||||
|
"runtime": {
|
||||||
|
"ScriptCore.dll": {}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"libraries": {
|
||||||
|
"ScriptCore/1.0.0": {
|
||||||
|
"type": "project",
|
||||||
|
"serviceable": false,
|
||||||
|
"sha512": ""
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"additionalProbingPaths": [
|
||||||
|
"C:\\Users\\Simon\\.dotnet\\store\\|arch|\\|tfm|",
|
||||||
|
"C:\\Users\\Simon\\.nuget\\packages",
|
||||||
|
"C:\\Program Files (x86)\\Microsoft Visual Studio\\Shared\\NuGetPackages"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"runtimeOptions": {
|
||||||
|
"tfm": "net7.0",
|
||||||
|
"rollForward": "LatestMinor",
|
||||||
|
"framework": {
|
||||||
|
"name": "Microsoft.NETCore.App",
|
||||||
|
"version": "7.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,748 @@
|
|||||||
|
using System.IO;
|
||||||
|
using System;
|
||||||
|
using GlitchyEngine;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
|
namespace GlitchyEditor.Assets.Importers;
|
||||||
|
|
||||||
|
// Based on https://github.com/Diron-P/DDSReader/blob/main/dds_loader.h
|
||||||
|
|
||||||
|
public struct LoadedSurface
|
||||||
|
{
|
||||||
|
public Span<uint8> Data;
|
||||||
|
public uint32 Pitch;
|
||||||
|
public uint32 SlicePitch;
|
||||||
|
|
||||||
|
public int ArrayIndex;
|
||||||
|
public int CubeFace;
|
||||||
|
public int MipLevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
public struct LoadedTextureInfo
|
||||||
|
{
|
||||||
|
public enum Dimension
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
Texture1D,
|
||||||
|
Texture2D,
|
||||||
|
Texture3D
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint8[] PixelData = null;
|
||||||
|
public DirectX.DXGI.Format PixelFormat = .Unknown;
|
||||||
|
public int MipMapCount = 0;
|
||||||
|
public int ArraySize = 0;
|
||||||
|
public Dimension Dimension = .Unknown;
|
||||||
|
public bool IsCubeMap;
|
||||||
|
|
||||||
|
public int Width;
|
||||||
|
public int Height;
|
||||||
|
public int Depth;
|
||||||
|
}
|
||||||
|
|
||||||
|
static class DdsImporter
|
||||||
|
{
|
||||||
|
private const uint32 MagicWord = 0x20534444; // 'DDS
|
||||||
|
|
||||||
|
public enum LoadError
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
WrongMagicWord,
|
||||||
|
StreamReadFailed,
|
||||||
|
InvalidArraySize,
|
||||||
|
WrongDimensions,
|
||||||
|
IncompleteCubemap
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum HeaderFlags : uint32
|
||||||
|
{
|
||||||
|
/// Required in every .dds file.
|
||||||
|
DDSD_CAPS = 0x1,
|
||||||
|
/// Required in every .dds file.
|
||||||
|
DDSD_HEIGHT = 0x2,
|
||||||
|
/// Required in every .dds file.
|
||||||
|
DDSD_WIDTH = 0x4,
|
||||||
|
/// Required in every .dds file.
|
||||||
|
DDSD_PITCH = 0x8,
|
||||||
|
/// Required in every .dds file.
|
||||||
|
DDSD_PIXELFORMAT = 0x1000,
|
||||||
|
/// Required in a mipmapped texture.
|
||||||
|
DDSD_MIPMAPCOUNT = 0x20000,
|
||||||
|
/// Required when pitch is provided for a compressed texture.
|
||||||
|
DDSD_LINEARSIZE = 0x80000,
|
||||||
|
/// Required in a depth texture.
|
||||||
|
DDSD_DEPTH = 0x800000
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum Caps1 : uint32
|
||||||
|
{
|
||||||
|
/// Should be set, when the file contains multiple surfaces (e.g. Cubemaps or Mipmaps).
|
||||||
|
Complex = 0x8,
|
||||||
|
/// Should be set, if the file contains mipmaps.
|
||||||
|
MipMap = 0x400000,
|
||||||
|
/// Should always be set.
|
||||||
|
Texture = 0x1000
|
||||||
|
}
|
||||||
|
|
||||||
|
[AllowDuplicates]
|
||||||
|
private enum Caps2 : uint32
|
||||||
|
{
|
||||||
|
Cubemap = 0x200,
|
||||||
|
Cubemap_PositiveX = 0x400,
|
||||||
|
Cubemap_NegativeX = 0x800,
|
||||||
|
Cubemap_X = Cubemap_PositiveX | Cubemap_NegativeX,
|
||||||
|
Cubemap_PositiveY = 0x1000,
|
||||||
|
Cubemap_NegativeY = 0x2000,
|
||||||
|
Cubemap_Y = Cubemap_PositiveY | Cubemap_NegativeY,
|
||||||
|
Cubemap_PositiveZ = 0x4000,
|
||||||
|
Cubemap_NegativeZ = 0x8000,
|
||||||
|
Cubemap_Z = Cubemap_PositiveZ | Cubemap_NegativeZ,
|
||||||
|
/// This is the flag that should be set for Cubemaps in DX10+
|
||||||
|
Cubemap_AllFaces = Cubemap | Cubemap_X | Cubemap_Y | Cubemap_Z,
|
||||||
|
|
||||||
|
Volume = 0x200000,
|
||||||
|
}
|
||||||
|
|
||||||
|
[CRepr]
|
||||||
|
private struct DdsHeader
|
||||||
|
{
|
||||||
|
/// Size of this structure. This member must be set to 124.
|
||||||
|
private uint32 Size;
|
||||||
|
/// Flags to indicate which members contain valid data.
|
||||||
|
public HeaderFlags Flags;
|
||||||
|
/// Surface height (in pixels).
|
||||||
|
public uint32 Height;
|
||||||
|
/// Surface width (in pixels).
|
||||||
|
public uint32 Width;
|
||||||
|
public uint32 PitchOrLinearSize;
|
||||||
|
/// Depth of a volume texture (in pixels), otherwise unused.
|
||||||
|
public uint32 Depth;
|
||||||
|
/// Number of mipmap levels, otherwise unused.
|
||||||
|
public uint32 MipMapCount;
|
||||||
|
/// Unused.
|
||||||
|
private uint32[11] Reserved1;
|
||||||
|
/// The pixel format.
|
||||||
|
public DdsPixelFormat PixelFormat;
|
||||||
|
public Caps1 Caps;
|
||||||
|
public Caps2 Caps2;
|
||||||
|
/// Unused.
|
||||||
|
private uint32 dwCaps3;
|
||||||
|
/// Unused.
|
||||||
|
private uint32 dwCaps4;
|
||||||
|
/// Unused.
|
||||||
|
private uint32 dwReserved2;
|
||||||
|
}
|
||||||
|
|
||||||
|
private enum SurfaceType : uint32
|
||||||
|
{
|
||||||
|
/// Texture contains alpha data; dwRGBAlphaBitMask contains valid data.
|
||||||
|
AlphaPixels = 0x1,
|
||||||
|
/// Used in some older DDS files for alpha channel only uncompressed data (dwRGBBitCount contains the alpha channel bitcount; dwABitMask contains valid data)
|
||||||
|
Alpha = 0x2,
|
||||||
|
|
||||||
|
/// Texture contains compressed RGB data; dwFourCC contains valid data.
|
||||||
|
FourCC = 0x4,
|
||||||
|
/// Texture contains uncompressed RGB data; dwRGBBitCount and the RGB masks (dwRBitMask, dwGBitMask, dwBBitMask) contain valid data.
|
||||||
|
RGB = 0x40,
|
||||||
|
|
||||||
|
RGBA = RGB | AlphaPixels,
|
||||||
|
|
||||||
|
/// Used in some older DDS files for YUV uncompressed data (dwRGBBitCount contains the YUV bit count;
|
||||||
|
/// dwRBitMask contains the Y mask, dwGBitMask contains the U mask, dwBBitMask contains the V mask)
|
||||||
|
YUV = 0x200,
|
||||||
|
|
||||||
|
/// Used in some older DDS files for single channel color uncompressed data (dwRGBBitCount contains the luminance channel bit count;
|
||||||
|
/// dwRBitMask contains the channel mask). Can be combined with DDPF_ALPHAPIXELS for a two channel DDS file.
|
||||||
|
Luminance = 0x20000
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint32 MakeFourCC(char8 c0, char8 c1, char8 c2, char8 c3)
|
||||||
|
{
|
||||||
|
return ((uint32)c3 << 24 | (uint32) c2 << 16 | (uint32) c1 << 8 | (uint32) c0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*private enum FourCC : uint32
|
||||||
|
{
|
||||||
|
DXT1 = MakeFourCC('D', 'X', 'T', '1'),
|
||||||
|
DXT2 = MakeFourCC('D', 'X', 'T', '2'),
|
||||||
|
DXT3 = MakeFourCC('D', 'X', 'T', '3'),
|
||||||
|
DXT4 = MakeFourCC('D', 'X', 'T', '4'),
|
||||||
|
DXT5 = MakeFourCC('D', 'X', 'T', '5'),
|
||||||
|
/// indicates the prescense of the DDS_HEADER_DXT10 extended header
|
||||||
|
DX10 = MakeFourCC('D', 'X', '1', '0'),
|
||||||
|
}*/
|
||||||
|
|
||||||
|
[CRepr]
|
||||||
|
private struct DdsPixelFormat
|
||||||
|
{
|
||||||
|
/// Structure size; set to 32 (bytes).
|
||||||
|
private uint32 Size;
|
||||||
|
/// Values which indicate what type of data is in the surface.
|
||||||
|
public SurfaceType SurfaceType;
|
||||||
|
public uint32 FourCC;
|
||||||
|
/// Number of bits in an RGB (possibly including alpha) format. Valid when dwFlags includes DDPF_RGB, DDPF_LUMINANCE, or DDPF_YUV.
|
||||||
|
public uint32 RGBBitCount;
|
||||||
|
/// Red (or luminance or Y) mask for reading color data. For instance, given the A8R8G8B8 format, the red mask would be 0x00ff0000.
|
||||||
|
public uint32 RBitMask;
|
||||||
|
/// Green (or U) mask for reading color data. For instance, given the A8R8G8B8 format, the green mask would be 0x0000ff00.
|
||||||
|
public uint32 GBitMask;
|
||||||
|
/// Blue (or V) mask for reading color data. For instance, given the A8R8G8B8 format, the blue mask would be 0x000000ff.
|
||||||
|
public uint32 BBitMask;
|
||||||
|
/// Alpha mask for reading alpha data. dwFlags must include DDPF_ALPHAPIXELS or DDPF_ALPHA. For instance, given the A8R8G8B8 format, the alpha mask would be 0xff000000.
|
||||||
|
public uint32 ABitMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum ResourceDimensions : uint32
|
||||||
|
{
|
||||||
|
Texture1D = 2,
|
||||||
|
Texture2D = 3,
|
||||||
|
Texture3D = 4
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum MiscFlags : uint32
|
||||||
|
{
|
||||||
|
TextureCube = 0x4,
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AlphaMode : uint32
|
||||||
|
{
|
||||||
|
Unknown = 0x0,
|
||||||
|
Straight = 0x1,
|
||||||
|
Premultiplied = 0x2,
|
||||||
|
Opaque = 0x3,
|
||||||
|
/// Any alpha channel content is being used as a 4th channel and is not intended to represent transparency (straight or premultiplied).
|
||||||
|
Custom = 0x4
|
||||||
|
}
|
||||||
|
|
||||||
|
/// DDS header extension to handle resource arrays, DXGI pixel formats that don't map to the legacy Microsoft DirectDraw pixel format structures, and additional metadata.
|
||||||
|
[CRepr]
|
||||||
|
private struct DdsDxt10Header
|
||||||
|
{
|
||||||
|
public DirectX.DXGI.Format PixelFormat;
|
||||||
|
public ResourceDimensions ResourceDimension;
|
||||||
|
public MiscFlags MiscFlags;
|
||||||
|
/// Number of elements in the array. For a 2D cubemap this is the number of cubes, so the file contains ArraySize * 6 2D textures.
|
||||||
|
/// For a 3D Texture this must be 1.
|
||||||
|
public uint32 ArraySize;
|
||||||
|
|
||||||
|
public AlphaMode AlphaMode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Result<void, LoadError> DecodeHeader(Stream data, out DdsHeader header, out DdsDxt10Header? extendedHeader)
|
||||||
|
{
|
||||||
|
header = ?;
|
||||||
|
extendedHeader = null;
|
||||||
|
|
||||||
|
// Check the magic word
|
||||||
|
Result<uint32> magicWord = data.Read<uint32>();
|
||||||
|
|
||||||
|
if (magicWord case .Err)
|
||||||
|
return .Err(.StreamReadFailed);
|
||||||
|
|
||||||
|
if (magicWord != MagicWord)
|
||||||
|
return .Err(.WrongMagicWord);
|
||||||
|
|
||||||
|
// Load the header
|
||||||
|
Result<DdsHeader> headerResult = data.Read<DdsHeader>();
|
||||||
|
|
||||||
|
if (headerResult case .Err)
|
||||||
|
return .Err(.StreamReadFailed);
|
||||||
|
|
||||||
|
header = headerResult;
|
||||||
|
|
||||||
|
// If available, load the extended header
|
||||||
|
if (header.PixelFormat.SurfaceType.HasFlag(.FourCC) && header.PixelFormat.FourCC == MakeFourCC('D', 'X', '1', '0'))
|
||||||
|
{
|
||||||
|
Result<DdsDxt10Header> extendedHeaderResult = data.Read<DdsDxt10Header>();
|
||||||
|
|
||||||
|
if (headerResult case .Err)
|
||||||
|
return .Err(.StreamReadFailed);
|
||||||
|
|
||||||
|
extendedHeader = extendedHeaderResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsBitMask(DdsPixelFormat ddspf, uint32 rBitMask, uint32 gBitMask, uint32 bBitMask, uint32 aBitMask)
|
||||||
|
{
|
||||||
|
return ddspf.RBitMask == rBitMask && ddspf.GBitMask == gBitMask && ddspf.BBitMask == bBitMask && ddspf.ABitMask == aBitMask;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static DirectX.DXGI.Format GetFormat(in DdsHeader header, in DdsDxt10Header? extendedheader, bool isSrgb)
|
||||||
|
{
|
||||||
|
if (extendedheader != null)
|
||||||
|
return extendedheader.Value.PixelFormat;
|
||||||
|
|
||||||
|
DdsPixelFormat pixelFormat = header.PixelFormat;
|
||||||
|
|
||||||
|
// Currently supports only basic dxgi formats.
|
||||||
|
//if (pixelFormat.SurfaceType.HasFlag(.RGBA))
|
||||||
|
if (pixelFormat.SurfaceType.HasFlag(.RGB))
|
||||||
|
{
|
||||||
|
switch (pixelFormat.RGBBitCount)
|
||||||
|
{
|
||||||
|
case 32:
|
||||||
|
if (IsBitMask(pixelFormat, 0x000000FF, 0x0000FF00, 0x00FF0000, 0xFF000000))
|
||||||
|
return isSrgb ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0x00FF0000, 0x0000FF00, 0x000000FF, 0xFF000000))
|
||||||
|
return isSrgb ? .B8G8R8A8_UNorm_SRGB : .B8G8R8A8_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0x00FF0000, 0x0000FF00, 0x000000FF, 0))
|
||||||
|
return isSrgb ? .B8G8R8X8_UNorm_SRGB : .B8G8R8X8_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0x000003FF, 0x000FFc00, 0x3FF00000, 0))
|
||||||
|
return .R10G10B10A2_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0x3FF00000, 0x000FFc00, 0x000003FF, 0))
|
||||||
|
return .R10G10B10A2_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0x0000FFFF, 0xFFFF0000, 0, 0))
|
||||||
|
return .R16G16_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0xFFFFFFFF, 0, 0, 0))
|
||||||
|
return .R32_Float;
|
||||||
|
|
||||||
|
case 24:
|
||||||
|
// NO 24 bit formats
|
||||||
|
return .Unknown;
|
||||||
|
|
||||||
|
case 16:
|
||||||
|
if (IsBitMask(pixelFormat, 0x7C00, 0x03E0, 0x001F, 0x8000))
|
||||||
|
return .B5G5R5A1_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0xF800, 0x07E0, 0x001F, 0))
|
||||||
|
return .B5G6R5_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0x0F00, 0x00F0, 0x000F, 0xF000))
|
||||||
|
return .B4G4R4A4_UNORM;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0x00FF, 0, 0, 0xFF00))
|
||||||
|
return .R8G8_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0xFFFF, 0, 0, 0))
|
||||||
|
return .R16_UNorm;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
if (IsBitMask(pixelFormat, 0xFF, 0, 0, 0))
|
||||||
|
return .R8_UNorm;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return .Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pixelFormat.SurfaceType.HasFlag(.Luminance))
|
||||||
|
{
|
||||||
|
switch (pixelFormat.RGBBitCount)
|
||||||
|
{
|
||||||
|
case 16:
|
||||||
|
if (IsBitMask(pixelFormat, 0xFFFF, 0, 0, 0))
|
||||||
|
return .R16_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0x00FF, 0, 0, 0xFF00))
|
||||||
|
return .R8G8_UNorm;
|
||||||
|
|
||||||
|
case 8:
|
||||||
|
if (IsBitMask(pixelFormat, 0xFF, 0, 0, 0))
|
||||||
|
return .R8_UNorm;
|
||||||
|
|
||||||
|
if (IsBitMask(pixelFormat, 0x00FF, 0, 0, 0xFF00))
|
||||||
|
return .R8G8_UNorm; // Some DDS writers assume the bitcount should be 8 instead of 16
|
||||||
|
|
||||||
|
default:
|
||||||
|
return .Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pixelFormat.SurfaceType.HasFlag(.Luminance))
|
||||||
|
{
|
||||||
|
if (pixelFormat.RGBBitCount == 8)
|
||||||
|
{
|
||||||
|
return .A8_UNorm;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (pixelFormat.SurfaceType.HasFlag(.FourCC))
|
||||||
|
{
|
||||||
|
switch (pixelFormat.FourCC)
|
||||||
|
{
|
||||||
|
case MakeFourCC('D', 'X', 'T', '1'):
|
||||||
|
return isSrgb ? .BC1_UNorm_SRGB : .BC1_UNorm;
|
||||||
|
case MakeFourCC('D', 'X', 'T', '3'):
|
||||||
|
return isSrgb ? .BC2_UNorm_SRGB : .BC2_UNorm;
|
||||||
|
case MakeFourCC('D', 'X', 'T', '5'):
|
||||||
|
return isSrgb ? .BC3_UNorm_SRGB : .BC3_UNorm;
|
||||||
|
|
||||||
|
// Legacy compression formats.
|
||||||
|
case MakeFourCC('D', 'X', 'T', '2'):
|
||||||
|
return isSrgb ? .BC2_UNorm_SRGB : .BC2_UNorm;
|
||||||
|
case MakeFourCC('D', 'X', 'T', '4'):
|
||||||
|
return isSrgb ? .BC3_UNorm_SRGB : .BC3_UNorm;
|
||||||
|
|
||||||
|
case MakeFourCC('B', 'C', '4', 'U'), MakeFourCC('A', 'T', 'I', '1'):
|
||||||
|
return .BC4_UNorm;
|
||||||
|
case MakeFourCC('B', 'C', '4', 'S'):
|
||||||
|
return .BC4_SNorm;
|
||||||
|
case MakeFourCC('B', 'C', '5', 'U'), MakeFourCC('A', 'T', 'I', '2'):
|
||||||
|
return .BC5_UNorm;
|
||||||
|
case MakeFourCC('B', 'C', '5', 'S'):
|
||||||
|
return .BC5_SNorm;
|
||||||
|
|
||||||
|
case MakeFourCC('R', 'G', 'B', 'G'):
|
||||||
|
return .R8G8_B8G8_UNorm;
|
||||||
|
case MakeFourCC('G', 'R', 'G', 'B'):
|
||||||
|
return .G8R8_G8B8_UNorm;
|
||||||
|
|
||||||
|
case MakeFourCC('Y', 'U', 'Y', '2'):
|
||||||
|
return .YUY2;
|
||||||
|
|
||||||
|
case 36:
|
||||||
|
return .R16G16B16A16_UNorm;
|
||||||
|
case 111:
|
||||||
|
return .R16_Float;
|
||||||
|
case 112:
|
||||||
|
return .R16G16_Float;
|
||||||
|
case 113:
|
||||||
|
return .R16G16B16A16_Float;
|
||||||
|
case 114:
|
||||||
|
return .R32_Float;
|
||||||
|
case 115:
|
||||||
|
return .R32G32_Float;
|
||||||
|
case 116:
|
||||||
|
return .R32G32B32A32_Float;
|
||||||
|
default:
|
||||||
|
return .Unknown;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void GetPitch(uint32 width, uint32 height, DirectX.DXGI.Format format, out uint32 rowBytes, out uint32 numRows, out uint64 numBytes)
|
||||||
|
{
|
||||||
|
rowBytes = 0;
|
||||||
|
numRows = 0;
|
||||||
|
numBytes = 0;
|
||||||
|
|
||||||
|
bool bc = false;
|
||||||
|
bool packed = false;
|
||||||
|
bool planar = false;
|
||||||
|
uint32 bpe = 0;
|
||||||
|
|
||||||
|
switch (format)
|
||||||
|
{
|
||||||
|
case .BC1_Typeless, .BC1_UNorm, .BC1_UNorm_SRGB,
|
||||||
|
.BC4_Typeless, .BC4_UNorm, .BC4_SNorm:
|
||||||
|
bc = true;
|
||||||
|
bpe = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case .BC2_Typeless, .BC2_UNorm, .BC2_UNorm_SRGB,
|
||||||
|
.BC3_Typeless, .BC3_UNorm, .BC3_UNorm_SRGB,
|
||||||
|
.BC5_Typeless, .BC5_UNorm, .BC5_SNorm,
|
||||||
|
.BC6H_Typeless, .BC6H_UF16, .BC6H_SF16,
|
||||||
|
.BC7_Typeless, .BC7_UNorm, .BC7_UNorm_SRGB:
|
||||||
|
bc = true;
|
||||||
|
bpe = 16;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case .R8G8_B8G8_UNorm, .G8R8_G8B8_UNorm, .YUY2:
|
||||||
|
packed = true;
|
||||||
|
bpe = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case .Y210, .Y216:
|
||||||
|
packed = true;
|
||||||
|
bpe = 8;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case .NV12, .P208, .OPAQUE_420:
|
||||||
|
planar = true;
|
||||||
|
bpe = 2;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case .P010, .P016:
|
||||||
|
planar = true;
|
||||||
|
bpe = 4;
|
||||||
|
break;
|
||||||
|
|
||||||
|
/*
|
||||||
|
case .D16_UNORM_S8_UINT:
|
||||||
|
case .R16_UNORM_X8_TYPELESS:
|
||||||
|
case .X16_TYPELESS_G8_UINT:
|
||||||
|
planar = true;
|
||||||
|
bpe = 4;
|
||||||
|
break;
|
||||||
|
*/
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (bc)
|
||||||
|
{
|
||||||
|
uint32 numBlocksWide = 0;
|
||||||
|
if (width > 0)
|
||||||
|
{
|
||||||
|
numBlocksWide = Math.Max(1, (width + 3u) / 4u);
|
||||||
|
}
|
||||||
|
uint32 numBlocksHigh = 0;
|
||||||
|
if (height > 0)
|
||||||
|
{
|
||||||
|
numBlocksHigh = Math.Max(1, (height + 3u) / 4u);
|
||||||
|
}
|
||||||
|
rowBytes = numBlocksWide * bpe;
|
||||||
|
numRows = numBlocksHigh;
|
||||||
|
numBytes = rowBytes * numBlocksHigh;
|
||||||
|
}
|
||||||
|
else if (packed)
|
||||||
|
{
|
||||||
|
rowBytes = (((uint32)width + 1u) >> 1) * bpe;
|
||||||
|
numRows = height;
|
||||||
|
numBytes = rowBytes * height;
|
||||||
|
}
|
||||||
|
else if (format == .NV11)
|
||||||
|
{
|
||||||
|
rowBytes = ((width + 3u) >> 2) * 4u;
|
||||||
|
numRows = height * 2u; // Direct3D makes this simplifying assumption, although it is larger than the 4:1:1 data
|
||||||
|
numBytes = rowBytes * numRows;
|
||||||
|
}
|
||||||
|
else if (planar)
|
||||||
|
{
|
||||||
|
rowBytes = ((width + 1u) >> 1) * bpe;
|
||||||
|
numBytes = (rowBytes * height) + ((rowBytes * height + 1u) >> 1);
|
||||||
|
numRows = height + ((height + 1u) >> 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
uint32 bpp = format.BitsPerPixel();// BitsPerPixel(format);
|
||||||
|
if (bpp == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
rowBytes = (width * bpp + 7u) / 8u; // round up to nearest byte
|
||||||
|
numRows = height;
|
||||||
|
numBytes = rowBytes * height;
|
||||||
|
}
|
||||||
|
|
||||||
|
//#if defined(_M_IX86) || defined(_M_ARM) || defined(_M_HYBRID_X86_ARM64)
|
||||||
|
/*static_assert(sizeof(size_t) == 4, "Not a 32-bit platform!");
|
||||||
|
if (numBytes > UINT32_MAX || rowBytes > UINT32_MAX || numRows > UINT32_MAX)
|
||||||
|
return HRESULT_FROM_WIN32(ERROR_ARITHMETIC_OVERFLOW);*/
|
||||||
|
/*#else
|
||||||
|
static_assert(sizeof(size_t) == 8, "Not a 64-bit platform!");
|
||||||
|
#endif*/
|
||||||
|
|
||||||
|
/*if (outNumBytes)
|
||||||
|
{
|
||||||
|
*outNumBytes = static_cast<size_t>(numBytes);
|
||||||
|
}
|
||||||
|
if (outRowBytes)
|
||||||
|
{
|
||||||
|
*outRowBytes = static_cast<size_t>(rowBytes);
|
||||||
|
}
|
||||||
|
if (outNumRows)
|
||||||
|
{
|
||||||
|
*outNumRows = static_cast<size_t>(numRows);
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
|
public static Result<void, LoadError> LoadDds(Stream data, bool isSrgb, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
||||||
|
{
|
||||||
|
// TODO: Care about alpha mode
|
||||||
|
|
||||||
|
textureInfo = .();
|
||||||
|
|
||||||
|
var headerResult = DecodeHeader(data, let header, let extendedHeader);
|
||||||
|
|
||||||
|
if (headerResult case .Err)
|
||||||
|
return headerResult;
|
||||||
|
|
||||||
|
int surfaceCount = 1;
|
||||||
|
|
||||||
|
if (header.Flags.HasFlag(.DDSD_MIPMAPCOUNT) || header.MipMapCount != 0)
|
||||||
|
{
|
||||||
|
if (header.MipMapCount == 0)
|
||||||
|
Log.EngineLogger.Warning("Mipmap count is zero, even though the flags say it shouldn't.");
|
||||||
|
|
||||||
|
if (!header.Flags.HasFlag(.DDSD_MIPMAPCOUNT))
|
||||||
|
Log.EngineLogger.Warning("Mipmap count is not zero, even though the mipmap count flag isn't set.");
|
||||||
|
|
||||||
|
textureInfo.MipMapCount = header.MipMapCount;
|
||||||
|
surfaceCount *= textureInfo.MipMapCount;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textureInfo.MipMapCount = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (extendedHeader != null)
|
||||||
|
{
|
||||||
|
textureInfo.ArraySize = extendedHeader.Value.ArraySize;
|
||||||
|
surfaceCount *= textureInfo.ArraySize;
|
||||||
|
|
||||||
|
if (textureInfo.ArraySize == 0)
|
||||||
|
return .Err(.InvalidArraySize);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textureInfo.ArraySize = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (header.Caps2.HasFlag(.Cubemap))
|
||||||
|
{
|
||||||
|
if (!header.Caps2.HasFlag(.Cubemap_AllFaces))
|
||||||
|
Log.EngineLogger.Warning("Texture might only contains partial cubemap, this is not allowed. (Defined Cubemap-Flag, but not all cubemap faces)");
|
||||||
|
|
||||||
|
surfaceCount *= 6;
|
||||||
|
textureInfo.IsCubeMap = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
textureInfo.PixelFormat = GetFormat(header, extendedHeader, isSrgb);
|
||||||
|
|
||||||
|
textureInfo.Width = header.Width;
|
||||||
|
textureInfo.Height = header.Height;
|
||||||
|
textureInfo.Depth = header.Depth;
|
||||||
|
|
||||||
|
switch (extendedHeader?.ResourceDimension)
|
||||||
|
{
|
||||||
|
case .Texture1D:
|
||||||
|
textureInfo.Dimension = .Texture1D;
|
||||||
|
|
||||||
|
if (header.Flags.HasFlag(.DDSD_HEIGHT) && header.Height != 1)
|
||||||
|
return .Err(.WrongDimensions);
|
||||||
|
|
||||||
|
textureInfo.Height = 1;
|
||||||
|
textureInfo.Depth = 1;
|
||||||
|
|
||||||
|
case .Texture2D:
|
||||||
|
textureInfo.Dimension = .Texture2D;
|
||||||
|
|
||||||
|
textureInfo.Depth = 1;
|
||||||
|
|
||||||
|
case .Texture3D:
|
||||||
|
textureInfo.Dimension = .Texture3D;
|
||||||
|
case null:
|
||||||
|
if (header.Flags.HasFlag(.DDSD_DEPTH))
|
||||||
|
textureInfo.Dimension = .Texture3D;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
textureInfo.Dimension = .Texture2D;
|
||||||
|
textureInfo.Depth = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make sure we have enough space in the list (avoid allocations later)
|
||||||
|
surfaces.Reserve(surfaceCount);
|
||||||
|
|
||||||
|
uint32 scanLineSize = 0;
|
||||||
|
uint32 slicePitch = 0;
|
||||||
|
uint64 numBytes = 0;
|
||||||
|
uint32 blockSize = 0; // Block size in bytes.
|
||||||
|
|
||||||
|
switch (textureInfo.PixelFormat)
|
||||||
|
{
|
||||||
|
case .BC1_UNorm, .BC1_UNorm_SRGB, .BC1_Typeless,
|
||||||
|
.BC4_UNorm, .BC4_SNorm, .BC4_Typeless:
|
||||||
|
blockSize = 8;
|
||||||
|
case .BC2_UNorm, .BC2_UNorm_SRGB, .BC2_Typeless,
|
||||||
|
.BC3_UNorm, .BC3_UNorm_SRGB, .BC3_Typeless,
|
||||||
|
.BC5_UNorm, .BC5_SNorm, .BC5_Typeless,
|
||||||
|
.BC7_UNorm, .BC7_UNorm_SRGB, .BC7_Typeless:
|
||||||
|
blockSize = 16;
|
||||||
|
default:
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32 width = 0;
|
||||||
|
uint32 height = 0;
|
||||||
|
uint32 depth = 0;
|
||||||
|
|
||||||
|
uint32 index = 0;
|
||||||
|
|
||||||
|
uint offset = 0;
|
||||||
|
|
||||||
|
for (uint32 arrayIndex = 0; arrayIndex < textureInfo.ArraySize; arrayIndex++)
|
||||||
|
{
|
||||||
|
for (uint32 cubeFace = 0; cubeFace < (textureInfo.IsCubeMap ? 6 : 1); cubeFace++)
|
||||||
|
{
|
||||||
|
width = header.Width;
|
||||||
|
height = header.Height;
|
||||||
|
depth = header.Depth;
|
||||||
|
|
||||||
|
for (uint32 mipLevel = 0; mipLevel < textureInfo.MipMapCount; ++mipLevel)
|
||||||
|
{
|
||||||
|
/*// This will recalculate te pitch of the main image as well.
|
||||||
|
if (header.Flags.HasFlag(.DDSD_LINEARSIZE))
|
||||||
|
{
|
||||||
|
// compressed textures
|
||||||
|
scanLineSize = Math.Max(1, ((width + 3u) / 4u)) * blockSize;
|
||||||
|
uint32 numScanLines = Math.Max(1, ((height + 3u) / 4u));
|
||||||
|
numBytes = scanLineSize * numScanLines;
|
||||||
|
}
|
||||||
|
else if (header.Flags.HasFlag(.DDSD_PITCH))
|
||||||
|
{
|
||||||
|
// uncompressed data
|
||||||
|
scanLineSize = (width * header.PixelFormat.RGBBitCount + 7u) / 8u;
|
||||||
|
numBytes = scanLineSize * height;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
scanLineSize = header.PitchOrLinearSize;
|
||||||
|
numBytes = scanLineSize * height;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
GetPitch(width, height, textureInfo.PixelFormat, out scanLineSize, let numRows, out numBytes);
|
||||||
|
|
||||||
|
|
||||||
|
LoadedSurface surface = .();
|
||||||
|
// We don't know how large data-array is, so we don't have one yet.
|
||||||
|
// Only save the offset, we will adjust the pointer later.
|
||||||
|
surface.Data = Span<uint8>((uint8*)(void*)offset, (int)numBytes);
|
||||||
|
surface.Pitch = scanLineSize;
|
||||||
|
//surface.SlicePitch = slicePitch;
|
||||||
|
surface.SlicePitch = scanLineSize * numRows;
|
||||||
|
|
||||||
|
surface.ArrayIndex = arrayIndex;
|
||||||
|
surface.CubeFace = cubeFace;
|
||||||
|
surface.MipLevel = mipLevel;
|
||||||
|
|
||||||
|
surfaces.Add(surface);
|
||||||
|
|
||||||
|
++index;
|
||||||
|
|
||||||
|
width >>= 1;
|
||||||
|
height >>= 1;
|
||||||
|
depth >>= 1;
|
||||||
|
|
||||||
|
if (width == 0)
|
||||||
|
{
|
||||||
|
width = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (height == 0)
|
||||||
|
{
|
||||||
|
height = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
offset += numBytes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
textureInfo.PixelData = new uint8[offset];
|
||||||
|
|
||||||
|
Result<int> pixelDataResult = data.TryRead(textureInfo.PixelData);
|
||||||
|
|
||||||
|
if (pixelDataResult case .Err)
|
||||||
|
{
|
||||||
|
delete textureInfo.PixelData;
|
||||||
|
return .Err(.StreamReadFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ref LoadedSurface surface in ref surfaces)
|
||||||
|
{
|
||||||
|
// Data pointer so far only has the offset inside the array.
|
||||||
|
// Move the pointer, so that it is inside the array.
|
||||||
|
surface.Data.Ptr += (uint)(void*)textureInfo.PixelData.Ptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -99,7 +99,8 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
{
|
{
|
||||||
for (let (name, arguments) in effect.[Friend]_variableDescriptions)
|
for (let (name, arguments) in effect.[Friend]_variableDescriptions)
|
||||||
{
|
{
|
||||||
let variable = effect.Variables[name];
|
if (!effect.Variables.TryGetVariable(name, let variable))
|
||||||
|
continue;
|
||||||
|
|
||||||
bool hasPreviewName = TryGetValue(arguments, "Preview", var previewName);
|
bool hasPreviewName = TryGetValue(arguments, "Preview", var previewName);
|
||||||
|
|
||||||
@@ -107,35 +108,69 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
|
|
||||||
bool hasPreviewType = TryGetValue(arguments, "Type", var previewType);
|
bool hasPreviewType = TryGetValue(arguments, "Type", var previewType);
|
||||||
|
|
||||||
if (hasPreviewType && previewType.Get<String>() == "Color")
|
if (hasPreviewType && (previewType.Get<String>() == "Color" || previewType.Get<String>() == "ColorHDR"))
|
||||||
|
{
|
||||||
|
if (previewType.Get<String>().Equals("Color", .InvariantCultureIgnoreCase))
|
||||||
{
|
{
|
||||||
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
||||||
|
|
||||||
if (variable.Columns == 3)
|
if (variable.Columns == 3)
|
||||||
{
|
{
|
||||||
material.GetVariable<Vector3>(variable.Name, var value);
|
material.GetVariable<float3>(variable.Name, var value);
|
||||||
|
|
||||||
value = (Vector3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit3(displayName.Ptr, *(float[3]*)&value))
|
if (ImGui.ColorEdit3(displayName.Ptr, *(float[3]*)&value))
|
||||||
{
|
{
|
||||||
value = (Vector3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (variable.Columns == 4)
|
else if (variable.Columns == 4)
|
||||||
{
|
{
|
||||||
material.GetVariable<Vector4>(variable.Name, var value);
|
material.GetVariable<float4>(variable.Name, var value);
|
||||||
|
|
||||||
value = (Vector4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
||||||
|
|
||||||
if (ImGui.ColorEdit4(displayName.Ptr, *(float[4]*)&value))
|
if (ImGui.ColorEdit4(displayName.Ptr, *(float[4]*)&value))
|
||||||
{
|
{
|
||||||
value = (Vector4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (previewType.Get<String>().Equals("ColorHDR", .InvariantCultureIgnoreCase))
|
||||||
|
{
|
||||||
|
Log.EngineLogger.AssertDebug(variable.Type == .Float && variable.Rows == 1);
|
||||||
|
|
||||||
|
if (variable.Columns == 3)
|
||||||
|
{
|
||||||
|
material.GetVariable<float3>(variable.Name, var value);
|
||||||
|
|
||||||
|
value = (float3)ColorRGB.LinearToSRGB((ColorRGB)value);
|
||||||
|
|
||||||
|
if (ImGui.ColorEdit3(displayName.Ptr, *(float[3]*)&value, .HDR | .Float))
|
||||||
|
{
|
||||||
|
value = (float3)ColorRGB.SRgbToLinear((ColorRGB)value);
|
||||||
|
material.SetVariable(variable.Name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (variable.Columns == 4)
|
||||||
|
{
|
||||||
|
material.GetVariable<float4>(variable.Name, var value);
|
||||||
|
|
||||||
|
value = (float4)ColorRGBA.LinearToSRGB((ColorRGBA)value);
|
||||||
|
|
||||||
|
if (ImGui.ColorEdit4(displayName.Ptr, *(float[4]*)&value, .HDR | .Float))
|
||||||
|
{
|
||||||
|
value = (float4)ColorRGBA.SRgbToLinear((ColorRGBA)value);
|
||||||
|
material.SetVariable(variable.Name, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//ImGui.ColorEdit3("", null, .HDR | .Float)
|
||||||
|
|
||||||
else if (variable.Type == .Float && variable.Rows == 1)
|
else if (variable.Type == .Float && variable.Rows == 1)
|
||||||
{
|
{
|
||||||
bool hasMin = TryGetValue(arguments, "Min", var min);
|
bool hasMin = TryGetValue(arguments, "Min", var min);
|
||||||
@@ -154,28 +189,28 @@ class MaterialAssetPropertiesEditor : AssetPropertiesEditor
|
|||||||
if (ImGui.EditVector<1>(displayName, ref *(float[1]*)&value, .(), 0.1f, 100.0f, minV, maxV))
|
if (ImGui.EditVector<1>(displayName, ref *(float[1]*)&value, .(), 0.1f, 100.0f, minV, maxV))
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
case 2:
|
case 2:
|
||||||
material.GetVariable<Vector2>(variable.Name, var value);
|
material.GetVariable<float2>(variable.Name, var value);
|
||||||
|
|
||||||
Vector2 minV = hasMin ? min.Get<Vector2>() : .(float.MinValue);
|
float2 minV = hasMin ? min.Get<float2>() : (float2)float.MinValue;
|
||||||
Vector2 maxV = hasMax ? max.Get<Vector2>() : .(float.MaxValue);
|
float2 maxV = hasMax ? max.Get<float2>() : (float2)float.MaxValue;
|
||||||
|
|
||||||
if (ImGui.EditVector2(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
if (ImGui.Editfloat2(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
case 3:
|
case 3:
|
||||||
material.GetVariable<Vector3>(variable.Name, var value);
|
material.GetVariable<float3>(variable.Name, var value);
|
||||||
|
|
||||||
Vector3 minV = hasMin ? min.Get<Vector3>() : .(float.MinValue);
|
float3 minV = hasMin ? min.Get<float3>() : (float3)float.MinValue;
|
||||||
Vector3 maxV = hasMax ? max.Get<Vector3>() : .(float.MaxValue);
|
float3 maxV = hasMax ? max.Get<float3>() : (float3)float.MaxValue;
|
||||||
|
|
||||||
if (ImGui.EditVector3(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
if (ImGui.Editfloat3(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
case 4:
|
case 4:
|
||||||
material.GetVariable<Vector4>(variable.Name, var value);
|
material.GetVariable<float4>(variable.Name, var value);
|
||||||
|
|
||||||
Vector4 minV = hasMin ? min.Get<Vector4>() : .(float.MinValue);
|
float4 minV = hasMin ? min.Get<float4>() : (float4)float.MinValue;
|
||||||
Vector4 maxV = hasMax ? max.Get<Vector4>() : .(float.MaxValue);
|
float4 maxV = hasMax ? max.Get<float4>() : (float4)float.MaxValue;
|
||||||
|
|
||||||
if (ImGui.EditVector4(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
if (ImGui.Editfloat4(displayName, ref value, .Zero, 0.1f, 100.0f, minV, maxV))
|
||||||
material.SetVariable(variable.Name, value);
|
material.SetVariable(variable.Name, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -198,14 +233,22 @@ class MaterialAssetLoaderConfig : AssetLoaderConfig
|
|||||||
[BonTarget]
|
[BonTarget]
|
||||||
public enum VariableValue
|
public enum VariableValue
|
||||||
{
|
{
|
||||||
|
case bool(bool Value);
|
||||||
|
case bool2(bool2 Value);
|
||||||
|
case bool3(bool3 Value);
|
||||||
|
case bool4(bool4 Value);
|
||||||
|
case int(int Value);
|
||||||
|
case int2(int2 Value);
|
||||||
|
case int3(int3 Value);
|
||||||
|
case int4(int4 Value);
|
||||||
|
case uint(uint Value);
|
||||||
|
case uint2(uint2 Value);
|
||||||
|
case uint3(uint3 Value);
|
||||||
|
case uint4(uint4 Value);
|
||||||
case Float(float Value);
|
case Float(float Value);
|
||||||
case Float2(Vector2 Value);
|
case Float2(float2 Value);
|
||||||
case Float3(Vector3 Value);
|
case Float3(float3 Value);
|
||||||
case Float4(Vector4 Value);
|
case Float4(float4 Value);
|
||||||
case Int(int Value);
|
|
||||||
case Int2(Int2 Value);
|
|
||||||
case Int3(Int3 Value);
|
|
||||||
case Int4(Int4 Value);
|
|
||||||
case ColorRGB(ColorRGB Value);
|
case ColorRGB(ColorRGB Value);
|
||||||
case ColorRGBA(ColorRGBA Value);
|
case ColorRGBA(ColorRGBA Value);
|
||||||
case None;
|
case None;
|
||||||
@@ -347,6 +390,7 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
|
|||||||
|
|
||||||
for (let (slotName, textureIdentifier) in materialFile.Textures)
|
for (let (slotName, textureIdentifier) in materialFile.Textures)
|
||||||
{
|
{
|
||||||
|
|
||||||
AssetHandle<Texture> texture = contentManager.LoadAsset(textureIdentifier);
|
AssetHandle<Texture> texture = contentManager.LoadAsset(textureIdentifier);
|
||||||
|
|
||||||
if (texture.IsInvalid)
|
if (texture.IsInvalid)
|
||||||
@@ -402,7 +446,7 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
|
|||||||
|
|
||||||
for (let (slotName, texture) in material.[Friend]_textures)
|
for (let (slotName, texture) in material.[Friend]_textures)
|
||||||
{
|
{
|
||||||
Texture textureAsset = texture.Get();
|
Texture textureAsset = texture.Handle.Get();
|
||||||
|
|
||||||
materialFile.Textures.Add(new String(slotName), new String(textureAsset?.Identifier ?? ""));
|
materialFile.Textures.Add(new String(slotName), new String(textureAsset?.Identifier ?? ""));
|
||||||
}
|
}
|
||||||
@@ -450,13 +494,13 @@ class MaterialAssetLoader : IAssetLoader, IAssetSaver //, IReloadingAssetLoader
|
|||||||
material.GetVariable<float>(variable.Name, let value);
|
material.GetVariable<float>(variable.Name, let value);
|
||||||
variableValue = .Float(value);
|
variableValue = .Float(value);
|
||||||
case 2:
|
case 2:
|
||||||
material.GetVariable<Vector2>(variable.Name, let value);
|
material.GetVariable<float2>(variable.Name, let value);
|
||||||
variableValue = .Float2(value);
|
variableValue = .Float2(value);
|
||||||
case 3:
|
case 3:
|
||||||
material.GetVariable<Vector3>(variable.Name, let value);
|
material.GetVariable<float3>(variable.Name, let value);
|
||||||
variableValue = .Float3(value);
|
variableValue = .Float3(value);
|
||||||
case 4:
|
case 4:
|
||||||
material.GetVariable<Vector4>(variable.Name, let value);
|
material.GetVariable<float4>(variable.Name, let value);
|
||||||
variableValue = .Float4(value);
|
variableValue = .Float4(value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,8 @@ using GlitchyEngine.Renderer;
|
|||||||
using GlitchyEngine.Math;
|
using GlitchyEngine.Math;
|
||||||
using DirectXTK;
|
using DirectXTK;
|
||||||
using ImGui;
|
using ImGui;
|
||||||
|
using GlitchyEditor.Assets.Importers;
|
||||||
|
using System.Diagnostics;
|
||||||
|
|
||||||
namespace GlitchyEditor.Assets;
|
namespace GlitchyEditor.Assets;
|
||||||
|
|
||||||
@@ -164,6 +166,9 @@ class EditorTextureAssetLoaderConfig : AssetLoaderConfig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using internal GlitchyEngine.Renderer;
|
||||||
|
using internal GlitchyEngine.Platform.DX11;
|
||||||
|
|
||||||
class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
||||||
{
|
{
|
||||||
private static readonly List<StringView> _fileExtensions = new .(){".png", ".dds"} ~ delete _; // ".jpg", ".bmp"
|
private static readonly List<StringView> _fileExtensions = new .(){".png", ".dds"} ~ delete _; // ".jpg", ".bmp"
|
||||||
@@ -230,23 +235,80 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
|||||||
return .Unknown;
|
return .Unknown;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** \brief Loads the texture from the specified path.
|
||||||
|
* @param path The path of the texture to load.
|
||||||
|
* @param texture The reference to the pointer that will hold the texture.
|
||||||
|
* @returns true if the texture was loaded successfully; false otherwise.
|
||||||
|
*/
|
||||||
|
protected static bool LoadDdsResourcePlatform(Stream stream)
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
uint8[] ddsData = new:ScopedAlloc! uint8[stream.Length];
|
||||||
|
|
||||||
|
var result = stream.TryRead(ddsData);
|
||||||
|
|
||||||
|
if (result case .Err(let err))
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error($"Failed to read texture data from stream. Error: {err}");
|
||||||
|
}
|
||||||
|
|
||||||
|
DirectX.D3D11.ID3D11Texture2D* texture = null;
|
||||||
|
DirectX.D3D11.ID3D11ShaderResourceView* view = null;
|
||||||
|
|
||||||
|
DirectX.Common.HResult loadResult = DDSTextureLoader.CreateDDSTextureFromMemory(GlitchyEngine.Platform.DX11.NativeDevice,
|
||||||
|
ddsData.Ptr, (uint)ddsData.Count, (.)&texture, &view);
|
||||||
|
|
||||||
|
view.Release();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private static Texture LoadTexture(Stream data, EditorTextureAssetLoaderConfig config)
|
private static Texture LoadTexture(Stream data, EditorTextureAssetLoaderConfig config)
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
Texture texture = null;
|
List<LoadedSurface> surfaces = scope .();
|
||||||
|
LoadedTextureInfo textureInfo;
|
||||||
|
|
||||||
|
// Make sure we clean up the pixel data
|
||||||
|
defer { delete textureInfo.PixelData; }
|
||||||
|
|
||||||
|
|
||||||
switch(GetTextureType(data))
|
switch(GetTextureType(data))
|
||||||
{
|
{
|
||||||
case .DDS:
|
case .DDS:
|
||||||
texture = LoadDds(data, config);
|
|
||||||
|
var v = data.Position;
|
||||||
|
|
||||||
|
//LoadDdsResourcePlatform(data);
|
||||||
|
|
||||||
|
data.Position = v;
|
||||||
|
|
||||||
|
Result<void> result = LoadDds(data, config, surfaces, out textureInfo);
|
||||||
|
|
||||||
|
if (result case .Err)
|
||||||
|
return null;
|
||||||
|
|
||||||
case .PNG:
|
case .PNG:
|
||||||
texture = LoadPng(data, config);
|
Result<void> result = LoadPng(data, config, surfaces, out textureInfo);
|
||||||
|
|
||||||
|
if (result case .Err)
|
||||||
|
return null;
|
||||||
|
|
||||||
case .Unknown:
|
case .Unknown:
|
||||||
Log.EngineLogger.Error("Unknown texture format.");
|
Log.EngineLogger.Error("Unknown texture format.");
|
||||||
texture = null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make the format SRGB or non-SRGB
|
||||||
|
if (config.IsSRGB)
|
||||||
|
textureInfo.PixelFormat = textureInfo.PixelFormat.GetSRGB();
|
||||||
|
else
|
||||||
|
textureInfo.PixelFormat = textureInfo.PixelFormat.GetNonSRGB();
|
||||||
|
|
||||||
|
Texture texture = CreateTexture(surfaces, textureInfo);
|
||||||
|
|
||||||
if (texture != null)
|
if (texture != null)
|
||||||
{
|
{
|
||||||
SetSampler(texture, config);
|
SetSampler(texture, config);
|
||||||
@@ -256,10 +318,88 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
|||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Texture2D LoadPng(Stream data, EditorTextureAssetLoaderConfig config)
|
private static Texture CreateTexture(List<LoadedSurface> surfaces, LoadedTextureInfo textureInfo)
|
||||||
|
{
|
||||||
|
TextureSliceData[] slices = scope TextureSliceData[surfaces.Count];
|
||||||
|
|
||||||
|
for (int i < slices.Count)
|
||||||
|
{
|
||||||
|
slices[i] = .(surfaces[i].Data.Ptr, surfaces[i].Pitch, surfaces[i].SlicePitch);
|
||||||
|
}
|
||||||
|
|
||||||
|
//slices[0].SlicePitch = (.)(surfaces[0].Pitch * textureInfo.Height);
|
||||||
|
|
||||||
|
switch (textureInfo.Dimension)
|
||||||
|
{
|
||||||
|
//case .Texture1D:
|
||||||
|
case .Texture2D:
|
||||||
|
if (textureInfo.IsCubeMap)
|
||||||
|
{
|
||||||
|
Texture2DDesc staging = .();
|
||||||
|
|
||||||
|
staging.Width = (.)textureInfo.Width;
|
||||||
|
staging.Height = (.)textureInfo.Height;
|
||||||
|
|
||||||
|
staging.MipLevels = (.)textureInfo.MipMapCount;
|
||||||
|
staging.ArraySize = (.)textureInfo.ArraySize;
|
||||||
|
|
||||||
|
staging.Format = textureInfo.PixelFormat;
|
||||||
|
|
||||||
|
// TODO: allow enabling read/write
|
||||||
|
staging.CpuAccess = .None;
|
||||||
|
staging.Usage = .Default;
|
||||||
|
|
||||||
|
TextureCube cubeTexture = new TextureCube(staging);
|
||||||
|
|
||||||
|
//cubeTexture.SetData();
|
||||||
|
|
||||||
|
for (let surface in surfaces)
|
||||||
|
{
|
||||||
|
cubeTexture.SetData(surface.Data.Ptr, surface.Pitch / staging.Width, (TextureCubeFace)surface.CubeFace, (.)surface.ArrayIndex, (.)surface.MipLevel);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cubeTexture;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Texture2DDesc staging = .();
|
||||||
|
|
||||||
|
staging.Width = (.)textureInfo.Width;
|
||||||
|
staging.Height = (.)textureInfo.Height;
|
||||||
|
|
||||||
|
staging.MipLevels = (.)textureInfo.MipMapCount;
|
||||||
|
staging.ArraySize = (.)textureInfo.ArraySize;
|
||||||
|
|
||||||
|
staging.Format = textureInfo.PixelFormat;
|
||||||
|
|
||||||
|
// TODO: allow enabling read/write
|
||||||
|
staging.CpuAccess = .None;
|
||||||
|
staging.Usage = .Immutable;
|
||||||
|
|
||||||
|
Texture2D stagingTexture = new Texture2D(staging);
|
||||||
|
|
||||||
|
stagingTexture.SetData(slices);
|
||||||
|
|
||||||
|
/*for (let surface in surfaces)
|
||||||
|
{
|
||||||
|
stagingTexture.[Friend]PlatformSetData(surface.Data.Ptr, surface.Pitch / staging.Width, 0, 0, staging.Width, staging.Height, (.)surface.ArrayIndex, (.)surface.MipLevel, .Write);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
return stagingTexture;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
Runtime.NotImplemented();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Result<void> LoadPng(Stream data, EditorTextureAssetLoaderConfig config, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
textureInfo = .();
|
||||||
|
|
||||||
uint8[] pngData = new:ScopedAlloc! uint8[data.Length];
|
uint8[] pngData = new:ScopedAlloc! uint8[data.Length];
|
||||||
|
|
||||||
var result = data.TryRead(pngData);
|
var result = data.TryRead(pngData);
|
||||||
@@ -267,7 +407,7 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
|||||||
if (result case .Err(let err))
|
if (result case .Err(let err))
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error($"Failed to read data from stream. Texture: Error: {err}");
|
Log.EngineLogger.Error($"Failed to read data from stream. Texture: Error: {err}");
|
||||||
return null;
|
return .Err;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8* rawData = null;
|
uint8* rawData = null;
|
||||||
@@ -285,25 +425,55 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
|||||||
if (errorCode != 0)
|
if (errorCode != 0)
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Error($"Failed to decode PNG file {errorCode}.");
|
Log.EngineLogger.Error($"Failed to decode PNG file {errorCode}.");
|
||||||
return null;
|
return .Err;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Texture2DDesc desc = .(width, height, config.IsSRGB ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm, 1, 1, .Immutable);
|
uint8[] pixelData = new uint8[4 * width * height];
|
||||||
Texture2D texture = new Texture2D(desc);
|
Internal.MemCpy(pixelData.Ptr, rawData, pixelData.Count);
|
||||||
texture.SetData<Color>((.)rawData);
|
|
||||||
|
LoadedSurface surface = .();
|
||||||
|
surface.Data = Span<uint8>(pixelData);
|
||||||
|
surface.Pitch = 4 * width;
|
||||||
|
surface.SlicePitch = 0;
|
||||||
|
surface.ArrayIndex = 0;
|
||||||
|
surface.MipLevel = 0;
|
||||||
|
|
||||||
|
surfaces.Add(surface);
|
||||||
|
|
||||||
|
//Texture2DDesc desc = .(width, height, config.IsSRGB ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm, 1, 1, .Immutable);
|
||||||
|
//Texture2D texture = new Texture2D(desc);
|
||||||
|
//texture.SetData<Color>((.)rawData);
|
||||||
|
|
||||||
// TODO: Generate mip maps
|
// TODO: Generate mip maps
|
||||||
|
|
||||||
return texture;
|
textureInfo.PixelData = pixelData;
|
||||||
|
textureInfo.Width = width;
|
||||||
|
textureInfo.Height = height;
|
||||||
|
textureInfo.Depth = 1;
|
||||||
|
|
||||||
|
textureInfo.ArraySize = 1;
|
||||||
|
textureInfo.MipMapCount = 1;
|
||||||
|
|
||||||
|
textureInfo.Dimension = .Texture2D;
|
||||||
|
|
||||||
|
textureInfo.IsCubeMap = false;
|
||||||
|
|
||||||
|
textureInfo.PixelFormat = config.IsSRGB ? .R8G8B8A8_UNorm_SRGB : .R8G8B8A8_UNorm;
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
|
||||||
|
//return texture;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Texture LoadDds(Stream data, EditorTextureAssetLoaderConfig config)
|
private static Result<void> LoadDds(Stream data, EditorTextureAssetLoaderConfig config, List<LoadedSurface> surfaces, out LoadedTextureInfo textureInfo)
|
||||||
{
|
{
|
||||||
// TODO: Move the loading of Dds files here.
|
var result = DdsImporter.LoadDds(data, config.IsSRGB, surfaces, out textureInfo);
|
||||||
Texture2D texture = new [Friend]Texture2D(data);
|
|
||||||
|
|
||||||
return texture;
|
if (result case .Err)
|
||||||
|
return .Err;
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void SetSampler(Texture texture, EditorTextureAssetLoaderConfig config)
|
private static void SetSampler(Texture texture, EditorTextureAssetLoaderConfig config)
|
||||||
@@ -315,12 +485,38 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static Texture2D _placeholder2D;
|
private static Texture2D _placeholder2D;
|
||||||
|
private static TextureCube _placeholderCube;
|
||||||
|
|
||||||
private static Texture2D _error2D;
|
private static Texture2D _error2D;
|
||||||
|
private static TextureCube _errorCube;
|
||||||
|
|
||||||
public Asset GetPlaceholderAsset(Type assetType)
|
public Asset GetPlaceholderAsset(Type assetType)
|
||||||
{
|
{
|
||||||
switch (assetType)
|
switch (assetType)
|
||||||
{
|
{
|
||||||
|
case typeof(TextureCube):
|
||||||
|
if (_placeholderCube == null)
|
||||||
|
{
|
||||||
|
// TODO: immutable
|
||||||
|
Texture2DDesc desc = .(1, 1, .R8G8B8A8_UNorm, 1, 1, .Default, .None);
|
||||||
|
|
||||||
|
_placeholderCube = new TextureCube(desc);
|
||||||
|
_placeholderCube.SamplerState = SamplerStateManager.PointWrap;
|
||||||
|
Color color = Color.Cyan;
|
||||||
|
_placeholderCube.SetData<Color>(&color, .PositiveX);
|
||||||
|
_placeholderCube.SetData<Color>(&color, .NegativeX);
|
||||||
|
_placeholderCube.SetData<Color>(&color, .PositiveY);
|
||||||
|
_placeholderCube.SetData<Color>(&color, .NegativeY);
|
||||||
|
_placeholderCube.SetData<Color>(&color, .PositiveZ);
|
||||||
|
_placeholderCube.SetData<Color>(&color, .NegativeZ);
|
||||||
|
|
||||||
|
Content.ManageAsset(_placeholderCube);
|
||||||
|
_placeholderCube.ReleaseRef();
|
||||||
|
|
||||||
|
_placeholderCube.[Friend]Complete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _placeholderCube;
|
||||||
case typeof(Texture2D):
|
case typeof(Texture2D):
|
||||||
fallthrough;
|
fallthrough;
|
||||||
default:
|
default:
|
||||||
@@ -347,6 +543,31 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
|||||||
{
|
{
|
||||||
switch (assetType)
|
switch (assetType)
|
||||||
{
|
{
|
||||||
|
case typeof(TextureCube):
|
||||||
|
if (_placeholderCube == null)
|
||||||
|
{
|
||||||
|
// TODO: immutable
|
||||||
|
Texture2DDesc desc = .(2, 2, .R8G8B8A8_UNorm, 1, 1, .Default, .None);
|
||||||
|
|
||||||
|
_errorCube = new TextureCube(desc);
|
||||||
|
_errorCube.SamplerState = SamplerStateManager.PointWrap;
|
||||||
|
|
||||||
|
Color[4] color = .(Color.HotPink, Color.Black, Color.Black, Color.HotPink);
|
||||||
|
|
||||||
|
_errorCube.SetData<Color>(&color, .PositiveX);
|
||||||
|
_errorCube.SetData<Color>(&color, .NegativeX);
|
||||||
|
_errorCube.SetData<Color>(&color, .PositiveY);
|
||||||
|
_errorCube.SetData<Color>(&color, .NegativeY);
|
||||||
|
_errorCube.SetData<Color>(&color, .PositiveZ);
|
||||||
|
_errorCube.SetData<Color>(&color, .NegativeZ);
|
||||||
|
|
||||||
|
Content.ManageAsset(_errorCube);
|
||||||
|
_errorCube.ReleaseRef();
|
||||||
|
|
||||||
|
_errorCube.[Friend]Complete = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return _placeholderCube;
|
||||||
case typeof(Texture2D):
|
case typeof(Texture2D):
|
||||||
fallthrough;
|
fallthrough;
|
||||||
default:
|
default:
|
||||||
@@ -356,7 +577,9 @@ class EditorTextureAssetLoader : IAssetLoader//, IReloadingAssetLoader
|
|||||||
|
|
||||||
_error2D = new Texture2D(desc);
|
_error2D = new Texture2D(desc);
|
||||||
_error2D.SamplerState = SamplerStateManager.PointWrap;
|
_error2D.SamplerState = SamplerStateManager.PointWrap;
|
||||||
|
|
||||||
Color[4] color = .(Color.HotPink, Color.Black, Color.Black, Color.HotPink);
|
Color[4] color = .(Color.HotPink, Color.Black, Color.Black, Color.HotPink);
|
||||||
|
|
||||||
_error2D.SetData<Color>(&color);
|
_error2D.SetData<Color>(&color);
|
||||||
|
|
||||||
Content.ManageAsset(_error2D);
|
Content.ManageAsset(_error2D);
|
||||||
|
|||||||
@@ -0,0 +1,612 @@
|
|||||||
|
using ImGui;
|
||||||
|
using System;
|
||||||
|
using GlitchyEngine.Content;
|
||||||
|
using GlitchyEngine.Renderer;
|
||||||
|
using GlitchyEngine.Math;
|
||||||
|
using GlitchyEngine;
|
||||||
|
namespace GlitchyEditor.EditWindows;
|
||||||
|
|
||||||
|
class AssetViewer : EditorWindow
|
||||||
|
{
|
||||||
|
public const String s_WindowTitle = "Asset Viewer";
|
||||||
|
|
||||||
|
public EditorContentManager _manager;
|
||||||
|
|
||||||
|
private AssetHandle _selectedAsset;
|
||||||
|
|
||||||
|
append TexturererViewerer _textureViewer = .();
|
||||||
|
|
||||||
|
public this(EditorContentManager contentManager)
|
||||||
|
{
|
||||||
|
_manager = contentManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void InternalShow()
|
||||||
|
{
|
||||||
|
if(!ImGui.Begin(s_WindowTitle, &_open, .None))
|
||||||
|
{
|
||||||
|
ImGui.End();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PushStyleVar(.CellPadding, .(0, 0));
|
||||||
|
|
||||||
|
bool alt_pressed = ImGui.GetIO().KeyAlt;
|
||||||
|
|
||||||
|
if (ImGui.BeginTable("AssetViewerTable", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
||||||
|
{
|
||||||
|
if (alt_pressed)
|
||||||
|
{
|
||||||
|
// Header anzeigen, damit sie neu angeordnet werden können
|
||||||
|
ImGui.TableSetupColumn("Assets");
|
||||||
|
ImGui.TableSetupColumn("Viewer");
|
||||||
|
ImGui.TableHeadersRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
|
||||||
|
if (ImGui.BeginChild("Assets"))
|
||||||
|
{
|
||||||
|
DrawAssetList();
|
||||||
|
|
||||||
|
ImGui.EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
if (ImGui.BeginChild("Files"))
|
||||||
|
{
|
||||||
|
DrawAssetViewer();
|
||||||
|
|
||||||
|
ImGui.EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PopStyleVar(1);
|
||||||
|
|
||||||
|
ImGui.End();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawAssetList()
|
||||||
|
{
|
||||||
|
for (let (handle, asset) in _manager.[Friend]_handleToAsset)
|
||||||
|
{
|
||||||
|
// TODO: gucken, was der Typ ist
|
||||||
|
|
||||||
|
String name = scope String();
|
||||||
|
|
||||||
|
if (asset.Identifier.IsWhiteSpace)
|
||||||
|
name.Append("Unnamed");
|
||||||
|
else
|
||||||
|
name.Append(asset.Identifier);
|
||||||
|
|
||||||
|
name.Append(" (");
|
||||||
|
asset.GetType().GetName(name);
|
||||||
|
name.Append(") [");
|
||||||
|
name.AppendF($"{handle.ID}]");
|
||||||
|
|
||||||
|
name.TrimStart();
|
||||||
|
|
||||||
|
ImGui.TreeNodeFlags flags = .Leaf;
|
||||||
|
|
||||||
|
if(handle == _selectedAsset)
|
||||||
|
flags |= .Selected;
|
||||||
|
|
||||||
|
if (ImGui.TreeNodeEx(name, flags, name))
|
||||||
|
{
|
||||||
|
if (ImGui.IsItemClicked(.Left))
|
||||||
|
_selectedAsset = handle;
|
||||||
|
|
||||||
|
ImGui.TreePop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DrawAssetViewer()
|
||||||
|
{
|
||||||
|
if (_selectedAsset.IsInvalid)
|
||||||
|
{
|
||||||
|
ImGui.Text("Select an asset to view it.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Asset asset = _selectedAsset.Get<Asset>();
|
||||||
|
|
||||||
|
/*if (!asset.Complete)
|
||||||
|
{
|
||||||
|
ImGui.Text("Loading asset...");
|
||||||
|
return;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
/*switch (asset.GetType())
|
||||||
|
{
|
||||||
|
case typeof(RenderTargetGroup):
|
||||||
|
DrawRenderTargetGroupViewer((RenderTargetGroup)asset);
|
||||||
|
case typeof(Texture):
|
||||||
|
_textureViewer.ViewTexture((Texture)asset);
|
||||||
|
|
||||||
|
}*/
|
||||||
|
|
||||||
|
if (var texture = asset as Texture)
|
||||||
|
_textureViewer.ViewTexture(texture);
|
||||||
|
if (var texture = asset as RenderTargetGroup)
|
||||||
|
_textureViewer.ViewTexture(texture);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class TexturererViewerer
|
||||||
|
{
|
||||||
|
enum BackgroundMode : int32
|
||||||
|
{
|
||||||
|
White,
|
||||||
|
Black,
|
||||||
|
Pink,
|
||||||
|
Checkerboard,
|
||||||
|
CustomColor
|
||||||
|
}
|
||||||
|
|
||||||
|
enum SampleMode : int32
|
||||||
|
{
|
||||||
|
Point,
|
||||||
|
Linear
|
||||||
|
}
|
||||||
|
|
||||||
|
enum ColorChannelSwizzle : int32
|
||||||
|
{
|
||||||
|
None,
|
||||||
|
R,
|
||||||
|
G,
|
||||||
|
B,
|
||||||
|
A
|
||||||
|
}
|
||||||
|
|
||||||
|
AssetHandle<Effect> _effect;
|
||||||
|
AssetHandle<Effect> _renderTargetEffect;
|
||||||
|
|
||||||
|
float _zoom = 1.0f;
|
||||||
|
|
||||||
|
BackgroundMode _backgroundMode = .Checkerboard;
|
||||||
|
ColorRGBA _backgroundColor;
|
||||||
|
|
||||||
|
SampleMode _sampleMode = .Linear;
|
||||||
|
|
||||||
|
RenderTarget2D _target ~ _?.ReleaseRef();
|
||||||
|
// TODO: we don't need depth!
|
||||||
|
DepthStencilTarget _depth ~ _?.ReleaseRef();
|
||||||
|
|
||||||
|
public this()
|
||||||
|
{
|
||||||
|
_effect = Content.LoadAsset("Shaders\\textureViewerShader.hlsl");
|
||||||
|
_renderTargetEffect = Content.LoadAsset("Shaders\\RenderTargetGroupViewer.hlsl");
|
||||||
|
}
|
||||||
|
|
||||||
|
float2 _position;
|
||||||
|
|
||||||
|
bool _moving;
|
||||||
|
|
||||||
|
float _colorOffset = 0;
|
||||||
|
float _colorScale = 1;
|
||||||
|
float _alphaOffset = 0;
|
||||||
|
float _alphaScale = 1;
|
||||||
|
|
||||||
|
int32 _mipLevel = 0;
|
||||||
|
int32 _arraySlice = 0;
|
||||||
|
int32 _groupIndex = 0;
|
||||||
|
|
||||||
|
ColorChannelSwizzle _swizzleR = .R;
|
||||||
|
ColorChannelSwizzle _swizzleG = .G;
|
||||||
|
ColorChannelSwizzle _swizzleB = .B;
|
||||||
|
ColorChannelSwizzle _swizzleA = .A;
|
||||||
|
|
||||||
|
public void ShowSettings(float width, float height, int maxMips, int arraySize, RenderTargetGroup rtGroup)
|
||||||
|
{
|
||||||
|
char8*[] items = scope .("White", "Black", "Pink", "Checkerboard", "Custom Color");
|
||||||
|
|
||||||
|
if (ImGui.CollapsingHeader("View"))
|
||||||
|
{
|
||||||
|
ImGui.SliderFloat("Zoom", &_zoom, 0.01f, 100.0f);
|
||||||
|
|
||||||
|
float maxDimension = max(width, height);
|
||||||
|
|
||||||
|
ImGui.SliderFloat2("Position", *(float[2]*)&_position, 2 * -maxDimension * _zoom, 2 * maxDimension * _zoom);
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
ImGui.Combo("Background", (.)&_backgroundMode, items.Ptr, (.)items.Count);
|
||||||
|
|
||||||
|
if (_backgroundMode == .CustomColor)
|
||||||
|
{
|
||||||
|
ImGui.ColorPicker4("Color", ref _backgroundColor);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.CollapsingHeader("Sampling"))
|
||||||
|
{
|
||||||
|
items = scope .("Point", "Linear");
|
||||||
|
|
||||||
|
ImGui.Combo("Sampler", (.)&_sampleMode, items.Ptr, (.)items.Count);
|
||||||
|
|
||||||
|
ImGui.SliderInt("Mip Level", &_mipLevel, 0, (int32)maxMips);
|
||||||
|
ImGui.SliderInt("Array Slice", &_arraySlice, 0, (int32)arraySize);
|
||||||
|
|
||||||
|
ImGui.BeginDisabled(rtGroup == null);
|
||||||
|
|
||||||
|
ImGui.SliderInt("Group Target", &_groupIndex, (rtGroup?.HasDepth == true) ? -1 : 0, (int32)(rtGroup?.ColorTargetCount ?? 1) - 1);
|
||||||
|
|
||||||
|
ImGui.TextUnformatted(scope $"Target name: {(rtGroup?.GetTargetDescription(_groupIndex).DebugName ?? "???")}");
|
||||||
|
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.CollapsingHeader("Color and Transparency"))
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("Channel Swizzle:");
|
||||||
|
|
||||||
|
if (ImGui.BeginTable("ColorAndAlpha", 4))
|
||||||
|
{
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
|
||||||
|
ImGui.PushID("Color");
|
||||||
|
|
||||||
|
ImGui.TextUnformatted("Color:");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.DragFloat("Offset", &_colorOffset, 0.1f);
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.DragFloat("Scale", &_colorScale, 0.1f);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
if (ImGui.Button("Reset"))
|
||||||
|
{
|
||||||
|
_colorOffset = 0.0f;
|
||||||
|
_colorScale = 1.0f;
|
||||||
|
}
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.BeginDisabled();
|
||||||
|
if (ImGui.Button("Auto"))
|
||||||
|
{
|
||||||
|
Runtime.NotImplemented();
|
||||||
|
}
|
||||||
|
ImGui.EndDisabled();
|
||||||
|
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
|
||||||
|
ImGui.PushID("Alpha");
|
||||||
|
|
||||||
|
ImGui.TextUnformatted("Alpha:");
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.DragFloat("Offset", &_alphaOffset, 0.1f);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
ImGui.DragFloat("Scale", &_alphaScale, 0.1f);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
if (ImGui.Button("Reset"))
|
||||||
|
{
|
||||||
|
_alphaOffset = 0.0f;
|
||||||
|
_alphaScale = 1.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.PopID();
|
||||||
|
|
||||||
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
ImGui.TextUnformatted("Channel Swizzle:");
|
||||||
|
|
||||||
|
if (ImGui.BeginTable("SwizzleTable", 9))
|
||||||
|
{
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
|
||||||
|
SwizzleCombo("R", ref _swizzleR);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
SwizzleCombo("G", ref _swizzleG);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
SwizzleCombo("B", ref _swizzleB);
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
SwizzleCombo("A", ref _swizzleA);
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
if (ImGui.Button("Reset swizzle"))
|
||||||
|
{
|
||||||
|
_swizzleR = .R;
|
||||||
|
_swizzleG = .G;
|
||||||
|
_swizzleB = .B;
|
||||||
|
_swizzleA = .A;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SwizzleCombo(StringView text, ref ColorChannelSwizzle swizzle)
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted(text);
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
if (ImGui.BeginCombo(scope $"##swizzle{text}", scope $"{swizzle}"))
|
||||||
|
{
|
||||||
|
if (ImGui.Selectable("R", swizzle == .R))
|
||||||
|
swizzle = .R;
|
||||||
|
|
||||||
|
if (ImGui.Selectable("G", swizzle == .G))
|
||||||
|
swizzle = .G;
|
||||||
|
|
||||||
|
if (ImGui.Selectable("B", swizzle == .B))
|
||||||
|
swizzle = .B;
|
||||||
|
|
||||||
|
if (ImGui.Selectable("A", swizzle == .A))
|
||||||
|
swizzle = .A;
|
||||||
|
|
||||||
|
if (ImGui.Selectable("None", swizzle == .None))
|
||||||
|
swizzle = .None;
|
||||||
|
|
||||||
|
ImGui.EndCombo();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ViewTexture(RenderTargetGroup texture)
|
||||||
|
{
|
||||||
|
ShowSettings(texture.Width, texture.Height, texture.MipLevels - 1, texture.ArraySize - 1, texture);
|
||||||
|
|
||||||
|
if (ImGui.BeginChild("imageChild"))
|
||||||
|
{
|
||||||
|
UpdateInput();
|
||||||
|
|
||||||
|
var viewportSize = ImGui.GetContentRegionAvail();
|
||||||
|
|
||||||
|
viewportSize.x = Math.Max(viewportSize.x, 1);
|
||||||
|
viewportSize.y = Math.Max(viewportSize.y, 1);
|
||||||
|
|
||||||
|
if(_target == null || viewportSize.x != _target.Width || viewportSize.y != _target.Height)
|
||||||
|
{
|
||||||
|
_target?.ReleaseRef();
|
||||||
|
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm_SRGB, (.)viewportSize.x, (.)viewportSize.y));
|
||||||
|
_target.SamplerState = SamplerStateManager.PointClamp;
|
||||||
|
_depth?.ReleaseRef();
|
||||||
|
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderBackground();
|
||||||
|
|
||||||
|
RenderTexture(texture);
|
||||||
|
|
||||||
|
ImGui.Image(_target, viewportSize);
|
||||||
|
|
||||||
|
ImGui.EndChild();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ViewTexture(Texture texture)
|
||||||
|
{
|
||||||
|
ShowSettings(texture.Width, texture.Height, texture.MipLevels - 1, texture.ArraySize - 1, null);
|
||||||
|
|
||||||
|
if (ImGui.BeginChild("imageChild"))
|
||||||
|
{
|
||||||
|
UpdateInput();
|
||||||
|
|
||||||
|
var viewportSize = ImGui.GetContentRegionAvail();
|
||||||
|
|
||||||
|
viewportSize.x = Math.Max(viewportSize.x, 1);
|
||||||
|
viewportSize.y = Math.Max(viewportSize.y, 1);
|
||||||
|
|
||||||
|
if(_target == null || viewportSize.x != _target.Width || viewportSize.y != _target.Height)
|
||||||
|
{
|
||||||
|
_target?.ReleaseRef();
|
||||||
|
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm_SRGB, (.)viewportSize.x, (.)viewportSize.y));
|
||||||
|
_target.SamplerState = SamplerStateManager.PointClamp;
|
||||||
|
_depth?.ReleaseRef();
|
||||||
|
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderBackground();
|
||||||
|
|
||||||
|
RenderTexture(texture);
|
||||||
|
|
||||||
|
ImGui.Image(_target, viewportSize);
|
||||||
|
|
||||||
|
ImGui.EndChild();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float lastWheel;
|
||||||
|
|
||||||
|
private void UpdateInput()
|
||||||
|
{
|
||||||
|
var windowPos = ImGui.GetWindowPos();
|
||||||
|
var mousePos = ImGui.GetIO().MousePos;
|
||||||
|
float2 mouseInWindow = .(mousePos.x - windowPos.x, mousePos.y - windowPos.y);
|
||||||
|
|
||||||
|
bool windowHovered = ImGui.IsWindowHovered();
|
||||||
|
|
||||||
|
if(windowHovered && Input.IsMouseButtonPressing(.MiddleButton))
|
||||||
|
{
|
||||||
|
_moving = true;
|
||||||
|
}
|
||||||
|
else if(Input.IsMouseButtonReleased(.MiddleButton))
|
||||||
|
{
|
||||||
|
_moving = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(windowHovered || _moving)
|
||||||
|
{
|
||||||
|
float mouseWheel = ImGui.GetIO().MouseWheel;
|
||||||
|
|
||||||
|
float delta = mouseWheel - lastWheel;
|
||||||
|
|
||||||
|
if(delta != 0)
|
||||||
|
{
|
||||||
|
_position -= mouseInWindow;
|
||||||
|
_position /= _zoom;
|
||||||
|
|
||||||
|
_zoom *= Math.Pow(1.1f, delta);
|
||||||
|
|
||||||
|
_position *= _zoom;
|
||||||
|
_position += mouseInWindow;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if(_moving)
|
||||||
|
{
|
||||||
|
int2 movement = Input.GetMouseMovement();
|
||||||
|
|
||||||
|
_position.X += movement.X;
|
||||||
|
_position.Y += movement.Y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OrthographicCamera _camera = new OrthographicCamera() ~ delete _;
|
||||||
|
|
||||||
|
private void RenderBackground()
|
||||||
|
{
|
||||||
|
Viewport vp = .(0, 0, _target.Width, _target.Height);
|
||||||
|
RenderCommand.SetViewport(vp);
|
||||||
|
|
||||||
|
// TODO: don't clear pink!
|
||||||
|
RenderCommand.Clear(_target, .Pink);
|
||||||
|
RenderCommand.Clear(_depth, .Depth, 1.0f, 0);
|
||||||
|
|
||||||
|
//_target.Bind();
|
||||||
|
RenderCommand.SetRenderTarget(_target);
|
||||||
|
RenderCommand.SetDepthStencilTarget(_depth);
|
||||||
|
RenderCommand.BindRenderTargets();
|
||||||
|
|
||||||
|
float2 targetSize = float2(_target.Width, _target.Height);
|
||||||
|
|
||||||
|
_camera.Left = 0;
|
||||||
|
_camera.Top = 0;
|
||||||
|
_camera.Right = targetSize.X;
|
||||||
|
_camera.Bottom = -targetSize.Y;
|
||||||
|
_camera.NearPlane = -5;
|
||||||
|
_camera.FarPlane = 5;
|
||||||
|
_camera.Update();
|
||||||
|
|
||||||
|
Renderer2D.BeginScene(_camera);
|
||||||
|
|
||||||
|
switch(_backgroundMode)
|
||||||
|
{
|
||||||
|
case .Black:
|
||||||
|
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .Black);
|
||||||
|
case .White:
|
||||||
|
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .White);
|
||||||
|
case .Pink:
|
||||||
|
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .HotPink);
|
||||||
|
case .CustomColor:
|
||||||
|
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, _backgroundColor);
|
||||||
|
case .Checkerboard:
|
||||||
|
float quadSize = 50.0f;
|
||||||
|
|
||||||
|
float2 numQuads = (targetSize / 500f) * 10f;
|
||||||
|
|
||||||
|
for(float x = 0; x < numQuads.X; x++)
|
||||||
|
{
|
||||||
|
for(float y = 0; y < numQuads.Y; y++)
|
||||||
|
{
|
||||||
|
Renderer2D.DrawQuadPivotCorner(float3(x * quadSize, -y * quadSize, 1), quadSize.XX, 0, ((x + y) % 2 == 0) ? .White : .Gray);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
Renderer2D.EndScene();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderTexture(TextureViewBinding viewedTexture, float2 textureSize, Format format)
|
||||||
|
{
|
||||||
|
float2 mippedTextureSize = float2((int)textureSize.X >> _mipLevel, (int)textureSize.X >> _mipLevel);
|
||||||
|
|
||||||
|
// Sicherstellen, dass die Auflösung nicht 0 wird
|
||||||
|
mippedTextureSize = max(mippedTextureSize, 1);
|
||||||
|
|
||||||
|
//float2 textureSize = float2(viewedTexture.Width, viewedTexture.Height);
|
||||||
|
float2 zoomedTextureSize = textureSize * _zoom;
|
||||||
|
|
||||||
|
// TODO: Sampler state for rt group
|
||||||
|
//var sampler = viewedTexture.SamplerState;
|
||||||
|
|
||||||
|
/*switch(_sampleMode)
|
||||||
|
{
|
||||||
|
case .Point:
|
||||||
|
viewedTexture.SamplerState = SamplerStateManager.PointClamp;
|
||||||
|
case .Linear:
|
||||||
|
viewedTexture.SamplerState = SamplerStateManager.LinearClamp;
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//Renderer2D.BeginScene(_camera, .SortByTexture, _effect);
|
||||||
|
|
||||||
|
// float3(_position * .(1, -1), 0)
|
||||||
|
RenderCommand.Clear(_depth, .Depth, 1.0f, 0);
|
||||||
|
|
||||||
|
Matrix matrix = .Translation(float3(_position * .(1, -1), 0)) * .Scaling(float3(zoomedTextureSize, 1));
|
||||||
|
|
||||||
|
// TODO: ViewProjection kommt nicht korrekt an?
|
||||||
|
_renderTargetEffect.Variables["WorldViewProjection"].SetData(_camera.ViewProjection * matrix);
|
||||||
|
_renderTargetEffect.Variables["ColorOffset"].SetData(_colorOffset);
|
||||||
|
_renderTargetEffect.Variables["ColorScale"].SetData(_colorScale);
|
||||||
|
_renderTargetEffect.Variables["AlphaOffset"].SetData(_alphaOffset);
|
||||||
|
_renderTargetEffect.Variables["AlphaScale"].SetData(_alphaScale);
|
||||||
|
|
||||||
|
_renderTargetEffect.Variables["Texels"].SetData(mippedTextureSize);
|
||||||
|
|
||||||
|
_renderTargetEffect.Variables["MipLevel"].SetData((float)_mipLevel);
|
||||||
|
|
||||||
|
_renderTargetEffect.Variables["Swizzle"].SetData(int4((int32)_swizzleR, (int32)_swizzleG, (int32)_swizzleB, (int32)_swizzleA));
|
||||||
|
|
||||||
|
if (format.IsInt())
|
||||||
|
{
|
||||||
|
// Int Texture
|
||||||
|
_renderTargetEffect.Variables["Mode"].SetData(1);
|
||||||
|
_renderTargetEffect.SetTexture("IntTexture", viewedTexture);
|
||||||
|
_renderTargetEffect.SetTexture("UIntTexture", null);
|
||||||
|
_renderTargetEffect.SetTexture("Texture", null);
|
||||||
|
}
|
||||||
|
else if (format.IsUInt())
|
||||||
|
{
|
||||||
|
// UInt Texture
|
||||||
|
_renderTargetEffect.Variables["Mode"].SetData(2);
|
||||||
|
_renderTargetEffect.SetTexture("IntTexture", null);
|
||||||
|
_renderTargetEffect.SetTexture("UIntTexture", viewedTexture);
|
||||||
|
_renderTargetEffect.SetTexture("Texture", null);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Float Texture
|
||||||
|
_renderTargetEffect.Variables["Mode"].SetData(0);
|
||||||
|
_renderTargetEffect.SetTexture("IntTexture", null);
|
||||||
|
_renderTargetEffect.SetTexture("UIntTexture", null);
|
||||||
|
_renderTargetEffect.SetTexture("Texture", viewedTexture);
|
||||||
|
}
|
||||||
|
|
||||||
|
_renderTargetEffect.Variables["Swizzle"].SetData(int4((int32)_swizzleR, (int32)_swizzleG, (int32)_swizzleB, (int32)_swizzleA));
|
||||||
|
|
||||||
|
_renderTargetEffect.ApplyChanges();
|
||||||
|
_renderTargetEffect.Bind();
|
||||||
|
|
||||||
|
Quad.Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderTexture(RenderTargetGroup viewedTexture)
|
||||||
|
{
|
||||||
|
var desc = _groupIndex >= 0 ? viewedTexture.[Friend]_colorTargetDescriptions[_groupIndex] : viewedTexture.[Friend]_depthTargetDescription;
|
||||||
|
|
||||||
|
RenderTexture(viewedTexture.GetViewBinding(_groupIndex), float2(viewedTexture.Width, viewedTexture.Height), desc.Format.GetShaderViewFormat());
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RenderTexture(Texture viewedTexture)
|
||||||
|
{
|
||||||
|
RenderTexture(viewedTexture.GetViewBinding(), float2(viewedTexture.Width, viewedTexture.Height), viewedTexture.Format);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ using System.Collections;
|
|||||||
using GlitchyEngine.Renderer;
|
using GlitchyEngine.Renderer;
|
||||||
using GlitchyEngine;
|
using GlitchyEngine;
|
||||||
using GlitchyEngine.Content;
|
using GlitchyEngine.Content;
|
||||||
|
using GlitchyEngine.Scripting;
|
||||||
|
|
||||||
namespace GlitchyEditor.EditWindows
|
namespace GlitchyEditor.EditWindows
|
||||||
{
|
{
|
||||||
@@ -68,6 +69,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ShowComponentEditor<Rigidbody2DComponent>("Rigidbody 2D", entity, => ShowRigidBody2DComponentEditor, => ShowComponentContextMenu<Rigidbody2DComponent>);
|
ShowComponentEditor<Rigidbody2DComponent>("Rigidbody 2D", entity, => ShowRigidBody2DComponentEditor, => ShowComponentContextMenu<Rigidbody2DComponent>);
|
||||||
ShowComponentEditor<BoxCollider2DComponent>("Box collider 2D", entity, => ShowBoxCollider2DComponentEditor, => ShowComponentContextMenu<BoxCollider2DComponent>);
|
ShowComponentEditor<BoxCollider2DComponent>("Box collider 2D", entity, => ShowBoxCollider2DComponentEditor, => ShowComponentContextMenu<BoxCollider2DComponent>);
|
||||||
ShowComponentEditor<CircleCollider2DComponent>("Circle collider 2D", entity, => ShowCircleCollider2DComponentEditor, => ShowComponentContextMenu<CircleCollider2DComponent>);
|
ShowComponentEditor<CircleCollider2DComponent>("Circle collider 2D", entity, => ShowCircleCollider2DComponentEditor, => ShowComponentContextMenu<CircleCollider2DComponent>);
|
||||||
|
ShowComponentEditor<ScriptComponent>("Script Component", entity, => ShowScriptComponentEditor, => ShowComponentContextMenu<ScriptComponent>);
|
||||||
|
|
||||||
ShowAddComponentButton(entity);
|
ShowAddComponentButton(entity);
|
||||||
}
|
}
|
||||||
@@ -158,16 +160,32 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
||||||
|
|
||||||
Vector3 position = transform.Position;
|
float3 position = transform.Position;
|
||||||
if (ImGui.EditVector3("Position", ref position, .Zero, 0.1f, textWidth))
|
if (ImGui.Editfloat3("Position", ref position, .Zero, 0.1f, textWidth))
|
||||||
|
{
|
||||||
transform.Position = position;
|
transform.Position = position;
|
||||||
|
|
||||||
Vector3 rotationEuler = MathHelper.ToDegrees(transform.EditorRotationEuler);
|
// if necessary reposition Rigidbody2D
|
||||||
if (ImGui.EditVector3("Rotation", ref rotationEuler, .Zero, 0.1f, textWidth))
|
if (entity.TryGetComponent<Rigidbody2DComponent>(let rigidbody2D))
|
||||||
|
{
|
||||||
|
rigidbody2D.SetPosition(position.XY);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 rotationEuler = MathHelper.ToDegrees(transform.EditorRotationEuler);
|
||||||
|
if (ImGui.Editfloat3("Rotation", ref rotationEuler, .Zero, 0.1f, textWidth))
|
||||||
|
{
|
||||||
transform.EditorRotationEuler = MathHelper.ToRadians(rotationEuler);
|
transform.EditorRotationEuler = MathHelper.ToRadians(rotationEuler);
|
||||||
|
|
||||||
Vector3 scale = transform.Scale;
|
// if necessary reposition Rigidbody2D
|
||||||
if (ImGui.EditVector3("Scale", ref scale, .One, 0.1f, textWidth))
|
if (entity.TryGetComponent<Rigidbody2DComponent>(let rigidbody2D))
|
||||||
|
{
|
||||||
|
rigidbody2D.SetAngle(rotationEuler.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
float3 scale = transform.Scale;
|
||||||
|
if (ImGui.Editfloat3("Scale", ref scale, .One, 0.1f, textWidth))
|
||||||
transform.Scale = scale;
|
transform.Scale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,12 +391,12 @@ namespace GlitchyEditor.EditWindows
|
|||||||
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
||||||
|
|
||||||
|
|
||||||
Vector2 offset = boxCollider.Offset;
|
float2 offset = boxCollider.Offset;
|
||||||
if (ImGui.EditVector2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
if (ImGui.Editfloat2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
||||||
boxCollider.Offset = offset;
|
boxCollider.Offset = offset;
|
||||||
|
|
||||||
Vector2 size = boxCollider.Size;
|
float2 size = boxCollider.Size;
|
||||||
if (ImGui.EditVector2("Size", ref size, .Zero, 0.1f, textWidth))
|
if (ImGui.Editfloat2("Size", ref size, .Zero, 0.1f, textWidth))
|
||||||
boxCollider.Size = size;
|
boxCollider.Size = size;
|
||||||
|
|
||||||
float density = boxCollider.Density;
|
float density = boxCollider.Density;
|
||||||
@@ -404,8 +422,8 @@ namespace GlitchyEditor.EditWindows
|
|||||||
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
textWidth += ImGui.GetStyle().FramePadding.x * 3.0f;
|
||||||
|
|
||||||
|
|
||||||
Vector2 offset = circleCollider.Offset;
|
float2 offset = circleCollider.Offset;
|
||||||
if (ImGui.EditVector2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
if (ImGui.Editfloat2("Offset", ref offset, .Zero, 0.1f, textWidth))
|
||||||
circleCollider.Offset = offset;
|
circleCollider.Offset = offset;
|
||||||
|
|
||||||
float radius = circleCollider.Radius;
|
float radius = circleCollider.Radius;
|
||||||
@@ -429,6 +447,273 @@ namespace GlitchyEditor.EditWindows
|
|||||||
circleCollider.RestitutionThreshold = restitutionThreshold;
|
circleCollider.RestitutionThreshold = restitutionThreshold;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void ShowScriptComponentEditor(Entity entity, ScriptComponent* scriptComponent)
|
||||||
|
{
|
||||||
|
static char8[64] buffer = .();
|
||||||
|
|
||||||
|
StringView search = StringView();
|
||||||
|
|
||||||
|
//char8* scriptLabel = scriptComponent.Instance?.ScriptClass.FullName.ToScopeCStr!() ?? "Select Script...";
|
||||||
|
char8* scriptLabel = scriptComponent.Instance?.ScriptClass.FullName.CStr() ?? "Select Script...";
|
||||||
|
|
||||||
|
if (ImGui.Button(scriptLabel))
|
||||||
|
ImGui.OpenPopup("SelectScript");
|
||||||
|
|
||||||
|
if (ImGui.BeginPopup("SelectScript"))
|
||||||
|
{
|
||||||
|
ImGui.InputText("##ScriptSearch", &buffer, buffer.Count);
|
||||||
|
|
||||||
|
search = StringView(&buffer);
|
||||||
|
|
||||||
|
for (let (className, scriptClass) in ScriptEngine.EntityClasses)
|
||||||
|
{
|
||||||
|
if (!search.IsWhiteSpace && !className.Contains(search, true))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (ImGui.Selectable(className.ToScopeCStr!(),
|
||||||
|
className == scriptComponent.ScriptClassName))
|
||||||
|
{
|
||||||
|
//scriptComponent.Instance = new ScriptInstance(scriptClass);
|
||||||
|
// decrement refCount to 1 (scriptComponent.Instance increments its)
|
||||||
|
//scriptComponent.Instance.ReleaseRef();
|
||||||
|
//ScriptEngine.InitializeInstance(entity, scriptComponent);
|
||||||
|
|
||||||
|
scriptComponent.ScriptClassName = scriptClass.FullName;
|
||||||
|
|
||||||
|
//ScriptEngine.CreateScriptFieldMap(entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
ScriptClass scriptClass = ScriptEngine.GetScriptClass(scriptComponent.ScriptClassName);
|
||||||
|
|
||||||
|
/*T GetFieldValue<T>()
|
||||||
|
{
|
||||||
|
return scriptComponent.Instance.GetFieldValue<T>(monoField);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFieldValue<T>(in T value)
|
||||||
|
{
|
||||||
|
scriptComponent.Instance.SetFieldValue<T>(monoField, value);
|
||||||
|
}*/
|
||||||
|
|
||||||
|
T GetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField)
|
||||||
|
{
|
||||||
|
return scriptInstance.GetFieldValue<T>(scriptField);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField, out T value)
|
||||||
|
{
|
||||||
|
value = scriptInstance.GetFieldValue<T>(scriptField);
|
||||||
|
}
|
||||||
|
|
||||||
|
void SetFieldValue<T>(ScriptInstance scriptInstance, in ScriptField scriptField, in T value)
|
||||||
|
{
|
||||||
|
scriptInstance.SetFieldValue<T>(scriptField, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (scriptComponent.Instance?.IsInitialized == true)
|
||||||
|
{
|
||||||
|
SharpClass sharpClass = scriptComponent.Instance.ScriptClass;
|
||||||
|
ScriptInstance scriptInstance = scriptComponent.Instance;
|
||||||
|
|
||||||
|
for (let (fieldName, scriptField) in sharpClass.Fields)
|
||||||
|
{
|
||||||
|
var monoField = scriptField.[Friend]_monoField;
|
||||||
|
|
||||||
|
switch (scriptField.FieldType)
|
||||||
|
{
|
||||||
|
case .Bool:
|
||||||
|
var value = GetFieldValue<bool>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.Checkbox(fieldName.ToScopeCStr!(), &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
|
||||||
|
case .SByte:
|
||||||
|
var value = GetFieldValue<int8>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .S8, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
case .Short:
|
||||||
|
var value = GetFieldValue<int16>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .S16, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
case .Int:
|
||||||
|
var value = GetFieldValue<int32>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .S32, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
case .Long:
|
||||||
|
var value = GetFieldValue<int64>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .S64, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
|
||||||
|
case .Byte:
|
||||||
|
var value = GetFieldValue<uint8>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .U8, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
case .UShort:
|
||||||
|
var value = GetFieldValue<uint16>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .U16, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
case .UInt:
|
||||||
|
var value = GetFieldValue<uint32>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .U32, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
case .ULong:
|
||||||
|
var value = GetFieldValue<uint64>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .U64, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
|
||||||
|
case .Float:
|
||||||
|
var value = GetFieldValue<float>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Float, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
|
||||||
|
case .float2:
|
||||||
|
GetFieldValue<float2>(scriptInstance, scriptField, var value);
|
||||||
|
if (ImGui.Editfloat2(fieldName, ref value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
case .float3:
|
||||||
|
GetFieldValue<float3>(scriptInstance, scriptField, var value);
|
||||||
|
if (ImGui.Editfloat3(fieldName, ref value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
case .float4:
|
||||||
|
GetFieldValue<float4>(scriptInstance, scriptField, var value);
|
||||||
|
if (ImGui.Editfloat4(fieldName, ref value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
|
||||||
|
case .Double:
|
||||||
|
var value = GetFieldValue<double>(scriptInstance, scriptField);
|
||||||
|
if (ImGui.DragScalar(fieldName.ToScopeCStr!(), .Double, &value))
|
||||||
|
SetFieldValue(scriptInstance, scriptField, value);
|
||||||
|
|
||||||
|
case .Entity:
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
case .Enum:
|
||||||
|
// TODO!
|
||||||
|
case .Struct:
|
||||||
|
// TODO!
|
||||||
|
default:
|
||||||
|
Log.EngineLogger.Error($"Unhandled field type {scriptField.FieldType}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (scriptClass != null)
|
||||||
|
{
|
||||||
|
let scriptFields = ScriptEngine.GetScriptFieldMap(entity);
|
||||||
|
|
||||||
|
for (var (name, field) in ref scriptFields)
|
||||||
|
{
|
||||||
|
switch (field.Type)
|
||||||
|
{
|
||||||
|
case .Bool:
|
||||||
|
var value = field.GetData<bool>();
|
||||||
|
if (ImGui.Checkbox(name.CStr(), &value))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
|
case .SByte:
|
||||||
|
var value = field.GetData<int8>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .S8, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Short:
|
||||||
|
var value = field.GetData<int16>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .S16, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Int:
|
||||||
|
var value = field.GetData<int32>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .S32, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Int2:
|
||||||
|
var value = field.GetData<int2>();
|
||||||
|
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 2))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Int3:
|
||||||
|
var value = field.GetData<int3>();
|
||||||
|
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 3))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Int4:
|
||||||
|
var value = field.GetData<int4>();
|
||||||
|
if (ImGui.DragScalarN(name.CStr(), .S32, &value, 4))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Long:
|
||||||
|
var value = field.GetData<int64>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .S64, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
|
case .Byte:
|
||||||
|
var value = field.GetData<uint8>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .U8, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .UShort:
|
||||||
|
var value = field.GetData<uint16>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .U16, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .UInt:
|
||||||
|
var value = field.GetData<uint32>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .U32, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .ULong:
|
||||||
|
var value = field.GetData<uint64>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .U64, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
|
case .Float:
|
||||||
|
var value = field.GetData<float>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .Float, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .float2:
|
||||||
|
var value = field.GetData<float2>();
|
||||||
|
if (ImGui.Editfloat2(name, ref value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .float3:
|
||||||
|
var value = field.GetData<float3>();
|
||||||
|
if (ImGui.Editfloat3(name, ref value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .float4:
|
||||||
|
var value = field.GetData<float4>();
|
||||||
|
if (ImGui.Editfloat4(name, ref value))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
|
case .Double:
|
||||||
|
var value = field.GetData<double>();
|
||||||
|
if (ImGui.DragScalar(name.CStr(), .Double, &value))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Double2:
|
||||||
|
var value = field.GetData<double2>();
|
||||||
|
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 2))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Double3:
|
||||||
|
var value = field.GetData<double3>();
|
||||||
|
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 3))
|
||||||
|
field.SetData(value);
|
||||||
|
case .Double4:
|
||||||
|
var value = field.GetData<double4>();
|
||||||
|
if (ImGui.DragScalarN(name.CStr(), .Double, &value, 4))
|
||||||
|
field.SetData(value);
|
||||||
|
|
||||||
|
case .Enum:
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
//case .String:
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
case .Entity:
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
case .Struct:
|
||||||
|
// TODO!
|
||||||
|
|
||||||
|
default:
|
||||||
|
Log.EngineLogger.Error($"Unhandled field type {field.Type}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
private static void LabelColumn(StringView label)
|
private static void LabelColumn(StringView label)
|
||||||
{
|
{
|
||||||
ImGui.TextUnformatted(label);
|
ImGui.TextUnformatted(label);
|
||||||
@@ -584,6 +869,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ShowComponentButton<CircleCollider2DComponent>("Circle collider 2D");
|
ShowComponentButton<CircleCollider2DComponent>("Circle collider 2D");
|
||||||
ShowComponentButton<MeshComponent>("Mesh");
|
ShowComponentButton<MeshComponent>("Mesh");
|
||||||
ShowComponentButton<MeshRendererComponent>("Mesh Renderer");
|
ShowComponentButton<MeshRendererComponent>("Mesh Renderer");
|
||||||
|
ShowComponentButton<ScriptComponent>("C# Script");
|
||||||
|
|
||||||
ImGui.EndCombo();
|
ImGui.EndCombo();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -48,6 +48,40 @@ namespace GlitchyEditor.EditWindows
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ImGui.PushStyleVar(.CellPadding, .(0, 0));
|
||||||
|
|
||||||
|
bool alt_pressed = ImGui.GetIO().KeyAlt;
|
||||||
|
|
||||||
|
if (ImGui.BeginTable("table", 2, .BordersInnerV | .Resizable | .Reorderable | .NoPadOuterX))
|
||||||
|
{
|
||||||
|
if (alt_pressed)
|
||||||
|
{
|
||||||
|
// Header anzeigen, damit sie neu angeordnet werden können
|
||||||
|
ImGui.TableSetupColumn("Folder Hierarchy");
|
||||||
|
ImGui.TableSetupColumn("Files");
|
||||||
|
ImGui.TableHeadersRow();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextRow();
|
||||||
|
ImGui.TableSetColumnIndex(0);
|
||||||
|
|
||||||
|
if (ImGui.BeginChild("Sidebar"))
|
||||||
|
{
|
||||||
|
DrawDirectorySideBar();
|
||||||
|
|
||||||
|
ImGui.EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.TableNextColumn();
|
||||||
|
|
||||||
|
DrawSearchBar();
|
||||||
|
|
||||||
|
ImGui.Separator();
|
||||||
|
|
||||||
|
if (ImGui.BeginChild("Files"))
|
||||||
|
{
|
||||||
|
DrawCurrentDirectory();
|
||||||
|
|
||||||
// Context menu when clicking on the background.
|
// Context menu when clicking on the background.
|
||||||
if (ImGui.BeginPopupContextWindow())
|
if (ImGui.BeginPopupContextWindow())
|
||||||
{
|
{
|
||||||
@@ -55,27 +89,29 @@ namespace GlitchyEditor.EditWindows
|
|||||||
ImGui.EndPopup();
|
ImGui.EndPopup();
|
||||||
}
|
}
|
||||||
|
|
||||||
ImGui.Columns(2);
|
|
||||||
|
|
||||||
ImGui.BeginChild("Sidebar");
|
|
||||||
|
|
||||||
DrawDirectorySideBar();
|
|
||||||
|
|
||||||
ImGui.EndChild();
|
ImGui.EndChild();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.NextColumn();
|
ImGui.EndTable();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.BeginChild("Files");
|
ImGui.PopStyleVar(1);
|
||||||
|
|
||||||
DrawCurrentDirectory();
|
|
||||||
|
|
||||||
ImGui.EndChild();
|
|
||||||
|
|
||||||
ImGui.Columns(1);
|
|
||||||
|
|
||||||
ImGui.End();
|
ImGui.End();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char8[256] _filesFilter = .();
|
||||||
|
bool _searchEverywhere;
|
||||||
|
|
||||||
|
private void DrawSearchBar()
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("Search:");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.InputText("##search", &_filesFilter, _filesFilter.Count);
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.Checkbox("Search everywhere", &_searchEverywhere);
|
||||||
|
}
|
||||||
|
|
||||||
/// Renders the context menu that is shown when the user right clicks on the background of the file browser.
|
/// Renders the context menu that is shown when the user right clicks on the background of the file browser.
|
||||||
private void ShowCurrentFolderContextMenu()
|
private void ShowCurrentFolderContextMenu()
|
||||||
{
|
{
|
||||||
@@ -132,20 +168,37 @@ namespace GlitchyEditor.EditWindows
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Vector2 DirectoryItemSize = .(110, 110);
|
private static float2 DirectoryItemSize = .(110, 110);
|
||||||
|
|
||||||
const Vector2 padding = .(24, 24);
|
const float2 padding = .(24, 24);
|
||||||
|
|
||||||
/// Renders the contents of _currentDirectory.
|
/// Renders the contents of _currentDirectory.
|
||||||
private void DrawCurrentDirectory()
|
private void DrawCurrentDirectory()
|
||||||
{
|
{
|
||||||
if (_currentDirectory.IsEmpty)
|
List<TreeNode<AssetNode>> files = null;
|
||||||
return;
|
|
||||||
|
|
||||||
ImGui.Style* style = ImGui.GetStyle();
|
ImGui.Style* style = ImGui.GetStyle();
|
||||||
|
|
||||||
float window_visible_x2 = ImGui.GetWindowPos().x + ImGui.GetWindowContentRegionMax().x;
|
float window_visible_x2 = ImGui.GetWindowPos().x + ImGui.GetWindowContentRegionMax().x;
|
||||||
|
|
||||||
|
StringView searchFilter = StringView(&_filesFilter);
|
||||||
|
|
||||||
|
if (_searchEverywhere && searchFilter.Length > 0)
|
||||||
|
{
|
||||||
|
files = scope:: List<TreeNode<AssetNode>>();
|
||||||
|
_manager.AssetHierarchy.[Friend]_assetHierarchy.ForEach(scope (node) =>
|
||||||
|
{
|
||||||
|
if (node->Name.Contains(searchFilter, true))
|
||||||
|
{
|
||||||
|
files.Add(node);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (_currentDirectory.IsEmpty)
|
||||||
|
return;
|
||||||
|
|
||||||
// Get the node of the current directory.
|
// Get the node of the current directory.
|
||||||
var currentDirectoryNode = _manager.AssetHierarchy.GetNodeFromPath(_currentDirectory);
|
var currentDirectoryNode = _manager.AssetHierarchy.GetNodeFromPath(_currentDirectory);
|
||||||
|
|
||||||
@@ -156,6 +209,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
files = currentDirectoryNode->Children;
|
||||||
|
|
||||||
|
// show back button (".."-File)
|
||||||
if (currentDirectoryNode->Parent != null)
|
if (currentDirectoryNode->Parent != null)
|
||||||
{
|
{
|
||||||
ImGui.PushID("Back");
|
ImGui.PushID("Back");
|
||||||
@@ -173,9 +229,13 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (var entry in currentDirectoryNode->Children)
|
for (var entry in files)
|
||||||
{
|
{
|
||||||
|
if (!entry->Name.Contains(searchFilter, true))
|
||||||
|
continue;
|
||||||
|
|
||||||
ImGui.PushID(entry->Name);
|
ImGui.PushID(entry->Name);
|
||||||
|
|
||||||
DrawDirectoryItem(entry);
|
DrawDirectoryItem(entry);
|
||||||
@@ -186,7 +246,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
float expectedButtonRight = currentButtonRight + style.ItemSpacing.x + DirectoryItemSize.X;
|
float expectedButtonRight = currentButtonRight + style.ItemSpacing.x + DirectoryItemSize.X;
|
||||||
|
|
||||||
// If we aren't the last entry and the next button won't fit on the same line we start a new line.
|
// If we aren't the last entry and the next button won't fit on the same line we start a new line.
|
||||||
if (entry != currentDirectoryNode->Children.Back && expectedButtonRight < window_visible_x2)
|
if (entry != files.Back && expectedButtonRight < window_visible_x2)
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
|
|
||||||
ImGui.PopID();
|
ImGui.PopID();
|
||||||
|
|||||||
@@ -32,9 +32,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
public uint32 SelectedEntityId {get; private set; }
|
public uint32 SelectedEntityId {get; private set; }
|
||||||
public bool SelectionChanged { get; private set; }
|
public bool SelectionChanged { get; private set; }
|
||||||
|
|
||||||
public Vector2 ViewportSize => (Vector2)_oldViewportSize;
|
public float2 ViewportSize => (float2)_oldViewportSize;
|
||||||
// Occurs when the viewport is resized.
|
// Occurs when the viewport is resized.
|
||||||
public Event<EventHandler<Vector2>> ViewportSizeChanged ~ _.Dispose();
|
public Event<EventHandler<float2>> ViewportSizeChanged ~ _.Dispose();
|
||||||
// Occurs when an entity was clicked.
|
// Occurs when an entity was clicked.
|
||||||
public Event<EventHandler<uint32>> EntityClicked ~ _.Dispose();
|
public Event<EventHandler<uint32>> EntityClicked ~ _.Dispose();
|
||||||
|
|
||||||
@@ -126,7 +126,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if(_oldViewportSize != viewportSize)
|
if(_oldViewportSize != viewportSize)
|
||||||
{
|
{
|
||||||
ViewportSizeChanged.Invoke(this, (Vector2)viewportSize);
|
ViewportSizeChanged.Invoke(this, (float2)viewportSize);
|
||||||
_viewPortChanged = true;
|
_viewPortChanged = true;
|
||||||
_oldViewportSize = viewportSize;
|
_oldViewportSize = viewportSize;
|
||||||
}
|
}
|
||||||
@@ -154,14 +154,14 @@ namespace GlitchyEditor.EditWindows
|
|||||||
{
|
{
|
||||||
_wrappedCursor = false;
|
_wrappedCursor = false;
|
||||||
|
|
||||||
let mousePos = (Vector2)ImGui.GetMousePos();
|
let mousePos = (float2)ImGui.GetMousePos();
|
||||||
let winPos = (Vector2)ImGui.GetWindowPos();
|
let winPos = (float2)ImGui.GetWindowPos();
|
||||||
let regionMin = winPos + (Vector2)ImGui.GetWindowContentRegionMin();
|
let regionMin = winPos + (float2)ImGui.GetWindowContentRegionMin();
|
||||||
let regionMax = winPos + (Vector2)ImGui.GetWindowContentRegionMax();
|
let regionMax = winPos + (float2)ImGui.GetWindowContentRegionMax();
|
||||||
|
|
||||||
ImGui.DrawRect((.)regionMin, (.)regionMax, .(0, 255, 0));
|
ImGui.DrawRect((.)regionMin, (.)regionMax, .(0, 255, 0));
|
||||||
|
|
||||||
Vector2 newMousePos = mousePos;
|
float2 newMousePos = mousePos;
|
||||||
|
|
||||||
if (mousePos.X < regionMin.X + 1)
|
if (mousePos.X < regionMin.X + 1)
|
||||||
{
|
{
|
||||||
@@ -181,9 +181,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
newMousePos.Y = regionMin.Y + 10;
|
newMousePos.Y = regionMin.Y + 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newMousePos != mousePos)
|
if (any(newMousePos != mousePos))
|
||||||
{
|
{
|
||||||
Input.SetMousePosition((Int2)newMousePos);
|
Input.SetMousePosition((int2)newMousePos);
|
||||||
// After wrapping the cursor the the other side, the camera controller must not compare the positions,
|
// After wrapping the cursor the the other side, the camera controller must not compare the positions,
|
||||||
// because the delta doesn't represent the correct movement of the cursor.
|
// because the delta doesn't represent the correct movement of the cursor.
|
||||||
// TODO: can be solved by using direct mouse movement instead of comparing positions
|
// TODO: can be solved by using direct mouse movement instead of comparing positions
|
||||||
@@ -195,7 +195,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
/// If the user clicks, the entity beneath the cursor will be selected.
|
/// If the user clicks, the entity beneath the cursor will be selected.
|
||||||
private void MousePicking(ImGui.Vec2 viewportSize, bool gizmoUsed)
|
private void MousePicking(ImGui.Vec2 viewportSize, bool gizmoUsed)
|
||||||
{
|
{
|
||||||
Vector2 relativeMouse = (Vector2)ImGui.GetMousePos() - (Vector2)ImGui.GetItemRectMin();
|
float2 relativeMouse = (float2)ImGui.GetMousePos() - (float2)ImGui.GetItemRectMin();
|
||||||
|
|
||||||
int rtWidth = _editor.EditorSceneRenderer.CompositeTarget.Width;
|
int rtWidth = _editor.EditorSceneRenderer.CompositeTarget.Width;
|
||||||
int rtHeight = _editor.EditorSceneRenderer.CompositeTarget.Height;
|
int rtHeight = _editor.EditorSceneRenderer.CompositeTarget.Height;
|
||||||
@@ -316,9 +316,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
parentView = parentTransformCmp.WorldTransform.Invert();
|
parentView = parentTransformCmp.WorldTransform.Invert();
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector3 snap = .(_snap);
|
float3 snap = (float3)_snap;
|
||||||
if (_gizmoType.HasFlag(.ROTATE))
|
if (_gizmoType.HasFlag(.ROTATE))
|
||||||
snap = .(_angleSnap);
|
snap = (float3)_angleSnap;
|
||||||
|
|
||||||
if (ImGuizmo.Manipulate((.)&view, (.)&projection, _gizmoType, _gizmoMode, (.)&worldTransform, null, _doSnap ? (.)&snap : null))
|
if (ImGuizmo.Manipulate((.)&view, (.)&projection, _gizmoType, _gizmoMode, (.)&worldTransform, null, _doSnap ? (.)&snap : null))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -20,9 +20,9 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
private RenderTargetGroup _renderTarget ~ _?.ReleaseRef();
|
private RenderTargetGroup _renderTarget ~ _?.ReleaseRef();
|
||||||
|
|
||||||
public Vector2 ViewportSize => (Vector2)_oldViewportSize;
|
public float2 ViewportSize => (float2)_oldViewportSize;
|
||||||
// Occurs when the viewport is resized.
|
// Occurs when the viewport is resized.
|
||||||
public Event<EventHandler<Vector2>> ViewportSizeChanged ~ _.Dispose();
|
public Event<EventHandler<float2>> ViewportSizeChanged ~ _.Dispose();
|
||||||
// Occurs when an entity was clicked.
|
// Occurs when an entity was clicked.
|
||||||
public Event<EventHandler<uint32>> EntityClicked ~ _.Dispose();
|
public Event<EventHandler<uint32>> EntityClicked ~ _.Dispose();
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ namespace GlitchyEditor.EditWindows
|
|||||||
|
|
||||||
if(_oldViewportSize != viewportSize)
|
if(_oldViewportSize != viewportSize)
|
||||||
{
|
{
|
||||||
ViewportSizeChanged.Invoke(this, (Vector2)viewportSize);
|
ViewportSizeChanged.Invoke(this, (float2)viewportSize);
|
||||||
_viewPortChanged = true;
|
_viewPortChanged = true;
|
||||||
_oldViewportSize = viewportSize;
|
_oldViewportSize = viewportSize;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ namespace GlitchyEditor
|
|||||||
private GameViewportWindow _gameViewportWindow ~ delete _;
|
private GameViewportWindow _gameViewportWindow ~ delete _;
|
||||||
private ContentBrowserWindow _contentBrowserWindow ~ delete _;
|
private ContentBrowserWindow _contentBrowserWindow ~ delete _;
|
||||||
private PropertiesWindow _propertiesWindow ~ delete _;
|
private PropertiesWindow _propertiesWindow ~ delete _;
|
||||||
|
private AssetViewer _assetViewer ~ delete _;
|
||||||
|
|
||||||
public Scene CurrentScene
|
public Scene CurrentScene
|
||||||
{
|
{
|
||||||
@@ -43,6 +44,7 @@ namespace GlitchyEditor
|
|||||||
public GameViewportWindow GameViewportWindow => _gameViewportWindow;
|
public GameViewportWindow GameViewportWindow => _gameViewportWindow;
|
||||||
public ContentBrowserWindow ContentBrowserWindow => _contentBrowserWindow;
|
public ContentBrowserWindow ContentBrowserWindow => _contentBrowserWindow;
|
||||||
public PropertiesWindow PropertiesWindow => _propertiesWindow;
|
public PropertiesWindow PropertiesWindow => _propertiesWindow;
|
||||||
|
public AssetViewer AssetViewer => _assetViewer;
|
||||||
|
|
||||||
public EditorCamera* CurrentCamera { get; set; }
|
public EditorCamera* CurrentCamera { get; set; }
|
||||||
|
|
||||||
@@ -68,6 +70,7 @@ namespace GlitchyEditor
|
|||||||
_componentEditWindow = new ComponentEditWindow(_entityHierarchyWindow);
|
_componentEditWindow = new ComponentEditWindow(_entityHierarchyWindow);
|
||||||
_contentBrowserWindow = new ContentBrowserWindow((.)Application.Get().ContentManager);
|
_contentBrowserWindow = new ContentBrowserWindow((.)Application.Get().ContentManager);
|
||||||
_propertiesWindow = new PropertiesWindow(this);
|
_propertiesWindow = new PropertiesWindow(this);
|
||||||
|
_assetViewer = new AssetViewer((.)Application.Get().ContentManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update()
|
public void Update()
|
||||||
@@ -78,6 +81,7 @@ namespace GlitchyEditor
|
|||||||
_componentEditWindow.Show();
|
_componentEditWindow.Show();
|
||||||
_contentBrowserWindow.Show();
|
_contentBrowserWindow.Show();
|
||||||
_propertiesWindow.Show();
|
_propertiesWindow.Show();
|
||||||
|
_assetViewer.Show();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,9 @@ namespace GlitchyEditor
|
|||||||
{
|
{
|
||||||
EditorContentManager _contentManager;
|
EditorContentManager _contentManager;
|
||||||
|
|
||||||
public this()
|
public this(String[] args)
|
||||||
{
|
{
|
||||||
PushLayer(new EditorLayer(_contentManager));
|
PushLayer(new EditorLayer(args, _contentManager));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IContentManager InitContentManager()
|
protected override IContentManager InitContentManager()
|
||||||
@@ -39,9 +39,9 @@ namespace GlitchyEditor
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Export, LinkName("CreateApplication")]
|
[Export, LinkName("CreateApplication")]
|
||||||
public static Application CreateApplication()
|
public static Application CreateApplication(String[] args)
|
||||||
{
|
{
|
||||||
return new EditorApp();
|
return new EditorApp(args);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ namespace GlitchyEditor
|
|||||||
public SubTexture2D Stop ~ _.ReleaseRef();
|
public SubTexture2D Stop ~ _.ReleaseRef();
|
||||||
public SubTexture2D Simulate ~ _.ReleaseRef();
|
public SubTexture2D Simulate ~ _.ReleaseRef();
|
||||||
public SubTexture2D Pause ~ _.ReleaseRef();
|
public SubTexture2D Pause ~ _.ReleaseRef();
|
||||||
|
public SubTexture2D SingleStep ~ _.ReleaseRef();
|
||||||
|
|
||||||
public SamplerState SamplerState
|
public SamplerState SamplerState
|
||||||
{
|
{
|
||||||
@@ -25,11 +26,11 @@ namespace GlitchyEditor
|
|||||||
set => _texture.Get().SamplerState = value;
|
set => _texture.Get().SamplerState = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public this(String texturePath, Vector2 iconSize)
|
public this(String texturePath, float2 iconSize)
|
||||||
{
|
{
|
||||||
_texture = Content.LoadAsset(texturePath, null, true);
|
_texture = Content.LoadAsset(texturePath, null, true);
|
||||||
|
|
||||||
Vector2 pen = .();
|
float2 pen = .();
|
||||||
|
|
||||||
DirectionalLight = GetNextGridTexture(ref pen, iconSize);
|
DirectionalLight = GetNextGridTexture(ref pen, iconSize);
|
||||||
Camera = GetNextGridTexture(ref pen, iconSize);
|
Camera = GetNextGridTexture(ref pen, iconSize);
|
||||||
@@ -39,9 +40,10 @@ namespace GlitchyEditor
|
|||||||
Stop = GetNextGridTexture(ref pen, iconSize);
|
Stop = GetNextGridTexture(ref pen, iconSize);
|
||||||
Simulate = GetNextGridTexture(ref pen, iconSize);
|
Simulate = GetNextGridTexture(ref pen, iconSize);
|
||||||
Pause = GetNextGridTexture(ref pen, iconSize);
|
Pause = GetNextGridTexture(ref pen, iconSize);
|
||||||
|
SingleStep = GetNextGridTexture(ref pen, iconSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SubTexture2D GetNextGridTexture(ref Vector2 pen, Vector2 iconSize)
|
private SubTexture2D GetNextGridTexture(ref float2 pen, float2 iconSize)
|
||||||
{
|
{
|
||||||
SubTexture2D subTexture = .CreateFromGrid(_texture, pen, iconSize);
|
SubTexture2D subTexture = .CreateFromGrid(_texture, pen, iconSize);
|
||||||
|
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ using GlitchyEngine.Renderer.Animation;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
using GlitchyEditor.Assets;
|
using GlitchyEditor.Assets;
|
||||||
|
using GlitchyEngine.Scripting;
|
||||||
|
|
||||||
namespace GlitchyEditor
|
namespace GlitchyEditor
|
||||||
{
|
{
|
||||||
@@ -69,6 +70,19 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
SceneState _sceneState = .Edit;
|
SceneState _sceneState = .Edit;
|
||||||
bool _isPaused = false;
|
bool _isPaused = false;
|
||||||
|
bool _singleStep = false;
|
||||||
|
|
||||||
|
private float _fixedTimestep = 1.0f / 60.0f;
|
||||||
|
|
||||||
|
append List<(String Name, String Path)> _recentProjectPaths = .() ~ {
|
||||||
|
for (var item in _)
|
||||||
|
{
|
||||||
|
delete item.Name;
|
||||||
|
delete item.Path;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
private GameTime _simulationGameTime = new .() ~ delete _;
|
||||||
|
|
||||||
/// Gets or sets the path of the current scene.
|
/// Gets or sets the path of the current scene.
|
||||||
public StringView SceneFilePath
|
public StringView SceneFilePath
|
||||||
@@ -83,25 +97,28 @@ namespace GlitchyEditor
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public this(EditorContentManager contentManager) : base("Editor")
|
[AllowAppend]
|
||||||
|
public this(String[] args, EditorContentManager contentManager) : base("Editor")
|
||||||
{
|
{
|
||||||
Application.Get().Window.IsVSync = false;
|
Application.Get().Window.IsVSync = true;
|
||||||
|
|
||||||
_contentManager = contentManager;
|
_contentManager = contentManager;
|
||||||
|
|
||||||
InitGraphics();
|
InitGraphics();
|
||||||
|
|
||||||
_editorScene = new Scene();
|
|
||||||
SetReference!(_activeScene, _editorScene);
|
|
||||||
|
|
||||||
_gameSceneRenderer = new SceneRenderer();
|
_gameSceneRenderer = new SceneRenderer();
|
||||||
_editorSceneRenderer = new SceneRenderer();
|
_editorSceneRenderer = new SceneRenderer();
|
||||||
|
|
||||||
_camera = EditorCamera(Vector3(3.5f, 1.25f, 2.75f), Quaternion.FromEulerAngles(MathHelper.ToRadians(40), MathHelper.ToRadians(25), 0), MathHelper.ToRadians(75), 0.1f, 1);
|
_camera = EditorCamera(float3(-3f, 3f, -3f), Quaternion.FromEulerAngles(MathHelper.ToRadians(40), MathHelper.ToRadians(25), 0), MathHelper.ToRadians(75), 0.1f, 1);
|
||||||
_camera.RenderTarget = _cameraTarget;
|
_camera.RenderTarget = _cameraTarget;
|
||||||
|
|
||||||
InitEditor();
|
InitEditor();
|
||||||
|
|
||||||
|
if (args.Count >= 1)
|
||||||
|
LoadSceneFile(args[0]);
|
||||||
|
|
||||||
|
// Create a new scene, if LoadSceneFile failed
|
||||||
|
if (_activeScene == null)
|
||||||
NewScene();
|
NewScene();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -188,11 +205,37 @@ namespace GlitchyEditor
|
|||||||
updateMode = .Physics;
|
updateMode = .Physics;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_sceneState != .Edit && _isPaused)
|
if (_sceneState != .Edit && _isPaused && !_singleStep)
|
||||||
updateMode = .None;
|
updateMode = .None;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If we are in edit mode we use the "official" gametime.
|
||||||
|
* However in play or simulation mode we use a simulation game time
|
||||||
|
* which is decoupled from the actual time. This allows us to manipulate
|
||||||
|
* the simulation speed without potentially messing with the rest of the editor.
|
||||||
|
*/
|
||||||
|
GameTime gt = null;
|
||||||
|
|
||||||
_activeScene.Update(gameTime, updateMode);
|
if (updateMode == .Editor)
|
||||||
|
{
|
||||||
|
gt = gameTime;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
gt = _simulationGameTime;
|
||||||
|
|
||||||
|
if (_singleStep)
|
||||||
|
{
|
||||||
|
_singleStep = false;
|
||||||
|
_simulationGameTime.ManualStepFrame(_fixedTimestep);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
_simulationGameTime.ManualStepFrame(gameTime.DeltaTime);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_activeScene.Update(gt, updateMode);
|
||||||
|
|
||||||
// Clear the swapchain-buffer
|
// Clear the swapchain-buffer
|
||||||
RenderCommand.Clear(null, .Color | .Depth, .(0.2f, 0.2f, 0.2f), 1.0f, 0);
|
RenderCommand.Clear(null, .Color | .Depth, .(0.2f, 0.2f, 0.2f), 1.0f, 0);
|
||||||
@@ -200,27 +243,36 @@ namespace GlitchyEditor
|
|||||||
RenderCommand.SetBlendState(_alphaBlendState);
|
RenderCommand.SetBlendState(_alphaBlendState);
|
||||||
RenderCommand.SetDepthStencilState(_depthStencilState);
|
RenderCommand.SetDepthStencilState(_depthStencilState);
|
||||||
|
|
||||||
|
if (_editor.GameViewportWindow.Visible)
|
||||||
|
{
|
||||||
|
_gameSceneRenderer.Scene = _activeScene;
|
||||||
|
|
||||||
|
_activeScene.SetViewportSize((uint32)_editor.GameViewportWindow.ViewportSize.X, (uint32)_editor.GameViewportWindow.ViewportSize.Y);
|
||||||
|
_gameSceneRenderer.SetViewportSize((uint32)_editor.GameViewportWindow.ViewportSize.X, (uint32)_editor.GameViewportWindow.ViewportSize.Y);
|
||||||
|
|
||||||
|
RenderCommand.Clear(_gameViewportTarget, .Color | .Depth, .(0.2f, 0.2f, 0.2f), 1.0f, 0);
|
||||||
|
_gameSceneRenderer.RenderRuntime(gameTime, _gameViewportTarget);
|
||||||
|
}
|
||||||
|
|
||||||
|
RenderCommand.SetBlendState(_alphaBlendState);
|
||||||
|
RenderCommand.SetDepthStencilState(_depthStencilState);
|
||||||
|
|
||||||
if (_editor.SceneViewportWindow.Visible)
|
if (_editor.SceneViewportWindow.Visible)
|
||||||
{
|
{
|
||||||
_camera.Update(gameTime);
|
_camera.Update(gameTime);
|
||||||
|
|
||||||
_editorSceneRenderer.Scene = _activeScene;
|
_editorSceneRenderer.Scene = _activeScene;
|
||||||
|
|
||||||
|
// Only use aspect ratio of editor-window, if game is not being rendered
|
||||||
|
if (!_editor.GameViewportWindow.Visible)
|
||||||
|
_activeScene.SetViewportSize((uint32)_editor.SceneViewportWindow.ViewportSize.X, (uint32)_editor.SceneViewportWindow.ViewportSize.Y);
|
||||||
|
|
||||||
|
_editorSceneRenderer.SetViewportSize((uint32)_editor.SceneViewportWindow.ViewportSize.X, (uint32)_editor.SceneViewportWindow.ViewportSize.Y);
|
||||||
|
|
||||||
RenderCommand.Clear(_editorViewportTarget, .Color | .Depth, .(0.2f, 0.2f, 0.2f), 1.0f, 0);
|
RenderCommand.Clear(_editorViewportTarget, .Color | .Depth, .(0.2f, 0.2f, 0.2f), 1.0f, 0);
|
||||||
_editorSceneRenderer.RenderEditor(gameTime, _camera, _editorViewportTarget, scope => DebugDraw3D, scope => DebugDraw2D);
|
_editorSceneRenderer.RenderEditor(gameTime, _camera, _editorViewportTarget, scope => DebugDraw3D, scope => DebugDraw2D);
|
||||||
}
|
}
|
||||||
|
|
||||||
RenderCommand.SetBlendState(_alphaBlendState);
|
|
||||||
RenderCommand.SetDepthStencilState(_depthStencilState);
|
|
||||||
|
|
||||||
if (_editor.GameViewportWindow.Visible)
|
|
||||||
{
|
|
||||||
_gameSceneRenderer.Scene = _activeScene;
|
|
||||||
|
|
||||||
RenderCommand.Clear(_gameViewportTarget, .Color | .Depth, .(0.2f, 0.2f, 0.2f), 1.0f, 0);
|
|
||||||
_gameSceneRenderer.RenderRuntime(gameTime, _gameViewportTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
RenderCommand.UnbindRenderTargets();
|
RenderCommand.UnbindRenderTargets();
|
||||||
RenderCommand.SetRenderTarget(null, 0, true);
|
RenderCommand.SetRenderTarget(null, 0, true);
|
||||||
RenderCommand.BindRenderTargets();
|
RenderCommand.BindRenderTargets();
|
||||||
@@ -248,14 +300,14 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
Matrix Billboard(Matrix transform)
|
Matrix Billboard(Matrix transform)
|
||||||
{
|
{
|
||||||
Vector3 worldPos = transform.Translation;
|
float3 worldPos = transform.Translation;
|
||||||
|
|
||||||
return Matrix.Translation(worldPos) * billboard;
|
return Matrix.Translation(worldPos) * billboard;
|
||||||
}
|
}
|
||||||
|
|
||||||
float CalculateAlpha(Vector3 pos)
|
float CalculateAlpha(float3 pos)
|
||||||
{
|
{
|
||||||
return Math.Clamp(1.5f - Vector3.Distance(_editor.CurrentCamera.Position, pos) / 50, 0, 1);
|
return Math.Clamp(1.5f - distance(_editor.CurrentCamera.Position, pos) / 50, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var (entity, transform, camera) in _activeScene.GetEntities<TransformComponent, CameraComponent>())
|
for (var (entity, transform, camera) in _activeScene.GetEntities<TransformComponent, CameraComponent>())
|
||||||
@@ -280,7 +332,7 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
for (float angle = 0; angle < MathHelper.TwoPi; angle += MathHelper.TwoPi / 5.0f)
|
for (float angle = 0; angle < MathHelper.TwoPi; angle += MathHelper.TwoPi / 5.0f)
|
||||||
{
|
{
|
||||||
Vector2 pos = MathHelper.CirclePoint(angle, 0.5f);
|
float2 pos = MathHelper.CirclePoint(angle, 0.5f);
|
||||||
|
|
||||||
Renderer.DrawRay(.(pos, 0), .(pos, 20), .White, transform.WorldTransform);
|
Renderer.DrawRay(.(pos, 0), .(pos, 20), .White, transform.WorldTransform);
|
||||||
}
|
}
|
||||||
@@ -319,7 +371,8 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
private bool OnImGuiRender(ImGuiRenderEvent event)
|
private bool OnImGuiRender(ImGuiRenderEvent event)
|
||||||
{
|
{
|
||||||
Input.ImGuiDebugDraw();
|
// TODO: make window
|
||||||
|
//Input.ImGuiDebugDraw();
|
||||||
|
|
||||||
//viewer.ViewTexture(Renderer.[Friend]_gBuffer.Target);
|
//viewer.ViewTexture(Renderer.[Friend]_gBuffer.Target);
|
||||||
|
|
||||||
@@ -365,7 +418,6 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
float centerX = ImGui.GetContentRegionMax().x / 2;
|
float centerX = ImGui.GetContentRegionMax().x / 2;
|
||||||
|
|
||||||
|
|
||||||
if (_sceneState == .Edit)
|
if (_sceneState == .Edit)
|
||||||
EditorButtons:
|
EditorButtons:
|
||||||
{
|
{
|
||||||
@@ -414,10 +466,17 @@ namespace GlitchyEditor
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
float totalWidth = size * 2 + padding * 2;
|
||||||
|
|
||||||
|
if (_isPaused)
|
||||||
|
{
|
||||||
|
totalWidth = size * 3 + padding * 4;
|
||||||
|
}
|
||||||
|
|
||||||
// Display the buttons for play/simulation state
|
// Display the buttons for play/simulation state
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.SetCursorPosX(centerX - size - padding);
|
ImGui.SetCursorPosX(centerX - totalWidth / 2.0f);
|
||||||
|
|
||||||
SubTexture2D pauseButtonIcon = _isPaused ? _editorIcons.Play : _editorIcons.Pause;
|
SubTexture2D pauseButtonIcon = _isPaused ? _editorIcons.Play : _editorIcons.Pause;
|
||||||
|
|
||||||
@@ -431,6 +490,42 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
ImGui.AttachTooltip(_isPaused ? "Resume" : "Pause");
|
ImGui.AttachTooltip(_isPaused ? "Resume" : "Pause");
|
||||||
|
|
||||||
|
if (_isPaused)
|
||||||
|
{
|
||||||
|
ImGui.PushID(2);
|
||||||
|
|
||||||
|
ImGui.SameLine();
|
||||||
|
|
||||||
|
SubTexture2D singleStepButtonIcon = _editorIcons.SingleStep;
|
||||||
|
|
||||||
|
if (ImGui.ImageButton(singleStepButtonIcon, .(size, size), .Zero, .Ones, 0))
|
||||||
|
{
|
||||||
|
DoSingleStep();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ImGui.BeginPopupContextItem())
|
||||||
|
{
|
||||||
|
ImGui.TextUnformatted("Time step:");
|
||||||
|
ImGui.SameLine();
|
||||||
|
ImGui.DragFloat("##timestep", &_fixedTimestep, 0.001f, 0.001f, 1000.0f, "%.4fs");
|
||||||
|
|
||||||
|
float fps = 1.0f / _fixedTimestep;
|
||||||
|
|
||||||
|
ImGui.TextUnformatted("Frame rate:");
|
||||||
|
ImGui.SameLine();
|
||||||
|
if (ImGui.DragFloat("##fps", &fps, 1.0f, 0.001f, 1000.0f, "%.3f FPS"))
|
||||||
|
{
|
||||||
|
_fixedTimestep = 1.0f / fps;
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.EndPopup();
|
||||||
|
}
|
||||||
|
|
||||||
|
ImGui.AttachTooltip("Step one Frame (Right-click to change time step)");
|
||||||
|
|
||||||
|
ImGui.PopID();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.SameLine();
|
ImGui.SameLine();
|
||||||
ImGui.PushID(1);
|
ImGui.PushID(1);
|
||||||
|
|
||||||
@@ -492,11 +587,16 @@ namespace GlitchyEditor
|
|||||||
_isPaused = false;
|
_isPaused = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void DoSingleStep()
|
||||||
|
{
|
||||||
|
_singleStep = true;
|
||||||
|
}
|
||||||
|
|
||||||
private void OnSceneStop()
|
private void OnSceneStop()
|
||||||
{
|
{
|
||||||
if (_sceneState == .Play)
|
if (_sceneState == .Play)
|
||||||
_activeScene.OnRuntimeStop();
|
_activeScene.OnRuntimeStop();
|
||||||
else
|
else if (_sceneState == .Simulate)
|
||||||
_activeScene.OnSimulationStop();
|
_activeScene.OnSimulationStop();
|
||||||
|
|
||||||
SetReference!(_activeScene, _editorScene);
|
SetReference!(_activeScene, _editorScene);
|
||||||
@@ -508,6 +608,8 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
_isPaused = false;
|
_isPaused = false;
|
||||||
|
|
||||||
|
if (_activeScene != null)
|
||||||
|
{
|
||||||
/*
|
/*
|
||||||
* Update the viewport size because if the game windows size changed in
|
* Update the viewport size because if the game windows size changed in
|
||||||
* "Game"-mode the updated aspect-rations will reset once we go back
|
* "Game"-mode the updated aspect-rations will reset once we go back
|
||||||
@@ -515,6 +617,7 @@ namespace GlitchyEditor
|
|||||||
*/
|
*/
|
||||||
GameViewportSizeChanged(null, _editor.GameViewportWindow.ViewportSize);
|
GameViewportSizeChanged(null, _editor.GameViewportWindow.ViewportSize);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Creates a new scene.
|
/// Creates a new scene.
|
||||||
private void NewScene()
|
private void NewScene()
|
||||||
@@ -523,8 +626,8 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
SceneFilePath = null;
|
SceneFilePath = null;
|
||||||
|
|
||||||
Scene newScene = new Scene();
|
using (Scene newScene = new Scene())
|
||||||
|
{
|
||||||
_camera.Position = .(-1.5f, 1.5f, -2.5f);
|
_camera.Position = .(-1.5f, 1.5f, -2.5f);
|
||||||
_camera.RotationEuler = .(MathHelper.ToRadians(25), MathHelper.ToRadians(35), 0);
|
_camera.RotationEuler = .(MathHelper.ToRadians(25), MathHelper.ToRadians(35), 0);
|
||||||
|
|
||||||
@@ -532,8 +635,8 @@ namespace GlitchyEditor
|
|||||||
{
|
{
|
||||||
let cameraEntity = newScene.CreateEntity("Camera");
|
let cameraEntity = newScene.CreateEntity("Camera");
|
||||||
let transform = cameraEntity.Transform;
|
let transform = cameraEntity.Transform;
|
||||||
transform.Position = Vector3(0, 2, -5);
|
transform.Position = float3(0, 2, -5);
|
||||||
transform.RotationEuler = Vector3(0, MathHelper.ToRadians(25), 0);
|
transform.RotationEuler = float3(0, MathHelper.ToRadians(25), 0);
|
||||||
|
|
||||||
let camera = cameraEntity.AddComponent<CameraComponent>();
|
let camera = cameraEntity.AddComponent<CameraComponent>();
|
||||||
camera.Primary = true;
|
camera.Primary = true;
|
||||||
@@ -554,14 +657,11 @@ namespace GlitchyEditor
|
|||||||
light.SceneLight.Color = .(1.0f, 0.95f, 0.8f);
|
light.SceneLight.Color = .(1.0f, 0.95f, 0.8f);
|
||||||
}
|
}
|
||||||
|
|
||||||
_editorScene.ReleaseRef();
|
SetReference!(_editorScene, newScene);
|
||||||
_editorScene = newScene;
|
|
||||||
_editor.CurrentScene = _editorScene;
|
_editor.CurrentScene = _editorScene;
|
||||||
var vpSize = _editor.SceneViewportWindow.ViewportSize;
|
|
||||||
_editorScene.OnViewportResize((.)vpSize.X, (.)vpSize.Y);
|
|
||||||
|
|
||||||
SetReference!(_activeScene, _editorScene);
|
SetReference!(_activeScene, _editorScene);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Saves the scene in the file that is was loaded from or saved to last. If there is no such path (i.e. it is a new scene) the save file dialog will open.
|
/// Saves the scene in the file that is was loaded from or saved to last. If there is no such path (i.e. it is a new scene) the save file dialog will open.
|
||||||
private void SaveScene()
|
private void SaveScene()
|
||||||
@@ -611,17 +711,41 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
SceneFilePath = scope String(filename);
|
SceneFilePath = scope String(filename);
|
||||||
|
|
||||||
_editorScene.ReleaseRef();
|
using (Scene newScene = new Scene())
|
||||||
_editorScene = new Scene();
|
{
|
||||||
|
SceneSerializer serializer = scope .(newScene);
|
||||||
|
let result = serializer.Deserialize(SceneFilePath);
|
||||||
|
|
||||||
|
// Make sure we actually loaded something!
|
||||||
|
if (result case .Ok)
|
||||||
|
{
|
||||||
|
SetReference!(_editorScene, newScene);
|
||||||
_editor.CurrentScene = _editorScene;
|
_editor.CurrentScene = _editorScene;
|
||||||
var vpSize = _editor.SceneViewportWindow.ViewportSize;
|
|
||||||
_editorScene.OnViewportResize((.)vpSize.X, (.)vpSize.Y);
|
|
||||||
|
|
||||||
SceneSerializer serializer = scope .(_editorScene);
|
|
||||||
serializer.Deserialize(SceneFilePath);
|
|
||||||
|
|
||||||
SetReference!(_activeScene, _editorScene);
|
SetReference!(_activeScene, _editorScene);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Log.EngineLogger.Error("Failed to load scene file.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void DrawOpenRecentProjectMenu()
|
||||||
|
{
|
||||||
|
int i = 0;
|
||||||
|
|
||||||
|
for (let (name, path) in _recentProjectPaths)
|
||||||
|
{
|
||||||
|
i++;
|
||||||
|
if (i >= 10)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (ImGui.MenuItem(scope $"{i}: {name} ({path})"))
|
||||||
|
{
|
||||||
|
LoadSceneFile(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void DrawMainMenuBar()
|
private void DrawMainMenuBar()
|
||||||
{
|
{
|
||||||
@@ -635,12 +759,19 @@ namespace GlitchyEditor
|
|||||||
if (ImGui.MenuItem("Save", "Ctrl+S"))
|
if (ImGui.MenuItem("Save", "Ctrl+S"))
|
||||||
SaveScene();
|
SaveScene();
|
||||||
|
|
||||||
if (ImGui.MenuItem("Save as...", "Ctrl+Shift+N"))
|
if (ImGui.MenuItem("Save as...", "Ctrl+Shift+S"))
|
||||||
SaveSceneAs();
|
SaveSceneAs();
|
||||||
|
|
||||||
if (ImGui.MenuItem("Open...", "Ctrl+O"))
|
if (ImGui.MenuItem("Open...", "Ctrl+O"))
|
||||||
OpenScene();
|
OpenScene();
|
||||||
|
|
||||||
|
if (ImGui.BeginMenu("Open Recent"))
|
||||||
|
{
|
||||||
|
DrawOpenRecentProjectMenu();
|
||||||
|
|
||||||
|
ImGui.EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
ImGui.Separator();
|
ImGui.Separator();
|
||||||
|
|
||||||
if (ImGui.MenuItem("Settings"))
|
if (ImGui.MenuItem("Settings"))
|
||||||
@@ -674,9 +805,21 @@ namespace GlitchyEditor
|
|||||||
if(ImGui.MenuItem(PropertiesWindow.s_WindowTitle))
|
if(ImGui.MenuItem(PropertiesWindow.s_WindowTitle))
|
||||||
_editor.PropertiesWindow.Open = true;
|
_editor.PropertiesWindow.Open = true;
|
||||||
|
|
||||||
|
if(ImGui.MenuItem(AssetViewer.s_WindowTitle))
|
||||||
|
_editor.AssetViewer.Open = true;
|
||||||
|
|
||||||
ImGui.EndMenu();
|
ImGui.EndMenu();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(ImGui.BeginMenu("Tools", true))
|
||||||
|
{
|
||||||
|
if(ImGui.MenuItem("Reload Scripts"))
|
||||||
|
ScriptEngine.ReloadAssemblies();
|
||||||
|
|
||||||
|
ImGui.EndMenu();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
ImGui.EndMainMenuBar();
|
ImGui.EndMainMenuBar();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -685,35 +828,33 @@ namespace GlitchyEditor
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EditorViewportSizeChanged(Object sender, Vector2 viewportSize)
|
private void EditorViewportSizeChanged(Object sender, float2 viewportSize)
|
||||||
{
|
{
|
||||||
|
if(viewportSize.X <= 0 || viewportSize.Y <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
uint32 sizeX = (uint32)viewportSize.X;
|
uint32 sizeX = (uint32)viewportSize.X;
|
||||||
uint32 sizeY = (uint32)viewportSize.Y;
|
uint32 sizeY = (uint32)viewportSize.Y;
|
||||||
|
|
||||||
if(sizeX == 0 || sizeY == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_editorViewportTarget.Resize(sizeX, sizeY);
|
_editorViewportTarget.Resize(sizeX, sizeY);
|
||||||
_cameraTarget.Resize(sizeX, sizeY);
|
_cameraTarget.Resize(sizeX, sizeY);
|
||||||
|
|
||||||
_camera.OnViewportResize(sizeX, sizeY);
|
_camera.OnViewportResize(sizeX, sizeY);
|
||||||
|
|
||||||
_editorSceneRenderer.OnViewportResize(sizeX, sizeY);
|
_activeScene.SetViewportSize(sizeX, sizeY);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void GameViewportSizeChanged(Object sender, Vector2 viewportSize)
|
private void GameViewportSizeChanged(Object sender, float2 viewportSize)
|
||||||
{
|
{
|
||||||
|
if(viewportSize.X <= 0 || viewportSize.Y <= 0)
|
||||||
|
return;
|
||||||
|
|
||||||
uint32 sizeX = (uint32)viewportSize.X;
|
uint32 sizeX = (uint32)viewportSize.X;
|
||||||
uint32 sizeY = (uint32)viewportSize.Y;
|
uint32 sizeY = (uint32)viewportSize.Y;
|
||||||
|
|
||||||
if(sizeX == 0 || sizeY == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
_gameViewportTarget.Resize(sizeX, sizeY);
|
_gameViewportTarget.Resize(sizeX, sizeY);
|
||||||
|
|
||||||
_activeScene.OnViewportResize(sizeX, sizeY);
|
_activeScene.SetViewportSize(sizeX, sizeY);
|
||||||
|
|
||||||
_gameSceneRenderer.OnViewportResize(sizeX, sizeY);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool OnKeyPressed(KeyPressedEvent e)
|
private bool OnKeyPressed(KeyPressedEvent e)
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ namespace GlitchyEditor
|
|||||||
_samplerPoint = SamplerStateManager.GetSampler(desc);
|
_samplerPoint = SamplerStateManager.GetSampler(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 _position;
|
float2 _position;
|
||||||
|
|
||||||
bool _moving;
|
bool _moving;
|
||||||
|
|
||||||
@@ -105,6 +105,7 @@ namespace GlitchyEditor
|
|||||||
{
|
{
|
||||||
_target?.ReleaseRef();
|
_target?.ReleaseRef();
|
||||||
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm, (.)viewportSize.x, (.)viewportSize.y));
|
_target = new RenderTarget2D(.(.R8G8B8A8_UNorm, (.)viewportSize.x, (.)viewportSize.y));
|
||||||
|
_target.SamplerState = SamplerStateManager.PointClamp;
|
||||||
_depth?.ReleaseRef();
|
_depth?.ReleaseRef();
|
||||||
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
_depth = new DepthStencilTarget((.)viewportSize.x, (.)viewportSize.y, .D16_UNorm);
|
||||||
}
|
}
|
||||||
@@ -124,7 +125,7 @@ namespace GlitchyEditor
|
|||||||
{
|
{
|
||||||
var windowPos = ImGui.GetWindowPos();
|
var windowPos = ImGui.GetWindowPos();
|
||||||
var mousePos = ImGui.GetIO().MousePos;
|
var mousePos = ImGui.GetIO().MousePos;
|
||||||
Vector2 mouseInWindow = .(mousePos.x - windowPos.x, mousePos.y - windowPos.y);
|
float2 mouseInWindow = .(mousePos.x - windowPos.x, mousePos.y - windowPos.y);
|
||||||
|
|
||||||
bool windowHovered = ImGui.IsWindowHovered();
|
bool windowHovered = ImGui.IsWindowHovered();
|
||||||
|
|
||||||
@@ -158,7 +159,7 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
if(_moving)
|
if(_moving)
|
||||||
{
|
{
|
||||||
Int2 movement = Input.GetMouseMovement();
|
int2 movement = Input.GetMouseMovement();
|
||||||
|
|
||||||
_position.X += movement.X;
|
_position.X += movement.X;
|
||||||
_position.Y += movement.Y;
|
_position.Y += movement.Y;
|
||||||
@@ -181,10 +182,10 @@ namespace GlitchyEditor
|
|||||||
_context.SetDepthStencilTarget(_depth);
|
_context.SetDepthStencilTarget(_depth);
|
||||||
_context.BindRenderTargets();
|
_context.BindRenderTargets();
|
||||||
|
|
||||||
Vector2 textureSize = Vector2(viewedTexture.Width, viewedTexture.Height);
|
float2 textureSize = float2(viewedTexture.Width, viewedTexture.Height);
|
||||||
Vector2 zoomedTextureSize = textureSize * _zoom;
|
float2 zoomedTextureSize = textureSize * _zoom;
|
||||||
|
|
||||||
Vector2 targetSize = Vector2(_target.Width, _target.Height);
|
float2 targetSize = float2(_target.Width, _target.Height);
|
||||||
|
|
||||||
_effect.Variables["ColorOffset"].SetData(_colorOffset);
|
_effect.Variables["ColorOffset"].SetData(_colorOffset);
|
||||||
_effect.Variables["ColorScale"].SetData(_colorScale);
|
_effect.Variables["ColorScale"].SetData(_colorScale);
|
||||||
@@ -204,19 +205,19 @@ namespace GlitchyEditor
|
|||||||
switch(_backgroundMode)
|
switch(_backgroundMode)
|
||||||
{
|
{
|
||||||
case .Black:
|
case .Black:
|
||||||
Renderer2D.DrawQuadPivotCorner(Vector3(0, 0, 1), targetSize, 0, .Black);
|
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .Black);
|
||||||
case .White:
|
case .White:
|
||||||
Renderer2D.DrawQuadPivotCorner(Vector3(0, 0, 1), targetSize, 0, .White);
|
Renderer2D.DrawQuadPivotCorner(float3(0, 0, 1), targetSize, 0, .White);
|
||||||
case .Checkerboard:
|
case .Checkerboard:
|
||||||
float quadSize = 50.0f;
|
float quadSize = 50.0f;
|
||||||
|
|
||||||
Vector2 numQuads = (targetSize / 500f) * 10f;
|
float2 numQuads = (targetSize / 500f) * 10f;
|
||||||
|
|
||||||
for(float x = 0; x < numQuads.X; x++)
|
for(float x = 0; x < numQuads.X; x++)
|
||||||
{
|
{
|
||||||
for(float y = 0; y < numQuads.Y; y++)
|
for(float y = 0; y < numQuads.Y; y++)
|
||||||
{
|
{
|
||||||
Renderer2D.DrawQuadPivotCorner(Vector3(x * quadSize, -y * quadSize, 1), quadSize.XX, 0, ((x + y) % 2 == 0) ? .White : .Gray);
|
Renderer2D.DrawQuadPivotCorner(float3(x * quadSize, -y * quadSize, 1), quadSize.XX, 0, ((x + y) % 2 == 0) ? .White : .Gray);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -236,7 +237,7 @@ namespace GlitchyEditor
|
|||||||
|
|
||||||
Renderer2D.BeginScene(_camera, .SortByTexture, _effect);
|
Renderer2D.BeginScene(_camera, .SortByTexture, _effect);
|
||||||
|
|
||||||
Renderer2D.DrawQuad(Vector3(_position * .(1, -1), 0), zoomedTextureSize, 0, viewedTexture);
|
Renderer2D.DrawQuad(float3(_position * .(1, -1), 0), zoomedTextureSize, 0, viewedTexture);
|
||||||
|
|
||||||
Renderer2D.EndScene();
|
Renderer2D.EndScene();
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
FileVersion = 1
|
FileVersion = 1
|
||||||
Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", FreeType = "*", cgltf-beef = "*", msdfgen-beef = "*", ImGui = "*", ImGuiImplDX11 = "*", ImGuiImplWin32 = "*", ImGuizmo = "*", Beefy2D = "*", LodePng = "*", GlitchyEngineHelper = "*", bon = "*", box2d-beef = "*", "Beef.Linq" = "*"}
|
Dependencies = {GlitchLog = "*", corlib = "*", DirectX = "*", FreeType = "*", cgltf-beef = "*", msdfgen-beef = "*", ImGui = "*", ImGuiImplDX11 = "*", ImGuiImplWin32 = "*", ImGuizmo = "*", Beefy2D = "*", LodePng = "*", GlitchyEngineHelper = "*", bon = "*", box2d-beef = "*", "Beef.Linq" = "*", NetHostBeef = "*"}
|
||||||
|
|
||||||
[Project]
|
[Project]
|
||||||
Name = "GlitchyEngine"
|
Name = "GlitchyEngine"
|
||||||
@@ -25,3 +25,24 @@ PreprocessorMacros = ["TEST", "GE_WINDOWS"]
|
|||||||
|
|
||||||
[Configs.Debug.Win64]
|
[Configs.Debug.Win64]
|
||||||
PreprocessorMacros = ["DEBUG", "GE_PROFILE", "GE_PROFILE_RENDERER", "GE_PROFILE_RESOURCES", "IMGUI"]
|
PreprocessorMacros = ["DEBUG", "GE_PROFILE", "GE_PROFILE_RENDERER", "GE_PROFILE_RESOURCES", "IMGUI"]
|
||||||
|
|
||||||
|
[[ProjectFolder.Items]]
|
||||||
|
Type = "AutoFolder"
|
||||||
|
Name = "Math"
|
||||||
|
|
||||||
|
[[ProjectFolder.Items.Items]]
|
||||||
|
Type = "IgnoreSource"
|
||||||
|
Name = "Vector2.bf"
|
||||||
|
|
||||||
|
[[ProjectFolder.Items.Items]]
|
||||||
|
Type = "IgnoreSource"
|
||||||
|
Name = "Vector3.bf"
|
||||||
|
|
||||||
|
[[ProjectFolder.Items.Items]]
|
||||||
|
Type = "IgnoreSource"
|
||||||
|
Name = "Vector4.bf"
|
||||||
|
|
||||||
|
[[ProjectFolder.Items.Items]]
|
||||||
|
Type = "IgnoreFolder"
|
||||||
|
Name = "Vectors"
|
||||||
|
AutoInclude = true
|
||||||
|
|||||||
@@ -4,6 +4,9 @@ using GlitchyEngine.ImGui;
|
|||||||
using GlitchyEngine.Renderer;
|
using GlitchyEngine.Renderer;
|
||||||
using GlitchyEngine.Debug;
|
using GlitchyEngine.Debug;
|
||||||
using GlitchyEngine.Content;
|
using GlitchyEngine.Content;
|
||||||
|
using GlitchyEngine.Scripting;
|
||||||
|
using System.Collections;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace GlitchyEngine
|
namespace GlitchyEngine
|
||||||
{
|
{
|
||||||
@@ -27,6 +30,9 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
private IContentManager _contentManager;
|
private IContentManager _contentManager;
|
||||||
|
|
||||||
|
private append List<delegate void()> _jobQueue = .() ~ ClearAndDeleteItems!(_);
|
||||||
|
private append Monitor _jobQueueMutex = .();
|
||||||
|
|
||||||
public bool IsRunning => _running;
|
public bool IsRunning => _running;
|
||||||
public Window Window => _window;
|
public Window Window => _window;
|
||||||
|
|
||||||
@@ -36,9 +42,11 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
public GameTime GameTime => _gameTime;
|
public GameTime GameTime => _gameTime;
|
||||||
|
|
||||||
[Inline]
|
[Inline, Obsolete("Use Application.Instance instead.", false)]
|
||||||
public static Application Get() => s_Instance;
|
public static Application Get() => s_Instance;
|
||||||
|
|
||||||
|
public static Application Instance => s_Instance;
|
||||||
|
|
||||||
public Settings Settings {get; private set;} = new .() ~ delete _;
|
public Settings Settings {get; private set;} = new .() ~ delete _;
|
||||||
|
|
||||||
public this()
|
public this()
|
||||||
@@ -68,6 +76,7 @@ namespace GlitchyEngine
|
|||||||
RenderCommand.RendererAPI = _rendererApi;
|
RenderCommand.RendererAPI = _rendererApi;
|
||||||
|
|
||||||
Renderer.Init();
|
Renderer.Init();
|
||||||
|
ScriptEngine.Init();
|
||||||
|
|
||||||
#if IMGUI
|
#if IMGUI
|
||||||
_imGuiLayer = new ImGuiLayer();
|
_imGuiLayer = new ImGuiLayer();
|
||||||
@@ -90,6 +99,7 @@ namespace GlitchyEngine
|
|||||||
Profiler.ProfileFunction!();
|
Profiler.ProfileFunction!();
|
||||||
|
|
||||||
SamplerStateManager.Uninit();
|
SamplerStateManager.Uninit();
|
||||||
|
|
||||||
Renderer.Deinit();
|
Renderer.Deinit();
|
||||||
|
|
||||||
delete _contentManager;
|
delete _contentManager;
|
||||||
@@ -99,6 +109,8 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
delete _gameTime;
|
delete _gameTime;
|
||||||
delete _layerStack;
|
delete _layerStack;
|
||||||
|
|
||||||
|
ScriptEngine.Shutdown();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnEvent(Event e)
|
public void OnEvent(Event e)
|
||||||
@@ -152,6 +164,8 @@ namespace GlitchyEngine
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
RunJobs();
|
||||||
|
|
||||||
if(allowFrame && !_isMinimized)
|
if(allowFrame && !_isMinimized)
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileScope!("Update Layers");
|
Debug.Profiler.ProfileScope!("Update Layers");
|
||||||
@@ -213,5 +227,29 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Executes the given Job on the main thread. Takes ownership of the delegate.
|
||||||
|
public void InvokeOnMainThread(delegate void() ownJob)
|
||||||
|
{
|
||||||
|
using (_jobQueueMutex.Enter())
|
||||||
|
{
|
||||||
|
_jobQueue.Add(ownJob);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RunJobs()
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileFunction!();
|
||||||
|
|
||||||
|
using (_jobQueueMutex.Enter())
|
||||||
|
{
|
||||||
|
for (let job in _jobQueue)
|
||||||
|
{
|
||||||
|
job();
|
||||||
|
}
|
||||||
|
|
||||||
|
ClearAndDeleteItems!(_jobQueue);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,6 +56,62 @@ namespace GlitchyEngine.Collections
|
|||||||
{
|
{
|
||||||
return ref node.Value;
|
return ref node.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public delegate void ElementFunc(TreeNode<T> currentNode);
|
||||||
|
|
||||||
|
public enum IterationMode
|
||||||
|
{
|
||||||
|
BreadthFirst,
|
||||||
|
DepthFirst
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForEach(ElementFunc func, IterationMode iterationMode = .DepthFirst)
|
||||||
|
{
|
||||||
|
if (iterationMode == .BreadthFirst)
|
||||||
|
{
|
||||||
|
ForEach_BreadthFirst(func);
|
||||||
|
}
|
||||||
|
else if (iterationMode == .DepthFirst)
|
||||||
|
{
|
||||||
|
ForEach_DepthFirst(func);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForEach_BreadthFirst(ElementFunc func)
|
||||||
|
{
|
||||||
|
Queue<TreeNode<T>> nodes = scope .();
|
||||||
|
nodes.Add(this);
|
||||||
|
|
||||||
|
while (!nodes.IsEmpty)
|
||||||
|
{
|
||||||
|
TreeNode<T> node = nodes.PopFront();
|
||||||
|
|
||||||
|
func(node);
|
||||||
|
|
||||||
|
for (var child in node.Children)
|
||||||
|
{
|
||||||
|
nodes.Add(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ForEach_DepthFirst(ElementFunc func)
|
||||||
|
{
|
||||||
|
List<TreeNode<T>> nodes = scope .();
|
||||||
|
nodes.Add(this);
|
||||||
|
|
||||||
|
while (!nodes.IsEmpty)
|
||||||
|
{
|
||||||
|
TreeNode<T> node = nodes.PopBack();
|
||||||
|
|
||||||
|
func(node);
|
||||||
|
|
||||||
|
for (var child in node.Children)
|
||||||
|
{
|
||||||
|
nodes.Add(child);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static
|
static
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ struct AssetHandle : IHashable
|
|||||||
public bool IsValid => this != .Invalid;
|
public bool IsValid => this != .Invalid;
|
||||||
public bool IsInvalid => this == .Invalid;
|
public bool IsInvalid => this == .Invalid;
|
||||||
|
|
||||||
|
public UUID ID => _uuid;
|
||||||
|
|
||||||
/// Create a new random AssetHandle
|
/// Create a new random AssetHandle
|
||||||
public this()
|
public this()
|
||||||
{
|
{
|
||||||
@@ -73,6 +75,11 @@ struct AssetHandle : IHashable
|
|||||||
|
|
||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ToString(String strBuffer)
|
||||||
|
{
|
||||||
|
_uuid.ToString(strBuffer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AssetHandle<T> where T : Asset
|
struct AssetHandle<T> where T : Asset
|
||||||
|
|||||||
@@ -367,15 +367,15 @@ namespace GlitchyEngine.Content
|
|||||||
|
|
||||||
Log.EngineLogger.AssertDebug(positions != null, "The model appears to have no position data?!");
|
Log.EngineLogger.AssertDebug(positions != null, "The model appears to have no position data?!");
|
||||||
|
|
||||||
Vector3[] normals = new Vector3[positions.Count];
|
float3[] normals = new float3[positions.Count];
|
||||||
|
|
||||||
if(primitive.Indices != null)
|
if(primitive.Indices != null)
|
||||||
GenerateNormals(primitive.Indices, positions, normals);
|
GenerateNormals(primitive.Indices, positions, normals);
|
||||||
else
|
else
|
||||||
GenerateNormals(positions, normals);
|
GenerateNormals(positions, normals);
|
||||||
|
|
||||||
VertexBuffer vertexBuffer = new VertexBuffer((uint32)sizeof(Vector3), (uint32)normals.Count, .Immutable);
|
VertexBuffer vertexBuffer = new VertexBuffer((uint32)sizeof(float3), (uint32)normals.Count, .Immutable);
|
||||||
vertexBuffer.SetData<Vector3>(normals);
|
vertexBuffer.SetData<float3>(normals);
|
||||||
|
|
||||||
bindings.Add(vertexBuffer.Binding);
|
bindings.Add(vertexBuffer.Binding);
|
||||||
|
|
||||||
@@ -405,20 +405,20 @@ namespace GlitchyEngine.Content
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generates the normals for one triangle
|
/// Generates the normals for one triangle
|
||||||
static mixin GenerateTriangleNormals(int index0, int index1, int index2, CGLTF.Accessor* positions, Vector3[] normals)
|
static mixin GenerateTriangleNormals(int index0, int index1, int index2, CGLTF.Accessor* positions, float3[] normals)
|
||||||
{
|
{
|
||||||
Vector3 position0 = GetEntry<Vector3>(positions, (.)index0);
|
float3 position0 = GetEntry<float3>(positions, (.)index0);
|
||||||
Vector3 position1 = GetEntry<Vector3>(positions, (.)index1);
|
float3 position1 = GetEntry<float3>(positions, (.)index1);
|
||||||
Vector3 position2 = GetEntry<Vector3>(positions, (.)index2);
|
float3 position2 = GetEntry<float3>(positions, (.)index2);
|
||||||
|
|
||||||
ref Vector3 normal0 = ref normals[(.)index0];
|
ref float3 normal0 = ref normals[(.)index0];
|
||||||
ref Vector3 normal1 = ref normals[(.)index1];
|
ref float3 normal1 = ref normals[(.)index1];
|
||||||
ref Vector3 normal2 = ref normals[(.)index2];
|
ref float3 normal2 = ref normals[(.)index2];
|
||||||
|
|
||||||
Vector3 e0 = position1 - position0;
|
float3 e0 = position1 - position0;
|
||||||
Vector3 e1 = position2 - position0;
|
float3 e1 = position2 - position0;
|
||||||
|
|
||||||
Vector3 normal = Vector3.Cross(e0, e1);
|
float3 normal = cross(e0, e1);
|
||||||
|
|
||||||
normal0 += normal;
|
normal0 += normal;
|
||||||
normal1 += normal;
|
normal1 += normal;
|
||||||
@@ -426,16 +426,16 @@ namespace GlitchyEngine.Content
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
static void NormalizeNormals(Vector3[] normals)
|
static void NormalizeNormals(float3[] normals)
|
||||||
{
|
{
|
||||||
for(int i < normals.Count)
|
for(int i < normals.Count)
|
||||||
{
|
{
|
||||||
normals[i].Normalize();
|
normalize(normals[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Generates normals for the given model using indexed geometry
|
/// Generates normals for the given model using indexed geometry
|
||||||
static void GenerateNormals(CGLTF.Accessor* indices, CGLTF.Accessor* positions, Vector3[] normals)
|
static void GenerateNormals(CGLTF.Accessor* indices, CGLTF.Accessor* positions, float3[] normals)
|
||||||
{
|
{
|
||||||
/// Enumerate triangle-wise
|
/// Enumerate triangle-wise
|
||||||
for(uint t = 0; t < indices.Count; t += 3)
|
for(uint t = 0; t < indices.Count; t += 3)
|
||||||
@@ -451,7 +451,7 @@ namespace GlitchyEngine.Content
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Generates normals for the given model using nonindexed geometry
|
/// Generates normals for the given model using nonindexed geometry
|
||||||
static void GenerateNormals(CGLTF.Accessor* positions, Vector3[] normals)
|
static void GenerateNormals(CGLTF.Accessor* positions, float3[] normals)
|
||||||
{
|
{
|
||||||
/// Enumerate triangle-wise
|
/// Enumerate triangle-wise
|
||||||
for(int i = 0; i < (.)positions.Count; i += 3)
|
for(int i = 0; i < (.)positions.Count; i += 3)
|
||||||
@@ -554,7 +554,7 @@ namespace GlitchyEngine.Content
|
|||||||
for(int i < samples)
|
for(int i < samples)
|
||||||
{
|
{
|
||||||
float timeStamp = GetEntry<float>(channel.Sampler.Input, i);
|
float timeStamp = GetEntry<float>(channel.Sampler.Input, i);
|
||||||
Vector3 sample = GetEntry<Vector3>(channel.Sampler.Output, i);
|
float3 sample = GetEntry<float3>(channel.Sampler.Output, i);
|
||||||
|
|
||||||
jointAnimation.TranslationChannel.TimeStamps[i] = timeStamp;
|
jointAnimation.TranslationChannel.TimeStamps[i] = timeStamp;
|
||||||
jointAnimation.TranslationChannel.Values[i] = sample;
|
jointAnimation.TranslationChannel.Values[i] = sample;
|
||||||
@@ -582,7 +582,7 @@ namespace GlitchyEngine.Content
|
|||||||
for(int i < samples)
|
for(int i < samples)
|
||||||
{
|
{
|
||||||
float timeStamp = GetEntry<float>(channel.Sampler.Input, i);
|
float timeStamp = GetEntry<float>(channel.Sampler.Input, i);
|
||||||
Vector3 sample = GetEntry<Vector3>(channel.Sampler.Output, i);
|
float3 sample = GetEntry<float3>(channel.Sampler.Output, i);
|
||||||
|
|
||||||
jointAnimation.ScaleChannel.TimeStamps[i] = timeStamp;
|
jointAnimation.ScaleChannel.TimeStamps[i] = timeStamp;
|
||||||
jointAnimation.ScaleChannel.Values[i] = sample;
|
jointAnimation.ScaleChannel.Values[i] = sample;
|
||||||
@@ -606,11 +606,11 @@ namespace GlitchyEngine.Content
|
|||||||
{
|
{
|
||||||
case typeof(float):
|
case typeof(float):
|
||||||
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 1);
|
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 1);
|
||||||
case typeof(Vector2):
|
case typeof(float2):
|
||||||
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 2);
|
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 2);
|
||||||
case typeof(Vector3):
|
case typeof(float3):
|
||||||
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 3);
|
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 3);
|
||||||
case typeof(Vector4), typeof(Quaternion):
|
case typeof(float4), typeof(Quaternion):
|
||||||
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 4);
|
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 4);
|
||||||
case typeof(Matrix):
|
case typeof(Matrix):
|
||||||
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 16);
|
CGLTF.AccessorReadFloat(accessor, (uint)index, (float*)&result, 16);
|
||||||
|
|||||||
@@ -36,6 +36,11 @@ namespace GlitchyEngine.Core
|
|||||||
return (int)_uuid;
|
return (int)_uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override void ToString(String strBuffer)
|
||||||
|
{
|
||||||
|
_uuid.ToString(strBuffer);
|
||||||
|
}
|
||||||
|
|
||||||
static void Serialize(BonWriter writer, ValueView val, BonEnvironment env, SerializeValueState state)
|
static void Serialize(BonWriter writer, ValueView val, BonEnvironment env, SerializeValueState state)
|
||||||
{
|
{
|
||||||
UUID uuid = *(UUID*)val.dataPtr;
|
UUID uuid = *(UUID*)val.dataPtr;
|
||||||
|
|||||||
@@ -98,5 +98,16 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
_frameCount++;
|
_frameCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tells the timer that a frame has passed and updates the counters according to the given time step.
|
||||||
|
*/
|
||||||
|
public void ManualStepFrame(float deltaTimeSeconds)
|
||||||
|
{
|
||||||
|
_frameTime = TimeSpan.FromSeconds(deltaTimeSeconds);
|
||||||
|
_totalTime += _frameTime;
|
||||||
|
|
||||||
|
_frameCount++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
using DirectX.Common;
|
using DirectX.Common;
|
||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
|
using System.Collections;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace GlitchyEngine
|
namespace GlitchyEngine
|
||||||
{
|
{
|
||||||
@@ -14,6 +16,15 @@ namespace GlitchyEngine
|
|||||||
oldDest?.ReleaseRef();
|
oldDest?.ReleaseRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Releases the reference to destination, writes newValue into it and adds a reference to newValue.
|
||||||
|
public static mixin SetReferenceVar<T>(T destination, T newValue) where T: var
|
||||||
|
{
|
||||||
|
var oldDest = destination;
|
||||||
|
destination = newValue;
|
||||||
|
destination?.AddRef();
|
||||||
|
oldDest?.Release();
|
||||||
|
}
|
||||||
|
|
||||||
/// Releases the reference to value and nullifies it.
|
/// Releases the reference to value and nullifies it.
|
||||||
public static mixin ReleaseRefAndNullify<T>(T value) where T: RefCounter
|
public static mixin ReleaseRefAndNullify<T>(T value) where T: RefCounter
|
||||||
{
|
{
|
||||||
@@ -37,5 +48,50 @@ namespace GlitchyEngine
|
|||||||
value?.ReleaseRef();
|
value?.ReleaseRef();
|
||||||
container.Clear();
|
container.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static mixin DeleteDictionaryAndReleaseValues(var container)
|
||||||
|
{
|
||||||
|
if (container != null)
|
||||||
|
{
|
||||||
|
for (var value in container)
|
||||||
|
{
|
||||||
|
value.value?.ReleaseRef();
|
||||||
|
}
|
||||||
|
delete container;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static mixin ClearDictionaryAndDeleteKeys(var dictionary)
|
||||||
|
{
|
||||||
|
if (dictionary != null)
|
||||||
|
{
|
||||||
|
for (var value in dictionary)
|
||||||
|
delete value.key;
|
||||||
|
delete dictionary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static mixin ClearDictionaryAndDeleteValues(var dictionary)
|
||||||
|
{
|
||||||
|
if (dictionary != null)
|
||||||
|
{
|
||||||
|
for (var value in dictionary)
|
||||||
|
delete value.value;
|
||||||
|
delete dictionary;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static mixin ClearDictionaryAndDeleteKeysAndValues(var dictionary)
|
||||||
|
{
|
||||||
|
if (dictionary != null)
|
||||||
|
{
|
||||||
|
for (var value in dictionary)
|
||||||
|
{
|
||||||
|
delete value.key;
|
||||||
|
delete value.value;
|
||||||
|
}
|
||||||
|
delete dictionary;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace GlitchyEngine.Math
|
|||||||
{
|
{
|
||||||
extension ColorRGBA
|
extension ColorRGBA
|
||||||
{
|
{
|
||||||
internal uint32 ImGuiU32 => ImGui.ImGui.ColorConvertFloat4ToU32((.)(Vector4)this);
|
internal uint32 ImGuiU32 => ImGui.ImGui.ColorConvertFloat4ToU32((.)(float4)this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -20,14 +20,14 @@ namespace ImGui
|
|||||||
{
|
{
|
||||||
extension Vec2
|
extension Vec2
|
||||||
{
|
{
|
||||||
public static explicit operator Vector2(Vec2 v) => .(v.x, v.y);
|
public static explicit operator float2(Vec2 v) => .(v.x, v.y);
|
||||||
public static explicit operator Vec2(Vector2 v) => .(v.X, v.Y);
|
public static explicit operator Vec2(float2 v) => .(v.X, v.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Vec4
|
extension Vec4
|
||||||
{
|
{
|
||||||
public static explicit operator Vector4(Vec4 v) => .(v.x, v.y, v.z, v.w);
|
public static explicit operator float4(Vec4 v) => .(v.x, v.y, v.z, v.w);
|
||||||
public static explicit operator Vec4(Vector4 v) => .(v.X, v.Y, v.Z, v.W);
|
public static explicit operator Vec4(float4 v) => .(v.X, v.Y, v.Z, v.W);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*public static bool IsItemJustDeactivated()
|
/*public static bool IsItemJustDeactivated()
|
||||||
@@ -75,7 +75,7 @@ namespace ImGui
|
|||||||
if (uv0 != .Zero || uv1 != .Ones)
|
if (uv0 != .Zero || uv1 != .Ones)
|
||||||
Runtime.NotImplemented();
|
Runtime.NotImplemented();
|
||||||
|
|
||||||
Vector2 v = (.)subTexture.TexCoords.XY + subTexture.TexCoords.ZW;
|
float2 v = (.)subTexture.TexCoords.XY + subTexture.TexCoords.ZW;
|
||||||
|
|
||||||
Image(subTexture.Texture.GetViewBinding(), size, (.)subTexture.TexCoords.XY, (.)v, tint_col, border_col);
|
Image(subTexture.Texture.GetViewBinding(), size, (.)subTexture.TexCoords.XY, (.)v, tint_col, border_col);
|
||||||
}
|
}
|
||||||
@@ -92,7 +92,7 @@ namespace ImGui
|
|||||||
if (uv0 != .Zero || uv1 != .Ones)
|
if (uv0 != .Zero || uv1 != .Ones)
|
||||||
Runtime.NotImplemented();
|
Runtime.NotImplemented();
|
||||||
|
|
||||||
Vector2 v = (.)subTexture.TexCoords.XY + subTexture.TexCoords.ZW;
|
float2 v = (.)subTexture.TexCoords.XY + subTexture.TexCoords.ZW;
|
||||||
|
|
||||||
return ImageButton(subTexture.Texture.GetViewBinding(), size, (.)subTexture.TexCoords.XY, (.)v, frame_padding, bg_col, tint_col);
|
return ImageButton(subTexture.Texture.GetViewBinding(), size, (.)subTexture.TexCoords.XY, (.)v, frame_padding, bg_col, tint_col);
|
||||||
}
|
}
|
||||||
@@ -107,19 +107,19 @@ namespace ImGui
|
|||||||
protected internal static extern void CleanupFrame();
|
protected internal static extern void CleanupFrame();
|
||||||
|
|
||||||
/// Control to edit a vector 2 with drag functionality and reset buttons
|
/// Control to edit a vector 2 with drag functionality and reset buttons
|
||||||
public static bool EditVector2(StringView label, ref Vector2 value, Vector2 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, Vector2 minValue = .Zero, Vector2 maxValue = .Zero)
|
public static bool Editfloat2(StringView label, ref float2 value, float2 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float2 minValue = .Zero, float2 maxValue = .Zero)
|
||||||
{
|
{
|
||||||
return EditVector<2>(label, ref *(float[2]*)&value, (float[2])resetValues, dragSpeed, columnWidth, (float[2])minValue, (float[2])maxValue);
|
return EditVector<2>(label, ref *(float[2]*)&value, (float[2])resetValues, dragSpeed, columnWidth, (float[2])minValue, (float[2])maxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Control to edit a vector 3 with drag functionality and reset buttons
|
/// Control to edit a vector 3 with drag functionality and reset buttons
|
||||||
public static bool EditVector3(StringView label, ref Vector3 value, Vector3 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, Vector3 minValue = .Zero, Vector3 maxValue = .Zero)
|
public static bool Editfloat3(StringView label, ref float3 value, float3 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float3 minValue = .Zero, float3 maxValue = .Zero)
|
||||||
{
|
{
|
||||||
return EditVector<3>(label, ref *(float[3]*)&value, (float[3])resetValues, dragSpeed, columnWidth, (float[3])minValue, (float[3])maxValue);
|
return EditVector<3>(label, ref *(float[3]*)&value, (float[3])resetValues, dragSpeed, columnWidth, (float[3])minValue, (float[3])maxValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Control to edit a vector 4 with drag functionality and reset buttons
|
/// Control to edit a vector 4 with drag functionality and reset buttons
|
||||||
public static bool EditVector4(StringView label, ref Vector4 value, Vector4 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, Vector4 minValue = .Zero, Vector4 maxValue = .Zero)
|
public static bool Editfloat4(StringView label, ref float4 value, float4 resetValues = .Zero, float dragSpeed = 0.1f, float columnWidth = 100f, float4 minValue = .Zero, float4 maxValue = .Zero)
|
||||||
{
|
{
|
||||||
return EditVector<4>(label, ref *(float[4]*)&value, (float[4])resetValues, dragSpeed, columnWidth, (float[4])minValue, (float[4])maxValue);
|
return EditVector<4>(label, ref *(float[4]*)&value, (float[4])resetValues, dragSpeed, columnWidth, (float[4])minValue, (float[4])maxValue);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -119,8 +119,6 @@ namespace GlitchyEngine.ImGui
|
|||||||
|
|
||||||
Begin();
|
Begin();
|
||||||
|
|
||||||
ImGui.ShowDemoWindow();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileScope!("ImGuiRenderEvent");
|
Debug.Profiler.ProfileScope!("ImGuiRenderEvent");
|
||||||
|
|
||||||
@@ -142,7 +140,11 @@ namespace GlitchyEngine.ImGui
|
|||||||
RenderCommand.BindRenderTargets();
|
RenderCommand.BindRenderTargets();
|
||||||
|
|
||||||
#if GE_GRAPHICS_DX11
|
#if GE_GRAPHICS_DX11
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
ImGuiImplDX11.RenderDrawData(ImGui.GetDrawData());
|
ImGuiImplDX11.RenderDrawData(ImGui.GetDrawData());
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
ImGui.CleanupFrame();
|
ImGui.CleanupFrame();
|
||||||
|
|||||||
+10
-10
@@ -28,15 +28,15 @@ namespace GlitchyEngine
|
|||||||
public static extern bool IsKeyReleasing(Key keycode);
|
public static extern bool IsKeyReleasing(Key keycode);
|
||||||
|
|
||||||
// TODO: Should Input be able to set mousepos?
|
// TODO: Should Input be able to set mousepos?
|
||||||
public static extern void SetMousePosition(Int2 pos);
|
public static extern void SetMousePosition(int2 pos);
|
||||||
|
|
||||||
public static extern bool IsMouseButtonPressed(MouseButton button);
|
public static extern bool IsMouseButtonPressed(MouseButton button);
|
||||||
public static extern bool IsMouseButtonReleased(MouseButton button);
|
public static extern bool IsMouseButtonReleased(MouseButton button);
|
||||||
public static extern bool IsMouseButtonPressing(MouseButton button);
|
public static extern bool IsMouseButtonPressing(MouseButton button);
|
||||||
public static extern bool IsMouseButtonReleasing(MouseButton button);
|
public static extern bool IsMouseButtonReleasing(MouseButton button);
|
||||||
public static extern Int2 GetMousePosition();
|
public static extern int2 GetMousePosition();
|
||||||
public static extern Int2 GetMouseMovement();
|
public static extern int2 GetMouseMovement();
|
||||||
public static extern Int2 GetRawMouseMovement();
|
public static extern int2 GetRawMouseMovement();
|
||||||
public static extern int32 GetMouseX();
|
public static extern int32 GetMouseX();
|
||||||
public static extern int32 GetMouseY();
|
public static extern int32 GetMouseY();
|
||||||
|
|
||||||
@@ -44,9 +44,9 @@ namespace GlitchyEngine
|
|||||||
// public static extern bool WasMouseButtonPressing(MouseButton button);
|
// public static extern bool WasMouseButtonPressing(MouseButton button);
|
||||||
public static extern bool WasMouseButtonReleased(MouseButton button);
|
public static extern bool WasMouseButtonReleased(MouseButton button);
|
||||||
//public static extern bool WasMouseButtonReleasing(MouseButton button);
|
//public static extern bool WasMouseButtonReleasing(MouseButton button);
|
||||||
public static extern Int2 GetLastMousePosition();
|
public static extern int2 GetLastMousePosition();
|
||||||
public static extern Int2 GetLastMouseMovement();
|
public static extern int2 GetLastMouseMovement();
|
||||||
public static extern Int2 GetLastRawMouseMovement();
|
public static extern int2 GetLastRawMouseMovement();
|
||||||
public static extern int32 GetLastMouseX();
|
public static extern int32 GetLastMouseX();
|
||||||
public static extern int32 GetLastMouseY();
|
public static extern int32 GetLastMouseY();
|
||||||
|
|
||||||
@@ -121,14 +121,14 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
public static class Mouse
|
public static class Mouse
|
||||||
{
|
{
|
||||||
private static append List<(Int2 Position, int Hash)> _lockPositions = .();
|
private static append List<(int2 Position, int Hash)> _lockPositions = .();
|
||||||
|
|
||||||
public static void LockCurrentPosition(int hash)
|
public static void LockCurrentPosition(int hash)
|
||||||
{
|
{
|
||||||
LockPosition(Input.GetMousePosition(), hash);
|
LockPosition(Input.GetMousePosition(), hash);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void LockPosition(Int2 pos, int hash)
|
public static void LockPosition(int2 pos, int hash)
|
||||||
{
|
{
|
||||||
for (var entry in _lockPositions)
|
for (var entry in _lockPositions)
|
||||||
{
|
{
|
||||||
@@ -156,7 +156,7 @@ namespace GlitchyEngine
|
|||||||
//Log.EngineLogger.AssertDebug(false, "No mouse lock position with hash found.");
|
//Log.EngineLogger.AssertDebug(false, "No mouse lock position with hash found.");
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Int2? LockedPosition;
|
public static int2? LockedPosition;
|
||||||
|
|
||||||
public static void NewFrame()
|
public static void NewFrame()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -53,10 +53,10 @@ namespace GlitchyEngine.Math
|
|||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
#unwarn
|
#unwarn
|
||||||
public static explicit operator Vector3(ColorRGB color) => *(Vector3*)&color;
|
public static explicit operator float3(ColorRGB color) => *(float3*)&color;
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
#unwarn
|
#unwarn
|
||||||
public static explicit operator ColorRGB(Vector3 color) => *(ColorRGB*)&color;
|
public static explicit operator ColorRGB(float3 color) => *(ColorRGB*)&color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -329,10 +329,10 @@ namespace GlitchyEngine.Math
|
|||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
#unwarn
|
#unwarn
|
||||||
public static explicit operator Vector4(ColorRGBA color) => *(Vector4*)&color;
|
public static explicit operator float4(ColorRGBA color) => *(float4*)&color;
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
#unwarn
|
#unwarn
|
||||||
public static explicit operator ColorRGBA(Vector4 color) => *(ColorRGBA*)&color;
|
public static explicit operator ColorRGBA(float4 color) => *(ColorRGBA*)&color;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ namespace System
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public Vector2 XX => Vector2((float)this);
|
public float2 XX => (float2)this;
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public Vector3 XXX => Vector3((float)this);
|
public float3 XXX => (float3)this;
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public Vector4 XXXX => Vector4((float)this);
|
public float4 XXXX => (float4)this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,12 +13,32 @@ namespace System
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public Int2 XX => Int2((int32)this);
|
public int2 XX => (int32)this;
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public Int3 XXX => Int3((int32)this);
|
public int3 XXX => (int32)this;
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
public Int4 XXXX => Int4((int32)this);
|
public int4 XXXX => (int32)this;
|
||||||
|
}
|
||||||
|
|
||||||
|
extension UInt32
|
||||||
|
{
|
||||||
|
public uint32 X
|
||||||
|
{
|
||||||
|
[Inline]
|
||||||
|
get => (uint32)this;
|
||||||
|
[Inline]
|
||||||
|
set mut => this = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public uint2 XX => (uint32)this;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public uint3 XXX => (uint32)this;
|
||||||
|
|
||||||
|
[Inline]
|
||||||
|
public uint4 XXXX => (uint32)this;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,831 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math;
|
||||||
|
|
||||||
|
// TODO: Not all functions are available for scalars yet
|
||||||
|
|
||||||
|
static
|
||||||
|
{
|
||||||
|
/// Returns true if at least one of the components is true.
|
||||||
|
public static bool any(bool value) => value;
|
||||||
|
/// Returns true if at least one of the components is true.
|
||||||
|
public static bool any(bool2 value) => value.X || value.Y;
|
||||||
|
/// Returns true if at least one of the components is true.
|
||||||
|
public static bool any(bool3 value) => value.X || value.Y || value.Z;
|
||||||
|
/// Returns true if at least one of the components is true.
|
||||||
|
public static bool any(bool4 value) => value.X || value.Y || value.Z || value.W;
|
||||||
|
|
||||||
|
/// Returns true if all of the components are true.
|
||||||
|
public static bool all(bool value) => value;
|
||||||
|
/// Returns true if all of the components are true.
|
||||||
|
public static bool all(bool2 value) => value.X && value.Y;
|
||||||
|
/// Returns true if all of the components are true.
|
||||||
|
public static bool all(bool3 value) => value.X && value.Y && value.Z;
|
||||||
|
/// Returns true if all of the components are true.
|
||||||
|
public static bool all(bool4 value) => value.X && value.Y && value.Z && value.W;
|
||||||
|
|
||||||
|
#region abs
|
||||||
|
|
||||||
|
public static float abs(float value)
|
||||||
|
{
|
||||||
|
return Math.Abs(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float2 abs(float2 value)
|
||||||
|
{
|
||||||
|
return float2(Math.Abs(value.X), Math.Abs(value.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float3 abs(float3 value)
|
||||||
|
{
|
||||||
|
return float3(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float4 abs(float4 value)
|
||||||
|
{
|
||||||
|
return float4(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z), Math.Abs(value.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int abs(int value)
|
||||||
|
{
|
||||||
|
return Math.Abs(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int2 abs(int2 value)
|
||||||
|
{
|
||||||
|
return int2(Math.Abs(value.X), Math.Abs(value.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int3 abs(int3 value)
|
||||||
|
{
|
||||||
|
return int3(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int4 abs(int4 value)
|
||||||
|
{
|
||||||
|
return int4(Math.Abs(value.X), Math.Abs(value.Y), Math.Abs(value.Z), Math.Abs(value.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region modf / frac / trunc
|
||||||
|
|
||||||
|
// Splits the value x into fractional and integer parts, each of which has the same sign as x.
|
||||||
|
public static float modf(float x, out float integerPart)
|
||||||
|
{
|
||||||
|
return Math.[Friend]modff(x.X, out integerPart);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Splits the value x into fractional and integer parts, each of which has the same sign as x.
|
||||||
|
public static float2 modf(float2 x, out float2 integerPart)
|
||||||
|
{
|
||||||
|
float2 fracPart;
|
||||||
|
|
||||||
|
fracPart.X = Math.[Friend]modff(x.X, out integerPart.X);
|
||||||
|
fracPart.Y = Math.[Friend]modff(x.Y, out integerPart.Y);
|
||||||
|
|
||||||
|
return fracPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Splits the value x into fractional and integer parts, each of which has the same sign as x.
|
||||||
|
public static float3 modf(float3 x, out float3 integerPart)
|
||||||
|
{
|
||||||
|
float3 fracPart;
|
||||||
|
|
||||||
|
fracPart.X = Math.[Friend]modff(x.X, out integerPart.X);
|
||||||
|
fracPart.Y = Math.[Friend]modff(x.Y, out integerPart.Y);
|
||||||
|
fracPart.Z = Math.[Friend]modff(x.Z, out integerPart.Z);
|
||||||
|
|
||||||
|
return fracPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Splits the value x into fractional and integer parts, each of which has the same sign as x.
|
||||||
|
public static float4 modf(float4 x, out float4 integerPart)
|
||||||
|
{
|
||||||
|
float4 fracPart;
|
||||||
|
|
||||||
|
fracPart.X = Math.[Friend]modff(x.X, out integerPart.X);
|
||||||
|
fracPart.Y = Math.[Friend]modff(x.Y, out integerPart.Y);
|
||||||
|
fracPart.Z = Math.[Friend]modff(x.Z, out integerPart.Z);
|
||||||
|
fracPart.W = Math.[Friend]modff(x.W, out integerPart.W);
|
||||||
|
|
||||||
|
return fracPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Returns the fractional (or decimal) part of x; which is greater than or equal to 0 and less than 1.
|
||||||
|
public static float2 frac(float2 x) => [Inline]modf(x, let _);
|
||||||
|
|
||||||
|
// Returns the fractional (or decimal) part of x; which is greater than or equal to 0 and less than 1.
|
||||||
|
public static float3 frac(float3 x) => [Inline]modf(x, let _);
|
||||||
|
|
||||||
|
// Returns the fractional (or decimal) part of x; which is greater than or equal to 0 and less than 1.
|
||||||
|
public static float4 frac(float4 x) => [Inline]modf(x, let _);
|
||||||
|
|
||||||
|
|
||||||
|
// Truncates a floating-point value to the integer component.
|
||||||
|
public static float2 trunc(float2 x)
|
||||||
|
{
|
||||||
|
return float2(Math.Truncate(x.X), Math.Truncate(x.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncates a floating-point value to the integer component.
|
||||||
|
public static float3 trunc(float3 x)
|
||||||
|
{
|
||||||
|
return float3(Math.Truncate(x.X), Math.Truncate(x.Y), Math.Truncate(x.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Truncates a floating-point value to the integer component.
|
||||||
|
public static float4 trunc(float4 x)
|
||||||
|
{
|
||||||
|
return float4(Math.Truncate(x.X), Math.Truncate(x.Y), Math.Truncate(x.Z), Math.Truncate(x.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region infinity and nan check
|
||||||
|
|
||||||
|
/// Determines if the specified floating-point value is finite.
|
||||||
|
public static bool2 isfinite(float2 value)
|
||||||
|
{
|
||||||
|
return bool2(value.X.IsFinite, value.Y.IsFinite);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines if the specified floating-point value is finite.
|
||||||
|
public static bool3 isfinite(float3 value)
|
||||||
|
{
|
||||||
|
return bool3(value.X.IsFinite, value.Y.IsFinite, value.Z.IsFinite);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines if the specified floating-point value is finite.
|
||||||
|
public static bool4 isfinite(float4 value)
|
||||||
|
{
|
||||||
|
return bool4(value.X.IsFinite, value.Y.IsFinite, value.Z.IsFinite, value.W.IsFinite);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines if the specified value is infinite.
|
||||||
|
public static bool2 isinf(float2 value)
|
||||||
|
{
|
||||||
|
return bool2(value.X.IsInfinity, value.Y.IsInfinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines if the specified value is infinite.
|
||||||
|
public static bool3 isinf(float3 value)
|
||||||
|
{
|
||||||
|
return bool3(value.X.IsInfinity, value.Y.IsInfinity, value.Z.IsInfinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines if the specified value is infinite.
|
||||||
|
public static bool4 isinf(float4 value)
|
||||||
|
{
|
||||||
|
return bool4(value.X.IsInfinity, value.Y.IsInfinity, value.Z.IsInfinity, value.W.IsInfinity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines if the specified value is infinite.
|
||||||
|
public static bool2 isnan(float2 value)
|
||||||
|
{
|
||||||
|
return bool2(value.X.IsNaN, value.Y.IsNaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines if the specified value is infinite.
|
||||||
|
public static bool3 isnan(float3 value)
|
||||||
|
{
|
||||||
|
return bool3(value.X.IsNaN, value.Y.IsNaN, value.Z.IsNaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Determines if the specified value is infinite.
|
||||||
|
public static bool4 isnan(float4 value)
|
||||||
|
{
|
||||||
|
return bool4(value.X.IsNaN, value.Y.IsNaN, value.Z.IsNaN, value.W.IsNaN);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Sign
|
||||||
|
|
||||||
|
/// Returns the sign of x.
|
||||||
|
public static int32 sign(float x)
|
||||||
|
{
|
||||||
|
return (int32)Math.Sign(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sign of x.
|
||||||
|
public static int2 sign(float2 x)
|
||||||
|
{
|
||||||
|
return int2((int32)Math.Sign(x.X), (int32)Math.Sign(x.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sign of x.
|
||||||
|
public static int3 sign(float3 x)
|
||||||
|
{
|
||||||
|
return int3((int32)Math.Sign(x.X), (int32)Math.Sign(x.Y), (int32)Math.Sign(x.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sign of x.
|
||||||
|
public static int4 sign(float4 x)
|
||||||
|
{
|
||||||
|
return int4((int32)Math.Sign(x.X), (int32)Math.Sign(x.Y), (int32)Math.Sign(x.Z), (int32)Math.Sign(x.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sign of x.
|
||||||
|
public static int32 sign(int x)
|
||||||
|
{
|
||||||
|
return (int32)Math.Sign(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sign of x.
|
||||||
|
public static int2 sign(int2 x)
|
||||||
|
{
|
||||||
|
return int2((int32)Math.Sign(x.X), (int32)Math.Sign(x.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sign of x.
|
||||||
|
public static int3 sign(int3 x)
|
||||||
|
{
|
||||||
|
return int3((int32)Math.Sign(x.X), (int32)Math.Sign(x.Y), (int32)Math.Sign(x.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the sign of x.
|
||||||
|
public static int4 sign(int4 x)
|
||||||
|
{
|
||||||
|
return int4((int32)Math.Sign(x.X), (int32)Math.Sign(x.Y), (int32)Math.Sign(x.Z), (int32)Math.Sign(x.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region ceil / floor / round
|
||||||
|
|
||||||
|
public static float ceil(float value)
|
||||||
|
{
|
||||||
|
return Math.Ceiling(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float2 ceil(float2 value)
|
||||||
|
{
|
||||||
|
return float2(Math.Ceiling(value.X), Math.Ceiling(value.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float3 ceil(float3 value)
|
||||||
|
{
|
||||||
|
return float3(Math.Ceiling(value.X), Math.Ceiling(value.Y), Math.Ceiling(value.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float4 ceil(float4 value)
|
||||||
|
{
|
||||||
|
return float4(Math.Ceiling(value.X), Math.Ceiling(value.Y), Math.Ceiling(value.Z), Math.Ceiling(value.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float floor(float value)
|
||||||
|
{
|
||||||
|
return Math.Floor(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float2 floor(float2 value)
|
||||||
|
{
|
||||||
|
return float2(Math.Floor(value.X), Math.Floor(value.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float3 floor(float3 value)
|
||||||
|
{
|
||||||
|
return float3(Math.Floor(value.X), Math.Floor(value.Y), Math.Floor(value.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float4 floor(float4 value)
|
||||||
|
{
|
||||||
|
return float4(Math.Floor(value.X), Math.Floor(value.Y), Math.Floor(value.Z), Math.Floor(value.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rounds the specified value to the nearest integer.
|
||||||
|
public static float round(float value)
|
||||||
|
{
|
||||||
|
return Math.Round(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rounds the specified value to the nearest integer.
|
||||||
|
public static float2 round(float2 value)
|
||||||
|
{
|
||||||
|
return float2(Math.Round(value.X), Math.Round(value.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rounds the specified value to the nearest integer.
|
||||||
|
public static float3 round(float3 value)
|
||||||
|
{
|
||||||
|
return float3(Math.Round(value.X), Math.Round(value.Y), Math.Round(value.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Rounds the specified value to the nearest integer.
|
||||||
|
public static float4 round(float4 value)
|
||||||
|
{
|
||||||
|
return float4(Math.Round(value.X), Math.Round(value.Y), Math.Round(value.Z), Math.Round(value.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region min / max
|
||||||
|
|
||||||
|
public static float min(float x, float y)
|
||||||
|
{
|
||||||
|
return Math.Min(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float2 min(float2 x, float2 y)
|
||||||
|
{
|
||||||
|
return float2(Math.Min(x.X, y.X), Math.Min(x.Y, y.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float3 min(float3 x, float3 y)
|
||||||
|
{
|
||||||
|
return float3(Math.Min(x.X, y.X), Math.Min(x.Y, y.Y), Math.Min(x.Z, y.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float4 min(float4 x, float4 y)
|
||||||
|
{
|
||||||
|
return float4(Math.Min(x.X, y.X), Math.Min(x.Y, y.Y), Math.Min(x.Z, y.Z), Math.Min(x.W, y.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float max(float x, float y)
|
||||||
|
{
|
||||||
|
return Math.Max(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float2 max(float2 x, float2 y)
|
||||||
|
{
|
||||||
|
return float2(Math.Max(x.X, y.X), Math.Max(x.Y, y.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float3 max(float3 x, float3 y)
|
||||||
|
{
|
||||||
|
return float3(Math.Max(x.X, y.X), Math.Max(x.Y, y.Y), Math.Max(x.Z, y.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float4 max(float4 x, float4 y)
|
||||||
|
{
|
||||||
|
return float4(Math.Max(x.X, y.X), Math.Max(x.Y, y.Y), Math.Max(x.Z, y.Z), Math.Max(x.W, y.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region exp, pow, log
|
||||||
|
|
||||||
|
// TODO: log, log10, log2
|
||||||
|
|
||||||
|
/// Returns x raised to the power of y.
|
||||||
|
public static float pow(float x, float y)
|
||||||
|
{
|
||||||
|
return Math.Pow(x, y);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns x raised to the power of y.
|
||||||
|
public static float2 pow(float2 x, float2 y)
|
||||||
|
{
|
||||||
|
return float2(Math.Pow(x.X, y.X), Math.Pow(x.Y, y.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns x raised to the power of y.
|
||||||
|
public static float3 pow(float3 x, float3 y)
|
||||||
|
{
|
||||||
|
return float3(Math.Pow(x.X, y.X), Math.Pow(x.Y, y.Y), Math.Pow(x.Z, y.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns x raised to the power of y.
|
||||||
|
public static float4 pow(float4 x, float4 y)
|
||||||
|
{
|
||||||
|
return float4(Math.Pow(x.X, y.X), Math.Pow(x.Y, y.Y), Math.Pow(x.Z, y.Z), Math.Pow(x.W, y.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base-e exponential, or e^x, of the specified value.
|
||||||
|
public static float exp(float x)
|
||||||
|
{
|
||||||
|
return Math.Exp(x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base-e exponential, or e^x, of the specified value.
|
||||||
|
public static float2 exp(float2 x)
|
||||||
|
{
|
||||||
|
return float2(Math.Exp(x.X), Math.Exp(x.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base-e exponential, or e^x, of the specified value.
|
||||||
|
public static float3 exp(float3 x)
|
||||||
|
{
|
||||||
|
return float3(Math.Exp(x.X), Math.Exp(x.Y), Math.Exp(x.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base-e exponential, or e^x, of the specified value.
|
||||||
|
public static float4 exp(float4 x)
|
||||||
|
{
|
||||||
|
return float4(Math.Exp(x.X), Math.Exp(x.Y), Math.Exp(x.Z), Math.Exp(x.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base 2 exponential, or 2^x, of the specified value.
|
||||||
|
public static float exp2(float x)
|
||||||
|
{
|
||||||
|
return Math.Pow(2, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base 2 exponential, or 2^x, of the specified value.
|
||||||
|
public static float2 exp2(float2 x)
|
||||||
|
{
|
||||||
|
return float2(Math.Pow(2, x.X), Math.Pow(2, x.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base 2 exponential, or 2^x, of the specified value.
|
||||||
|
public static float3 exp2(float3 x)
|
||||||
|
{
|
||||||
|
return float3(Math.Pow(2, x.X), Math.Pow(2, x.Y), Math.Pow(2, x.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the base 2 exponential, or 2^x, of the specified value.
|
||||||
|
public static float4 exp2(float4 x)
|
||||||
|
{
|
||||||
|
return float4(Math.Pow(2, x.X), Math.Pow(2, x.Y), Math.Pow(2, x.Z), Math.Pow(2, x.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Degrees / Radians
|
||||||
|
|
||||||
|
public static float toDegrees(float radians) => radians * MathHelper.RadToDeg;
|
||||||
|
public static float2 toDegrees(float2 radians) => radians * MathHelper.RadToDeg;
|
||||||
|
public static float3 toDegrees(float3 radians) => radians * MathHelper.RadToDeg;
|
||||||
|
public static float4 toDegrees(float4 radians) => radians * MathHelper.RadToDeg;
|
||||||
|
|
||||||
|
public static float toRadians(float degrees) => degrees * MathHelper.DegToRad;
|
||||||
|
public static float2 toRadians(float2 degrees) => degrees * MathHelper.DegToRad;
|
||||||
|
public static float3 toRadians(float3 degrees) => degrees * MathHelper.DegToRad;
|
||||||
|
public static float4 toRadians(float4 degrees) => degrees * MathHelper.DegToRad;
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Clamp
|
||||||
|
|
||||||
|
public static float clamp(float value, float min, float max)
|
||||||
|
{
|
||||||
|
return Math.Clamp(value.X, min.X, max.X);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float2 clamp(float2 value, float2 min, float2 max)
|
||||||
|
{
|
||||||
|
return float2(Math.Clamp(value.X, min.X, max.X), Math.Clamp(value.Y, min.Y, max.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float3 clamp(float3 value, float3 min, float3 max)
|
||||||
|
{
|
||||||
|
return float3(Math.Clamp(value.X, min.X, max.X), Math.Clamp(value.Y, min.Y, max.Y), Math.Clamp(value.Z, min.Z, max.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float4 clamp(float4 value, float4 min, float4 max)
|
||||||
|
{
|
||||||
|
return float4(Math.Clamp(value.X, min.X, max.X), Math.Clamp(value.Y, min.Y, max.Y), Math.Clamp(value.Z, min.Z, max.Z), Math.Clamp(value.W, min.W, max.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int2 clamp(int2 value, int2 min, int2 max)
|
||||||
|
{
|
||||||
|
return int2(Math.Clamp(value.X, min.X, max.X), Math.Clamp(value.Y, min.Y, max.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int3 clamp(int3 value, int3 min, int3 max)
|
||||||
|
{
|
||||||
|
return int3(Math.Clamp(value.X, min.X, max.X), Math.Clamp(value.Y, min.Y, max.Y), Math.Clamp(value.Z, min.Z, max.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int4 clamp(int4 value, int4 min, int4 max)
|
||||||
|
{
|
||||||
|
return int4(Math.Clamp(value.X, min.X, max.X), Math.Clamp(value.Y, min.Y, max.Y), Math.Clamp(value.Z, min.Z, max.Z), Math.Clamp(value.W, min.W, max.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Lerp
|
||||||
|
|
||||||
|
/// Performs a linear interpolation.
|
||||||
|
// @param x The first vector value.
|
||||||
|
// @param y The second vector value.
|
||||||
|
// @param y A value that linearly interpolates between x and y.
|
||||||
|
public static float lerp(float x, float y, float s)
|
||||||
|
{
|
||||||
|
return x + s * (y - x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs a linear interpolation.
|
||||||
|
// @param x The first vector value.
|
||||||
|
// @param y The second vector value.
|
||||||
|
// @param y A value that linearly interpolates between x and y.
|
||||||
|
public static float2 lerp(float2 x, float2 y, float s)
|
||||||
|
{
|
||||||
|
return x + s * (y - x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs a linear interpolation.
|
||||||
|
// @param x The first vector value.
|
||||||
|
// @param y The second vector value.
|
||||||
|
// @param y A value that linearly interpolates between x and y.
|
||||||
|
public static float3 lerp(float3 x, float3 y, float s)
|
||||||
|
{
|
||||||
|
return x + s * (y - x);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Performs a linear interpolation.
|
||||||
|
// @param x The first vector value.
|
||||||
|
// @param y The second vector value.
|
||||||
|
// @param y A value that linearly interpolates between x and y.
|
||||||
|
public static float4 lerp(float4 x, float4 y, float s)
|
||||||
|
{
|
||||||
|
return x + s * (y - x);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
// mul? hlsl has like 280 overloads...
|
||||||
|
|
||||||
|
public static float normalize(float value) => 1.0f;
|
||||||
|
public static float2 normalize(float2 value) => value / length(value);
|
||||||
|
public static float3 normalize(float3 value) => value / length(value);
|
||||||
|
public static float4 normalize(float4 value) => value / length(value);
|
||||||
|
|
||||||
|
// pow
|
||||||
|
|
||||||
|
#region Reflect and Refract
|
||||||
|
|
||||||
|
/// Returns a reflection vector using an incident ray and a surface normal.
|
||||||
|
public static float2 reflect(float2 incident, float2 normal) => incident - 2 * normal * dot(incident, normal);
|
||||||
|
/// Returns a reflection vector using an incident ray and a surface normal.
|
||||||
|
public static float3 reflect(float3 incident, float3 normal) => incident - 2 * normal * dot(incident, normal);
|
||||||
|
/// Returns a reflection vector using an incident ray and a surface normal.
|
||||||
|
public static float4 reflect(float4 incident, float4 normal) => incident - 2 * normal * dot(incident, normal);
|
||||||
|
|
||||||
|
// Source: https://thebookofshaders.com/glossary/?search=refract
|
||||||
|
/// Returns a refraction vector using an entering ray, a surface normal, and a refraction index.
|
||||||
|
public static float2 refract(float2 incident, float2 normal, float refractionIndex)
|
||||||
|
{
|
||||||
|
float dot_n_i = dot(normal, incident);
|
||||||
|
|
||||||
|
float k = 1.0f - refractionIndex * refractionIndex * (1.0f - dot_n_i * dot_n_i);
|
||||||
|
|
||||||
|
if (k < 0.0f)
|
||||||
|
return 0.0f;
|
||||||
|
else
|
||||||
|
return refractionIndex * incident - (refractionIndex * dot_n_i + sqrt(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a refraction vector using an entering ray, a surface normal, and a refraction index.
|
||||||
|
public static float3 refract(float3 incident, float3 normal, float refractionIndex)
|
||||||
|
{
|
||||||
|
float dot_n_i = dot(normal, incident);
|
||||||
|
|
||||||
|
float k = 1.0f - refractionIndex * refractionIndex * (1.0f - dot_n_i * dot_n_i);
|
||||||
|
|
||||||
|
if (k < 0.0f)
|
||||||
|
return 0.0f;
|
||||||
|
else
|
||||||
|
return refractionIndex * incident - (refractionIndex * dot_n_i + sqrt(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a refraction vector using an entering ray, a surface normal, and a refraction index.
|
||||||
|
public static float4 refract(float4 incident, float4 normal, float refractionIndex)
|
||||||
|
{
|
||||||
|
float dot_n_i = dot(normal, incident);
|
||||||
|
|
||||||
|
float k = 1.0f - refractionIndex * refractionIndex * (1.0f - dot_n_i * dot_n_i);
|
||||||
|
|
||||||
|
if (k < 0.0f)
|
||||||
|
return 0.0f;
|
||||||
|
else
|
||||||
|
return refractionIndex * incident - (refractionIndex * dot_n_i + sqrt(k));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
/// Calculates the per component square root of the given value.
|
||||||
|
public static float sqrt(float value)
|
||||||
|
{
|
||||||
|
return Math.Sqrt(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculates the per component square root of the given value.
|
||||||
|
public static float2 sqrt(float2 value)
|
||||||
|
{
|
||||||
|
return float2(Math.Sqrt(value.X), Math.Sqrt(value.Y));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculates the per component square root of the given value.
|
||||||
|
public static float3 sqrt(float3 value)
|
||||||
|
{
|
||||||
|
return float3(Math.Sqrt(value.X), Math.Sqrt(value.Y), Math.Sqrt(value.Z));
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Calculates the per component square root of the given value.
|
||||||
|
public static float4 sqrt(float4 value)
|
||||||
|
{
|
||||||
|
return float4(Math.Sqrt(value.X), Math.Sqrt(value.Y), Math.Sqrt(value.Z), Math.Sqrt(value.W));
|
||||||
|
}
|
||||||
|
|
||||||
|
// saturate (I don't think there is a faster way than simply using clamp, so simply use clamp...)
|
||||||
|
|
||||||
|
#region Step / Smoothstep
|
||||||
|
|
||||||
|
/// Compares two values, returning 0 or 1 based on which value is greater.
|
||||||
|
/// @returns 1 if the x parameter is greater than or equal to the y parameter; otherwise, 0.
|
||||||
|
public static float step(float y, float x)
|
||||||
|
{
|
||||||
|
return (x >= y) ? 1.0f : 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compares two values, returning 0 or 1 based on which value is greater.
|
||||||
|
/// @returns 1 if the x parameter is greater than or equal to the y parameter; otherwise, 0.
|
||||||
|
public static float2 step(float2 y, float2 x)
|
||||||
|
{
|
||||||
|
bool2 b = (x >= y);
|
||||||
|
|
||||||
|
return float2(b.X ? 1.0f : 0.0f, b.Y ? 1.0f : 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compares two values, returning 0 or 1 based on which value is greater.
|
||||||
|
/// @returns 1 if the x parameter is greater than or equal to the y parameter; otherwise, 0.
|
||||||
|
public static float3 step(float3 y, float3 x)
|
||||||
|
{
|
||||||
|
bool3 b = (x >= y);
|
||||||
|
|
||||||
|
return float3(b.X ? 1.0f : 0.0f, b.Y ? 1.0f : 0.0f, b.Z ? 1.0f : 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Compares two values, returning 0 or 1 based on which value is greater.
|
||||||
|
/// @returns 1 if the x parameter is greater than or equal to the y parameter; otherwise, 0.
|
||||||
|
public static float4 step(float4 y, float4 x)
|
||||||
|
{
|
||||||
|
bool4 b = (x >= y);
|
||||||
|
|
||||||
|
return float4(b.X ? 1.0f : 0.0f, b.Y ? 1.0f : 0.0f, b.Z ? 1.0f : 0.0f, b.W ? 1.0f : 0.0f);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Source: https://thebookofshaders.com/glossary/?search=smoothstep
|
||||||
|
|
||||||
|
/// Returns a smooth Hermite interpolation between 0 and 1, if x is in the range [min, max].
|
||||||
|
/// @returns Returns 0 if x is less than min; 1 if x is greater than max; otherwise, a value between 0 and 1 if x is in the range [min, max].
|
||||||
|
public static float smoothstep(float min, float max, float x)
|
||||||
|
{
|
||||||
|
float t = clamp((x - min) / (max - min), 0.0f, 1.0f);
|
||||||
|
return t * t * (3.0f - 2.0f * t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a smooth Hermite interpolation between 0 and 1, if x is in the range [min, max].
|
||||||
|
/// @returns Returns 0 if x is less than min; 1 if x is greater than max; otherwise, a value between 0 and 1 if x is in the range [min, max].
|
||||||
|
public static float2 smoothstep(float2 min, float2 max, float2 x)
|
||||||
|
{
|
||||||
|
float2 t = clamp((x - min) / (max - min), 0.0f, 1.0f);
|
||||||
|
return t * t * (3.0f - 2.0f * t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a smooth Hermite interpolation between 0 and 1, if x is in the range [min, max].
|
||||||
|
/// @returns Returns 0 if x is less than min; 1 if x is greater than max; otherwise, a value between 0 and 1 if x is in the range [min, max].
|
||||||
|
public static float3 smoothstep(float3 min, float3 max, float3 x)
|
||||||
|
{
|
||||||
|
float3 t = clamp((x - min) / (max - min), 0.0f, 1.0f);
|
||||||
|
return t * t * (3.0f - 2.0f * t);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns a smooth Hermite interpolation between 0 and 1, if x is in the range [min, max].
|
||||||
|
/// @returns Returns 0 if x is less than min; 1 if x is greater than max; otherwise, a value between 0 and 1 if x is in the range [min, max].
|
||||||
|
public static float4 smoothstep(float4 min, float4 max, float4 x)
|
||||||
|
{
|
||||||
|
float4 t = clamp((x - min) / (max - min), 0.0f, 1.0f);
|
||||||
|
return t * t * (3.0f - 2.0f * t);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region Reject / Project
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the projection of a onto b
|
||||||
|
*/
|
||||||
|
public static float2 project(float2 a, float2 b)
|
||||||
|
{
|
||||||
|
return (b * (dot(a, b) / dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the projection of a onto b
|
||||||
|
*/
|
||||||
|
public static float3 project(float3 a, float3 b)
|
||||||
|
{
|
||||||
|
return (b * (dot(a, b) / dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the projection of a onto b
|
||||||
|
*/
|
||||||
|
public static float4 project(float4 a, float4 b)
|
||||||
|
{
|
||||||
|
return (b * (dot(a, b) / dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the rejection of a from b
|
||||||
|
*/
|
||||||
|
public static float2 reject(float2 a, float2 b)
|
||||||
|
{
|
||||||
|
return (a - b * (dot(a, b) / dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the rejection of a from b
|
||||||
|
*/
|
||||||
|
public static float3 reject(float3 a, float3 b)
|
||||||
|
{
|
||||||
|
return (a - b * (dot(a, b) / dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the rejection of a from b
|
||||||
|
*/
|
||||||
|
public static float4 reject(float4 a, float4 b)
|
||||||
|
{
|
||||||
|
return (a - b * (dot(a, b) / dot(b, b)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region dot
|
||||||
|
|
||||||
|
public static float dot(float2 left, float2 right)
|
||||||
|
{
|
||||||
|
return left.X * right.X + left.Y * right.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float dot(float3 left, float3 right)
|
||||||
|
{
|
||||||
|
return left.X * right.X + left.Y * right.Y + left.Z * right.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float dot(float4 left, float4 right)
|
||||||
|
{
|
||||||
|
return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int dot(int2 left, int2 right)
|
||||||
|
{
|
||||||
|
return left.X * right.X + left.Y * right.Y;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int dot(int3 left, int3 right)
|
||||||
|
{
|
||||||
|
return left.X * right.X + left.Y * right.Y + left.Z * right.Z;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static int dot(int4 left, int4 right)
|
||||||
|
{
|
||||||
|
return left.X * right.X + left.Y * right.Y + left.Z * right.Z + left.W * right.W;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
#region lengthSq / length / DistanceSq / Distance
|
||||||
|
|
||||||
|
public static float lengthSq(float2 value) => dot(value, value);
|
||||||
|
|
||||||
|
public static float lengthSq(float3 value) => dot(value, value);
|
||||||
|
|
||||||
|
public static float lengthSq(float4 value) => dot(value, value);
|
||||||
|
|
||||||
|
public static int lengthSq(int2 value) => dot(value, value);
|
||||||
|
|
||||||
|
public static int lengthSq(int3 value) => dot(value, value);
|
||||||
|
|
||||||
|
public static int lengthSq(int4 value) => dot(value, value);
|
||||||
|
|
||||||
|
public static float length(float2 value) => Math.Sqrt(lengthSq(value));
|
||||||
|
|
||||||
|
public static float length(float3 value) => Math.Sqrt(lengthSq(value));
|
||||||
|
|
||||||
|
public static float length(float4 value) => Math.Sqrt(lengthSq(value));
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public static float distanceSq(float2 left, float2 right) => dot(left, right);
|
||||||
|
|
||||||
|
public static float distanceSq(float3 left, float3 right) => dot(left, right);
|
||||||
|
|
||||||
|
public static float distanceSq(float4 left, float4 right) => dot(left, right);
|
||||||
|
|
||||||
|
public static float distance(float2 left, float2 right) => Math.Sqrt(distanceSq(left, right));
|
||||||
|
|
||||||
|
public static float distance(float3 left, float3 right) => Math.Sqrt(distanceSq(left, right));
|
||||||
|
|
||||||
|
public static float distance(float4 left, float4 right) => Math.Sqrt(distanceSq(left, right));
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public static float3 cross(float3 left, float3 right)
|
||||||
|
{
|
||||||
|
return float3(
|
||||||
|
left.Y * right.Z - left.Z * right.Y,
|
||||||
|
left.Z * right.X - left.X * right.Z,
|
||||||
|
left.X * right.Y - left.Y * right.X);
|
||||||
|
}
|
||||||
|
|
||||||
|
// transpose und determinante für Matrizen
|
||||||
|
|
||||||
|
// sin, cos, tan, asin, acos, atan, atan2, cosh, sinh, tanh
|
||||||
|
}
|
||||||
@@ -30,19 +30,19 @@ namespace GlitchyEngine.Math
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Converts the given radians to degrees
|
// Converts the given radians to degrees
|
||||||
public static Vector2 ToDegrees(Vector2 radians)
|
public static float2 ToDegrees(float2 radians)
|
||||||
{
|
{
|
||||||
return radians * RadToDeg;
|
return radians * RadToDeg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts the given radians to degrees
|
// Converts the given radians to degrees
|
||||||
public static Vector3 ToDegrees(Vector3 radians)
|
public static float3 ToDegrees(float3 radians)
|
||||||
{
|
{
|
||||||
return radians * RadToDeg;
|
return radians * RadToDeg;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts the given radians to degrees
|
// Converts the given radians to degrees
|
||||||
public static Vector4 ToDegrees(Vector4 radians)
|
public static float4 ToDegrees(float4 radians)
|
||||||
{
|
{
|
||||||
return radians * RadToDeg;
|
return radians * RadToDeg;
|
||||||
}
|
}
|
||||||
@@ -54,19 +54,19 @@ namespace GlitchyEngine.Math
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Converts the given degrees to radians
|
// Converts the given degrees to radians
|
||||||
public static Vector2 ToRadians(Vector2 degrees)
|
public static float2 ToRadians(float2 degrees)
|
||||||
{
|
{
|
||||||
return degrees * DegToRad;
|
return degrees * DegToRad;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts the given degrees to radians
|
// Converts the given degrees to radians
|
||||||
public static Vector3 ToRadians(Vector3 degrees)
|
public static float3 ToRadians(float3 degrees)
|
||||||
{
|
{
|
||||||
return degrees * DegToRad;
|
return degrees * DegToRad;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Converts the given degrees to radians
|
// Converts the given degrees to radians
|
||||||
public static Vector4 ToRadians(Vector4 degrees)
|
public static float4 ToRadians(float4 degrees)
|
||||||
{
|
{
|
||||||
return degrees * DegToRad;
|
return degrees * DegToRad;
|
||||||
}
|
}
|
||||||
@@ -79,24 +79,24 @@ namespace GlitchyEngine.Math
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the point that lies on the unit circle at the specified angle.
|
/// Returns the point that lies on the unit circle at the specified angle.
|
||||||
public static Vector2 CirclePoint(float angle, float radius = 1.0f)
|
public static float2 CirclePoint(float angle, float radius = 1.0f)
|
||||||
{
|
{
|
||||||
return .(Math.Cos(angle), Math.Sin(angle)) * radius;
|
return .(Math.Cos(angle), Math.Sin(angle)) * radius;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector2 Pow(Vector2 v, float p)
|
public static float2 Pow(float2 v, float p)
|
||||||
{
|
{
|
||||||
return Vector2(Math.Pow(v.X, p), Math.Pow(v.Y, p));
|
return float2(Math.Pow(v.X, p), Math.Pow(v.Y, p));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector3 Pow(Vector3 v, float p)
|
public static float3 Pow(float3 v, float p)
|
||||||
{
|
{
|
||||||
return Vector3(Math.Pow(v.X, p), Math.Pow(v.Y, p), Math.Pow(v.Z, p));
|
return float3(Math.Pow(v.X, p), Math.Pow(v.Y, p), Math.Pow(v.Z, p));
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector4 Pow(Vector4 v, float p)
|
public static float4 Pow(float4 v, float p)
|
||||||
{
|
{
|
||||||
return Vector4(Math.Pow(v.X, p), Math.Pow(v.Y, p), Math.Pow(v.Z, p), Math.Pow(v.W, p));
|
return float4(Math.Pow(v.X, p), Math.Pow(v.Y, p), Math.Pow(v.Z, p), Math.Pow(v.W, p));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ public struct Matrix
|
|||||||
|
|
||||||
public using Values V;
|
public using Values V;
|
||||||
public float[4][4] Values;
|
public float[4][4] Values;
|
||||||
public Vector4[4] Columns;
|
public float4[4] Columns;
|
||||||
|
|
||||||
/// Creates a new zero-matrix.
|
/// Creates a new zero-matrix.
|
||||||
public this() => this = default;
|
public this() => this = default;
|
||||||
@@ -53,7 +53,7 @@ public struct Matrix
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new matrix and initializes it with the given column-vectors.
|
/// Creates a new matrix and initializes it with the given column-vectors.
|
||||||
public this(Vector4 c0, Vector4 c1, Vector4 c2, Vector4 c3)
|
public this(float4 c0, float4 c1, float4 c2, float4 c3)
|
||||||
{
|
{
|
||||||
Columns[0] = c0;
|
Columns[0] = c0;
|
||||||
Columns[1] = c1;
|
Columns[1] = c1;
|
||||||
@@ -61,47 +61,47 @@ public struct Matrix
|
|||||||
Columns[3] = c3;
|
Columns[3] = c3;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref Vector3 Right
|
public ref float3 Right
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
#unwarn
|
#unwarn
|
||||||
return ref *(Vector3*)&Columns[0];
|
return ref *(float3*)&Columns[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref Vector3 Up
|
public ref float3 Up
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
#unwarn
|
#unwarn
|
||||||
return ref *(Vector3*)&Columns[1];
|
return ref *(float3*)&Columns[1];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref Vector3 Forward
|
public ref float3 Forward
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
#unwarn
|
#unwarn
|
||||||
return ref *(Vector3*)&Columns[2];
|
return ref *(float3*)&Columns[2];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref Vector3 Translation
|
public ref float3 Translation
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
#unwarn
|
#unwarn
|
||||||
return ref *(Vector3*)&Columns[3];
|
return ref *(float3*)&Columns[3];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Scale
|
public float3 Scale
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
get => .(_11, _22, _33);
|
get => .(_11, _22, _33);
|
||||||
@@ -134,12 +134,12 @@ public struct Matrix
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ref Vector4 this[int column]
|
public ref float4 this[int column]
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
#unwarn
|
#unwarn
|
||||||
return ref *(Vector4*)&Columns[column];
|
return ref *(float4*)&Columns[column];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -150,7 +150,7 @@ public struct Matrix
|
|||||||
Internal.ThrowIndexOutOfRange();
|
Internal.ThrowIndexOutOfRange();
|
||||||
|
|
||||||
#unwarn
|
#unwarn
|
||||||
return ref *(Vector4*)&Columns[column];
|
return ref *(float4*)&Columns[column];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -351,12 +351,12 @@ public struct Matrix
|
|||||||
/**
|
/**
|
||||||
* Multiplies a matrix and a column-vector resulting in a column vector.
|
* Multiplies a matrix and a column-vector resulting in a column vector.
|
||||||
*/
|
*/
|
||||||
public static Vector4 operator *(Matrix matrix, Vector4 columnVector)
|
public static float4 operator *(Matrix matrix, float4 columnVector)
|
||||||
{
|
{
|
||||||
#unwarn
|
#unwarn
|
||||||
var m = &matrix.V;
|
var m = &matrix.V;
|
||||||
|
|
||||||
Vector4 result = ?;
|
float4 result = ?;
|
||||||
result.X = (m._11 * columnVector.X) + (m._12 * columnVector.Y) + (m._13 * columnVector.Z) + (m._14 * columnVector.W);
|
result.X = (m._11 * columnVector.X) + (m._12 * columnVector.Y) + (m._13 * columnVector.Z) + (m._14 * columnVector.W);
|
||||||
result.Y = (m._21 * columnVector.X) + (m._22 * columnVector.Y) + (m._23 * columnVector.Z) + (m._24 * columnVector.W);
|
result.Y = (m._21 * columnVector.X) + (m._22 * columnVector.Y) + (m._23 * columnVector.Z) + (m._24 * columnVector.W);
|
||||||
result.Z = (m._31 * columnVector.X) + (m._32 * columnVector.Y) + (m._33 * columnVector.Z) + (m._34 * columnVector.W);
|
result.Z = (m._31 * columnVector.X) + (m._32 * columnVector.Y) + (m._33 * columnVector.Z) + (m._34 * columnVector.W);
|
||||||
@@ -367,12 +367,12 @@ public struct Matrix
|
|||||||
/**
|
/**
|
||||||
* Multiplies a row-vector and a matrix resulting in a row vector.
|
* Multiplies a row-vector and a matrix resulting in a row vector.
|
||||||
*/
|
*/
|
||||||
public static Vector4 operator *(Vector4 rowVector, Matrix matrix)
|
public static float4 operator *(float4 rowVector, Matrix matrix)
|
||||||
{
|
{
|
||||||
#unwarn
|
#unwarn
|
||||||
var m = &matrix.V;
|
var m = &matrix.V;
|
||||||
|
|
||||||
Vector4 result = ?;
|
float4 result = ?;
|
||||||
result.X = (rowVector.X * m._11) + (rowVector.Y * m._21) + (rowVector.Z * m._31) + (rowVector.W * m._41);
|
result.X = (rowVector.X * m._11) + (rowVector.Y * m._21) + (rowVector.Z * m._31) + (rowVector.W * m._41);
|
||||||
result.Y = (rowVector.X * m._12) + (rowVector.Y * m._22) + (rowVector.Z * m._32) + (rowVector.W * m._42);
|
result.Y = (rowVector.X * m._12) + (rowVector.Y * m._22) + (rowVector.Z * m._32) + (rowVector.W * m._42);
|
||||||
result.Z = (rowVector.X * m._13) + (rowVector.Y * m._23) + (rowVector.Z * m._33) + (rowVector.W * m._43);
|
result.Z = (rowVector.X * m._13) + (rowVector.Y * m._23) + (rowVector.Z * m._33) + (rowVector.W * m._43);
|
||||||
@@ -406,7 +406,7 @@ public struct Matrix
|
|||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matrix Scaling(Vector3 scale)
|
public static Matrix Scaling(float3 scale)
|
||||||
{
|
{
|
||||||
return .(scale.X, 0, 0, 0,
|
return .(scale.X, 0, 0, 0,
|
||||||
0, scale.Y, 0, 0,
|
0, scale.Y, 0, 0,
|
||||||
@@ -422,7 +422,7 @@ public struct Matrix
|
|||||||
0, 0, 0, 1);
|
0, 0, 0, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Matrix Translation(Vector3 translation)
|
public static Matrix Translation(float3 translation)
|
||||||
{
|
{
|
||||||
return .(1, 0, 0, translation.X,
|
return .(1, 0, 0, translation.X,
|
||||||
0, 1, 0, translation.Y,
|
0, 1, 0, translation.Y,
|
||||||
@@ -470,25 +470,22 @@ public struct Matrix
|
|||||||
* @param up A vector defining the up direction of the camera.
|
* @param up A vector defining the up direction of the camera.
|
||||||
* @returns a view matrix.
|
* @returns a view matrix.
|
||||||
*/
|
*/
|
||||||
public static Matrix LookAt(Vector3 position, Vector3 target, Vector3 up)
|
public static Matrix LookAt(float3 position, float3 target, float3 up)
|
||||||
{
|
{
|
||||||
Vector3 forward = target - position;
|
float3 forward = normalize(target - position);
|
||||||
forward.Normalize();
|
|
||||||
|
|
||||||
Vector3 right = Vector3.Cross(up, forward);
|
float3 right = normalize(cross(up, forward));
|
||||||
right.Normalize();
|
|
||||||
|
|
||||||
Vector3 newUp = Vector3.Cross(forward, right);
|
float3 newUp = normalize(cross(forward, right));
|
||||||
newUp.Normalize();
|
|
||||||
|
|
||||||
Matrix result = .Identity;
|
Matrix result = .Identity;
|
||||||
|
|
||||||
result.Forward = forward;
|
result.Forward = forward;
|
||||||
result.Up = up;
|
result.Up = up;
|
||||||
result.Right = right;
|
result.Right = right;
|
||||||
result.Translation.X = -Vector3.Dot(position, right);
|
result.Translation.X = -dot(position, right);
|
||||||
result.Translation.Y = -Vector3.Dot(position, up);
|
result.Translation.Y = -dot(position, up);
|
||||||
result.Translation.Z = -Vector3.Dot(position, forward);
|
result.Translation.Z = -dot(position, forward);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -511,22 +508,22 @@ public struct Matrix
|
|||||||
{
|
{
|
||||||
// From: Lengyel, Eric. Foundations of Game Engine Development, Volume 1: Mathematics (S.61). Kindle-Version.
|
// From: Lengyel, Eric. Foundations of Game Engine Development, Volume 1: Mathematics (S.61). Kindle-Version.
|
||||||
|
|
||||||
Vector3 a = *(Vector3*)&Columns[0];
|
float3 a = *(float3*)&Columns[0];
|
||||||
Vector3 b = *(Vector3*)&Columns[1];
|
float3 b = *(float3*)&Columns[1];
|
||||||
Vector3 c = *(Vector3*)&Columns[2];
|
float3 c = *(float3*)&Columns[2];
|
||||||
Vector3 d = *(Vector3*)&Columns[3];
|
float3 d = *(float3*)&Columns[3];
|
||||||
|
|
||||||
float x = this[3, 0];
|
float x = this[3, 0];
|
||||||
float y = this[3, 1];
|
float y = this[3, 1];
|
||||||
float z = this[3, 2];
|
float z = this[3, 2];
|
||||||
float w = this[3, 3];
|
float w = this[3, 3];
|
||||||
|
|
||||||
Vector3 s = Vector3.Cross(a, b);
|
float3 s = cross(a, b);
|
||||||
Vector3 t = Vector3.Cross(c, d);
|
float3 t = cross(c, d);
|
||||||
Vector3 u = y * a - x * b;
|
float3 u = y * a - x * b;
|
||||||
Vector3 v = w * c - z * d;
|
float3 v = w * c - z * d;
|
||||||
|
|
||||||
return Vector3.Dot(s, v) + Vector3.Dot(t, u);
|
return dot(s, v) + dot(t, u);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -537,39 +534,39 @@ public struct Matrix
|
|||||||
// From: Lengyel, Eric. Foundations of Game Engine Development, Volume 1: Mathematics (S.61). Kindle-Version.
|
// From: Lengyel, Eric. Foundations of Game Engine Development, Volume 1: Mathematics (S.61). Kindle-Version.
|
||||||
|
|
||||||
#unwarn
|
#unwarn
|
||||||
Vector3 a = *(Vector3*)&Columns[0];
|
float3 a = *(float3*)&Columns[0];
|
||||||
#unwarn
|
#unwarn
|
||||||
Vector3 b = *(Vector3*)&Columns[1];
|
float3 b = *(float3*)&Columns[1];
|
||||||
#unwarn
|
#unwarn
|
||||||
Vector3 c = *(Vector3*)&Columns[2];
|
float3 c = *(float3*)&Columns[2];
|
||||||
#unwarn
|
#unwarn
|
||||||
Vector3 d = *(Vector3*)&Columns[3];
|
float3 d = *(float3*)&Columns[3];
|
||||||
|
|
||||||
float x = this[3, 0];
|
float x = this[3, 0];
|
||||||
float y = this[3, 1];
|
float y = this[3, 1];
|
||||||
float z = this[3, 2];
|
float z = this[3, 2];
|
||||||
float w = this[3, 3];
|
float w = this[3, 3];
|
||||||
|
|
||||||
Vector3 s = Vector3.Cross(a, b);
|
float3 s = cross(a, b);
|
||||||
Vector3 t = Vector3.Cross(c, d);
|
float3 t = cross(c, d);
|
||||||
Vector3 u = y * a - x * b;
|
float3 u = y * a - x * b;
|
||||||
Vector3 v = w * c - z * d;
|
float3 v = w * c - z * d;
|
||||||
|
|
||||||
float invDet = 1.0f / (Vector3.Dot(s, v) + Vector3.Dot(t, u));
|
float invDet = 1.0f / (dot(s, v) + dot(t, u));
|
||||||
|
|
||||||
s *= invDet;
|
s *= invDet;
|
||||||
t *= invDet;
|
t *= invDet;
|
||||||
u *= invDet;
|
u *= invDet;
|
||||||
v *= invDet;
|
v *= invDet;
|
||||||
|
|
||||||
Vector3 r0 = Vector3.Cross(b, v) + t * y;
|
float3 r0 = cross(b, v) + t * y;
|
||||||
Vector3 r1 = Vector3.Cross(v, a) - t * x;
|
float3 r1 = cross(v, a) - t * x;
|
||||||
Vector3 r2 = Vector3.Cross(d, u) + s * w;
|
float3 r2 = cross(d, u) + s * w;
|
||||||
Vector3 r3 = Vector3.Cross(u, c) - s * z;
|
float3 r3 = cross(u, c) - s * z;
|
||||||
return .(r0.X, r0.Y, r0.Z, -Vector3.Dot(b, t),
|
return .(r0.X, r0.Y, r0.Z, -dot(b, t),
|
||||||
r1.X, r1.Y, r1.Z, Vector3.Dot(a, t),
|
r1.X, r1.Y, r1.Z, dot(a, t),
|
||||||
r2.X, r2.Y, r2.Z, -Vector3.Dot(d, s),
|
r2.X, r2.Y, r2.Z, -dot(d, s),
|
||||||
r3.X, r3.Y, r3.Z, Vector3.Dot(c, s));
|
r3.X, r3.Y, r3.Z, dot(c, s));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Calculates the inverse of the matrix.
|
/// Calculates the inverse of the matrix.
|
||||||
@@ -578,39 +575,39 @@ public struct Matrix
|
|||||||
// From: Lengyel, Eric. Foundations of Game Engine Development, Volume 1: Mathematics (S.61). Kindle-Version.
|
// From: Lengyel, Eric. Foundations of Game Engine Development, Volume 1: Mathematics (S.61). Kindle-Version.
|
||||||
|
|
||||||
#unwarn
|
#unwarn
|
||||||
Vector3 a = *(Vector3*)&matrix.Columns[0];
|
float3 a = *(float3*)&matrix.Columns[0];
|
||||||
#unwarn
|
#unwarn
|
||||||
Vector3 b = *(Vector3*)&matrix.Columns[1];
|
float3 b = *(float3*)&matrix.Columns[1];
|
||||||
#unwarn
|
#unwarn
|
||||||
Vector3 c = *(Vector3*)&matrix.Columns[2];
|
float3 c = *(float3*)&matrix.Columns[2];
|
||||||
#unwarn
|
#unwarn
|
||||||
Vector3 d = *(Vector3*)&matrix.Columns[3];
|
float3 d = *(float3*)&matrix.Columns[3];
|
||||||
|
|
||||||
float x = matrix[3, 0];
|
float x = matrix[3, 0];
|
||||||
float y = matrix[3, 1];
|
float y = matrix[3, 1];
|
||||||
float z = matrix[3, 2];
|
float z = matrix[3, 2];
|
||||||
float w = matrix[3, 3];
|
float w = matrix[3, 3];
|
||||||
|
|
||||||
Vector3 s = Vector3.Cross(a, b);
|
float3 s = cross(a, b);
|
||||||
Vector3 t = Vector3.Cross(c, d);
|
float3 t = cross(c, d);
|
||||||
Vector3 u = y * a - x * b;
|
float3 u = y * a - x * b;
|
||||||
Vector3 v = w * c - z * d;
|
float3 v = w * c - z * d;
|
||||||
|
|
||||||
float invDet = 1.0f / (Vector3.Dot(s, v) + Vector3.Dot(t, u));
|
float invDet = 1.0f / (dot(s, v) + dot(t, u));
|
||||||
|
|
||||||
s *= invDet;
|
s *= invDet;
|
||||||
t *= invDet;
|
t *= invDet;
|
||||||
u *= invDet;
|
u *= invDet;
|
||||||
v *= invDet;
|
v *= invDet;
|
||||||
|
|
||||||
Vector3 r0 = Vector3.Cross(b, v) + t * y;
|
float3 r0 = cross(b, v) + t * y;
|
||||||
Vector3 r1 = Vector3.Cross(v, a) - t * x;
|
float3 r1 = cross(v, a) - t * x;
|
||||||
Vector3 r2 = Vector3.Cross(d, u) + s * w;
|
float3 r2 = cross(d, u) + s * w;
|
||||||
Vector3 r3 = Vector3.Cross(u, c) - s * z;
|
float3 r3 = cross(u, c) - s * z;
|
||||||
return .(r0.X, r0.Y, r0.Z, -Vector3.Dot(b, t),
|
return .(r0.X, r0.Y, r0.Z, -dot(b, t),
|
||||||
r1.X, r1.Y, r1.Z, Vector3.Dot(a, t),
|
r1.X, r1.Y, r1.Z, dot(a, t),
|
||||||
r2.X, r2.Y, r2.Z, -Vector3.Dot(d, s),
|
r2.X, r2.Y, r2.Z, -dot(d, s),
|
||||||
r3.X, r3.Y, r3.Z, Vector3.Dot(c, s));
|
r3.X, r3.Y, r3.Z, dot(c, s));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -792,9 +789,9 @@ public struct Matrix
|
|||||||
*/
|
*/
|
||||||
public void Orthogonalize() mut
|
public void Orthogonalize() mut
|
||||||
{
|
{
|
||||||
Columns[1] -= .Project(Columns[1], Columns[0]);
|
Columns[1] -= project(Columns[1], Columns[0]);
|
||||||
Columns[2] -= .Project(Columns[2], Columns[0]) + .Project(Columns[2], Columns[1]);
|
Columns[2] -= project(Columns[2], Columns[0]) + project(Columns[2], Columns[1]);
|
||||||
Columns[3] -= .Project(Columns[3], Columns[0]) + .Project(Columns[3], Columns[1]) + .Project(Columns[3], Columns[2]);
|
Columns[3] -= project(Columns[3], Columns[0]) + project(Columns[3], Columns[1]) + project(Columns[3], Columns[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -802,10 +799,10 @@ public struct Matrix
|
|||||||
*/
|
*/
|
||||||
public void Orthonormalize() mut
|
public void Orthonormalize() mut
|
||||||
{
|
{
|
||||||
Columns[0].Normalize();
|
Columns[0] = normalize(Columns[0]);
|
||||||
Columns[1] = .Normalize(.Reject(Columns[1], Columns[0]));
|
Columns[1] = normalize(reject(Columns[1], Columns[0]));
|
||||||
Columns[2] = .Normalize(.Reject(.Reject(Columns[2], Columns[0]), Columns[1]));
|
Columns[2] = normalize(reject(reject(Columns[2], Columns[0]), Columns[1]));
|
||||||
Columns[3] = .Normalize(.Reject(.Reject(.Reject(Columns[2], Columns[0]), Columns[1]), Columns[2]));
|
Columns[3] = normalize(reject(reject(reject(Columns[2], Columns[0]), Columns[1]), Columns[2]));
|
||||||
}
|
}
|
||||||
public static Self RotationQuaternion(Quaternion rotation)
|
public static Self RotationQuaternion(Quaternion rotation)
|
||||||
{
|
{
|
||||||
@@ -845,7 +842,7 @@ public struct Matrix
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Decompose(Self matrix, out Vector3 position, out Quaternion rotation, out Vector3 scale)
|
public static void Decompose(Self matrix, out float3 position, out Quaternion rotation, out float3 scale)
|
||||||
{
|
{
|
||||||
var matrix;
|
var matrix;
|
||||||
|
|
||||||
@@ -857,9 +854,9 @@ public struct Matrix
|
|||||||
// TODO: this doesn't detect mirroring
|
// TODO: this doesn't detect mirroring
|
||||||
|
|
||||||
// Extract scaling from matrix
|
// Extract scaling from matrix
|
||||||
scale.X = (*(Vector3*)&matrix.Columns[0]).Magnitude();
|
scale.X = length(*(float3*)&matrix.Columns[0]);
|
||||||
scale.Y = (*(Vector3*)&matrix.Columns[1]).Magnitude();
|
scale.Y = length(*(float3*)&matrix.Columns[1]);
|
||||||
scale.Z = (*(Vector3*)&matrix.Columns[2]).Magnitude();
|
scale.Z = length(*(float3*)&matrix.Columns[2]);
|
||||||
|
|
||||||
if(MathHelper.IsZero(scale.X) || MathHelper.IsZero(scale.Y) || MathHelper.IsZero(scale.Z))
|
if(MathHelper.IsZero(scale.X) || MathHelper.IsZero(scale.Y) || MathHelper.IsZero(scale.Z))
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ namespace GlitchyEngine.Math
|
|||||||
W = w;
|
W = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
public this(Vector3 xy, float z, float w)
|
public this(float3 xy, float z, float w)
|
||||||
{
|
{
|
||||||
X = xy.X;
|
X = xy.X;
|
||||||
Y = xy.Y;
|
Y = xy.Y;
|
||||||
@@ -30,7 +30,7 @@ namespace GlitchyEngine.Math
|
|||||||
W = w;
|
W = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
public this(Vector3 xyz, float w)
|
public this(float3 xyz, float w)
|
||||||
{
|
{
|
||||||
X = xyz.X;
|
X = xyz.X;
|
||||||
Y = xyz.Y;
|
Y = xyz.Y;
|
||||||
@@ -38,7 +38,7 @@ namespace GlitchyEngine.Math
|
|||||||
W = w;
|
W = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
public this(Vector4 vector)
|
public this(float4 vector)
|
||||||
{
|
{
|
||||||
X = vector.X;
|
X = vector.X;
|
||||||
Y = vector.Y;
|
Y = vector.Y;
|
||||||
@@ -46,7 +46,7 @@ namespace GlitchyEngine.Math
|
|||||||
W = vector.W;
|
W = vector.W;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Vector
|
public float3 Vector
|
||||||
{
|
{
|
||||||
get => .(X, Y, Z);
|
get => .(X, Y, Z);
|
||||||
set mut
|
set mut
|
||||||
@@ -195,11 +195,11 @@ namespace GlitchyEngine.Math
|
|||||||
{
|
{
|
||||||
Quaternion result;
|
Quaternion result;
|
||||||
|
|
||||||
Vector3 v = l.Vector * r.Vector + (l.W * r.Vector) + (r.W * l.Vector);
|
float3 v = l.Vector * r.Vector + (l.W * r.Vector) + (r.W * l.Vector);
|
||||||
result.X = v.X;
|
result.X = v.X;
|
||||||
result.Y = v.Y;
|
result.Y = v.Y;
|
||||||
result.Z = v.Z;
|
result.Z = v.Z;
|
||||||
result.W = (l.W * r.W) - Vector3.Dot(l.Vector, r.Vector);
|
result.W = (l.W * r.W) - dot(l.Vector, r.Vector);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@@ -220,11 +220,11 @@ namespace GlitchyEngine.Math
|
|||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
#unwarn
|
#unwarn
|
||||||
public static implicit operator Vector4(in Self value) => *(Vector4*)&value;
|
public static implicit operator float4(in Self value) => *(float4*)&value;
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
#unwarn
|
#unwarn
|
||||||
public static implicit operator Quaternion(in Vector4 value) => *(Quaternion*)&value;
|
public static implicit operator Quaternion(in float4 value) => *(Quaternion*)&value;
|
||||||
|
|
||||||
public static bool operator ==(Quaternion l, Quaternion r)
|
public static bool operator ==(Quaternion l, Quaternion r)
|
||||||
{
|
{
|
||||||
@@ -236,7 +236,7 @@ namespace GlitchyEngine.Math
|
|||||||
return l.X != r.X && l.Y != r.Y && l.Z != r.Z && l.W != r.W;
|
return l.X != r.X && l.Y != r.Y && l.Z != r.Z && l.W != r.W;
|
||||||
}
|
}
|
||||||
|
|
||||||
public (Vector3 Axis, float Angle) ToAxisAngle()
|
public (float3 Axis, float Angle) ToAxisAngle()
|
||||||
{
|
{
|
||||||
// scalar part = cos(θ/2)
|
// scalar part = cos(θ/2)
|
||||||
// So, we can extract the angle directly.
|
// So, we can extract the angle directly.
|
||||||
@@ -247,12 +247,12 @@ namespace GlitchyEngine.Math
|
|||||||
// We assume quaternion is unit length, so subtracting w^2 gives us length of just vector part (aka sin(θ/2)).
|
// We assume quaternion is unit length, so subtracting w^2 gives us length of just vector part (aka sin(θ/2)).
|
||||||
float length = Math.Sqrt(1.0f - (W * W));
|
float length = Math.Sqrt(1.0f - (W * W));
|
||||||
|
|
||||||
Vector3 axis;
|
float3 axis;
|
||||||
|
|
||||||
// Normalize vector part to get the axis!
|
// Normalize vector part to get the axis!
|
||||||
if(length == 0)
|
if(length == 0)
|
||||||
{
|
{
|
||||||
axis = Vector3.Zero;
|
axis = float3.Zero;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -265,9 +265,9 @@ namespace GlitchyEngine.Math
|
|||||||
return (axis, angle);
|
return (axis, angle);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Quaternion FromAxisAngle(Vector3 axis, float angle)
|
public static Quaternion FromAxisAngle(float3 axis, float angle)
|
||||||
{
|
{
|
||||||
float lengthSq = axis.MagnitudeSquared();
|
float lengthSq = lengthSq(axis);
|
||||||
|
|
||||||
if(lengthSq == 0)
|
if(lengthSq == 0)
|
||||||
{
|
{
|
||||||
@@ -316,11 +316,11 @@ namespace GlitchyEngine.Math
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Vector3 ToEulerAngles(Quaternion q)
|
public static float3 ToEulerAngles(Quaternion q)
|
||||||
{
|
{
|
||||||
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
|
// http://www.euclideanspace.com/maths/geometry/rotations/conversions/quaternionToEuler/
|
||||||
|
|
||||||
Vector3 result;
|
float3 result;
|
||||||
|
|
||||||
float sqw = q.W*q.W;
|
float sqw = q.W*q.W;
|
||||||
float sqx = q.X*q.X;
|
float sqx = q.X*q.X;
|
||||||
@@ -354,7 +354,7 @@ namespace GlitchyEngine.Math
|
|||||||
float y = 2.0f * (Y * Z + W * X);
|
float y = 2.0f * (Y * Z + W * X);
|
||||||
float x = W * W - X * X - Y * Y + Z * Z;
|
float x = W * W - X * X - Y * Y + Z * Z;
|
||||||
|
|
||||||
if (Vector2(x, y).Equals(.Zero)) //avoid atan2(0,0) - handle singularity - Matiis
|
if (float2(x, y).Equals(.Zero)) //avoid atan2(0,0) - handle singularity - Matiis
|
||||||
return 2.0f * Math.Atan2(X, W);
|
return 2.0f * Math.Atan2(X, W);
|
||||||
|
|
||||||
return Math.Atan2(y, x);
|
return Math.Atan2(y, x);
|
||||||
@@ -370,7 +370,7 @@ namespace GlitchyEngine.Math
|
|||||||
float y = 2.0f * (X * Y + W * Z);
|
float y = 2.0f * (X * Y + W * Z);
|
||||||
float x = W * W + X * X - Y * Y - Z * Z;
|
float x = W * W + X * X - Y * Y - Z * Z;
|
||||||
|
|
||||||
if (Vector2(x, y).Equals(.Zero)) //avoid atan2(0,0) - handle singularity - Matiis
|
if (float2(x, y).Equals(.Zero)) //avoid atan2(0,0) - handle singularity - Matiis
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return Math.Atan2(y, x);
|
return Math.Atan2(y, x);
|
||||||
|
|||||||
@@ -1,299 +0,0 @@
|
|||||||
using Bon;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Math
|
|
||||||
{
|
|
||||||
[BonTarget]
|
|
||||||
[SwizzleVector(2, "GlitchyEngine.Math.Vector")]
|
|
||||||
public struct Vector2
|
|
||||||
{
|
|
||||||
public const Vector2 Zero = .(0f, 0f);
|
|
||||||
public const Vector2 UnitX = .(1f, 0f);
|
|
||||||
public const Vector2 UnitY = .(0f, 1f);
|
|
||||||
public const Vector2 One = .(1f, 1f);
|
|
||||||
|
|
||||||
public const int ComponentCount = 2;
|
|
||||||
|
|
||||||
public float X, Y;
|
|
||||||
|
|
||||||
public this() => this = default;
|
|
||||||
|
|
||||||
public this(float value)
|
|
||||||
{
|
|
||||||
X = value;
|
|
||||||
Y = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(float x, float y)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ref float this[int index]
|
|
||||||
{
|
|
||||||
[Checked]
|
|
||||||
get mut
|
|
||||||
{
|
|
||||||
if(index < 0 || index >= ComponentCount)
|
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
|
||||||
|
|
||||||
return ref (&X)[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
get mut => ref (&X)[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public float this[int index]
|
|
||||||
{
|
|
||||||
[Checked]
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if(index < 0 || index >= ComponentCount)
|
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
|
||||||
|
|
||||||
if(index == 0)
|
|
||||||
return X;
|
|
||||||
else
|
|
||||||
return Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if(index == 0)
|
|
||||||
return X;
|
|
||||||
else
|
|
||||||
return Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Checked]
|
|
||||||
set mut
|
|
||||||
{
|
|
||||||
if(index < 0 || index >= ComponentCount)
|
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
|
||||||
|
|
||||||
if(index == 0)
|
|
||||||
X = value;
|
|
||||||
else
|
|
||||||
Y = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
set mut
|
|
||||||
{
|
|
||||||
if(index == 0)
|
|
||||||
X = value;
|
|
||||||
else
|
|
||||||
Y = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the magnitude (length) of this vector.
|
|
||||||
* @remarks MagnitudeSquared might be used if only the relative length is relevant.
|
|
||||||
*/
|
|
||||||
public float Magnitude()
|
|
||||||
{
|
|
||||||
return Math.Sqrt(X * X + Y * Y);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the squared magnitude (length) of this vector.
|
|
||||||
*/
|
|
||||||
public float MagnitudeSquared()
|
|
||||||
{
|
|
||||||
return X * X + Y * Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO: Normalization interface is bad
|
|
||||||
[Checked]
|
|
||||||
public void Normalize() mut
|
|
||||||
{
|
|
||||||
if(this == .Zero)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this /= Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Normalize() mut
|
|
||||||
{
|
|
||||||
this /= Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector2 Normalize(Vector2 v)
|
|
||||||
{
|
|
||||||
return v / v.Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float Dot(Vector2 l, Vector2 r)
|
|
||||||
{
|
|
||||||
return l.X * r.X + l.Y * r.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the projection of a onto b
|
|
||||||
*/
|
|
||||||
public static Vector2 Project(Vector2 a, Vector2 b)
|
|
||||||
{
|
|
||||||
return (b * (Dot(a, b) / Dot(b, b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the rejection of a from b
|
|
||||||
*/
|
|
||||||
public static Vector2 Reject(Vector2 a, Vector2 b)
|
|
||||||
{
|
|
||||||
return (a - b * (Dot(a, b) / Dot(b, b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interpolates linearly between two given vectors.
|
|
||||||
* @param a The first vector.
|
|
||||||
* @param b The second vector.
|
|
||||||
* @param interpolationValue The value that linearly interpolates between a and b.
|
|
||||||
* (0 means a will be returned, 1 means b will be returned.)
|
|
||||||
* @returns The resulting linear interpolation.
|
|
||||||
*/
|
|
||||||
public static Vector2 Lerp(Vector2 a, Vector2 b, float interpolationValue)
|
|
||||||
{
|
|
||||||
return a + interpolationValue * (b - a);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector2 Min(Vector2 a, Vector2 b)
|
|
||||||
{
|
|
||||||
return .(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector2 Max(Vector2 a, Vector2 b)
|
|
||||||
{
|
|
||||||
return .(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assignment operators
|
|
||||||
//
|
|
||||||
|
|
||||||
// Addition
|
|
||||||
|
|
||||||
public void operator +=(Vector2 value) mut
|
|
||||||
{
|
|
||||||
X += value.X;
|
|
||||||
Y += value.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator +=(float scalar) mut
|
|
||||||
{
|
|
||||||
X += scalar;
|
|
||||||
Y += scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtraction
|
|
||||||
|
|
||||||
public void operator -=(Vector2 value) mut
|
|
||||||
{
|
|
||||||
X -= value.X;
|
|
||||||
Y -= value.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator -=(float scalar) mut
|
|
||||||
{
|
|
||||||
X -= scalar;
|
|
||||||
Y -= scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiplication
|
|
||||||
|
|
||||||
public void operator *=(Vector2 value) mut
|
|
||||||
{
|
|
||||||
X *= value.X;
|
|
||||||
Y *= value.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator *=(float scalar) mut
|
|
||||||
{
|
|
||||||
X *= scalar;
|
|
||||||
Y *= scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Division
|
|
||||||
|
|
||||||
public void operator /=(float scalar) mut
|
|
||||||
{
|
|
||||||
float f = 1.0f / scalar;
|
|
||||||
X *= f;
|
|
||||||
Y *= f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator /=(Vector2 value) mut
|
|
||||||
{
|
|
||||||
X /= value.X;
|
|
||||||
Y /= value.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// operators
|
|
||||||
//
|
|
||||||
|
|
||||||
// Addition
|
|
||||||
|
|
||||||
public static Vector2 operator +(Vector2 left, Vector2 right) => Vector2(left.X + right.X, left.Y + right.Y);
|
|
||||||
|
|
||||||
public static Vector2 operator +(Vector2 value, float scalar) => Vector2(value.X + scalar, value.Y + scalar);
|
|
||||||
|
|
||||||
public static Vector2 operator +(float scalar, Vector2 value) => Vector2(scalar + value.X, scalar + value.Y);
|
|
||||||
|
|
||||||
public static Vector2 operator +(Vector2 value) => value;
|
|
||||||
|
|
||||||
// Subtraction
|
|
||||||
|
|
||||||
public static Vector2 operator -(Vector2 left, Vector2 right) => Vector2(left.X - right.X, left.Y - right.Y);
|
|
||||||
|
|
||||||
public static Vector2 operator -(Vector2 value, float scalar) => Vector2(value.X - scalar, value.Y - scalar);
|
|
||||||
|
|
||||||
public static Vector2 operator -(float scalar, Vector2 value) => Vector2(scalar - value.X, scalar - value.Y);
|
|
||||||
|
|
||||||
public static Vector2 operator -(Vector2 value) => Vector2(-value.X, -value.Y);
|
|
||||||
|
|
||||||
// Multiplication
|
|
||||||
|
|
||||||
public static Vector2 operator *(Vector2 left, Vector2 right) => Vector2(left.X * right.X, left.Y * right.Y);
|
|
||||||
|
|
||||||
public static Vector2 operator *(Vector2 value, float scalar) => Vector2(value.X * scalar, value.Y * scalar);
|
|
||||||
|
|
||||||
public static Vector2 operator *(float scalar, Vector2 value) => Vector2(scalar * value.X, scalar * value.Y);
|
|
||||||
|
|
||||||
// Division
|
|
||||||
|
|
||||||
public static Vector2 operator /(Vector2 left, Vector2 right) => Vector2(left.X / right.X, left.Y / right.Y);
|
|
||||||
|
|
||||||
public static Vector2 operator /(Vector2 value, float scalar)
|
|
||||||
{
|
|
||||||
float inv = 1.0f / scalar;
|
|
||||||
return Vector2(value.X * inv, value.Y * inv);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector2 operator /(float scalar, Vector2 value) => Vector2(scalar / value.X, scalar / value.Y);
|
|
||||||
|
|
||||||
// Equality
|
|
||||||
|
|
||||||
public static bool operator ==(Vector2 left, Vector2 right) => left.X == right.X && left.Y == right.Y;
|
|
||||||
|
|
||||||
public static bool operator !=(Vector2 left, Vector2 right) => left.X != right.X || left.Y != right.Y;
|
|
||||||
|
|
||||||
public override void ToString(String strBuffer) => strBuffer.AppendF("X:{0} Y:{1}", X, Y);
|
|
||||||
|
|
||||||
public bool Equals(Vector2 v, float epsilon = Math.[Friend]sMachineEpsilonFloat)
|
|
||||||
{
|
|
||||||
return (Math.Abs(v.X - X) < epsilon) && (Math.Abs(v.Y - Y) < epsilon);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
public static explicit operator Self(float value) => Self(value);
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
#unwarn
|
|
||||||
public static explicit operator float[2](Vector2 value) => *(float[2]*)&value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,349 +0,0 @@
|
|||||||
using Bon;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Math
|
|
||||||
{
|
|
||||||
[BonTarget]
|
|
||||||
[SwizzleVector(3, "GlitchyEngine.Math.Vector")]
|
|
||||||
public struct Vector3
|
|
||||||
{
|
|
||||||
public const Vector3 Zero = .(0f, 0f, 0f);
|
|
||||||
public const Vector3 UnitX = .(1f, 0f, 0f);
|
|
||||||
public const Vector3 UnitY = .(0f, 1f, 0f);
|
|
||||||
public const Vector3 UnitZ = .(0f, 0f, 1f);
|
|
||||||
public const Vector3 One = .(1f, 1f, 1f);
|
|
||||||
|
|
||||||
public const Vector3 Forward = .(0f, 0f, 1f);
|
|
||||||
public const Vector3 Backward = .(0f, 0f, -1f);
|
|
||||||
public const Vector3 Left = .(-1f, 0f, 0f);
|
|
||||||
public const Vector3 Right = .(1f, 0f, 0f);
|
|
||||||
public const Vector3 Up = .(0f, 1f, 0f);
|
|
||||||
public const Vector3 Down = .(0f, -1f, 0f);
|
|
||||||
|
|
||||||
public const int ComponentCount = 3;
|
|
||||||
|
|
||||||
public float X, Y, Z;
|
|
||||||
|
|
||||||
public this() => this = default;
|
|
||||||
|
|
||||||
public this(float value)
|
|
||||||
{
|
|
||||||
X = value;
|
|
||||||
Y = value;
|
|
||||||
Z = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Vector2 value, float z = 0.0f)
|
|
||||||
{
|
|
||||||
X = value.X;
|
|
||||||
Y = value.Y;
|
|
||||||
Z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(float x, float y, float z)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = y;
|
|
||||||
Z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Vector3 value)
|
|
||||||
{
|
|
||||||
X = value.X;
|
|
||||||
Y = value.Y;
|
|
||||||
Z = value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Vector4 value)
|
|
||||||
{
|
|
||||||
X = value.X;
|
|
||||||
Y = value.Y;
|
|
||||||
Z = value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ref float this[int index]
|
|
||||||
{
|
|
||||||
[Checked]
|
|
||||||
get mut
|
|
||||||
{
|
|
||||||
if(index < 0 || index >= ComponentCount)
|
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
|
||||||
|
|
||||||
return ref (&X)[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
get mut => ref (&X)[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public float this[int index]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
switch(index)
|
|
||||||
{
|
|
||||||
case 0: return X;
|
|
||||||
case 1: return Y;
|
|
||||||
case 2: return Z;
|
|
||||||
default: Internal.ThrowIndexOutOfRange(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set mut
|
|
||||||
{
|
|
||||||
switch(index)
|
|
||||||
{
|
|
||||||
case 0: X = value;
|
|
||||||
case 1: Y = value;
|
|
||||||
case 2: Z = value;
|
|
||||||
default: Internal.ThrowIndexOutOfRange(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the magnitude (length) of this vector.
|
|
||||||
* @remarks If the exact magnitude isn't needed (e.g. for comparisons) consider using MagnitudeSquared which doesn't use the square root operation.
|
|
||||||
*/
|
|
||||||
public float Magnitude() => Math.Sqrt(X * X + Y * Y + Z * Z);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the squared magnitude (length) of this vector.
|
|
||||||
* @remarks This function avoids the square root operation to calculate the magnitude and is thus more suitable for comparisons where the exact magnitude isn't needed.
|
|
||||||
*/
|
|
||||||
public float MagnitudeSquared() => X * X + Y * Y + Z * Z;
|
|
||||||
|
|
||||||
/// Normalizes this vector.
|
|
||||||
[Checked]
|
|
||||||
public void Normalize() mut
|
|
||||||
{
|
|
||||||
if(this == .Zero)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this /= Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Normalizes this vector.
|
|
||||||
public void Normalize() mut
|
|
||||||
{
|
|
||||||
this /= Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a copy of this Vector with a magnitude of 1.
|
|
||||||
[Checked]
|
|
||||||
public Vector3 Normalized()
|
|
||||||
{
|
|
||||||
if(this == .Zero)
|
|
||||||
return .Zero;
|
|
||||||
|
|
||||||
return this / Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a copy of this Vector with a magnitude of 1.
|
|
||||||
public Vector3 Normalized()
|
|
||||||
{
|
|
||||||
return this / Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Returns a copy of the given Vector with a magnitude of 1.
|
|
||||||
public static Vector3 Normalize(Vector3 v)
|
|
||||||
{
|
|
||||||
return v / v.Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculates the dot product of two vectors.
|
|
||||||
public static float Dot(Vector3 l, Vector3 r) => l.X * r.X + l.Y * r.Y + l.Z * r.Z;
|
|
||||||
|
|
||||||
/// Calculates the distance between two vectors.
|
|
||||||
public static float Distance(Vector3 a, Vector3 b) => (a - b).[Inline]Magnitude();
|
|
||||||
|
|
||||||
/// Calculates the squared distance between two vectors.
|
|
||||||
public static float DistanceSquared(Vector3 a, Vector3 b) => (a - b).[Inline]MagnitudeSquared();
|
|
||||||
|
|
||||||
/// Calculates the cross product of two vectors.
|
|
||||||
public static Vector3 Cross(Vector3 l, Vector3 r)
|
|
||||||
{
|
|
||||||
return .(l.Y * r.Z - l.Z * r.Y,
|
|
||||||
l.Z * r.X - l.X * r.Z,
|
|
||||||
l.X * r.Y - l.Y * r.X);
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculates the projection of a onto b.
|
|
||||||
public static Vector3 Project(Vector3 a, Vector3 b)
|
|
||||||
{
|
|
||||||
return (b * (Dot(a, b) / Dot(b, b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Calculates the rejection of a from b.
|
|
||||||
public static Vector3 Reject(Vector3 a, Vector3 b)
|
|
||||||
{
|
|
||||||
return (a - b * (Dot(a, b) / Dot(b, b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector3 Floor(Vector3 value) => .(Math.Floor(value.X), Math.Floor(value.Y), Math.Floor(value.Z));
|
|
||||||
|
|
||||||
public static Vector3 Ceiling(Vector3 value) => .(Math.Ceiling(value.X), Math.Ceiling(value.Y), Math.Ceiling(value.Z));
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interpolates linearly between two given vectors.
|
|
||||||
* @param a The first vector.
|
|
||||||
* @param b The second vector.
|
|
||||||
* @param interpolationValue The value that linearly interpolates between a and b.
|
|
||||||
* (0 means a will be returned, 1 means b will be returned.)
|
|
||||||
* @returns The resulting linear interpolation.
|
|
||||||
*/
|
|
||||||
public static Vector3 Lerp(Vector3 a, Vector3 b, float interpolationValue)
|
|
||||||
{
|
|
||||||
return a + interpolationValue * (b - a);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector3 Min(Vector3 a, Vector3 b) => .(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Min(a.Z, b.Z));
|
|
||||||
|
|
||||||
public static Vector3 Max(Vector3 a, Vector3 b) => .(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y), Math.Min(a.Z, b.Z));
|
|
||||||
|
|
||||||
public static Vector3 Abs(Vector3 v) => .(Math.Abs(v.X), Math.Abs(v.Y), Math.Abs(v.Z));
|
|
||||||
|
|
||||||
public static Vector3 Clamp(Vector3 v, Vector3 min, Vector3 max)
|
|
||||||
{
|
|
||||||
return .(Math.Clamp(v.X, min.X, max.X),
|
|
||||||
Math.Clamp(v.Y, min.Y, max.Y),
|
|
||||||
Math.Clamp(v.X, min.Z, max.Z));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assignment operators
|
|
||||||
//
|
|
||||||
|
|
||||||
// Addition
|
|
||||||
|
|
||||||
public void operator +=(Vector3 value) mut
|
|
||||||
{
|
|
||||||
X += value.X;
|
|
||||||
Y += value.Y;
|
|
||||||
Z += value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator +=(float scalar) mut
|
|
||||||
{
|
|
||||||
X += scalar;
|
|
||||||
Y += scalar;
|
|
||||||
Z += scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtraction
|
|
||||||
|
|
||||||
public void operator -=(Vector3 value) mut
|
|
||||||
{
|
|
||||||
X -= value.X;
|
|
||||||
Y -= value.Y;
|
|
||||||
Z -= value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator -=(float scalar) mut
|
|
||||||
{
|
|
||||||
X -= scalar;
|
|
||||||
Y -= scalar;
|
|
||||||
Z -= scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiplication
|
|
||||||
|
|
||||||
public void operator *=(Vector3 value) mut
|
|
||||||
{
|
|
||||||
X *= value.X;
|
|
||||||
Y *= value.Y;
|
|
||||||
Z *= value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator *=(float scalar) mut
|
|
||||||
{
|
|
||||||
X *= scalar;
|
|
||||||
Y *= scalar;
|
|
||||||
Z *= scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Division
|
|
||||||
|
|
||||||
public void operator /=(Vector3 value) mut
|
|
||||||
{
|
|
||||||
X /= value.X;
|
|
||||||
Y /= value.Y;
|
|
||||||
Z /= value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator /=(float scalar) mut
|
|
||||||
{
|
|
||||||
float inv = 1.0f / scalar;
|
|
||||||
X *= inv;
|
|
||||||
Y *= inv;
|
|
||||||
Z *= inv;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// operators
|
|
||||||
//
|
|
||||||
|
|
||||||
// Addition
|
|
||||||
|
|
||||||
public static Vector3 operator +(Vector3 left, Vector3 right) => Vector3(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
|
||||||
|
|
||||||
public static Vector3 operator +(Vector3 value, float scalar) => Vector3(value.X + scalar, value.Y + scalar, value.Z + scalar);
|
|
||||||
|
|
||||||
public static Vector3 operator +(float scalar, Vector3 value) => Vector3(scalar + value.X, scalar + value.Y, scalar + value.Z);
|
|
||||||
|
|
||||||
public static Vector3 operator +(Vector3 value) => value;
|
|
||||||
|
|
||||||
// Subtraction
|
|
||||||
|
|
||||||
public static Vector3 operator -(Vector3 left, Vector3 right) => Vector3(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
|
||||||
|
|
||||||
public static Vector3 operator -(Vector3 value, float scalar) => Vector3(value.X - scalar, value.Y - scalar, value.Z - scalar);
|
|
||||||
|
|
||||||
public static Vector3 operator -(float scalar, Vector3 value) => Vector3(scalar - value.X, scalar - value.Y, scalar - value.Z);
|
|
||||||
|
|
||||||
public static Vector3 operator -(Vector3 value) => Vector3(-value.X, -value.Y, -value.Z);
|
|
||||||
|
|
||||||
// Multiplication
|
|
||||||
|
|
||||||
public static Vector3 operator *(Vector3 left, Vector3 right) => Vector3(left.X * right.X, left.Y * right.Y, left.Z * right.Z);
|
|
||||||
|
|
||||||
public static Vector3 operator *(Vector3 value, float scalar) => Vector3(value.X * scalar, value.Y * scalar, value.Z * scalar);
|
|
||||||
|
|
||||||
public static Vector3 operator *(float scalar, Vector3 value) => Vector3(scalar * value.X, scalar * value.Y, scalar * value.Z);
|
|
||||||
|
|
||||||
// Division
|
|
||||||
|
|
||||||
public static Vector3 operator /(Vector3 left, Vector3 right) => Vector3(left.X / right.X, left.Y / right.Y, left.Z / right.Z);
|
|
||||||
|
|
||||||
public static Vector3 operator /(Vector3 value, float scalar)
|
|
||||||
{
|
|
||||||
float inv = 1.0f / scalar;
|
|
||||||
return Vector3(value.X * inv, value.Y * inv, value.Z * inv);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector3 operator /(float scalar, Vector3 value) => Vector3(scalar / value.X, scalar / value.Y, scalar / value.Z);
|
|
||||||
|
|
||||||
// Modulo
|
|
||||||
|
|
||||||
public static Vector3 operator %(Vector3 left, Vector3 right) => Vector3(left.X % right.X, left.Y % right.Y, left.Z % right.Z);
|
|
||||||
|
|
||||||
public static Vector3 operator %(Vector3 value, float scalar) => Vector3(value.X % scalar, value.Y % scalar, value.Z % scalar);
|
|
||||||
|
|
||||||
public static Vector3 operator %(float scalar, Vector3 value) => Vector3(scalar % value.X, scalar % value.Y, scalar % value.Z);
|
|
||||||
|
|
||||||
// Equality
|
|
||||||
|
|
||||||
public static bool operator ==(Vector3 left, Vector3 right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z;
|
|
||||||
|
|
||||||
public static bool operator !=(Vector3 left, Vector3 right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z;
|
|
||||||
|
|
||||||
public override void ToString(String strBuffer) => strBuffer.AppendF("X:{0} Y:{1} Z:{2}", X, Y, Z);
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
public static explicit operator Self(float value) => Self(value);
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
#unwarn
|
|
||||||
public static explicit operator float[3](Vector3 value) => *(float[3]*)&value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,330 +0,0 @@
|
|||||||
using Bon;
|
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Math
|
|
||||||
{
|
|
||||||
[BonTarget]
|
|
||||||
[SwizzleVector(4, "GlitchyEngine.Math.Vector")]
|
|
||||||
public struct Vector4
|
|
||||||
{
|
|
||||||
public const Vector4 Zero = .(0f, 0f, 0f, 0f);
|
|
||||||
public const Vector4 UnitX = .(1f, 0f, 0f, 0f);
|
|
||||||
public const Vector4 UnitY = .(0f, 1f, 0f, 0f);
|
|
||||||
public const Vector4 UnitZ = .(0f, 0f, 1f, 0f);
|
|
||||||
public const Vector4 UnitW = .(0f, 0f, 0f, 1f);
|
|
||||||
public const Vector4 One = .(1f, 1f, 1f, 1f);
|
|
||||||
|
|
||||||
public const int ComponentCount = 4;
|
|
||||||
|
|
||||||
public float X, Y, Z, W;
|
|
||||||
|
|
||||||
public this() => this = default;
|
|
||||||
|
|
||||||
public this(float value)
|
|
||||||
{
|
|
||||||
X = value;
|
|
||||||
Y = value;
|
|
||||||
Z = value;
|
|
||||||
W = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Vector2 value, float z, float w)
|
|
||||||
{
|
|
||||||
X = value.X;
|
|
||||||
Y = value.Y;
|
|
||||||
Z = z;
|
|
||||||
W = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Vector2 value1, Vector2 value2)
|
|
||||||
{
|
|
||||||
X = value1.X;
|
|
||||||
Y = value1.Y;
|
|
||||||
Z = value2.X;
|
|
||||||
W = value2.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Vector3 value, float w)
|
|
||||||
{
|
|
||||||
X = value.X;
|
|
||||||
Y = value.Y;
|
|
||||||
Z = value.Z;
|
|
||||||
W = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(float x, float y, float z, float w)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = y;
|
|
||||||
Z = z;
|
|
||||||
W = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ref float this[int index]
|
|
||||||
{
|
|
||||||
[Checked]
|
|
||||||
get mut
|
|
||||||
{
|
|
||||||
if(index < 0 || index >= ComponentCount)
|
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
|
||||||
|
|
||||||
return ref (&X)[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
get mut => ref (&X)[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
public float this[int index]
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
switch(index)
|
|
||||||
{
|
|
||||||
case 0: return X;
|
|
||||||
case 1: return Y;
|
|
||||||
case 2: return Z;
|
|
||||||
case 3: return W;
|
|
||||||
default: Internal.ThrowIndexOutOfRange(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
set mut
|
|
||||||
{
|
|
||||||
switch(index)
|
|
||||||
{
|
|
||||||
case 0: X = value;
|
|
||||||
case 1: Y = value;
|
|
||||||
case 2: Z = value;
|
|
||||||
case 3: W = value;
|
|
||||||
default: Internal.ThrowIndexOutOfRange(1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the magnitude (length) of this vector.
|
|
||||||
* @remarks MagnitudeSquared might be used if only the relative length is relevant.
|
|
||||||
*/
|
|
||||||
public float Magnitude()
|
|
||||||
{
|
|
||||||
return Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the squared magnitude (length) of this vector.
|
|
||||||
*/
|
|
||||||
public float MagnitudeSquared()
|
|
||||||
{
|
|
||||||
return X * X + Y * Y + Z * Z + W * W;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Checked]
|
|
||||||
public void Normalize() mut
|
|
||||||
{
|
|
||||||
if(this == .Zero)
|
|
||||||
return;
|
|
||||||
|
|
||||||
this /= Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Normalize() mut
|
|
||||||
{
|
|
||||||
this /= Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector4 Normalize(Vector4 v)
|
|
||||||
{
|
|
||||||
if(v == .Zero)
|
|
||||||
return .Zero;
|
|
||||||
|
|
||||||
return v / v.Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
[Unchecked]
|
|
||||||
public static Vector4 Normalize(Vector4 v)
|
|
||||||
{
|
|
||||||
return v / v.Magnitude();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static float Dot(Vector4 l, Vector4 r)
|
|
||||||
{
|
|
||||||
return l.X * r.X + l.Y * r.Y + l.Z * r.Z + l.W * r.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the projection of a onto b
|
|
||||||
*/
|
|
||||||
public static Vector4 Project(Vector4 a, Vector4 b)
|
|
||||||
{
|
|
||||||
return (b * (Dot(a, b) / Dot(b, b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Calculates the rejection of a from b
|
|
||||||
*/
|
|
||||||
public static Vector4 Reject(Vector4 a, Vector4 b)
|
|
||||||
{
|
|
||||||
return (a - b * (Dot(a, b) / Dot(b, b)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Interpolates linearly between two given vectors.
|
|
||||||
* @param a The first vector.
|
|
||||||
* @param b The second vector.
|
|
||||||
* @param interpolationValue The value that linearly interpolates between a and b.
|
|
||||||
* (0 means a will be returned, 1 means b will be returned.)
|
|
||||||
* @returns The resulting linear interpolation.
|
|
||||||
*/
|
|
||||||
public static Vector4 Lerp(Vector4 a, Vector4 b, float interpolationValue)
|
|
||||||
{
|
|
||||||
return a + interpolationValue * (b - a);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector4 Min(Vector4 a, Vector4 b)
|
|
||||||
{
|
|
||||||
return .(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y), Math.Min(a.Z, b.Z), Math.Min(a.W, b.W));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector4 Max(Vector4 a, Vector4 b)
|
|
||||||
{
|
|
||||||
return .(Math.Max(a.X, b.X), Math.Max(a.Y, b.Y), Math.Min(a.Z, b.Z), Math.Min(a.W, b.W));
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assignment operators
|
|
||||||
//
|
|
||||||
|
|
||||||
// Addition
|
|
||||||
|
|
||||||
public void operator +=(Vector4 value) mut
|
|
||||||
{
|
|
||||||
X += value.X;
|
|
||||||
Y += value.Y;
|
|
||||||
Z += value.Z;
|
|
||||||
W += value.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator +=(float scalar) mut
|
|
||||||
{
|
|
||||||
X += scalar;
|
|
||||||
Y += scalar;
|
|
||||||
Z += scalar;
|
|
||||||
W += scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Subtraction
|
|
||||||
|
|
||||||
public void operator -=(Vector4 value) mut
|
|
||||||
{
|
|
||||||
X -= value.X;
|
|
||||||
Y -= value.Y;
|
|
||||||
Z -= value.Z;
|
|
||||||
W -= value.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator -=(float scalar) mut
|
|
||||||
{
|
|
||||||
X -= scalar;
|
|
||||||
Y -= scalar;
|
|
||||||
Z -= scalar;
|
|
||||||
W -= scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Multiplication
|
|
||||||
|
|
||||||
public void operator *=(Vector4 value) mut
|
|
||||||
{
|
|
||||||
X *= value.X;
|
|
||||||
Y *= value.Y;
|
|
||||||
Z *= value.Z;
|
|
||||||
W *= value.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator *=(float scalar) mut
|
|
||||||
{
|
|
||||||
X *= scalar;
|
|
||||||
Y *= scalar;
|
|
||||||
Z *= scalar;
|
|
||||||
W *= scalar;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Division
|
|
||||||
|
|
||||||
public void operator /=(float scalar) mut
|
|
||||||
{
|
|
||||||
float f = 1.0f / scalar;
|
|
||||||
X *= f;
|
|
||||||
Y *= f;
|
|
||||||
Z *= f;
|
|
||||||
W *= f;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator /=(Vector4 value) mut
|
|
||||||
{
|
|
||||||
X /= value.X;
|
|
||||||
Y /= value.Y;
|
|
||||||
Z /= value.Z;
|
|
||||||
W /= value.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// operators
|
|
||||||
//
|
|
||||||
|
|
||||||
// Addition
|
|
||||||
|
|
||||||
public static Vector4 operator +(Vector4 left, Vector4 right) => Vector4(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
|
||||||
|
|
||||||
public static Vector4 operator +(Vector4 value, float scalar) => Vector4(value.X + scalar, value.Y + scalar, value.Z + scalar, value.W + scalar);
|
|
||||||
|
|
||||||
public static Vector4 operator +(float scalar, Vector4 value) => Vector4(scalar + value.X, scalar + value.Y, scalar + value.Z, scalar + value.W);
|
|
||||||
|
|
||||||
public static Vector4 operator +(Vector4 value) => value;
|
|
||||||
|
|
||||||
// Subtraction
|
|
||||||
|
|
||||||
public static Vector4 operator -(Vector4 left, Vector4 right) => Vector4(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
|
||||||
|
|
||||||
public static Vector4 operator -(Vector4 value, float scalar) => Vector4(value.X - scalar, value.Y - scalar, value.Z - scalar, value.W - scalar);
|
|
||||||
|
|
||||||
public static Vector4 operator -(float scalar, Vector4 value) => Vector4(scalar - value.X, scalar - value.Y, scalar - value.Z, scalar - value.W);
|
|
||||||
|
|
||||||
public static Vector4 operator -(Vector4 value) => Vector4(-value.X, -value.Y, -value.Z, -value.W);
|
|
||||||
|
|
||||||
// Multiplication
|
|
||||||
|
|
||||||
public static Vector4 operator *(Vector4 left, Vector4 right) => Vector4(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
|
|
||||||
|
|
||||||
public static Vector4 operator *(Vector4 value, float scalar) => Vector4(value.X * scalar, value.Y * scalar, value.Z * scalar, value.W * scalar);
|
|
||||||
|
|
||||||
public static Vector4 operator *(float scalar, Vector4 value) => Vector4(scalar * value.X, scalar * value.Y, scalar * value.Z, scalar * value.W);
|
|
||||||
|
|
||||||
// Division
|
|
||||||
|
|
||||||
public static Vector4 operator /(Vector4 left, Vector4 right) => Vector4(left.X / right.X, left.Y / right.Y, left.Z / right.Z, left.W / right.W);
|
|
||||||
|
|
||||||
public static Vector4 operator /(Vector4 value, float scalar)
|
|
||||||
{
|
|
||||||
float inv = 1.0f / scalar;
|
|
||||||
return Vector4(value.X * inv, value.Y * inv, value.Z * inv, value.W * inv);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Vector4 operator /(float scalar, Vector4 value) => Vector4(scalar / value.X, scalar / value.Y, scalar / value.Z, scalar / value.W);
|
|
||||||
|
|
||||||
// Equality
|
|
||||||
|
|
||||||
public static bool operator ==(Vector4 left, Vector4 right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z && left.W == right.W;
|
|
||||||
|
|
||||||
public static bool operator !=(Vector4 left, Vector4 right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z || left.W != right.W;
|
|
||||||
|
|
||||||
public override void ToString(String strBuffer) => strBuffer.AppendF("X:{0} Y:{1} Z:{2} W:{3}", X, Y, Z, W);
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
public static explicit operator Self(float value) => Self(value);
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
#unwarn
|
|
||||||
public static explicit operator float[4](Vector4 value) => *(float[4]*)&value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,440 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math;
|
||||||
|
|
||||||
|
[AttributeUsage(.Struct | .Class)]
|
||||||
|
struct VectorAttribute<T, ComponentCount> : Attribute, IComptimeTypeApply where ComponentCount : const int
|
||||||
|
{
|
||||||
|
public const String[4] ComponentNames = .("X", "Y", "Z", "W");
|
||||||
|
public const String[4] LowerComponentNames = .("x", "y", "z", "w");
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public void ApplyToType(Type type)
|
||||||
|
{
|
||||||
|
GenerateFields(type);
|
||||||
|
|
||||||
|
GenerateCasts(type);
|
||||||
|
|
||||||
|
GenerateConstructors(type);
|
||||||
|
|
||||||
|
GenerateEqualityOperators(type);
|
||||||
|
|
||||||
|
GenerateArrayAccess(type);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
private void GenerateFields(Type type)
|
||||||
|
{
|
||||||
|
String fields = scope $"public {typeof(T)} ";
|
||||||
|
|
||||||
|
for (int i < ComponentCount)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
fields.Append(", ");
|
||||||
|
|
||||||
|
fields.Append(ComponentNames[i]);
|
||||||
|
}
|
||||||
|
fields.Append(";\n\n");
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, fields);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
private void GenerateCasts(Type type)
|
||||||
|
{
|
||||||
|
String constructorBody = scope String();
|
||||||
|
|
||||||
|
for (int i < ComponentCount)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
constructorBody.Append(", ");
|
||||||
|
|
||||||
|
constructorBody.Append("value");
|
||||||
|
}
|
||||||
|
|
||||||
|
String castSingleToVector = scope $"""
|
||||||
|
public static implicit operator Self({typeof(T)} value)
|
||||||
|
{{
|
||||||
|
return Self({constructorBody});
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, castSingleToVector);
|
||||||
|
|
||||||
|
String castVectorToArray = scope $"""
|
||||||
|
[System.Inline]
|
||||||
|
#unwarn
|
||||||
|
public static explicit operator {typeof(T)}[{ComponentCount}](Self value) => *({typeof(T)}[{ComponentCount}]*)&value;
|
||||||
|
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, castVectorToArray);
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Constructors
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
private void GenerateConstructors(Type type)
|
||||||
|
{
|
||||||
|
// Default constructor
|
||||||
|
//Compiler.EmitTypeBody(type, "public this() => this = default;\n\n");
|
||||||
|
|
||||||
|
// Single constructor
|
||||||
|
GenerateSingleConstructor(type);
|
||||||
|
|
||||||
|
if (ComponentCount == 3)
|
||||||
|
{
|
||||||
|
Generatefloat3Constructors(type);
|
||||||
|
}
|
||||||
|
else if (ComponentCount == 4)
|
||||||
|
{
|
||||||
|
Generatefloat4Constructors(type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
private void GenerateSingleConstructor(Type type)
|
||||||
|
{
|
||||||
|
String parameters = scope .();
|
||||||
|
|
||||||
|
for (int i < ComponentCount)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
parameters.Append(", ");
|
||||||
|
|
||||||
|
parameters.AppendF($"{typeof(T)} {LowerComponentNames[i]}");
|
||||||
|
}
|
||||||
|
|
||||||
|
String body = scope .();
|
||||||
|
|
||||||
|
for (int i < ComponentCount)
|
||||||
|
{
|
||||||
|
body.AppendF($"\t{ComponentNames[i]} = {LowerComponentNames[i]};\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
String constructor = scope $"""
|
||||||
|
public this({parameters})
|
||||||
|
{{
|
||||||
|
{body}
|
||||||
|
}}
|
||||||
|
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, constructor);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
private void Generatefloat3Constructors(Type type)
|
||||||
|
{
|
||||||
|
String baseName = type.GetName(.. scope String());
|
||||||
|
|
||||||
|
// Remove number from name
|
||||||
|
baseName.RemoveFromEnd(1);
|
||||||
|
|
||||||
|
String constructor1 = scope $"""
|
||||||
|
public this({baseName}2 xy, {typeof(T)} z)
|
||||||
|
{{
|
||||||
|
X = xy.X;
|
||||||
|
Y = xy.Y;
|
||||||
|
Z = z;
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, constructor1);
|
||||||
|
|
||||||
|
String constructor2 = scope $"""
|
||||||
|
public this({typeof(T)} x, {baseName}2 yz)
|
||||||
|
{{
|
||||||
|
X = x;
|
||||||
|
Y = yz.X;
|
||||||
|
Z = yz.Y;
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, constructor2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
private void Generatefloat4Constructors(Type type)
|
||||||
|
{
|
||||||
|
String baseName = type.GetName(.. scope String());
|
||||||
|
|
||||||
|
// Remove number from name
|
||||||
|
baseName.RemoveFromEnd(1);
|
||||||
|
|
||||||
|
String constructor = scope $"""
|
||||||
|
public this({baseName}2 xy, {baseName}2 zw)
|
||||||
|
{{
|
||||||
|
X = xy.X;
|
||||||
|
Y = xy.Y;
|
||||||
|
Z = zw.X;
|
||||||
|
W = zw.Y;
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, constructor);
|
||||||
|
|
||||||
|
|
||||||
|
String constructor1 = scope $"""
|
||||||
|
public this({baseName}2 xy, {typeof(T)} z, {typeof(T)} w)
|
||||||
|
{{
|
||||||
|
X = xy.X;
|
||||||
|
Y = xy.Y;
|
||||||
|
Z = z;
|
||||||
|
W = w;
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, constructor1);
|
||||||
|
|
||||||
|
String constructor2 = scope $"""
|
||||||
|
public this({typeof(T)} x, {baseName}2 yz, {typeof(T)} w)
|
||||||
|
{{
|
||||||
|
X = x;
|
||||||
|
Y = yz.X;
|
||||||
|
Z = yz.Y;
|
||||||
|
W = w;
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, constructor2);
|
||||||
|
|
||||||
|
String constructor3 = scope $"""
|
||||||
|
public this({typeof(T)} x, {typeof(T)} y, {baseName}2 zw)
|
||||||
|
{{
|
||||||
|
X = x;
|
||||||
|
Y = y;
|
||||||
|
Z = zw.X;
|
||||||
|
W = zw.Y;
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, constructor3);
|
||||||
|
|
||||||
|
|
||||||
|
String constructor4 = scope $"""
|
||||||
|
public this({baseName}3 xyz, {typeof(T)} w)
|
||||||
|
{{
|
||||||
|
X = xyz.X;
|
||||||
|
Y = xyz.Y;
|
||||||
|
Z = xyz.Z;
|
||||||
|
W = w;
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, constructor4);
|
||||||
|
|
||||||
|
String constructor5 = scope $"""
|
||||||
|
public this({typeof(T)} x, {baseName}3 yzw)
|
||||||
|
{{
|
||||||
|
X = x;
|
||||||
|
Y = yzw.X;
|
||||||
|
Z = yzw.Y;
|
||||||
|
W = yzw.Z;
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, constructor5);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion Constructors
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
private void GenerateEqualityOperators(Type type)
|
||||||
|
{
|
||||||
|
GenerateComparison(type, "==");
|
||||||
|
GenerateComparison(type, "!=");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public static void GenerateComparison(Type type, String op)
|
||||||
|
{
|
||||||
|
String boolConstructor = scope .();
|
||||||
|
|
||||||
|
for (int i < ComponentCount)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
boolConstructor.Append(", ");
|
||||||
|
|
||||||
|
boolConstructor.AppendF($"left.{ComponentNames[i]} {op} right.{ComponentNames[i]}");
|
||||||
|
}
|
||||||
|
|
||||||
|
String typeName = type.GetName(.. scope String());
|
||||||
|
|
||||||
|
String func = scope $"""
|
||||||
|
public static bool{ComponentCount} operator{op}({typeName} left, {typeName} right)
|
||||||
|
{{
|
||||||
|
return bool{ComponentCount}({boolConstructor});
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
private static void GenerateArrayAccess(Type type)
|
||||||
|
{
|
||||||
|
String arrayAccess = scope $"""
|
||||||
|
public {typeof(T)} this[int index]
|
||||||
|
{{
|
||||||
|
get
|
||||||
|
{{
|
||||||
|
if(index < 0 || index >= {ComponentCount})
|
||||||
|
System.Internal.ThrowIndexOutOfRange(1);
|
||||||
|
|
||||||
|
#unwarn
|
||||||
|
return (&X)[index];
|
||||||
|
}}
|
||||||
|
set mut
|
||||||
|
{{
|
||||||
|
if(index < 0 || index >= {ComponentCount})
|
||||||
|
System.Internal.ThrowIndexOutOfRange(1);
|
||||||
|
|
||||||
|
#unwarn
|
||||||
|
(&X)[index] = value;
|
||||||
|
}}
|
||||||
|
}}
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, arrayAccess);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.Struct | .Class)]
|
||||||
|
struct ComparableVectorAttribute<T, ComponentCount> : Attribute, IComptimeTypeApply where ComponentCount : const int
|
||||||
|
{
|
||||||
|
[Comptime]
|
||||||
|
public void ApplyToType(Type type)
|
||||||
|
{
|
||||||
|
VectorAttribute<T, ComponentCount>.GenerateComparison(type, ">");
|
||||||
|
VectorAttribute<T, ComponentCount>.GenerateComparison(type, ">=");
|
||||||
|
VectorAttribute<T, ComponentCount>.GenerateComparison(type, "<");
|
||||||
|
VectorAttribute<T, ComponentCount>.GenerateComparison(type, "<=");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[AttributeUsage(.Struct | .Class)]
|
||||||
|
struct VectorMathAttribute<T, ComponentCount> : Attribute, IComptimeTypeApply where ComponentCount : const int
|
||||||
|
{
|
||||||
|
public const String[4] ComponentNames = .("X", "Y", "Z", "W");
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public void ApplyToType(Type type)
|
||||||
|
{
|
||||||
|
GenerateUnaryOperatorOverloads(type);
|
||||||
|
|
||||||
|
GenerateOperatorOverloads(type, "+");
|
||||||
|
GenerateOperatorOverloads(type, "-");
|
||||||
|
GenerateOperatorOverloads(type, "*");
|
||||||
|
GenerateOperatorOverloads(type, "/");
|
||||||
|
GenerateOperatorOverloads(type, "%");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public static void GenerateUnaryOperatorOverloads(Type type)
|
||||||
|
{
|
||||||
|
String typeName = type.GetName(.. scope String());
|
||||||
|
|
||||||
|
String unaryAdd = scope $"""
|
||||||
|
public static {typeName} operator+({typeName} value) => value;
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, unaryAdd);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
String resultArguments = scope .();
|
||||||
|
|
||||||
|
for (int i < ComponentCount)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
resultArguments.Append(", ");
|
||||||
|
|
||||||
|
resultArguments.AppendF($"-value.{ComponentNames[i]}");
|
||||||
|
}
|
||||||
|
|
||||||
|
String unaryMinus = scope $"""
|
||||||
|
public static {typeName} operator-({typeName} value)
|
||||||
|
{{
|
||||||
|
return {typeName}({resultArguments});
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, unaryMinus);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
public static void GenerateOperatorOverloads(Type type, String op)
|
||||||
|
{
|
||||||
|
String typeName = type.GetName(.. scope String());
|
||||||
|
String componentTypeName = typeof(T).GetName(.. scope String());
|
||||||
|
|
||||||
|
[Comptime]
|
||||||
|
void EmitOperatorOverload(String leftType, String rightType, String resultArguments)
|
||||||
|
{
|
||||||
|
String func = scope $"""
|
||||||
|
public static {typeName} operator{op}({leftType} left, {rightType} right)
|
||||||
|
{{
|
||||||
|
return {typeName}({resultArguments});
|
||||||
|
}}
|
||||||
|
|
||||||
|
""";
|
||||||
|
|
||||||
|
Compiler.EmitTypeBody(type, func);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Vector + Vector
|
||||||
|
String resultArguments = scope .();
|
||||||
|
|
||||||
|
for (int i < ComponentCount)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
resultArguments.Append(", ");
|
||||||
|
|
||||||
|
resultArguments.AppendF($"left.{ComponentNames[i]} {op} right.{ComponentNames[i]}");
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitOperatorOverload(typeName, typeName, resultArguments);
|
||||||
|
|
||||||
|
// Vector + Scalar
|
||||||
|
resultArguments.Clear();
|
||||||
|
|
||||||
|
for (int i < ComponentCount)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
resultArguments.Append(", ");
|
||||||
|
|
||||||
|
resultArguments.AppendF($"left.{ComponentNames[i]} {op} right");
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitOperatorOverload(typeName, componentTypeName, resultArguments);
|
||||||
|
|
||||||
|
// Scalar + Vector
|
||||||
|
resultArguments.Clear();
|
||||||
|
|
||||||
|
for (int i < ComponentCount)
|
||||||
|
{
|
||||||
|
if (i != 0)
|
||||||
|
resultArguments.Append(", ");
|
||||||
|
|
||||||
|
resultArguments.AppendF($"left {op} right.{ComponentNames[i]}");
|
||||||
|
}
|
||||||
|
|
||||||
|
EmitOperatorOverload(componentTypeName, typeName, resultArguments);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,162 +0,0 @@
|
|||||||
#pragma warning disable 4204
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Math
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* A Vector with two components of type int32.
|
|
||||||
*/
|
|
||||||
[SwizzleVector(2, "Int")]
|
|
||||||
public struct Int2 : IHashable
|
|
||||||
{
|
|
||||||
public const Int2 Zero = .(0, 0);
|
|
||||||
public const Int2 UnitX = .(1, 0);
|
|
||||||
public const Int2 UnitY = .(0, 1);
|
|
||||||
public const Int2 One = .(1, 1);
|
|
||||||
|
|
||||||
public int32 X, Y;
|
|
||||||
|
|
||||||
public this() => this = default;
|
|
||||||
|
|
||||||
public this(int32 value)
|
|
||||||
{
|
|
||||||
X = value;
|
|
||||||
Y = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int value)
|
|
||||||
{
|
|
||||||
X = (.)value;
|
|
||||||
Y = (.)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, int32 y)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int x, int y)
|
|
||||||
{
|
|
||||||
X = (.)x;
|
|
||||||
Y = (.)y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ref int32 this[int index]
|
|
||||||
{
|
|
||||||
[Inline]
|
|
||||||
get
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
if(index < 0 || index >= 2)
|
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ref (&X)[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int32 MagnitudeSquared() => X * X + Y * Y;
|
|
||||||
|
|
||||||
public float Magnitude() => Math.Sqrt(X * X + Y * Y);
|
|
||||||
|
|
||||||
public Int2 Abs() => .(Math.Abs(X), Math.Abs(Y));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assignment operators
|
|
||||||
//
|
|
||||||
|
|
||||||
public void operator +=(Int2 value) mut
|
|
||||||
{
|
|
||||||
X += value.X;
|
|
||||||
Y += value.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator +=(int32 value) mut
|
|
||||||
{
|
|
||||||
X += value;
|
|
||||||
Y += value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator -=(Int2 value) mut
|
|
||||||
{
|
|
||||||
X -= value.X;
|
|
||||||
Y -= value.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator -=(int32 value) mut
|
|
||||||
{
|
|
||||||
X -= value;
|
|
||||||
Y -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator *=(Int2 value) mut
|
|
||||||
{
|
|
||||||
X *= value.X;
|
|
||||||
Y *= value.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator *=(int32 value) mut
|
|
||||||
{
|
|
||||||
X *= value;
|
|
||||||
Y *= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator /=(Int2 value) mut
|
|
||||||
{
|
|
||||||
X /= value.X;
|
|
||||||
Y /= value.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator /=(int32 value) mut
|
|
||||||
{
|
|
||||||
X /= value;
|
|
||||||
Y /= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Operators
|
|
||||||
|
|
||||||
public static Int2 operator +(Int2 value) => value;
|
|
||||||
public static Int2 operator +(Int2 left, Int2 right) => .(left.X + right.X, left.Y + right.Y);
|
|
||||||
public static Int2 operator +(Int2 left, int32 right) => .(left.X + right, left.Y + right);
|
|
||||||
public static Int2 operator +(int32 left, Int2 right) => .(left + right.X, left + right.Y);
|
|
||||||
|
|
||||||
public static Int2 operator -(Int2 value) => .(-value.X, -value.Y);
|
|
||||||
public static Int2 operator -(Int2 left, Int2 right) => .(left.X - right.X, left.Y - right.Y);
|
|
||||||
public static Int2 operator -(Int2 left, int32 right) => .(left.X - right, left.Y - right);
|
|
||||||
public static Int2 operator -(int32 left, Int2 right) => .(left - right.X, left - right.Y);
|
|
||||||
|
|
||||||
public static Int2 operator *(Int2 left, Int2 right) => .(left.X * right.X, left.Y * right.Y);
|
|
||||||
public static Int2 operator *(Int2 left, int32 right) => .(left.X * right, left.Y * right);
|
|
||||||
public static Int2 operator *(int32 left, Int2 right) => .(left * right.X, left * right.Y);
|
|
||||||
|
|
||||||
public static Int2 operator /(Int2 left, Int2 right) => .(left.X / right.X, left.Y / right.Y);
|
|
||||||
public static Int2 operator /(Int2 left, int32 right) => .(left.X / right, left.Y / right);
|
|
||||||
public static Int2 operator /(int32 left, Int2 right) => .(left / right.X, left / right.Y);
|
|
||||||
|
|
||||||
public static Int2 operator %(Int2 left, Int2 right) => .(left.X % right.X, left.Y % right.Y);
|
|
||||||
public static Int2 operator %(Int2 left, int32 right) => .(left.X % right, left.Y % right);
|
|
||||||
public static Int2 operator %(int32 left, Int2 right) => .(left % right.X, left % right.Y);
|
|
||||||
|
|
||||||
public static bool operator ==(Int2 left, Int2 right) => left.X == right.X && left.Y == right.Y;
|
|
||||||
public static bool operator ==(Int2 left, int32 right) => left.X == right && left.Y == right;
|
|
||||||
public static bool operator ==(int32 left, Int2 right) => left == right.X && left == right.Y;
|
|
||||||
|
|
||||||
public static bool operator !=(Int2 left, Int2 right) => left.X != right.X || left.Y != right.Y;
|
|
||||||
public static bool operator !=(Int2 left, int32 right) => left.X != right || left.Y != right;
|
|
||||||
public static bool operator !=(int32 left, Int2 right) => left != right.X || left != right.Y;
|
|
||||||
|
|
||||||
public override void ToString(String strBuffer) => strBuffer.AppendF($"X:{X} Y:{Y}");
|
|
||||||
|
|
||||||
public static explicit operator Vector2(Int2 point) => .(point.X, point.Y);
|
|
||||||
|
|
||||||
public static explicit operator Int2(Vector2 point) => .((int32)point.X, (int32)point.Y);
|
|
||||||
|
|
||||||
public int GetHashCode()
|
|
||||||
{
|
|
||||||
return (X * 39) ^ Y;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,206 +0,0 @@
|
|||||||
#pragma warning disable 4204
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Math
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* A Vector with three components of type int32.
|
|
||||||
*/
|
|
||||||
[SwizzleVector(3, "Int")]
|
|
||||||
public struct Int3 : IHashable
|
|
||||||
{
|
|
||||||
public const Int3 Zero = .(0, 0, 0);
|
|
||||||
public const Int3 UnitX = .(1, 0, 0);
|
|
||||||
public const Int3 UnitY = .(0, 1, 0);
|
|
||||||
public const Int3 UnitZ = .(0, 0, 1);
|
|
||||||
public const Int3 One = .(1, 1, 1);
|
|
||||||
|
|
||||||
public int32 X, Y, Z;
|
|
||||||
|
|
||||||
public this() => this = default;
|
|
||||||
|
|
||||||
public this(int32 value)
|
|
||||||
{
|
|
||||||
X = value;
|
|
||||||
Y = value;
|
|
||||||
Z = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int value)
|
|
||||||
{
|
|
||||||
X = (.)value;
|
|
||||||
Y = (.)value;
|
|
||||||
Z = (.)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, int32 y, int32 z)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = y;
|
|
||||||
Z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Int2 xy, int32 z)
|
|
||||||
{
|
|
||||||
X = xy.X;
|
|
||||||
Y = xy.Y;
|
|
||||||
Z = z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, Int2 yz)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = yz.X;
|
|
||||||
Z = yz.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int x, int y, int z)
|
|
||||||
{
|
|
||||||
X = (.)x;
|
|
||||||
Y = (.)y;
|
|
||||||
Z = (.)z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Int2 xy, int z)
|
|
||||||
{
|
|
||||||
X = xy.X;
|
|
||||||
Y = xy.Y;
|
|
||||||
Z = (.)z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int x, Int2 yz)
|
|
||||||
{
|
|
||||||
X = (.)x;
|
|
||||||
Y = yz.X;
|
|
||||||
Z = yz.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ref int32 this[int index]
|
|
||||||
{
|
|
||||||
[Inline]
|
|
||||||
get
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
if(index < 0 || index >= 3)
|
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ref (&X)[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int32 MagnitudeSquared() => X * X + Y * Y + Z * Z;
|
|
||||||
|
|
||||||
public float Magnitude() => Math.Sqrt(X * X + Y * Y + Z * Z);
|
|
||||||
|
|
||||||
public Int3 Abs() => .(Math.Abs(X), Math.Abs(Y), Math.Abs(Z));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assignment operators
|
|
||||||
//
|
|
||||||
|
|
||||||
public void operator +=(Int3 value) mut
|
|
||||||
{
|
|
||||||
X += value.X;
|
|
||||||
Y += value.Y;
|
|
||||||
Z += value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator +=(int32 value) mut
|
|
||||||
{
|
|
||||||
X += value;
|
|
||||||
Y += value;
|
|
||||||
Z += value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator -=(Int3 value) mut
|
|
||||||
{
|
|
||||||
X -= value.X;
|
|
||||||
Y -= value.Y;
|
|
||||||
Z -= value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator -=(int32 value) mut
|
|
||||||
{
|
|
||||||
X -= value;
|
|
||||||
Y -= value;
|
|
||||||
Z -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator *=(Int3 value) mut
|
|
||||||
{
|
|
||||||
X *= value.X;
|
|
||||||
Y *= value.Y;
|
|
||||||
Z *= value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator *=(int32 value) mut
|
|
||||||
{
|
|
||||||
X *= value;
|
|
||||||
Y *= value;
|
|
||||||
Z *= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator /=(Int3 value) mut
|
|
||||||
{
|
|
||||||
X /= value.X;
|
|
||||||
Y /= value.Y;
|
|
||||||
Z /= value.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator /=(int32 value) mut
|
|
||||||
{
|
|
||||||
X /= value;
|
|
||||||
Y /= value;
|
|
||||||
Z /= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Operators
|
|
||||||
|
|
||||||
public static Int3 operator +(Int3 value) => value;
|
|
||||||
public static Int3 operator +(Int3 left, Int3 right) => .(left.X + right.X, left.Y + right.Y, left.Z + right.Z);
|
|
||||||
public static Int3 operator +(Int3 left, int32 right) => .(left.X + right, left.Y + right, left.Z + right);
|
|
||||||
public static Int3 operator +(int32 left, Int3 right) => .(left + right.X, left + right.Y, left + right.Z);
|
|
||||||
|
|
||||||
public static Int3 operator -(Int3 value) => .(-value.X, -value.Y, -value.Z);
|
|
||||||
public static Int3 operator -(Int3 left, Int3 right) => .(left.X - right.X, left.Y - right.Y, left.Z - right.Z);
|
|
||||||
public static Int3 operator -(Int3 left, int32 right) => .(left.X - right, left.Y - right, left.Z- right);
|
|
||||||
public static Int3 operator -(int32 left, Int3 right) => .(left - right.X, left - right.Y, left - right.Z);
|
|
||||||
|
|
||||||
public static Int3 operator *(Int3 left, Int3 right) => .(left.X * right.X, left.Y * right.Y, left.Z * right.Z);
|
|
||||||
public static Int3 operator *(Int3 left, int32 right) => .(left.X * right, left.Y * right, left.Z * right);
|
|
||||||
public static Int3 operator *(int32 left, Int3 right) => .(left * right.X, left * right.Y, left * right.Z);
|
|
||||||
|
|
||||||
public static Int3 operator /(Int3 left, Int3 right) => .(left.X / right.X, left.Y / right.Y, left.Z / right.Z);
|
|
||||||
public static Int3 operator /(Int3 left, int32 right) => .(left.X / right, left.Y / right, left.Z / right);
|
|
||||||
public static Int3 operator /(int32 left, Int3 right) => .(left / right.X, left / right.Y, left / right.Z);
|
|
||||||
|
|
||||||
public static Int3 operator %(Int3 left, Int3 right) => .(left.X % right.X, left.Y % right.Y, left.Z % right.Z);
|
|
||||||
public static Int3 operator %(Int3 left, int32 right) => .(left.X % right, left.Y % right, left.Z % right);
|
|
||||||
public static Int3 operator %(int32 left, Int3 right) => .(left % right.X, left % right.Y, left % right.Z);
|
|
||||||
|
|
||||||
public static bool operator ==(Int3 left, Int3 right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z;
|
|
||||||
public static bool operator ==(Int3 left, int32 right) => left.X == right && left.Y == right && left.Z == right;
|
|
||||||
public static bool operator ==(int32 left, Int3 right) => left == right.X && left == right.Y && left == right.Z;
|
|
||||||
|
|
||||||
public static bool operator !=(Int3 left, Int3 right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z;
|
|
||||||
public static bool operator !=(Int3 left, int32 right) => left.X != right || left.Y != right || left.Z != right;
|
|
||||||
public static bool operator !=(int32 left, Int3 right) => left != right.X || left != right.Y || left != right.Z;
|
|
||||||
|
|
||||||
public override void ToString(String strBuffer) => strBuffer.AppendF($"X:{X} Y:{Y} Z:{Z}");
|
|
||||||
|
|
||||||
public static explicit operator Vector3(Int3 point) => .(point.X, point.Y, point.Z);
|
|
||||||
|
|
||||||
public static explicit operator Int3(Vector3 point) => .((int32)point.X, (int32)point.Y, (int32)point.Z);
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
public static explicit operator Int2(in Int3 point) => *(Int2*)&point;
|
|
||||||
|
|
||||||
public int GetHashCode()
|
|
||||||
{
|
|
||||||
return (((X * 39) ^ Y) * 39) ^ Z;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,234 +0,0 @@
|
|||||||
#pragma warning disable 4204
|
|
||||||
|
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace GlitchyEngine.Math
|
|
||||||
{
|
|
||||||
/**
|
|
||||||
* A Vector with four components of type int32.
|
|
||||||
*/
|
|
||||||
[SwizzleVector(4, "Int")]
|
|
||||||
public struct Int4 : IHashable
|
|
||||||
{
|
|
||||||
public const Int4 Zero = .(0, 0, 0, 0);
|
|
||||||
public const Int4 UnitX = .(1, 0, 0, 0);
|
|
||||||
public const Int4 UnitY = .(0, 1, 0, 0);
|
|
||||||
public const Int4 UnitZ = .(0, 0, 1, 0);
|
|
||||||
public const Int4 UnitW = .(0, 0, 0, 1);
|
|
||||||
public const Int4 One = .(1, 1, 1, 1);
|
|
||||||
|
|
||||||
public int32 X, Y, Z, W;
|
|
||||||
|
|
||||||
public this() => this = default;
|
|
||||||
|
|
||||||
public this(int32 value)
|
|
||||||
{
|
|
||||||
X = value;
|
|
||||||
Y = value;
|
|
||||||
Z = value;
|
|
||||||
W = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int value)
|
|
||||||
{
|
|
||||||
X = (.)value;
|
|
||||||
Y = (.)value;
|
|
||||||
Z = (.)value;
|
|
||||||
W = (.)value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, int32 y, int32 z, int32 w)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = y;
|
|
||||||
Z = z;
|
|
||||||
W = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Int2 xy, int32 z, int32 w)
|
|
||||||
{
|
|
||||||
X = xy.X;
|
|
||||||
Y = xy.Y;
|
|
||||||
Z = z;
|
|
||||||
W = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, Int2 yz, int32 w)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = yz.X;
|
|
||||||
Z = yz.Y;
|
|
||||||
W = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, int32 y, Int2 zw)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = y;
|
|
||||||
Z = zw.X;
|
|
||||||
W = zw.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Int2 xy, Int2 zw)
|
|
||||||
{
|
|
||||||
X = xy.X;
|
|
||||||
Y = xy.Y;
|
|
||||||
Z = zw.X;
|
|
||||||
W = zw.Y;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(Int3 xyz, int32 w)
|
|
||||||
{
|
|
||||||
X = xyz.X;
|
|
||||||
Y = xyz.Y;
|
|
||||||
Z = xyz.Z;
|
|
||||||
W = w;
|
|
||||||
}
|
|
||||||
|
|
||||||
public this(int32 x, Int3 yzw)
|
|
||||||
{
|
|
||||||
X = x;
|
|
||||||
Y = yzw.X;
|
|
||||||
Z = yzw.Y;
|
|
||||||
W = yzw.Z;
|
|
||||||
}
|
|
||||||
|
|
||||||
public ref int32 this[int index]
|
|
||||||
{
|
|
||||||
[Inline]
|
|
||||||
get
|
|
||||||
{
|
|
||||||
#if DEBUG
|
|
||||||
if(index < 0 || index >= 3)
|
|
||||||
Internal.ThrowIndexOutOfRange(1);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return ref (&X)[index];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public int32 MagnitudeSquared() => X * X + Y * Y + Z * Z + W * W;
|
|
||||||
|
|
||||||
public float Magnitude() => Math.Sqrt(X * X + Y * Y + Z * Z + W * W);
|
|
||||||
|
|
||||||
public Int4 Abs() => .(Math.Abs(X), Math.Abs(Y), Math.Abs(Z), Math.Abs(W));
|
|
||||||
|
|
||||||
//
|
|
||||||
// Assignment operators
|
|
||||||
//
|
|
||||||
|
|
||||||
public void operator +=(Int4 value) mut
|
|
||||||
{
|
|
||||||
X += value.X;
|
|
||||||
Y += value.Y;
|
|
||||||
Z += value.Z;
|
|
||||||
W += value.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator +=(int32 value) mut
|
|
||||||
{
|
|
||||||
X += value;
|
|
||||||
Y += value;
|
|
||||||
Z += value;
|
|
||||||
W += value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator -=(Int4 value) mut
|
|
||||||
{
|
|
||||||
X -= value.X;
|
|
||||||
Y -= value.Y;
|
|
||||||
Z -= value.Z;
|
|
||||||
W -= value.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator -=(int32 value) mut
|
|
||||||
{
|
|
||||||
X -= value;
|
|
||||||
Y -= value;
|
|
||||||
Z -= value;
|
|
||||||
W -= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator *=(Int4 value) mut
|
|
||||||
{
|
|
||||||
X *= value.X;
|
|
||||||
Y *= value.Y;
|
|
||||||
Z *= value.Z;
|
|
||||||
W *= value.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator *=(int32 value) mut
|
|
||||||
{
|
|
||||||
X *= value;
|
|
||||||
Y *= value;
|
|
||||||
Z *= value;
|
|
||||||
W *= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator /=(Int4 value) mut
|
|
||||||
{
|
|
||||||
X /= value.X;
|
|
||||||
Y /= value.Y;
|
|
||||||
Z /= value.Z;
|
|
||||||
W /= value.W;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void operator /=(int32 value) mut
|
|
||||||
{
|
|
||||||
X /= value;
|
|
||||||
Y /= value;
|
|
||||||
Z /= value;
|
|
||||||
W /= value;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Operators
|
|
||||||
|
|
||||||
public static Int4 operator +(Int4 value) => value;
|
|
||||||
public static Int4 operator +(Int4 left, Int4 right) => .(left.X + right.X, left.Y + right.Y, left.Z + right.Z, left.W + right.W);
|
|
||||||
public static Int4 operator +(Int4 left, int32 right) => .(left.X + right, left.Y + right, left.Z + right, left.W + right);
|
|
||||||
public static Int4 operator +(int32 left, Int4 right) => .(left + right.X, left + right.Y, left + right.Z, left + right.W);
|
|
||||||
|
|
||||||
public static Int4 operator -(Int4 value) => .(-value.X, -value.Y, -value.Z, -value.W);
|
|
||||||
public static Int4 operator -(Int4 left, Int4 right) => .(left.X - right.X, left.Y - right.Y, left.Z - right.Z, left.W - right.W);
|
|
||||||
public static Int4 operator -(Int4 left, int32 right) => .(left.X - right, left.Y - right, left.Z - right, left.W - right);
|
|
||||||
public static Int4 operator -(int32 left, Int4 right) => .(left - right.X, left - right.Y, left - right.Z, left - right.W);
|
|
||||||
|
|
||||||
public static Int4 operator *(Int4 left, Int4 right) => .(left.X * right.X, left.Y * right.Y, left.Z * right.Z, left.W * right.W);
|
|
||||||
public static Int4 operator *(Int4 left, int32 right) => .(left.X * right, left.Y * right, left.Z * right, left.W * right);
|
|
||||||
public static Int4 operator *(int32 left, Int4 right) => .(left * right.X, left * right.Y, left * right.Z, left * right.W);
|
|
||||||
|
|
||||||
public static Int4 operator /(Int4 left, Int4 right) => .(left.X / right.X, left.Y / right.Y, left.Z / right.Z, left.W / right.W);
|
|
||||||
public static Int4 operator /(Int4 left, int32 right) => .(left.X / right, left.Y / right, left.Z / right, left.W / right);
|
|
||||||
public static Int4 operator /(int32 left, Int4 right) => .(left / right.X, left / right.Y, left / right.Z, left / right.W);
|
|
||||||
|
|
||||||
public static Int4 operator %(Int4 left, Int4 right) => .(left.X % right.X, left.Y % right.Y, left.Z % right.Z, left.W % right.W);
|
|
||||||
public static Int4 operator %(Int4 left, int32 right) => .(left.X % right, left.Y % right, left.Z % right, left.W % right);
|
|
||||||
public static Int4 operator %(int32 left, Int4 right) => .(left % right.X, left % right.Y, left % right.Z, left % right.W);
|
|
||||||
|
|
||||||
public static bool operator ==(Int4 left, Int4 right) => left.X == right.X && left.Y == right.Y && left.Z == right.Z && left.W == right.W;
|
|
||||||
public static bool operator ==(Int4 left, int32 right) => left.X == right && left.Y == right && left.Z == right && left.W == right;
|
|
||||||
public static bool operator ==(int32 left, Int4 right) => left == right.X && left == right.Y && left == right.Z && left == right.W;
|
|
||||||
|
|
||||||
public static bool operator !=(Int4 left, Int4 right) => left.X != right.X || left.Y != right.Y || left.Z != right.Z || left.W != right.W;
|
|
||||||
public static bool operator !=(Int4 left, int32 right) => left.X != right || left.Y != right || left.Z != right || left.W != right;
|
|
||||||
public static bool operator !=(int32 left, Int4 right) => left != right.X || left != right.Y || left != right.Z || left != right.W;
|
|
||||||
|
|
||||||
public override void ToString(String strBuffer) => strBuffer.AppendF($"X:{X} Y:{Y} Z:{Z} W:{W}");
|
|
||||||
|
|
||||||
public static explicit operator Vector4(Int4 point) => .(point.X, point.Y, point.Z, point.W);
|
|
||||||
|
|
||||||
public static explicit operator Int4(Vector4 point) => .((int32)point.X, (int32)point.Y, (int32)point.Z, (int32)point.W);
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
public static explicit operator Int2(in Int4 point) => *(Int2*)&point;
|
|
||||||
|
|
||||||
[Inline]
|
|
||||||
public static explicit operator Int3(in Int4 point) => *(Int3*)&point;
|
|
||||||
|
|
||||||
public int GetHashCode()
|
|
||||||
{
|
|
||||||
return (((((X * 39) ^ Y) * 39) ^ Z) * 39) ^ W;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
using Bon;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math;
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<bool, 2>]
|
||||||
|
[SwizzleVector(2, "GlitchyEngine.Math.bool")]
|
||||||
|
struct bool2
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<bool, 3>]
|
||||||
|
[SwizzleVector(3, "GlitchyEngine.Math.bool")]
|
||||||
|
struct bool3
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<bool, 4>]
|
||||||
|
[SwizzleVector(4, "GlitchyEngine.Math.bool")]
|
||||||
|
struct bool4
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
@@ -0,0 +1,113 @@
|
|||||||
|
using Bon;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math;
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<double, 2>]
|
||||||
|
[ComparableVector<double, 2>]
|
||||||
|
[VectorMath<double, 2>]
|
||||||
|
[SwizzleVector(2, "GlitchyEngine.Math.double")]
|
||||||
|
public struct double2
|
||||||
|
{
|
||||||
|
public const double2 Zero = .(0, 0);
|
||||||
|
public const double2 UnitX = .(1, 0);
|
||||||
|
public const double2 UnitY = .(0, 1);
|
||||||
|
public const double2 One = .(1, 1);
|
||||||
|
|
||||||
|
public static explicit operator int2(double2 value)
|
||||||
|
{
|
||||||
|
return int2((int32)value.X, (int32)value.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator uint2(double2 value)
|
||||||
|
{
|
||||||
|
return uint2((uint32)value.X, (uint32)value.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator half2(double2 value)
|
||||||
|
{
|
||||||
|
return half2((half)value.X, (half)value.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator float2(double2 value)
|
||||||
|
{
|
||||||
|
return float2((float)value.X, (float)value.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<double, 3>]
|
||||||
|
[ComparableVector<double, 3>]
|
||||||
|
[VectorMath<double, 3>]
|
||||||
|
[SwizzleVector(3, "GlitchyEngine.Math.double")]
|
||||||
|
public struct double3
|
||||||
|
{
|
||||||
|
public const double3 Zero = .(0, 0, 0);
|
||||||
|
public const double3 UnitX = .(1, 0, 0);
|
||||||
|
public const double3 UnitY = .(0, 1, 0);
|
||||||
|
public const double3 UnitZ = .(0, 0, 1);
|
||||||
|
public const double3 One = .(1, 1, 1);
|
||||||
|
|
||||||
|
public const double3 Forward = .(0, 0, 1);
|
||||||
|
public const double3 Backward = .(0, 0, -1);
|
||||||
|
public const double3 Left = .(-1, 0, 0);
|
||||||
|
public const double3 Right = .(1, 0, 0);
|
||||||
|
public const double3 Up = .(0, 1, 0);
|
||||||
|
public const double3 Down = .(0, -1, 0);
|
||||||
|
|
||||||
|
public static explicit operator int3(double3 value)
|
||||||
|
{
|
||||||
|
return int3((int32)value.X, (int32)value.Y, (int32)value.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator uint3(double3 value)
|
||||||
|
{
|
||||||
|
return uint3((uint32)value.X, (uint32)value.Y, (uint32)value.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator half3(double3 value)
|
||||||
|
{
|
||||||
|
return half3((half)(float)value.X, (half)(float)value.Y, (half)(float)value.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator float3(double3 value)
|
||||||
|
{
|
||||||
|
return float3((float)value.X, (float)value.Y, (float)value.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<double, 4>]
|
||||||
|
[ComparableVector<double, 4>]
|
||||||
|
[VectorMath<double, 4>]
|
||||||
|
[SwizzleVector(4, "GlitchyEngine.Math.double")]
|
||||||
|
public struct double4
|
||||||
|
{
|
||||||
|
public const double4 Zero = .(0, 0, 0, 0);
|
||||||
|
public const double4 UnitX = .(1, 0, 0, 0);
|
||||||
|
public const double4 UnitY = .(0, 1, 0, 0);
|
||||||
|
public const double4 UnitZ = .(0, 0, 1, 0);
|
||||||
|
public const double4 UnitW = .(0, 0, 0, 1);
|
||||||
|
public const double4 One = .(1, 1, 1, 1);
|
||||||
|
|
||||||
|
public static explicit operator int4(double4 value)
|
||||||
|
{
|
||||||
|
return int4((int32)value.X, (int32)value.Y, (int32)value.Z, (int32)value.W);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator uint4(double4 value)
|
||||||
|
{
|
||||||
|
return uint4((uint32)value.X, (uint32)value.Y, (uint32)value.Z, (uint32)value.W);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator half4(double4 value)
|
||||||
|
{
|
||||||
|
return half4((half)(float)value.X, (half)(float)value.Y, (half)(float)value.Z, (half)(float)value.W);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator float4(double4 value)
|
||||||
|
{
|
||||||
|
return float4((float)value.X, (float)value.Y, (float)value.Z, (float)value.W);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,83 @@
|
|||||||
|
using Bon;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math;
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<float, 2>]
|
||||||
|
[ComparableVector<float, 2>]
|
||||||
|
[VectorMath<float, 2>]
|
||||||
|
[SwizzleVector(2, "GlitchyEngine.Math.float")]
|
||||||
|
public struct float2
|
||||||
|
{
|
||||||
|
public const float2 Zero = .(0f, 0f);
|
||||||
|
public const float2 UnitX = .(1f, 0f);
|
||||||
|
public const float2 UnitY = .(0f, 1f);
|
||||||
|
public const float2 One = .(1f, 1f);
|
||||||
|
|
||||||
|
public static implicit operator int2(float2 value)
|
||||||
|
{
|
||||||
|
return int2((int32)value.X, (int32)value.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator half2(float2 value)
|
||||||
|
{
|
||||||
|
return half2((half)value.X, (half)value.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<float, 3>]
|
||||||
|
[ComparableVector<float, 3>]
|
||||||
|
[VectorMath<float, 3>]
|
||||||
|
[SwizzleVector(3, "GlitchyEngine.Math.float")]
|
||||||
|
public struct float3
|
||||||
|
{
|
||||||
|
public const float3 Zero = .(0f, 0f, 0f);
|
||||||
|
public const float3 UnitX = .(1f, 0f, 0f);
|
||||||
|
public const float3 UnitY = .(0f, 1f, 0f);
|
||||||
|
public const float3 UnitZ = .(0f, 0f, 1f);
|
||||||
|
public const float3 One = .(1f, 1f, 1f);
|
||||||
|
|
||||||
|
public const float3 Forward = .(0f, 0f, 1f);
|
||||||
|
public const float3 Backward = .(0f, 0f, -1f);
|
||||||
|
public const float3 Left = .(-1f, 0f, 0f);
|
||||||
|
public const float3 Right = .(1f, 0f, 0f);
|
||||||
|
public const float3 Up = .(0f, 1f, 0f);
|
||||||
|
public const float3 Down = .(0f, -1f, 0f);
|
||||||
|
|
||||||
|
public static implicit operator int3(float3 value)
|
||||||
|
{
|
||||||
|
return int3((int32)value.X, (int32)value.Y, (int32)value.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator half3(float3 value)
|
||||||
|
{
|
||||||
|
return half3((half)value.X, (half)value.Y, (half)value.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<float, 4>]
|
||||||
|
[ComparableVector<float, 4>]
|
||||||
|
[VectorMath<float, 4>]
|
||||||
|
[SwizzleVector(4, "GlitchyEngine.Math.float")]
|
||||||
|
public struct float4
|
||||||
|
{
|
||||||
|
public const float4 Zero = .(0f, 0f, 0f, 0f);
|
||||||
|
public const float4 UnitX = .(1f, 0f, 0f, 0f);
|
||||||
|
public const float4 UnitY = .(0f, 1f, 0f, 0f);
|
||||||
|
public const float4 UnitZ = .(0f, 0f, 1f, 0f);
|
||||||
|
public const float4 UnitW = .(0f, 0f, 0f, 1f);
|
||||||
|
public const float4 One = .(1f, 1f, 1f, 1f);
|
||||||
|
|
||||||
|
public static implicit operator int4(float4 value)
|
||||||
|
{
|
||||||
|
return int4((int32)value.X, (int32)value.Y, (int32)value.Z, (int32)value.W);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator half4(float4 value)
|
||||||
|
{
|
||||||
|
return half4((half)value.X, (half)value.Y, (half)value.Z, (half)value.W);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,312 @@
|
|||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math;
|
||||||
|
|
||||||
|
/// Represents a 16bit floating point number. (IEEE 754 half-precision binary floating-point (binary16))
|
||||||
|
/// Note: Eventhough it is possible, it is not recommended to perform calculations on this type.
|
||||||
|
/// Most operations will simply convert the halfs to floats, perform the calculation and convert the result back to half.
|
||||||
|
struct half : IFloating, ISigned, IFormattable, IHashable, IEquatable<half>, ICanBeNaN
|
||||||
|
{
|
||||||
|
public const half MinValue = half(-65504); // Should be 0xFBFF
|
||||||
|
public const half MaxValue = half(65504); // Should be 0x7BFF
|
||||||
|
|
||||||
|
// The numbers for Inifnity, NaN and Zero need to be hardcoded as binaries,
|
||||||
|
// because the conversion intself relies on them.
|
||||||
|
|
||||||
|
public const half PositiveInfinity = half(0x7C00);
|
||||||
|
public const half NegativeInfinity = half(0xFC00);
|
||||||
|
public const half NaN = half(0x7CFF);
|
||||||
|
|
||||||
|
public const half Zero = half(0x0000);
|
||||||
|
public const half NegativeZero = half(0x8000);
|
||||||
|
|
||||||
|
private uint16 _data;
|
||||||
|
|
||||||
|
public bool IsNegative => (_data & Half_Sign_Mask) > 0;
|
||||||
|
|
||||||
|
public bool IsFinity => (_data & ~Half_Sign_Mask) < Half_Exponent_Mask;
|
||||||
|
public bool IsInfinity => (_data & ~Half_Sign_Mask) == Half_Exponent_Mask;
|
||||||
|
|
||||||
|
public bool IsPositiveInfinity => _data == PositiveInfinity._data;
|
||||||
|
public bool IsNegativeInfinity => _data == NegativeInfinity._data;
|
||||||
|
|
||||||
|
public bool IsNaN => (_data & ~Half_Sign_Mask) > Half_Exponent_Mask;
|
||||||
|
|
||||||
|
public bool IsSubnormal
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
var unsignedBits = _data & ~Half_Sign_Mask;
|
||||||
|
|
||||||
|
// Zero isn't normalized and if exponent is 0 we are unnormalized
|
||||||
|
return (unsignedBits != 0) && ((unsignedBits & Half_Exponent_Mask) == 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public this(float value)
|
||||||
|
{
|
||||||
|
this = FromFloat32(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private this(uint16 data)
|
||||||
|
{
|
||||||
|
_data = data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public explicit static operator half(float value) => FromFloat32(value);
|
||||||
|
public explicit static operator float(half value) => ToFloat32(value);
|
||||||
|
|
||||||
|
public static half FromFloat32(float value)
|
||||||
|
{
|
||||||
|
if (value == 0.0f)
|
||||||
|
return half(0x0000);
|
||||||
|
|
||||||
|
if (value == -0.0f)
|
||||||
|
return half(0x8000);
|
||||||
|
|
||||||
|
#unwarn
|
||||||
|
uint32 singleBits = *(uint32*)&value;
|
||||||
|
|
||||||
|
uint32 sign = GetSingleSignBit(singleBits);
|
||||||
|
int32 exponent = (int32)GetSingleExponent(singleBits);
|
||||||
|
uint32 mantissa = GetSingleMantissa(singleBits);
|
||||||
|
|
||||||
|
// Shift 13 so we truncate mantissa from 23 to 10 bits.
|
||||||
|
uint32 halfMantissa = mantissa >> 13;
|
||||||
|
|
||||||
|
if (exponent == 0xFF)
|
||||||
|
{
|
||||||
|
// largest possible single exponent -> either infinity or NaN
|
||||||
|
|
||||||
|
if (mantissa == 0)
|
||||||
|
{
|
||||||
|
// Infinity
|
||||||
|
return (sign == 1) ? NegativeInfinity : PositiveInfinity;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// NaN -> Keeps sign and mantissa intact
|
||||||
|
|
||||||
|
uint16 halfBits = SetHalfSignBit(0, (uint16)sign);
|
||||||
|
// Set all five exponent bits to 1
|
||||||
|
halfBits = SetHalfExponent(halfBits, 0x1F);
|
||||||
|
halfBits = SetHalfMantissa(halfBits, (uint16)halfMantissa);
|
||||||
|
|
||||||
|
return half(halfBits);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalized single
|
||||||
|
|
||||||
|
// excess-K decode and encode -127 is k for single, 15 is k for half
|
||||||
|
exponent = exponent - 127 + 15;
|
||||||
|
|
||||||
|
if (exponent < 0)
|
||||||
|
// The given number is too small for a half (even denormalized) -> return 0
|
||||||
|
return (sign == 1) ? NegativeZero : Zero;
|
||||||
|
|
||||||
|
if (exponent > 31)
|
||||||
|
// The given number is too large for a half -> return infinity
|
||||||
|
return (sign == 1) ? NegativeInfinity : PositiveInfinity;
|
||||||
|
|
||||||
|
// The given number fits -> convert (might become denormalized)
|
||||||
|
uint16 halfBits = SetHalfSignBit(0, (uint16)sign);
|
||||||
|
halfBits = SetHalfExponent(halfBits, (uint16)exponent);
|
||||||
|
halfBits = SetHalfMantissa(halfBits, (uint16)halfMantissa);
|
||||||
|
|
||||||
|
return half(halfBits);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static float ToFloat32(half value)
|
||||||
|
{
|
||||||
|
#unwarn
|
||||||
|
uint16 halfBits = *(uint16*)&value;
|
||||||
|
|
||||||
|
if (halfBits == Zero._data)
|
||||||
|
return 0.0f;
|
||||||
|
|
||||||
|
if (halfBits == NegativeZero._data)
|
||||||
|
return -0.0f;
|
||||||
|
|
||||||
|
uint16 sign = GetHalfSignBit(halfBits);
|
||||||
|
int16 exponent = (int16)GetHalfExponent(halfBits);
|
||||||
|
uint16 mantissa = GetHalfMantissa(halfBits);
|
||||||
|
|
||||||
|
// Shift 13 so we extend mantissa from 10 to 23 bits.
|
||||||
|
uint32 singleMantissa = (uint32)mantissa << 13;
|
||||||
|
|
||||||
|
if (exponent == 0x1F)
|
||||||
|
{
|
||||||
|
// largest possible half exponent -> either infinity or NaN
|
||||||
|
|
||||||
|
if (mantissa == 0)
|
||||||
|
{
|
||||||
|
// Infinity
|
||||||
|
return (sign == 1) ? float.NegativeInfinity : float.PositiveInfinity;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// NaN -> Keeps sign and mantissa intact
|
||||||
|
|
||||||
|
uint32 singleBits = SetSingleSignBit(0, sign);
|
||||||
|
// Set all five exponent bits to 1
|
||||||
|
singleBits = SetSingleExponent(halfBits, 0xFF);
|
||||||
|
singleBits = SetSingleMantissa(halfBits, singleMantissa);
|
||||||
|
|
||||||
|
return *(float*)&singleBits;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalized half
|
||||||
|
|
||||||
|
// excess-K decode and encode -127 is k for single, 15 is k for half
|
||||||
|
exponent = exponent - 15 + 127;
|
||||||
|
|
||||||
|
uint32 singleBits = SetSingleSignBit(0, sign);
|
||||||
|
singleBits = SetSingleExponent(singleBits, (uint32)exponent);
|
||||||
|
singleBits = SetSingleMantissa(singleBits, singleMantissa);
|
||||||
|
|
||||||
|
return *(float*)&singleBits;
|
||||||
|
}
|
||||||
|
|
||||||
|
#region Single <-> Half Helpers
|
||||||
|
|
||||||
|
const uint32 Single_Sign_Shift = 31;
|
||||||
|
const uint32 Single_Sign_Mask = 0x8000'0000; // 1 bit, offset 31
|
||||||
|
|
||||||
|
const uint32 Single_Exponent_Shift = 23;
|
||||||
|
const uint32 Single_Exponent_Mask = 0x7F80'0000; // 8 bit, offset 23
|
||||||
|
|
||||||
|
const uint32 Single_Mantissa_Mask = 0x007F'FFFF; // 23 bit, offset 0
|
||||||
|
|
||||||
|
const uint16 Half_Sign_Shift = 15;
|
||||||
|
const uint16 Half_Sign_Mask = 0x8000; // 1 bit, offset 15
|
||||||
|
|
||||||
|
const uint16 Half_Exponent_Shift = 10;
|
||||||
|
const uint16 Half_Exponent_Mask = 0x7C00; // 5 bit, offset 10
|
||||||
|
|
||||||
|
const uint16 Half_Mantissa_Mask = 0x03FF; // 10 bit, offset 0
|
||||||
|
|
||||||
|
private static uint32 GetSingleSignBit(uint32 singleData)
|
||||||
|
{
|
||||||
|
return (singleData >> Single_Sign_Shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint32 GetSingleExponent(uint32 singleData)
|
||||||
|
{
|
||||||
|
return (singleData & Single_Exponent_Mask) >> Single_Exponent_Shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint32 GetSingleMantissa(uint32 singleData)
|
||||||
|
{
|
||||||
|
return (singleData & Single_Mantissa_Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint32 SetSingleSignBit(uint32 singleData, uint32 signBit)
|
||||||
|
{
|
||||||
|
return ((signBit << Single_Sign_Shift) & Single_Sign_Mask) | (singleData & ~Single_Sign_Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint32 SetSingleExponent(uint32 singleData, uint32 exponent)
|
||||||
|
{
|
||||||
|
return ((exponent << Single_Exponent_Shift) & Single_Exponent_Mask) | (singleData & ~Single_Exponent_Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint32 SetSingleMantissa(uint32 singleData, uint32 mantissa)
|
||||||
|
{
|
||||||
|
return (mantissa & Single_Mantissa_Mask) | (singleData & ~Single_Mantissa_Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint16 GetHalfSignBit(uint16 HalfData)
|
||||||
|
{
|
||||||
|
return (HalfData >> Half_Sign_Shift);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint16 GetHalfExponent(uint16 HalfData)
|
||||||
|
{
|
||||||
|
return (HalfData & Half_Exponent_Mask) >> Half_Exponent_Shift;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint16 GetHalfMantissa(uint16 HalfData)
|
||||||
|
{
|
||||||
|
return (HalfData & Half_Mantissa_Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint16 SetHalfSignBit(uint16 HalfData, uint16 signBit)
|
||||||
|
{
|
||||||
|
return ((signBit << Half_Sign_Shift) & Half_Sign_Mask) | (HalfData & ~Half_Sign_Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint16 SetHalfExponent(uint16 HalfData, uint16 exponent)
|
||||||
|
{
|
||||||
|
return ((exponent << Half_Exponent_Shift) & Half_Exponent_Mask) | (HalfData & ~Half_Exponent_Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static uint16 SetHalfMantissa(uint16 HalfData, uint16 mantissa)
|
||||||
|
{
|
||||||
|
return (mantissa & Half_Mantissa_Mask) | (HalfData & ~Half_Mantissa_Mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endregion
|
||||||
|
|
||||||
|
public int GetHashCode()
|
||||||
|
{
|
||||||
|
return _data;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToString(String outString)
|
||||||
|
{
|
||||||
|
ToFloat32(this).ToString(outString);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ToString(String outString, String format, IFormatProvider formatProvider)
|
||||||
|
{
|
||||||
|
ToFloat32(this).ToString(outString, format, formatProvider);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static half operator +(half lhs, half rhs)
|
||||||
|
{
|
||||||
|
return (half)((float)lhs + (float)rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static half operator +(half value) => value;
|
||||||
|
|
||||||
|
public static half operator -(half lhs, half rhs)
|
||||||
|
{
|
||||||
|
return (half)((float)lhs - (float)rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static half operator -(half value)
|
||||||
|
{
|
||||||
|
uint16 signBit = GetHalfSignBit(value._data);
|
||||||
|
|
||||||
|
// Invert the sign bit (~)
|
||||||
|
return half(SetHalfSignBit(value._data, ~signBit));
|
||||||
|
}
|
||||||
|
|
||||||
|
public static half operator *(half lhs, half rhs)
|
||||||
|
{
|
||||||
|
return (half)((float)lhs * (float)rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static half operator /(half lhs, half rhs)
|
||||||
|
{
|
||||||
|
return (half)((float)lhs / (float)rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static half operator %(half lhs, half rhs)
|
||||||
|
{
|
||||||
|
return (half)((float)lhs % (float)rhs);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static bool operator==(half value1, half value2) => value1._data == value2._data;
|
||||||
|
|
||||||
|
public static bool operator!=(half value1, half value2) => value1._data != value2._data;
|
||||||
|
|
||||||
|
public static int operator<=>(half value1, half value2) => (float)value1 <=> (float)value2;
|
||||||
|
|
||||||
|
public bool Equals(half other)
|
||||||
|
{
|
||||||
|
return _data == other._data;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,43 @@
|
|||||||
|
using Bon;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math;
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<half, 2>]
|
||||||
|
[ComparableVector<half, 2>]
|
||||||
|
[VectorMath<half, 2>]
|
||||||
|
[SwizzleVector(2, "GlitchyEngine.Math.half")]
|
||||||
|
public struct half2
|
||||||
|
{
|
||||||
|
public static explicit operator float2(half2 value)
|
||||||
|
{
|
||||||
|
return float2((float)value.X, (float)value.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<half, 3>]
|
||||||
|
[ComparableVector<half, 3>]
|
||||||
|
[VectorMath<half, 3>]
|
||||||
|
[SwizzleVector(3, "GlitchyEngine.Math.half")]
|
||||||
|
public struct half3
|
||||||
|
{
|
||||||
|
public static explicit operator float3(half3 value)
|
||||||
|
{
|
||||||
|
return float3((float)value.X, (float)value.Y, (float)value.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<half, 4>]
|
||||||
|
[ComparableVector<half, 4>]
|
||||||
|
[VectorMath<half, 4>]
|
||||||
|
[SwizzleVector(4, "GlitchyEngine.Math.half")]
|
||||||
|
public struct half4
|
||||||
|
{
|
||||||
|
public static explicit operator float4(half4 value)
|
||||||
|
{
|
||||||
|
return float4((float)value.X, (float)value.Y, (float)value.Z, (float)value.W);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,148 @@
|
|||||||
|
using Bon;
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace GlitchyEngine.Math;
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<int32, 2>]
|
||||||
|
[ComparableVector<int32, 2>]
|
||||||
|
[VectorMath<int32, 2>]
|
||||||
|
[SwizzleVector(2, "GlitchyEngine.Math.int")]
|
||||||
|
public struct int2
|
||||||
|
{
|
||||||
|
public const int2 Zero = .(0, 0);
|
||||||
|
public const int2 UnitX = .(1, 0);
|
||||||
|
public const int2 UnitY = .(0, 1);
|
||||||
|
public const int2 One = .(1, 1);
|
||||||
|
|
||||||
|
public static implicit operator float2(int2 value)
|
||||||
|
{
|
||||||
|
return float2(value.X, value.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator uint2(int2 value)
|
||||||
|
{
|
||||||
|
return uint2((uint32)value.X, (uint32)value.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<int32, 3>]
|
||||||
|
[ComparableVector<int32, 3>]
|
||||||
|
[VectorMath<int32, 3>]
|
||||||
|
[SwizzleVector(3, "GlitchyEngine.Math.int")]
|
||||||
|
public struct int3
|
||||||
|
{
|
||||||
|
public const int3 Zero = .(0, 0, 0);
|
||||||
|
public const int3 UnitX = .(1, 0, 0);
|
||||||
|
public const int3 UnitY = .(0, 1, 0);
|
||||||
|
public const int3 UnitZ = .(0, 0, 1);
|
||||||
|
public const int3 One = .(1, 1, 1);
|
||||||
|
|
||||||
|
public static implicit operator float3(int3 value)
|
||||||
|
{
|
||||||
|
return float3(value.X, value.Y, value.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator uint3(int3 value)
|
||||||
|
{
|
||||||
|
return uint3((uint32)value.X, (uint32)value.Y, (uint32)value.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<int32, 4>]
|
||||||
|
[ComparableVector<int32, 4>]
|
||||||
|
[VectorMath<int32, 4>]
|
||||||
|
[SwizzleVector(4, "GlitchyEngine.Math.int")]
|
||||||
|
public struct int4
|
||||||
|
{
|
||||||
|
public const int4 Zero = .(0, 0, 0, 0);
|
||||||
|
public const int4 UnitX = .(1, 0, 0, 0);
|
||||||
|
public const int4 UnitY = .(0, 1, 0, 0);
|
||||||
|
public const int4 UnitZ = .(0, 0, 1, 0);
|
||||||
|
public const int4 UnitW = .(0, 0, 0, 1);
|
||||||
|
public const int4 One = .(1, 1, 1, 1);
|
||||||
|
|
||||||
|
public static implicit operator float4(int4 value)
|
||||||
|
{
|
||||||
|
return float4(value.X, value.Y, value.Z, value.W);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator uint4(int4 value)
|
||||||
|
{
|
||||||
|
return uint4((uint32)value.X, (uint32)value.Y, (uint32)value.Z, (uint32)value.W);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<uint32, 2>]
|
||||||
|
[ComparableVector<uint32, 2>]
|
||||||
|
//[VectorMath<uint32, 2>]
|
||||||
|
[SwizzleVector(2, "GlitchyEngine.Math.uint")]
|
||||||
|
public struct uint2
|
||||||
|
{
|
||||||
|
public const uint2 Zero = .(0, 0);
|
||||||
|
public const uint2 UnitX = .(1, 0);
|
||||||
|
public const uint2 UnitY = .(0, 1);
|
||||||
|
public const uint2 One = .(1, 1);
|
||||||
|
|
||||||
|
public static implicit operator float2(uint2 value)
|
||||||
|
{
|
||||||
|
return float2(value.X, value.Y);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator int2(uint2 value)
|
||||||
|
{
|
||||||
|
return int2((int32)value.X, (int32)value.Y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<uint32, 3>]
|
||||||
|
[ComparableVector<uint32, 3>]
|
||||||
|
//[VectorMath<uint32, 3>]
|
||||||
|
[SwizzleVector(3, "GlitchyEngine.Math.uint")]
|
||||||
|
public struct uint3
|
||||||
|
{
|
||||||
|
public const uint3 Zero = .(0, 0, 0);
|
||||||
|
public const uint3 UnitX = .(1, 0, 0);
|
||||||
|
public const uint3 UnitY = .(0, 1, 0);
|
||||||
|
public const uint3 UnitZ = .(0, 0, 1);
|
||||||
|
public const uint3 One = .(1, 1, 1);
|
||||||
|
|
||||||
|
public static implicit operator float3(uint3 value)
|
||||||
|
{
|
||||||
|
return float3(value.X, value.Y, value.Z);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator int3(uint3 value)
|
||||||
|
{
|
||||||
|
return int3((int32)value.X, (int32)value.Y, (int32)value.Z);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[BonTarget]
|
||||||
|
[Vector<uint32, 4>]
|
||||||
|
[ComparableVector<uint32, 4>]
|
||||||
|
//[VectorMath<uint32, 4>]
|
||||||
|
[SwizzleVector(4, "GlitchyEngine.Math.uint")]
|
||||||
|
public struct uint4
|
||||||
|
{
|
||||||
|
public const uint4 Zero = .(0, 0, 0, 0);
|
||||||
|
public const uint4 UnitX = .(1, 0, 0, 0);
|
||||||
|
public const uint4 UnitY = .(0, 1, 0, 0);
|
||||||
|
public const uint4 UnitZ = .(0, 0, 1, 0);
|
||||||
|
public const uint4 UnitW = .(0, 0, 0, 1);
|
||||||
|
public const uint4 One = .(1, 1, 1, 1);
|
||||||
|
|
||||||
|
public static implicit operator float4(uint4 value)
|
||||||
|
{
|
||||||
|
return float4(value.X, value.Y, value.Z, value.W);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static explicit operator int4(uint4 value)
|
||||||
|
{
|
||||||
|
return int4((int32)value.X, (int32)value.Y, (int32)value.Z, (int32)value.W);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -14,7 +14,7 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
private bool _rotation;
|
private bool _rotation;
|
||||||
|
|
||||||
private Vector3 _cameraPosition;
|
private float3 _cameraPosition;
|
||||||
private float _cameraRotation;
|
private float _cameraRotation;
|
||||||
private float _cameraTranslationSpeed = 1.0f;
|
private float _cameraTranslationSpeed = 1.0f;
|
||||||
private float _cameraRotationSpeed = 1.0f;
|
private float _cameraRotationSpeed = 1.0f;
|
||||||
@@ -41,7 +41,7 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
if(Application.Get().Window.IsActive)
|
if(Application.Get().Window.IsActive)
|
||||||
{
|
{
|
||||||
Vector3 movement = .();
|
float3 movement = .();
|
||||||
|
|
||||||
if(Input.IsKeyPressed(Key.W))
|
if(Input.IsKeyPressed(Key.W))
|
||||||
{
|
{
|
||||||
@@ -61,8 +61,8 @@ namespace GlitchyEngine
|
|||||||
movement.X += 1;
|
movement.X += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(movement != .Zero)
|
if(any(movement != .Zero))
|
||||||
movement.Normalize();
|
movement = normalize(movement);
|
||||||
|
|
||||||
movement *= (float)(gameTime.FrameTime.TotalSeconds) * _cameraTranslationSpeed * _zoomLevel;
|
movement *= (float)(gameTime.FrameTime.TotalSeconds) * _cameraTranslationSpeed * _zoomLevel;
|
||||||
|
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ namespace GlitchyEngine
|
|||||||
private float _aspectRatio;
|
private float _aspectRatio;
|
||||||
private float _fovY = Math.PI_f / 4;
|
private float _fovY = Math.PI_f / 4;
|
||||||
|
|
||||||
private Vector3 _cameraPosition;
|
private float3 _cameraPosition;
|
||||||
private Vector3 _cameraRotation;
|
private float3 _cameraRotation;
|
||||||
|
|
||||||
private float _cameraTranslationSpeed = 1.0f;
|
private float _cameraTranslationSpeed = 1.0f;
|
||||||
private float _cameraRotationSpeedX = 0.001f;
|
private float _cameraRotationSpeedX = 0.001f;
|
||||||
@@ -27,7 +27,7 @@ namespace GlitchyEngine
|
|||||||
set => _cameraTranslationSpeed = value;
|
set => _cameraTranslationSpeed = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector2 RotationSpeed
|
public float2 RotationSpeed
|
||||||
{
|
{
|
||||||
get => .(_cameraRotationSpeedX, _cameraRotationSpeedY);
|
get => .(_cameraRotationSpeedX, _cameraRotationSpeedY);
|
||||||
set
|
set
|
||||||
@@ -37,7 +37,7 @@ namespace GlitchyEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 CameraPosition
|
public float3 CameraPosition
|
||||||
{
|
{
|
||||||
get => _cameraPosition;
|
get => _cameraPosition;
|
||||||
set
|
set
|
||||||
@@ -48,7 +48,7 @@ namespace GlitchyEngine
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 CameraRotation
|
public float3 CameraRotation
|
||||||
{
|
{
|
||||||
get => _cameraRotation;
|
get => _cameraRotation;
|
||||||
set
|
set
|
||||||
@@ -100,7 +100,7 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
if(Application.Get().Window.IsActive)
|
if(Application.Get().Window.IsActive)
|
||||||
{
|
{
|
||||||
Vector3 movement = .();
|
float3 movement = .();
|
||||||
|
|
||||||
if(Input.IsKeyPressed(Key.W))
|
if(Input.IsKeyPressed(Key.W))
|
||||||
{
|
{
|
||||||
@@ -129,14 +129,14 @@ namespace GlitchyEngine
|
|||||||
movement.Y -= 1;
|
movement.Y -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(movement != .Zero)
|
if(any(movement != .Zero))
|
||||||
movement.Normalize();
|
normalize(movement);
|
||||||
|
|
||||||
movement *= (float)(gameTime.FrameTime.TotalSeconds) * _cameraTranslationSpeed;
|
movement *= (float)(gameTime.FrameTime.TotalSeconds) * _cameraTranslationSpeed;
|
||||||
|
|
||||||
Vector4 delta = Vector4(movement, 1.0f) * _camera.View;
|
float4 delta = float4(movement, 1.0f) * _camera.View;
|
||||||
|
|
||||||
_cameraPosition += Vector3(delta.X, delta.Y, delta.Z);
|
_cameraPosition += float3(delta.X, delta.Y, delta.Z);
|
||||||
//_cameraPosition += movement;
|
//_cameraPosition += movement;
|
||||||
|
|
||||||
// Camera rotation
|
// Camera rotation
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ using DirectX.Common;
|
|||||||
using DirectX.D3D11;
|
using DirectX.D3D11;
|
||||||
using DirectX.D3D11.SDKLayers;
|
using DirectX.D3D11.SDKLayers;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
namespace GlitchyEngine.Platform.DX11
|
namespace GlitchyEngine.Platform.DX11
|
||||||
{
|
{
|
||||||
@@ -18,6 +19,8 @@ namespace GlitchyEngine.Platform.DX11
|
|||||||
protected internal static ID3D11Device* NativeDevice;
|
protected internal static ID3D11Device* NativeDevice;
|
||||||
protected internal static ID3D11DeviceContext* NativeContext;
|
protected internal static ID3D11DeviceContext* NativeContext;
|
||||||
|
|
||||||
|
protected internal static Monitor ContextMonitor = new Monitor() ~ delete _;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
protected internal static ID3D11Debug* DebugDevice;
|
protected internal static ID3D11Debug* DebugDevice;
|
||||||
#endif
|
#endif
|
||||||
@@ -42,8 +45,11 @@ namespace GlitchyEngine.Platform.DX11
|
|||||||
HResult deviceResult;
|
HResult deviceResult;
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileScope!("D3D11.CreateDevice");
|
Debug.Profiler.ProfileScope!("D3D11.CreateDevice");
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
deviceResult = D3D11.CreateDevice(null, .Hardware, 0, deviceFlags, levels, &NativeDevice, &deviceLevel, &NativeContext);
|
deviceResult = D3D11.CreateDevice(null, .Hardware, 0, deviceFlags, levels, &NativeDevice, &deviceLevel, &NativeContext);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Log.EngineLogger.Assert(deviceResult.Succeeded, scope $"Failed to create D3D11 Device. Message({(int32)deviceResult}): {deviceResult}");
|
Log.EngineLogger.Assert(deviceResult.Succeeded, scope $"Failed to create D3D11 Device. Message({(int32)deviceResult}): {deviceResult}");
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ using Bon;
|
|||||||
|
|
||||||
namespace GlitchyEngine.Math
|
namespace GlitchyEngine.Math
|
||||||
{
|
{
|
||||||
extension Vector2
|
extension float2
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
public static implicit operator DirectX.Math.Vector2(in Self value) => *(DirectX.Math.Vector2*)&value;
|
public static implicit operator DirectX.Math.Vector2(in Self value) => *(DirectX.Math.Vector2*)&value;
|
||||||
@@ -17,7 +17,7 @@ namespace GlitchyEngine.Math
|
|||||||
public static implicit operator Self(in DirectX.Math.Vector2 value) => *(Self*)&value;
|
public static implicit operator Self(in DirectX.Math.Vector2 value) => *(Self*)&value;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Vector3
|
extension float3
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
public static implicit operator DirectX.Math.Vector3(in Self value) => *(DirectX.Math.Vector3*)&value;
|
public static implicit operator DirectX.Math.Vector3(in Self value) => *(DirectX.Math.Vector3*)&value;
|
||||||
@@ -26,7 +26,7 @@ namespace GlitchyEngine.Math
|
|||||||
public static implicit operator Self(in DirectX.Math.Vector3 value) => *(Self*)&value;
|
public static implicit operator Self(in DirectX.Math.Vector3 value) => *(Self*)&value;
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Vector4
|
extension float4
|
||||||
{
|
{
|
||||||
[Inline]
|
[Inline]
|
||||||
public static implicit operator DirectX.Math.Vector4(in Self value) => *(DirectX.Math.Vector4*)&value;
|
public static implicit operator DirectX.Math.Vector4(in Self value) => *(DirectX.Math.Vector4*)&value;
|
||||||
|
|||||||
@@ -100,14 +100,24 @@ namespace GlitchyEngine.Renderer
|
|||||||
{
|
{
|
||||||
case .Default:
|
case .Default:
|
||||||
Box dataBox = .(dstByteOffset, 0, 0, dstByteOffset + byteLength, 1, 1);
|
Box dataBox = .(dstByteOffset, 0, 0, dstByteOffset + byteLength, 1, 1);
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.UpdateSubresource(nativeBuffer, 0, &dataBox, data, byteLength, byteLength);
|
NativeContext.UpdateSubresource(nativeBuffer, 0, &dataBox, data, byteLength, byteLength);
|
||||||
|
}
|
||||||
case .Dynamic:
|
case .Dynamic:
|
||||||
Log.EngineLogger.Assert(mapType == .WriteDiscard || mapType == .WriteNoOverwrite, scope $"When writing to dynamic resources the map type must be {nameof(Renderer.MapType.WriteDiscard)} or {nameof(Renderer.MapType.WriteNoOverwrite)}.");
|
Log.EngineLogger.Assert(mapType == .WriteDiscard || mapType == .WriteNoOverwrite, scope $"When writing to dynamic resources the map type must be {nameof(Renderer.MapType.WriteDiscard)} or {nameof(Renderer.MapType.WriteNoOverwrite)}.");
|
||||||
// Todo: DoNotWaitFlag
|
// Todo: DoNotWaitFlag
|
||||||
MappedSubresource map = ?;
|
MappedSubresource map = ?;
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.Map(nativeBuffer, 0, (.)mapType, .None, &map);
|
NativeContext.Map(nativeBuffer, 0, (.)mapType, .None, &map);
|
||||||
|
}
|
||||||
Internal.MemCpy(((uint8*)map.Data) + dstByteOffset, data, byteLength);
|
Internal.MemCpy(((uint8*)map.Data) + dstByteOffset, data, byteLength);
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.Unmap(nativeBuffer, 0);
|
NativeContext.Unmap(nativeBuffer, 0);
|
||||||
|
}
|
||||||
case .Immutable:
|
case .Immutable:
|
||||||
Log.EngineLogger.Error("Can't set the data of an immutable resource.");
|
Log.EngineLogger.Error("Can't set the data of an immutable resource.");
|
||||||
return .Err;
|
return .Err;
|
||||||
|
|||||||
@@ -81,6 +81,8 @@ namespace GlitchyEngine.Renderer
|
|||||||
{
|
{
|
||||||
Debug.Profiler.ProfileRendererFunction!();
|
Debug.Profiler.ProfileRendererFunction!();
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.InputAssembler.SetVertexBuffers(0, nativeBuffers.Count, &nativeBuffers, &bufferStrides, &bufferOffsets);
|
NativeContext.InputAssembler.SetVertexBuffers(0, nativeBuffers.Count, &nativeBuffers, &bufferStrides, &bufferOffsets);
|
||||||
GraphicsContext.Get().SetVertexLayout(_vertexLayout);
|
GraphicsContext.Get().SetVertexLayout(_vertexLayout);
|
||||||
NativeContext.InputAssembler.SetPrimitiveTopology((.)_primitiveTopology);
|
NativeContext.InputAssembler.SetPrimitiveTopology((.)_primitiveTopology);
|
||||||
@@ -88,6 +90,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
if(_indexBuffer != null)
|
if(_indexBuffer != null)
|
||||||
NativeContext.InputAssembler.SetIndexBuffer(_indexBuffer.nativeBuffer, _indexBuffer.Format == .Index32Bit ? .R32_UInt : .R16_UInt, _indexByteOffset);
|
NativeContext.InputAssembler.SetIndexBuffer(_indexBuffer.nativeBuffer, _indexBuffer.Format == .Index32Bit ? .R32_UInt : .R16_UInt, _indexByteOffset);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void Unbind()
|
public override void Unbind()
|
||||||
{
|
{
|
||||||
@@ -97,6 +100,8 @@ namespace GlitchyEngine.Renderer
|
|||||||
uint32[nativeBuffers.Count] zeroStrides = .();
|
uint32[nativeBuffers.Count] zeroStrides = .();
|
||||||
uint32[nativeBuffers.Count] zeroOffsets = .();
|
uint32[nativeBuffers.Count] zeroOffsets = .();
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.InputAssembler.SetVertexBuffers(0, nativeBuffers.Count, &nullBuffers, &zeroStrides, &zeroOffsets);
|
NativeContext.InputAssembler.SetVertexBuffers(0, nativeBuffers.Count, &nullBuffers, &zeroStrides, &zeroOffsets);
|
||||||
NativeContext.InputAssembler.SetInputLayout(null);
|
NativeContext.InputAssembler.SetInputLayout(null);
|
||||||
NativeContext.InputAssembler.SetPrimitiveTopology(.Undefined);
|
NativeContext.InputAssembler.SetPrimitiveTopology(.Undefined);
|
||||||
@@ -105,5 +110,6 @@ namespace GlitchyEngine.Renderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -157,21 +157,30 @@ namespace GlitchyEngine.Renderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void BindRenderTargets()
|
public override void BindRenderTargets()
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
NativeContext.OutputMerger.SetRenderTargets(MaxRTVCount, &_renderTargets, _depthStencilTarget);
|
NativeContext.OutputMerger.SetRenderTargets(MaxRTVCount, &_renderTargets, _depthStencilTarget);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void ClearRenderTarget(RenderTarget2D renderTarget, ColorRGBA color)
|
public override void ClearRenderTarget(RenderTarget2D renderTarget, ColorRGBA color)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
NativeContext.ClearRenderTargetView((renderTarget ?? _swapChain.BackBuffer)._nativeRenderTargetView, color);
|
NativeContext.ClearRenderTargetView((renderTarget ?? _swapChain.BackBuffer)._nativeRenderTargetView, color);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetVertexBuffer(uint32 slot, Buffer buffer, uint32 stride, uint32 offset = 0)
|
public override void SetVertexBuffer(uint32 slot, Buffer buffer, uint32 stride, uint32 offset = 0)
|
||||||
{
|
{
|
||||||
// make stride and offset mutable so that we can take their pointers.
|
// make stride and offset mutable so that we can take their pointers.
|
||||||
var stride, offset;
|
var stride, offset;
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.InputAssembler.SetVertexBuffers(slot, 1, &buffer.nativeBuffer, &stride, &offset);
|
NativeContext.InputAssembler.SetVertexBuffers(slot, 1, &buffer.nativeBuffer, &stride, &offset);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Inline]
|
[Inline]
|
||||||
private void BindInputLayout()
|
private void BindInputLayout()
|
||||||
@@ -181,9 +190,12 @@ namespace GlitchyEngine.Renderer
|
|||||||
_currentInputLayout = _currentVertexLayout.GetNativeVertexLayout(_currentVertexShader.nativeCode);
|
_currentInputLayout = _currentVertexLayout.GetNativeVertexLayout(_currentVertexShader.nativeCode);
|
||||||
_currentInputLayout.AddRef();
|
_currentInputLayout.AddRef();
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.InputAssembler.SetInputLayout(_currentInputLayout);
|
NativeContext.InputAssembler.SetInputLayout(_currentInputLayout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void BindState()
|
private void BindState()
|
||||||
{
|
{
|
||||||
@@ -199,35 +211,50 @@ namespace GlitchyEngine.Renderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void Draw(uint32 vertexCount, uint32 startVertexIndex = 0)
|
public override void Draw(uint32 vertexCount, uint32 startVertexIndex = 0)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
BindState();
|
BindState();
|
||||||
|
|
||||||
NativeContext.Draw(vertexCount, startVertexIndex);
|
NativeContext.Draw(vertexCount, startVertexIndex);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void DrawIndexed(uint32 indexCount, uint32 startIndexLocation = 0, int32 vertexOffset = 0)
|
public override void DrawIndexed(uint32 indexCount, uint32 startIndexLocation = 0, int32 vertexOffset = 0)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
BindState();
|
BindState();
|
||||||
|
|
||||||
NativeContext.DrawIndexed(indexCount, startIndexLocation, vertexOffset);
|
NativeContext.DrawIndexed(indexCount, startIndexLocation, vertexOffset);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void DrawIndexedInstanced(uint32 indexCountPerInstance, uint32 instanceCount, uint32 startIndexLocation, int32 baseVertexLocation, uint32 startInstanceLocation)
|
public override void DrawIndexedInstanced(uint32 indexCountPerInstance, uint32 instanceCount, uint32 startIndexLocation, int32 baseVertexLocation, uint32 startInstanceLocation)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
BindState();
|
BindState();
|
||||||
|
|
||||||
NativeContext.DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
|
NativeContext.DrawIndexedInstanced(indexCountPerInstance, instanceCount, startIndexLocation, baseVertexLocation, startInstanceLocation);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetIndexBuffer(Buffer buffer, IndexFormat indexFormat = .Index16Bit, uint32 byteOffset = 0)
|
public override void SetIndexBuffer(Buffer buffer, IndexFormat indexFormat = .Index16Bit, uint32 byteOffset = 0)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
NativeContext.InputAssembler.SetIndexBuffer(buffer.nativeBuffer, indexFormat == .Index32Bit ? .R32_UInt : .R16_UInt, byteOffset);
|
NativeContext.InputAssembler.SetIndexBuffer(buffer.nativeBuffer, indexFormat == .Index32Bit ? .R32_UInt : .R16_UInt, byteOffset);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetViewports(uint32 viewportsCount, GlitchyEngine.Renderer.Viewport* viewports)
|
public override void SetViewports(uint32 viewportsCount, GlitchyEngine.Renderer.Viewport* viewports)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
NativeContext.Rasterizer.SetViewports(viewportsCount, (.)viewports);
|
NativeContext.Rasterizer.SetViewports(viewportsCount, (.)viewports);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetVertexLayout(VertexLayout vertexLayout)
|
public override void SetVertexLayout(VertexLayout vertexLayout)
|
||||||
{
|
{
|
||||||
@@ -240,9 +267,12 @@ namespace GlitchyEngine.Renderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void SetPrimitiveTopology(GlitchyEngine.Renderer.PrimitiveTopology primitiveTopology)
|
public override void SetPrimitiveTopology(GlitchyEngine.Renderer.PrimitiveTopology primitiveTopology)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
NativeContext.InputAssembler.SetPrimitiveTopology((DirectX.Common.PrimitiveTopology)primitiveTopology);
|
NativeContext.InputAssembler.SetPrimitiveTopology((DirectX.Common.PrimitiveTopology)primitiveTopology);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private uint32 _ps_FirstTexture;
|
private uint32 _ps_FirstTexture;
|
||||||
private uint32 _ps_BoundTextures;
|
private uint32 _ps_BoundTextures;
|
||||||
@@ -344,19 +374,28 @@ namespace GlitchyEngine.Renderer
|
|||||||
{
|
{
|
||||||
void** voidArray = scope void*[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]*;
|
void** voidArray = scope void*[D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT]*;
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.PixelShader.SetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, (.)voidArray);
|
NativeContext.PixelShader.SetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, (.)voidArray);
|
||||||
NativeContext.VertexShader.SetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, (.)voidArray);
|
NativeContext.VertexShader.SetShaderResources(0, D3D11_COMMONSHADER_INPUT_RESOURCE_SLOT_COUNT, (.)voidArray);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void BindVertexShader(VertexShader vertexShader)
|
public override void BindVertexShader(VertexShader vertexShader)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
BindShaderToStage(vertexShader);
|
BindShaderToStage(vertexShader);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void BindPixelShader(PixelShader pixelShader)
|
public override void BindPixelShader(PixelShader pixelShader)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
BindShaderToStage(pixelShader);
|
BindShaderToStage(pixelShader);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void BindConstantBuffer(Buffer buffer, int slot, ShaderStage stage)
|
public override void BindConstantBuffer(Buffer buffer, int slot, ShaderStage stage)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -444,11 +444,24 @@ namespace GlitchyEngine.Renderer
|
|||||||
|
|
||||||
Box srcBox = .(x, y, arraySlice, x + width, y + height, arraySlice + 1);
|
Box srcBox = .(x, y, arraySlice, x + width, y + height, arraySlice + 1);
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, texture, srcSubResource, &srcBox);
|
NativeContext.CopySubresourceRegion(stagingTexture, 0, 0, 0, 0, texture, srcSubResource, &srcBox);
|
||||||
|
}
|
||||||
|
|
||||||
MappedSubresource subresource = ?;
|
MappedSubresource subresource = ?;
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
result = NativeContext.Map(stagingTexture, 0, .Read, .None, &subresource);
|
result = NativeContext.Map(stagingTexture, 0, .Read, .None, &subresource);
|
||||||
defer NativeContext.Unmap(stagingTexture, 0);
|
}
|
||||||
|
|
||||||
|
defer
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
|
NativeContext.Unmap(stagingTexture, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (result != 0)
|
if (result != 0)
|
||||||
return .Err;
|
return .Err;
|
||||||
@@ -466,7 +479,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void CopyTo(RenderTargetGroup destination, int dstTarget, Int2 dstTopLeft, Int2 size, Int2 srcTopLeft, int srcTarget)
|
public override void CopyTo(RenderTargetGroup destination, int dstTarget, int2 dstTopLeft, int2 size, int2 srcTopLeft, int srcTarget)
|
||||||
{
|
{
|
||||||
ID3D11Texture2D* dstTexture = destination.GetNativeTexture(dstTarget);
|
ID3D11Texture2D* dstTexture = destination.GetNativeTexture(dstTarget);
|
||||||
ID3D11Texture2D* srcTexture = GetNativeTexture(srcTarget);
|
ID3D11Texture2D* srcTexture = GetNativeTexture(srcTarget);
|
||||||
@@ -475,9 +488,12 @@ namespace GlitchyEngine.Renderer
|
|||||||
|
|
||||||
Box srcBox = .((.)srcTopLeft.X, (.)srcTopLeft.Y, 0, (.)(srcTopLeft.X + size.X), (.)(srcTopLeft.Y + size.Y), 1);
|
Box srcBox = .((.)srcTopLeft.X, (.)srcTopLeft.Y, 0, (.)(srcTopLeft.X + size.X), (.)(srcTopLeft.Y + size.Y), 1);
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.CopySubresourceRegion(dstTexture, 0, (.)dstTopLeft.X, (.)dstTopLeft.Y, 0, srcTexture, 0, &srcBox);
|
NativeContext.CopySubresourceRegion(dstTexture, 0, (.)dstTopLeft.X, (.)dstTopLeft.Y, 0, srcTexture, 0, &srcBox);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -45,8 +45,11 @@ namespace GlitchyEngine.Renderer
|
|||||||
{
|
{
|
||||||
Debug.Profiler.ProfileRendererFunction!();
|
Debug.Profiler.ProfileRendererFunction!();
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.ClearRenderTargetView(RtOrBackbuffer!(renderTarget)._nativeRenderTargetView, color);
|
NativeContext.ClearRenderTargetView(RtOrBackbuffer!(renderTarget)._nativeRenderTargetView, color);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void Clear(DepthStencilTarget target, ClearOptions clearOptions, float depth, uint8 stencil)
|
public override void Clear(DepthStencilTarget target, ClearOptions clearOptions, float depth, uint8 stencil)
|
||||||
{
|
{
|
||||||
@@ -67,10 +70,15 @@ namespace GlitchyEngine.Renderer
|
|||||||
flags |= .Stencil;
|
flags |= .Stencil;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.ClearDepthStencilView(target.nativeView, flags, depth, stencil);
|
NativeContext.ClearDepthStencilView(target.nativeView, flags, depth, stencil);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void ClearRtv(DirectX.D3D11.ID3D11RenderTargetView* rtv, ClearColor clearColor)
|
private void ClearRtv(DirectX.D3D11.ID3D11RenderTargetView* rtv, ClearColor clearColor)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
switch(clearColor)
|
switch(clearColor)
|
||||||
{
|
{
|
||||||
@@ -99,6 +107,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
Runtime.NotImplemented();
|
Runtime.NotImplemented();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void Clear(RenderTargetGroup renderTarget, ClearOptions options, ClearColor? color = null, float? depth = null, uint8? stencil = null)
|
public override void Clear(RenderTargetGroup renderTarget, ClearOptions options, ClearColor? color = null, float? depth = null, uint8? stencil = null)
|
||||||
{
|
{
|
||||||
@@ -143,10 +152,13 @@ namespace GlitchyEngine.Renderer
|
|||||||
clearDepth = depth ?? clearDepth;
|
clearDepth = depth ?? clearDepth;
|
||||||
clearStencil = stencil ?? clearStencil;
|
clearStencil = stencil ?? clearStencil;
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.ClearDepthStencilView(renderTarget._nativeDepthTargetView, flags, clearDepth, clearStencil);
|
NativeContext.ClearDepthStencilView(renderTarget._nativeDepthTargetView, flags, clearDepth, clearStencil);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthBuffer)
|
public override void SetRenderTarget(RenderTarget2D renderTarget, int slot, bool setDepthBuffer)
|
||||||
{
|
{
|
||||||
@@ -199,8 +211,11 @@ namespace GlitchyEngine.Renderer
|
|||||||
Debug.Profiler.ProfileRendererFunction!();
|
Debug.Profiler.ProfileRendererFunction!();
|
||||||
|
|
||||||
SetReference!(_currentRasterizerState, rasterizerState);
|
SetReference!(_currentRasterizerState, rasterizerState);
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.Rasterizer.SetState(_currentRasterizerState.nativeRasterizerState);
|
NativeContext.Rasterizer.SetState(_currentRasterizerState.nativeRasterizerState);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private BlendState _currentBlendState ~ _?.ReleaseRef();
|
private BlendState _currentBlendState ~ _?.ReleaseRef();
|
||||||
|
|
||||||
@@ -209,8 +224,12 @@ namespace GlitchyEngine.Renderer
|
|||||||
Debug.Profiler.ProfileRendererFunction!();
|
Debug.Profiler.ProfileRendererFunction!();
|
||||||
|
|
||||||
SetReference!(_currentBlendState, blendState);
|
SetReference!(_currentBlendState, blendState);
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.OutputMerger.SetBlendState(_currentBlendState.nativeBlendState, blendFactor);
|
NativeContext.OutputMerger.SetBlendState(_currentBlendState.nativeBlendState, blendFactor);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private DepthStencilState _currentDepthStencilState ~ _?.ReleaseRef();
|
private DepthStencilState _currentDepthStencilState ~ _?.ReleaseRef();
|
||||||
|
|
||||||
@@ -219,8 +238,12 @@ namespace GlitchyEngine.Renderer
|
|||||||
Debug.Profiler.ProfileRendererFunction!();
|
Debug.Profiler.ProfileRendererFunction!();
|
||||||
|
|
||||||
SetReference!(_currentDepthStencilState, depthStencilState);
|
SetReference!(_currentDepthStencilState, depthStencilState);
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.OutputMerger.SetDepthStencilState(_currentDepthStencilState.nativeDepthStencilState, stencilReference);
|
NativeContext.OutputMerger.SetDepthStencilState(_currentDepthStencilState.nativeDepthStencilState, stencilReference);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public override void DrawIndexed(GeometryBinding geometry)
|
public override void DrawIndexed(GeometryBinding geometry)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -121,11 +121,14 @@ namespace GlitchyEngine.Renderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public override void Bind(uint32 slot)
|
public override void Bind(uint32 slot)
|
||||||
|
{
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
{
|
{
|
||||||
NativeContext.VertexShader.SetSamplers(slot, 1, &nativeSamplerState);
|
NativeContext.VertexShader.SetSamplers(slot, 1, &nativeSamplerState);
|
||||||
NativeContext.PixelShader.SetSamplers(slot, 1, &nativeSamplerState);
|
NativeContext.PixelShader.SetSamplers(slot, 1, &nativeSamplerState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -205,7 +205,30 @@ namespace GlitchyEngine.Renderer
|
|||||||
buffer.ReleaseRef();
|
buffer.ReleaseRef();
|
||||||
}
|
}
|
||||||
case .Texture:
|
case .Texture:
|
||||||
_textures.Add(scope String(bindDesc.Name), bindDesc.BindPoint, TextureViewBinding(null, null));
|
|
||||||
|
TextureDimension texDim;
|
||||||
|
|
||||||
|
switch (bindDesc.Dimension)
|
||||||
|
{
|
||||||
|
case .Texture1D:
|
||||||
|
texDim = .Texture1D;
|
||||||
|
case .Texture1DArray:
|
||||||
|
texDim = .Texture1DArray;
|
||||||
|
case .Texture2D:
|
||||||
|
texDim = .Texture2D;
|
||||||
|
case .Texture2DArray:
|
||||||
|
texDim = .Texture2DArray;
|
||||||
|
case .Texture3D:
|
||||||
|
texDim = .Texture3D;
|
||||||
|
case .TextureCube:
|
||||||
|
texDim = .TextureCube;
|
||||||
|
case .TextureCubeArray:
|
||||||
|
texDim = .TextureCubeArray;
|
||||||
|
default:
|
||||||
|
texDim = .Unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
_textures.Add(scope String(bindDesc.Name), bindDesc.BindPoint, TextureViewBinding(null, null), texDim);
|
||||||
case .Sampler:
|
case .Sampler:
|
||||||
// TODO: do we have to do something for samplers?
|
// TODO: do we have to do something for samplers?
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -19,43 +19,6 @@ namespace GlitchyEngine.Renderer
|
|||||||
extension Texture
|
extension Texture
|
||||||
{
|
{
|
||||||
protected internal ID3D11ShaderResourceView* _nativeResourceView ~ _?.Release();
|
protected internal ID3D11ShaderResourceView* _nativeResourceView ~ _?.Release();
|
||||||
|
|
||||||
/** \brief Loads the texture from the specified path.
|
|
||||||
* @param path The path of the texture to load.
|
|
||||||
* @param texture The reference to the pointer that will hold the texture.
|
|
||||||
* @returns true if the texture was loaded successfully; false otherwise.
|
|
||||||
*/
|
|
||||||
protected bool LoadDdsResourcePlatform<T>(Stream stream, ref T* texture) where T : ID3D11Resource
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
|
||||||
|
|
||||||
uint8[] ddsData = new:ScopedAlloc! uint8[stream.Length];
|
|
||||||
|
|
||||||
var result = stream.TryRead(ddsData);
|
|
||||||
|
|
||||||
if (result case .Err(let err))
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to read texture data from stream. Error: {err}");
|
|
||||||
}
|
|
||||||
|
|
||||||
((ID3D11Resource*)texture)?.Release();
|
|
||||||
_nativeResourceView?.Release();
|
|
||||||
|
|
||||||
HResult loadResult = DDSTextureLoader.CreateDDSTextureFromMemory(NativeDevice,
|
|
||||||
ddsData.Ptr, (uint)ddsData.Count, (.)&texture, &_nativeResourceView);
|
|
||||||
|
|
||||||
if(loadResult.Failed)
|
|
||||||
{
|
|
||||||
Log.EngineLogger.Error($"Failed to load texture. Error({(int)loadResult}): {loadResult}");
|
|
||||||
|
|
||||||
ReleaseAndNullify!(texture);
|
|
||||||
ReleaseAndNullify!(_nativeResourceView);
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension Texture2DDesc
|
extension Texture2DDesc
|
||||||
@@ -93,43 +56,65 @@ namespace GlitchyEngine.Renderer
|
|||||||
public override uint32 Height => nativeDesc.Height;
|
public override uint32 Height => nativeDesc.Height;
|
||||||
public override uint32 ArraySize => nativeDesc.ArraySize;
|
public override uint32 ArraySize => nativeDesc.ArraySize;
|
||||||
public override uint32 MipLevels => nativeDesc.MipLevels;
|
public override uint32 MipLevels => nativeDesc.MipLevels;
|
||||||
|
public override Format Format => nativeDesc.Format;
|
||||||
|
|
||||||
protected override void LoadDdsPlatform(Stream stream)
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
|
||||||
|
|
||||||
LoadDdsResourcePlatform(stream, ref nativeTexture);
|
/*protected override void CreateTexturePlatform(Texture2DDesc desc, bool isRenderTarget, void* data, uint32 linePitch)
|
||||||
|
|
||||||
let resType = nativeTexture.GetResourceType();
|
|
||||||
Log.EngineLogger.Assert(resType == .Texture2D, scope $"The texture is not a 2D texture (it is {resType}).");
|
|
||||||
|
|
||||||
nativeTexture.GetDescription(out nativeDesc);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void CreateTexturePlatform(Texture2DDesc desc, bool isRenderTarget, void* data, uint32 linePitch)
|
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
PrepareTexturePlatform(desc, isRenderTarget);
|
PrepareTexturePlatform(desc, isRenderTarget);
|
||||||
InternalCreateTexture(data, linePitch, 0);
|
InternalCreateTexture(data, linePitch, 0);
|
||||||
}
|
}*/
|
||||||
|
|
||||||
private void InternalCreateTexture(void* data, uint32 linePitch, uint32 slicePitch)
|
/// Creates the native texture. Initializes it, if slices is not null and has enough Entries to fill all slices.
|
||||||
|
/// @returns true if the texture has been initialized; false otherwise.
|
||||||
|
private bool InternalCreateTexture(Span<TextureSliceData> slices)
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
SubresourceData resData = .(data, linePitch, slicePitch);
|
SubresourceData[] data = null;
|
||||||
|
|
||||||
// If data is null, set subresourceData null
|
if (slices.Length == MipLevels * ArraySize)
|
||||||
SubresourceData* resDataPtr = data == null ? null : &resData;
|
{
|
||||||
|
data = scope:: SubresourceData[slices.Length];
|
||||||
|
|
||||||
var result = NativeDevice.CreateTexture2D(ref nativeDesc, resDataPtr, &nativeTexture);
|
for (int i < slices.Length)
|
||||||
|
{
|
||||||
|
TextureSliceData slice = slices[i];
|
||||||
|
|
||||||
|
data[i] = .(slice.Data, slice.LinePitch, slice.SlicePitch);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = NativeDevice.CreateTexture2D(ref nativeDesc, data?.Ptr, &nativeTexture);
|
||||||
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture 2D. Error ({result.Underlying}): {result}");
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture 2D. Error ({result.Underlying}): {result}");
|
||||||
|
|
||||||
result = NativeDevice.CreateShaderResourceView(nativeTexture, null, &_nativeResourceView);
|
result = NativeDevice.CreateShaderResourceView(nativeTexture, null, &_nativeResourceView);
|
||||||
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture view. Error ({result.Underlying}): {result}");
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture view. Error ({result.Underlying}): {result}");
|
||||||
|
|
||||||
|
// If Data is non-null the texture got initialized with data.
|
||||||
|
return (data != null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*private void InternalCreateTexture(void* data, uint32 linePitch, uint32 slicePitch)
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
/*SubresourceData resData = .(data, linePitch, slicePitch);
|
||||||
|
|
||||||
|
// If data is null, set subresourceData null
|
||||||
|
SubresourceData* resDataPtr = data == null ? null : &resData;*/
|
||||||
|
|
||||||
|
SubresourceData[2] resData = .(.(data, linePitch, slicePitch), .(null, 0, 0));
|
||||||
|
|
||||||
|
var result = NativeDevice.CreateTexture2D(ref nativeDesc, &resData, &nativeTexture);
|
||||||
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture 2D. Error ({result.Underlying}): {result}");
|
||||||
|
|
||||||
|
result = NativeDevice.CreateShaderResourceView(nativeTexture, null, &_nativeResourceView);
|
||||||
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture view. Error ({result.Underlying}): {result}");
|
||||||
|
}*/
|
||||||
|
|
||||||
protected override void PrepareTexturePlatform(Texture2DDesc desc, bool isRenderTarget)
|
protected override void PrepareTexturePlatform(Texture2DDesc desc, bool isRenderTarget)
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
@@ -145,6 +130,26 @@ namespace GlitchyEngine.Renderer
|
|||||||
nativeDesc.BindFlags |= .RenderTarget;
|
nativeDesc.BindFlags |= .RenderTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override Result<void> PlatformSetData(Span<TextureSliceData> slices)
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
if(nativeTexture == null)
|
||||||
|
{
|
||||||
|
if (InternalCreateTexture(slices))
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
Runtime.NotImplemented();
|
||||||
|
|
||||||
|
/*int index = firstArraySlice;
|
||||||
|
|
||||||
|
for (TextureSliceData slice in slices)
|
||||||
|
{
|
||||||
|
|
||||||
|
}*/
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Update Texture Arrays!
|
// TODO: Update Texture Arrays!
|
||||||
protected override Result<void> PlatformSetData(void* data, uint32 elementSize, uint32 destX,
|
protected override Result<void> PlatformSetData(void* data, uint32 elementSize, uint32 destX,
|
||||||
uint32 destY, uint32 destWidth, uint32 destHeight, uint32 arraySlice, uint32 mipLevel, GlitchyEngine.Renderer.MapType mapType)
|
uint32 destY, uint32 destWidth, uint32 destHeight, uint32 arraySlice, uint32 mipLevel, GlitchyEngine.Renderer.MapType mapType)
|
||||||
@@ -153,6 +158,21 @@ namespace GlitchyEngine.Renderer
|
|||||||
|
|
||||||
if(nativeTexture == null)
|
if(nativeTexture == null)
|
||||||
{
|
{
|
||||||
|
if(destX == 0 && destY == 0 && destWidth == nativeDesc.Width && destHeight == nativeDesc.Height &&
|
||||||
|
arraySlice == 0 && mipLevel == 0 && ArraySize == 1 && MipLevels == 1)
|
||||||
|
{
|
||||||
|
TextureSliceData[1] dataSlice = .(.(data, elementSize * destWidth, elementSize * destWidth * destHeight));
|
||||||
|
|
||||||
|
// Turns out we need to initialize all slices at once or none... so... tough shit, we cant early out here.
|
||||||
|
if (InternalCreateTexture(dataSlice))
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
InternalCreateTexture(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Old shit follows...
|
||||||
if(destX == 0 && destY == 0 && destWidth == nativeDesc.Width && destHeight == nativeDesc.Height)
|
if(destX == 0 && destY == 0 && destWidth == nativeDesc.Width && destHeight == nativeDesc.Height)
|
||||||
{
|
{
|
||||||
// We can pass the data while creating the buffer, so we can return here.
|
// We can pass the data while creating the buffer, so we can return here.
|
||||||
@@ -165,6 +185,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
Log.EngineLogger.Assert(nativeDesc.Usage != .Immutable, "The entire immutable texture has to be initialized.");
|
Log.EngineLogger.Assert(nativeDesc.Usage != .Immutable, "The entire immutable texture has to be initialized.");
|
||||||
InternalCreateTexture(null, 0, 0);
|
InternalCreateTexture(null, 0, 0);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
//Log.EngineLogger.AssertDebug();
|
//Log.EngineLogger.AssertDebug();
|
||||||
@@ -177,7 +198,12 @@ namespace GlitchyEngine.Renderer
|
|||||||
case .Default:
|
case .Default:
|
||||||
Box dataBox = .(destX, destY, 0, destX + destWidth, destY + destHeight, 1);
|
Box dataBox = .(destX, destY, 0, destX + destWidth, destY + destHeight, 1);
|
||||||
var rowPitch = elementSize * destWidth;
|
var rowPitch = elementSize * destWidth;
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
NativeContext.UpdateSubresource(nativeTexture, subresourceIndex, &dataBox, data, rowPitch, rowPitch * destHeight);
|
NativeContext.UpdateSubresource(nativeTexture, subresourceIndex, &dataBox, data, rowPitch, rowPitch * destHeight);
|
||||||
|
}
|
||||||
|
|
||||||
case .Dynamic:
|
case .Dynamic:
|
||||||
Runtime.NotImplemented();
|
Runtime.NotImplemented();
|
||||||
/*
|
/*
|
||||||
@@ -220,6 +246,187 @@ namespace GlitchyEngine.Renderer
|
|||||||
sourceBox.Back = 1;
|
sourceBox.Back = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure the destination was initialized
|
||||||
|
if(destination.nativeTexture == null)
|
||||||
|
destination.InternalCreateTexture(null);
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
|
NativeContext.CopySubresourceRegion(destination.nativeTexture,
|
||||||
|
D3D11.CalcSubresource(destMipSlice, destArraySlice, destination.MipLevels), destX, destY, 0,
|
||||||
|
source.nativeTexture, D3D11.CalcSubresource(srcMipSlice, srcArraySlice, source.MipLevels), (.)&sourceBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void CopyTo(Texture2D destination)
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
if(nativeTexture == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(nativeDesc.Format == destination.nativeDesc.Format,
|
||||||
|
"Source and destination resources must have the same texel-format.");
|
||||||
|
|
||||||
|
// Make sure the destination was initialized
|
||||||
|
if(destination.nativeTexture == null)
|
||||||
|
destination.InternalCreateTexture(null);
|
||||||
|
|
||||||
|
uint32 arraySlices = Math.Min(ArraySize, destination.ArraySize);
|
||||||
|
uint32 mipSlices = Math.Min(MipLevels, destination.MipLevels);
|
||||||
|
|
||||||
|
for(uint32 arraySlice < arraySlices)
|
||||||
|
for(uint32 mipSlice < mipSlices)
|
||||||
|
{
|
||||||
|
Box sourceBox = .(0, 0, 0, Width, Height, 1);
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
|
NativeContext.CopySubresourceRegion(destination.nativeTexture,
|
||||||
|
D3D11.CalcSubresource(mipSlice, arraySlice, destination.MipLevels), 0, 0, 0,
|
||||||
|
nativeTexture, D3D11.CalcSubresource(mipSlice, arraySlice, MipLevels), (.)&sourceBox);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override TextureViewBinding PlatformGetViewBinding()
|
||||||
|
{
|
||||||
|
return .(_nativeResourceView, _samplerState?.nativeSamplerState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension TextureCube
|
||||||
|
{
|
||||||
|
protected internal ID3D11Texture2D* nativeTexture ~ _?.Release();
|
||||||
|
protected internal NativeTex2DDesc nativeDesc;
|
||||||
|
|
||||||
|
public override uint32 Width => nativeDesc.Width;
|
||||||
|
public override uint32 Height => nativeDesc.Height;
|
||||||
|
public override uint32 ArraySize => nativeDesc.ArraySize / 6;
|
||||||
|
public override uint32 MipLevels => nativeDesc.MipLevels;
|
||||||
|
public override Format Format => nativeDesc.Format;
|
||||||
|
|
||||||
|
protected override void CreateTexturePlatform(Texture2DDesc desc, bool isRenderTarget, void* data, uint32 linePitch)
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
PrepareTexturePlatform(desc, isRenderTarget);
|
||||||
|
InternalCreateTexture(data, linePitch, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PrepareTexturePlatform(Texture2DDesc desc, bool isRenderTarget)
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
nativeTexture?.Release();
|
||||||
|
nativeTexture = null;
|
||||||
|
_nativeResourceView?.Release();
|
||||||
|
_nativeResourceView = null;
|
||||||
|
|
||||||
|
nativeDesc = (NativeTex2DDesc)desc;
|
||||||
|
// Make it a texture cube
|
||||||
|
nativeDesc.MiscFlags |= .TextureCube;
|
||||||
|
nativeDesc.ArraySize *= 6;
|
||||||
|
|
||||||
|
if(isRenderTarget)
|
||||||
|
nativeDesc.BindFlags |= .RenderTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void InternalCreateTexture(void* data, uint32 linePitch, uint32 slicePitch)
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
SubresourceData resData = .(data, linePitch, slicePitch);
|
||||||
|
|
||||||
|
// If data is null, set subresourceData null
|
||||||
|
SubresourceData* resDataPtr = null;//data == null ? null : &resData;
|
||||||
|
|
||||||
|
var result = NativeDevice.CreateTexture2D(ref nativeDesc, resDataPtr, &nativeTexture);
|
||||||
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture 2D. Error ({result.Underlying}): {result}");
|
||||||
|
|
||||||
|
result = NativeDevice.CreateShaderResourceView(nativeTexture, null, &_nativeResourceView);
|
||||||
|
Log.EngineLogger.Assert(result.Succeeded, scope $"Failed to create texture view. Error ({result.Underlying}): {result}");
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Update Texture Arrays!
|
||||||
|
protected override Result<void> PlatformSetData(void* data, uint32 elementSize, uint32 destX,
|
||||||
|
uint32 destY, uint32 destWidth, uint32 destHeight, uint32 arraySlice, uint32 mipLevel, GlitchyEngine.Renderer.MapType mapType)
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
if(nativeTexture == null)
|
||||||
|
{
|
||||||
|
if(destX == 0 && destY == 0 && destWidth == nativeDesc.Width && destHeight == nativeDesc.Height)
|
||||||
|
{
|
||||||
|
// We can pass the data while creating the buffer, so we can return here.
|
||||||
|
var rowPitch = elementSize * destWidth;
|
||||||
|
InternalCreateTexture(data, rowPitch, rowPitch * destHeight);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// If we don't set the entire texture we need to create the texture with unknown content and set it manually
|
||||||
|
Log.EngineLogger.Assert(nativeDesc.Usage != .Immutable, "The entire immutable texture has to be initialized.");
|
||||||
|
InternalCreateTexture(null, 0, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Log.EngineLogger.AssertDebug();
|
||||||
|
// TODO: Debug.Assert(dstByteOffset + byteLength <= _description.Size, "The destination offset and byte length are too long for the target buffer.");
|
||||||
|
|
||||||
|
uint32 subresourceIndex = D3D11.CalcSubresource(mipLevel, arraySlice, nativeDesc.MipLevels);
|
||||||
|
|
||||||
|
switch(nativeDesc.Usage)
|
||||||
|
{
|
||||||
|
case .Default:
|
||||||
|
Box dataBox = .(destX, destY, 0, destX + destWidth, destY + destHeight, 1);
|
||||||
|
var rowPitch = elementSize * destWidth;
|
||||||
|
|
||||||
|
using (ContextMonitor.Enter())
|
||||||
|
{
|
||||||
|
NativeContext.UpdateSubresource(nativeTexture, subresourceIndex, &dataBox, data, rowPitch, rowPitch * destHeight);
|
||||||
|
}
|
||||||
|
case .Dynamic:
|
||||||
|
Runtime.NotImplemented();
|
||||||
|
/*
|
||||||
|
Log.EngineLogger.Assert(mapType.CanWrite, "The map type has to have write access.");
|
||||||
|
// Todo: DoNotWaitFlag
|
||||||
|
MappedSubresource map = ?;
|
||||||
|
_context.nativeContext.Map(nativeBuffer, 0, (.)mapType, .None, &map);
|
||||||
|
Internal.MemCpy(((uint8*)map.Data) + dstByteOffset, data, byteLength);
|
||||||
|
_context.nativeContext.Unmap(nativeBuffer, 0);
|
||||||
|
*/
|
||||||
|
case .Immutable:
|
||||||
|
Log.EngineLogger.Error("Can't set the data of an immutable resource.");
|
||||||
|
return .Err;
|
||||||
|
default:
|
||||||
|
Log.EngineLogger.Error($"Unknown resource usage: {nativeDesc.Usage}");
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
|
||||||
|
return .Ok;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*public static override void CopySubresourceRegion(Texture2D source, Texture2D destination,
|
||||||
|
ResourceBox sourceBox = default, uint32 destX = 0, uint32 destY = 0,
|
||||||
|
uint32 srcArraySlice = 0, uint32 srcMipSlice = 0, uint32 destArraySlice = 0, uint32 destMipSlice = 0)
|
||||||
|
{
|
||||||
|
Debug.Profiler.ProfileResourceFunction!();
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(source != destination || srcArraySlice != destArraySlice
|
||||||
|
|| srcMipSlice != destMipSlice, "Cannot copy from and to the same sub resource.");
|
||||||
|
|
||||||
|
Log.EngineLogger.AssertDebug(source.nativeDesc.Format == destination.nativeDesc.Format,
|
||||||
|
"Source and destination resources must have the same texel-format.");
|
||||||
|
|
||||||
|
var sourceBox;
|
||||||
|
|
||||||
|
if(sourceBox.Right == 0)
|
||||||
|
{
|
||||||
|
sourceBox.Right = source.Width;
|
||||||
|
sourceBox.Bottom = source.Height;
|
||||||
|
sourceBox.Back = 1;
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the destination was initialized
|
// Make sure the destination was initialized
|
||||||
if(destination.nativeTexture == null)
|
if(destination.nativeTexture == null)
|
||||||
destination.InternalCreateTexture(null, 0, 0);
|
destination.InternalCreateTexture(null, 0, 0);
|
||||||
@@ -255,44 +462,13 @@ namespace GlitchyEngine.Renderer
|
|||||||
D3D11.CalcSubresource(mipSlice, arraySlice, destination.MipLevels), 0, 0, 0,
|
D3D11.CalcSubresource(mipSlice, arraySlice, destination.MipLevels), 0, 0, 0,
|
||||||
nativeTexture, D3D11.CalcSubresource(mipSlice, arraySlice, MipLevels), (.)&sourceBox);
|
nativeTexture, D3D11.CalcSubresource(mipSlice, arraySlice, MipLevels), (.)&sourceBox);
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
protected override TextureViewBinding PlatformGetViewBinding()
|
protected override TextureViewBinding PlatformGetViewBinding()
|
||||||
{
|
{
|
||||||
return .(_nativeResourceView, _samplerState?.nativeSamplerState);
|
return .(_nativeResourceView, _samplerState?.nativeSamplerState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TextureCube
|
|
||||||
{
|
|
||||||
protected internal ID3D11Texture2D* nativeTexture ~ _?.Release();
|
|
||||||
protected internal NativeTex2DDesc nativeDesc;
|
|
||||||
|
|
||||||
public override uint32 Width => nativeDesc.Width;
|
|
||||||
public override uint32 Height => nativeDesc.Height;
|
|
||||||
public override uint32 ArraySize => nativeDesc.ArraySize / 6;
|
|
||||||
public override uint32 MipLevels => nativeDesc.MipLevels;
|
|
||||||
|
|
||||||
protected override void LoadTexturePlatform(Stream stream)
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileResourceFunction!();
|
|
||||||
|
|
||||||
LoadDdsResourcePlatform(stream, ref nativeTexture);
|
|
||||||
|
|
||||||
let resType = nativeTexture.GetResourceType();
|
|
||||||
Log.EngineLogger.Assert(resType == .Texture2D, scope $"The texture \"{_path}\" is not a texture cube (it is {resType}).");
|
|
||||||
|
|
||||||
nativeTexture.GetDescription(out nativeDesc);
|
|
||||||
|
|
||||||
Log.EngineLogger.Assert(nativeDesc.MiscFlags.HasFlag(.TextureCube), scope $"The texture \"{_path}\" is not a texture cube.");
|
|
||||||
// TODO: load fallback texture
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override TextureViewBinding PlatformGetViewBinding()
|
|
||||||
{
|
|
||||||
return .(_nativeResourceView, _samplerState.nativeSamplerState);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -19,13 +19,13 @@ namespace GlitchyEngine
|
|||||||
//[CLink, CallingConvention(.Stdcall)]
|
//[CLink, CallingConvention(.Stdcall)]
|
||||||
//static extern int16 GetKeyState(int32 keycode);
|
//static extern int16 GetKeyState(int32 keycode);
|
||||||
[CLink, CallingConvention(.Stdcall)]
|
[CLink, CallingConvention(.Stdcall)]
|
||||||
static extern IntBool GetCursorPos(out Int2 p);
|
static extern IntBool GetCursorPos(out int2 p);
|
||||||
[CLink, CallingConvention(.Stdcall)]
|
[CLink, CallingConvention(.Stdcall)]
|
||||||
static extern IntBool SetCursorPos(c_int x, c_int y);
|
static extern IntBool SetCursorPos(c_int x, c_int y);
|
||||||
[CLink, CallingConvention(.Stdcall)]
|
[CLink, CallingConvention(.Stdcall)]
|
||||||
static extern IntBool ScreenToClient(HWnd hWnd, ref Int2 p);
|
static extern IntBool ScreenToClient(HWnd hWnd, ref int2 p);
|
||||||
[CLink, CallingConvention(.Stdcall)]
|
[CLink, CallingConvention(.Stdcall)]
|
||||||
static extern IntBool ClientToScreen(HWnd hWnd, ref Int2 p);
|
static extern IntBool ClientToScreen(HWnd hWnd, ref int2 p);
|
||||||
|
|
||||||
[Import("user32.lib"), CLink]
|
[Import("user32.lib"), CLink]
|
||||||
public static extern IntBool RegisterRawInputDevices(RAWINPUTDEVICE* pRawInputDevices, uint32 uiNumDevices, uint32 cbSize);
|
public static extern IntBool RegisterRawInputDevices(RAWINPUTDEVICE* pRawInputDevices, uint32 uiNumDevices, uint32 cbSize);
|
||||||
@@ -50,9 +50,9 @@ namespace GlitchyEngine
|
|||||||
struct WindowsInputState
|
struct WindowsInputState
|
||||||
{
|
{
|
||||||
public int8[256] KeyStates;
|
public int8[256] KeyStates;
|
||||||
public Int2 CursorPosition;
|
public int2 CursorPosition;
|
||||||
public Int2 CursorPositionDifference;
|
public int2 CursorPositionDifference;
|
||||||
public Int2 RawCursorMovement;
|
public int2 RawCursorMovement;
|
||||||
}
|
}
|
||||||
|
|
||||||
static WindowsInputState[2] IputStates;
|
static WindowsInputState[2] IputStates;
|
||||||
@@ -157,11 +157,11 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
public override static bool IsMouseButtonReleasing(MouseButton button) => IsMouseButtonReleased(button) && WasMouseButtonPressed(button);
|
public override static bool IsMouseButtonReleasing(MouseButton button) => IsMouseButtonReleased(button) && WasMouseButtonPressed(button);
|
||||||
|
|
||||||
public override static Int2 GetMousePosition() => CurrentState.CursorPosition;
|
public override static int2 GetMousePosition() => CurrentState.CursorPosition;
|
||||||
|
|
||||||
public override static Int2 GetMouseMovement() => CurrentState.CursorPositionDifference;
|
public override static int2 GetMouseMovement() => CurrentState.CursorPositionDifference;
|
||||||
|
|
||||||
public override static Int2 GetRawMouseMovement() => CurrentState.RawCursorMovement;
|
public override static int2 GetRawMouseMovement() => CurrentState.RawCursorMovement;
|
||||||
|
|
||||||
public override static int32 GetMouseX() => CurrentState.CursorPosition.X;
|
public override static int32 GetMouseX() => CurrentState.CursorPosition.X;
|
||||||
|
|
||||||
@@ -182,17 +182,17 @@ namespace GlitchyEngine
|
|||||||
return state >= 0;
|
return state >= 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override static Int2 GetLastMousePosition() => LastState.CursorPosition;
|
public override static int2 GetLastMousePosition() => LastState.CursorPosition;
|
||||||
|
|
||||||
public override static Int2 GetLastMouseMovement() => LastState.CursorPositionDifference;
|
public override static int2 GetLastMouseMovement() => LastState.CursorPositionDifference;
|
||||||
|
|
||||||
public override static Int2 GetLastRawMouseMovement() => LastState.RawCursorMovement;
|
public override static int2 GetLastRawMouseMovement() => LastState.RawCursorMovement;
|
||||||
|
|
||||||
public override static int32 GetLastMouseX() => LastState.CursorPosition.X;
|
public override static int32 GetLastMouseX() => LastState.CursorPosition.X;
|
||||||
|
|
||||||
public override static int32 GetLastMouseY() => LastState.CursorPosition.Y;
|
public override static int32 GetLastMouseY() => LastState.CursorPosition.Y;
|
||||||
|
|
||||||
public override static void SetMousePosition(Int2 pos)
|
public override static void SetMousePosition(int2 pos)
|
||||||
{
|
{
|
||||||
HWnd windowHandle = (HWnd)(int)Application.Get().Window.NativeWindow;
|
HWnd windowHandle = (HWnd)(int)Application.Get().Window.NativeWindow;
|
||||||
|
|
||||||
|
|||||||
@@ -67,13 +67,13 @@ namespace GlitchyEngine
|
|||||||
//
|
//
|
||||||
// Size
|
// Size
|
||||||
//
|
//
|
||||||
public override Int2 Size
|
public override int2 Size
|
||||||
{
|
{
|
||||||
get => *(Int2*)&_clientRect.Width;
|
get => *(int2*)&_clientRect.Width;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
*(Int2*)&_clientRect.Width = value;
|
*(int2*)&_clientRect.Width = value;
|
||||||
ApplyRectangle();
|
ApplyRectangle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,13 +103,13 @@ namespace GlitchyEngine
|
|||||||
//
|
//
|
||||||
// Position
|
// Position
|
||||||
//
|
//
|
||||||
public override Int2 Position
|
public override int2 Position
|
||||||
{
|
{
|
||||||
get => *(Int2*)&_clientRect;
|
get => *(int2*)&_clientRect;
|
||||||
|
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
*(Int2*)&_clientRect = value;
|
*(int2*)&_clientRect = value;
|
||||||
ApplyRectangle();
|
ApplyRectangle();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,7 +263,7 @@ namespace GlitchyEngine
|
|||||||
return .Ok;
|
return .Ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal Int2 _rawMouseMovementAccumulator;
|
internal int2 _rawMouseMovementAccumulator;
|
||||||
|
|
||||||
private static LRESULT MessageHandler(HWND hwnd, uint32 uMsg, WPARAM wParam, LPARAM lParam)
|
private static LRESULT MessageHandler(HWND hwnd, uint32 uMsg, WPARAM wParam, LPARAM lParam)
|
||||||
{
|
{
|
||||||
@@ -478,7 +478,7 @@ namespace GlitchyEngine
|
|||||||
window._eventCallback(event);
|
window._eventCallback(event);
|
||||||
|
|
||||||
// We accumulate the raw movements an collect them once each frame in WindowsInput.Impl_NewFrame()
|
// We accumulate the raw movements an collect them once each frame in WindowsInput.Impl_NewFrame()
|
||||||
window._rawMouseMovementAccumulator += Int2(raw.Data.Mouse.lLastX, raw.Data.Mouse.lLastY);
|
window._rawMouseMovementAccumulator += int2(raw.Data.Mouse.lLastX, raw.Data.Mouse.lLastY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace GlitchyEngine
|
|||||||
class Program
|
class Program
|
||||||
{
|
{
|
||||||
[LinkName("CreateApplication")]
|
[LinkName("CreateApplication")]
|
||||||
static extern Application CreateApplication();
|
static extern Application CreateApplication(String[] args);
|
||||||
|
|
||||||
public static int Main(String[] args)
|
public static int Main(String[] args)
|
||||||
{
|
{
|
||||||
@@ -23,7 +23,7 @@ namespace GlitchyEngine
|
|||||||
|
|
||||||
Stopwatch initWatch = scope Stopwatch();
|
Stopwatch initWatch = scope Stopwatch();
|
||||||
|
|
||||||
app = CreateApplication();
|
app = CreateApplication(args);
|
||||||
|
|
||||||
initWatch.Stop();
|
initWatch.Stop();
|
||||||
|
|
||||||
|
|||||||
@@ -188,9 +188,9 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
|
|
||||||
class JointAnimation// : IDisposable
|
class JointAnimation// : IDisposable
|
||||||
{
|
{
|
||||||
public JointAnimationChannel<Vector3> TranslationChannel ~ delete _;
|
public JointAnimationChannel<float3> TranslationChannel ~ delete _;
|
||||||
public JointAnimationChannel<Quaternion> RotationChannel ~ delete _;
|
public JointAnimationChannel<Quaternion> RotationChannel ~ delete _;
|
||||||
public JointAnimationChannel<Vector3> ScaleChannel ~ delete _;
|
public JointAnimationChannel<float3> ScaleChannel ~ delete _;
|
||||||
|
|
||||||
public float Duration
|
public float Duration
|
||||||
{
|
{
|
||||||
@@ -221,7 +221,7 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
case .Step:
|
case .Step:
|
||||||
result.Translation = previous;
|
result.Translation = previous;
|
||||||
case .Linear:
|
case .Linear:
|
||||||
result.Translation = Vector3.Lerp(previous, next, interpolationValue);
|
result.Translation = lerp(previous, next, interpolationValue);
|
||||||
default:
|
default:
|
||||||
result.Rotation = ?;
|
result.Rotation = ?;
|
||||||
Runtime.NotImplemented();
|
Runtime.NotImplemented();
|
||||||
@@ -262,7 +262,7 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
case .Step:
|
case .Step:
|
||||||
result.Scale = previous;
|
result.Scale = previous;
|
||||||
case .Linear:
|
case .Linear:
|
||||||
result.Scale = Vector3.Lerp(previous, next, interpolationValue);
|
result.Scale = lerp(previous, next, interpolationValue);
|
||||||
default:
|
default:
|
||||||
result.Rotation = ?;
|
result.Rotation = ?;
|
||||||
Runtime.NotImplemented();
|
Runtime.NotImplemented();
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ namespace GlitchyEngine.Renderer.Animation
|
|||||||
public struct JointPose
|
public struct JointPose
|
||||||
{
|
{
|
||||||
public Quaternion Rotation;
|
public Quaternion Rotation;
|
||||||
public Vector3 Translation;
|
public float3 Translation;
|
||||||
public Vector3 Scale;
|
public float3 Scale;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,139 @@
|
|||||||
using System;
|
using System;
|
||||||
using GlitchyEngine.Core;
|
using GlitchyEngine.Core;
|
||||||
|
|
||||||
|
namespace DirectX.DXGI
|
||||||
|
{
|
||||||
|
public extension Format
|
||||||
|
{
|
||||||
|
public bool IsInt()
|
||||||
|
{
|
||||||
|
switch(this)
|
||||||
|
{
|
||||||
|
case R32G32B32A32_SInt, R32G32B32_SInt, R16G16B16A16_SInt, R32G32_SInt, R8G8B8A8_SInt, R16G16_SInt,
|
||||||
|
R32_SInt, R8G8_SInt, R16_SInt, R8_SInt:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public bool IsUInt()
|
||||||
|
{
|
||||||
|
switch(this)
|
||||||
|
{
|
||||||
|
case R32G32B32A32_UInt, R32G32B32_UInt, R16G16B16A16_UInt, R32G32_UInt, R10G10B10A2_UInt, R8G8B8A8_UInt, R16G16_UInt,
|
||||||
|
R32_UInt, R8G8_UInt, R16_UInt, R8_UInt:
|
||||||
|
return true;
|
||||||
|
default:
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint32 BitsPerPixel()
|
||||||
|
{
|
||||||
|
switch (this)
|
||||||
|
{
|
||||||
|
case .R32G32B32A32_Typeless,.R32G32B32A32_Float,.R32G32B32A32_UInt,.R32G32B32A32_SInt:
|
||||||
|
return 128;
|
||||||
|
|
||||||
|
case .R32G32B32_Typeless,.R32G32B32_Float,.R32G32B32_UInt,.R32G32B32_SInt:
|
||||||
|
return 96;
|
||||||
|
|
||||||
|
case .R16G16B16A16_Typeless,.R16G16B16A16_Float,.R16G16B16A16_UNorm,.R16G16B16A16_UInt,.R16G16B16A16_SNorm,.R16G16B16A16_SInt,.R32G32_Typeless,.R32G32_Float,.R32G32_UInt,.R32G32_SInt,.R32G8X24_Typeless,.D32_Float_S8X24_UInt,.R32_Float_X8X24_Typeless,.X32_Typeless_G8X24_UInt,.Y416,.Y210,.Y216:
|
||||||
|
return 64;
|
||||||
|
|
||||||
|
case .R10G10B10A2_Typeless,.R10G10B10A2_UNorm,.R10G10B10A2_UInt,.R11G11B10_Float,.R8G8B8A8_Typeless,.R8G8B8A8_UNorm,.R8G8B8A8_UNorm_SRGB,.R8G8B8A8_UInt,.R8G8B8A8_SNorm,.R8G8B8A8_SInt,.R16G16_Typeless,.R16G16_Float,.R16G16_UNorm,.R16G16_UInt,.R16G16_SNorm,.R16G16_SInt,.R32_Typeless,.D32_Float,.R32_Float,.R32_UInt,.R32_SInt,.R24G8_Typeless,.D24_UNorm_S8_UInt,.R24_UNorm_X8_Typeless,.X24_Typeless_G8_UInt,.R9G9B9E5_SHAREDEXP,.R8G8_B8G8_UNorm,.G8R8_G8B8_UNorm,.B8G8R8A8_UNorm,.B8G8R8X8_UNorm,.R10G10B10_XR_BIAS_A2_UNorm,.B8G8R8A8_Typeless,.B8G8R8A8_UNorm_SRGB,.B8G8R8X8_Typeless,.B8G8R8X8_UNorm_SRGB,.AYUV,.Y410,.YUY2:
|
||||||
|
//#if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)
|
||||||
|
//case .R10G10B10_7E3_A2_Float,.R10G10B10_6E4_A2_Float,.R10G10B10_SNorm_A2_UNorm:
|
||||||
|
//#endif
|
||||||
|
return 32;
|
||||||
|
|
||||||
|
case .P010,.P016, .V408:
|
||||||
|
/*#if (_WIN32_WINNT >= _WIN32_WINNT_WIN10)
|
||||||
|
case .V408:
|
||||||
|
#endif
|
||||||
|
#if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)
|
||||||
|
case .D16_UNorm_S8_UInt,.R16_UNorm_X8_Typeless,.X16_Typeless_G8_UInt:
|
||||||
|
#endif*/
|
||||||
|
return 24;
|
||||||
|
|
||||||
|
case .R8G8_Typeless,.R8G8_UNorm,.R8G8_UInt,.R8G8_SNorm,.R8G8_SInt,.R16_Typeless,.R16_Float,.D16_UNorm,.R16_UNorm,.R16_UInt,.R16_SNorm,.R16_SInt,.B5G6R5_UNorm,.B5G5R5A1_UNorm,.A8P8,.B4G4R4A4_UNORM, .P208,.V208:
|
||||||
|
/*#if (_WIN32_WINNT >= _WIN32_WINNT_WIN10)
|
||||||
|
case .P208,.V208:
|
||||||
|
#endif*/
|
||||||
|
return 16;
|
||||||
|
|
||||||
|
case .NV12,.OPAQUE_420,.NV11:
|
||||||
|
return 12;
|
||||||
|
|
||||||
|
case .R8_Typeless,.R8_UNorm,.R8_UInt,.R8_SNorm,.R8_SInt,.A8_UNorm,.BC2_Typeless,.BC2_UNorm,.BC2_UNorm_SRGB,.BC3_Typeless,.BC3_UNorm,.BC3_UNorm_SRGB,.BC5_Typeless,.BC5_UNorm,.BC5_SNorm,.BC6H_Typeless,.BC6H_UF16,.BC6H_SF16,.BC7_Typeless,.BC7_UNorm,.BC7_UNorm_SRGB,.AI44,.IA44,.P8:
|
||||||
|
/*#if (defined(_XBOX_ONE) && defined(_TITLE)) || defined(_GAMING_XBOX)
|
||||||
|
case .R4G4_UNorm:
|
||||||
|
#endif*/
|
||||||
|
return 8;
|
||||||
|
|
||||||
|
case .R1_UNorm:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case .BC1_Typeless,.BC1_UNorm,.BC1_UNorm_SRGB,.BC4_Typeless,.BC4_UNorm,.BC4_SNorm:
|
||||||
|
return 4;
|
||||||
|
|
||||||
|
//case .Unknown,.FORCE_UInt:
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the SRGB-Format for the given Format, or the Format itself, if no SRGB-variant exists.
|
||||||
|
public Format GetSRGB()
|
||||||
|
{
|
||||||
|
switch (this)
|
||||||
|
{
|
||||||
|
case .BC1_UNorm:
|
||||||
|
return .BC1_UNorm_SRGB;
|
||||||
|
case .BC2_UNorm:
|
||||||
|
return .BC2_UNorm_SRGB;
|
||||||
|
case .BC3_UNorm:
|
||||||
|
return .BC3_UNorm_SRGB;
|
||||||
|
case .BC7_UNorm:
|
||||||
|
return .BC7_UNorm_SRGB;
|
||||||
|
case .R8G8B8A8_UNorm:
|
||||||
|
return .R8G8B8A8_UNorm_SRGB;
|
||||||
|
case .B8G8R8A8_UNorm:
|
||||||
|
return .B8G8R8A8_UNorm_SRGB;
|
||||||
|
case .B8G8R8X8_UNorm:
|
||||||
|
return .B8G8R8X8_UNorm_SRGB;
|
||||||
|
default:
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns the non-SRGB-Format for the given Format.
|
||||||
|
public Format GetNonSRGB()
|
||||||
|
{
|
||||||
|
switch (this)
|
||||||
|
{
|
||||||
|
case .BC1_UNorm_SRGB:
|
||||||
|
return .BC1_UNorm;
|
||||||
|
case .BC2_UNorm_SRGB:
|
||||||
|
return .BC2_UNorm;
|
||||||
|
case .BC3_UNorm_SRGB:
|
||||||
|
return .BC3_UNorm;
|
||||||
|
case .BC7_UNorm_SRGB:
|
||||||
|
return .BC7_UNorm;
|
||||||
|
case .R8G8B8A8_UNorm_SRGB:
|
||||||
|
return .R8G8B8A8_UNorm;
|
||||||
|
case .B8G8R8A8_UNorm_SRGB:
|
||||||
|
return .B8G8R8A8_UNorm;
|
||||||
|
case .B8G8R8X8_UNorm_SRGB:
|
||||||
|
return .B8G8R8X8_UNorm;
|
||||||
|
default:
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
namespace GlitchyEngine.Renderer
|
namespace GlitchyEngine.Renderer
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
@@ -29,6 +162,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
|
|
||||||
typealias Format = DirectX.DXGI.Format;
|
typealias Format = DirectX.DXGI.Format;
|
||||||
|
|
||||||
|
|
||||||
public struct BufferDescription
|
public struct BufferDescription
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -77,27 +77,39 @@ namespace GlitchyEngine.Renderer
|
|||||||
{
|
{
|
||||||
case typeof(bool):
|
case typeof(bool):
|
||||||
EnsureTypeMatch(1, 1, .Bool);
|
EnsureTypeMatch(1, 1, .Bool);
|
||||||
|
case typeof(bool2):
|
||||||
case typeof(float):
|
EnsureTypeMatch(1, 2, .Bool);
|
||||||
EnsureTypeMatch(1, 1, .Float);
|
case typeof(bool3):
|
||||||
case typeof(Vector2):
|
EnsureTypeMatch(1, 3, .Bool);
|
||||||
EnsureTypeMatch(1, 2, .Float);
|
case typeof(bool4):
|
||||||
case typeof(Vector3):
|
EnsureTypeMatch(1, 4, .Bool);
|
||||||
EnsureTypeMatch(1, 3, .Float);
|
|
||||||
case typeof(Vector4):
|
|
||||||
EnsureTypeMatch(1, 4, .Float);
|
|
||||||
|
|
||||||
case typeof(int32):
|
case typeof(int32):
|
||||||
EnsureTypeMatch(1, 1, .Int);
|
EnsureTypeMatch(1, 1, .Int);
|
||||||
case typeof(Int2):
|
case typeof(int2):
|
||||||
EnsureTypeMatch(1, 2, .Int);
|
EnsureTypeMatch(1, 2, .Int);
|
||||||
case typeof(Int3):
|
case typeof(int3):
|
||||||
EnsureTypeMatch(1, 3, .Int);
|
EnsureTypeMatch(1, 3, .Int);
|
||||||
case typeof(Int4):
|
case typeof(int4):
|
||||||
EnsureTypeMatch(1, 4, .Int);
|
EnsureTypeMatch(1, 4, .Int);
|
||||||
|
|
||||||
case typeof(uint32):
|
case typeof(uint32):
|
||||||
EnsureTypeMatch(1, 1, .UInt);
|
EnsureTypeMatch(1, 1, .UInt);
|
||||||
|
case typeof(uint2):
|
||||||
|
EnsureTypeMatch(1, 2, .UInt);
|
||||||
|
case typeof(uint3):
|
||||||
|
EnsureTypeMatch(1, 3, .UInt);
|
||||||
|
case typeof(uint4):
|
||||||
|
EnsureTypeMatch(1, 4, .UInt);
|
||||||
|
|
||||||
|
case typeof(float):
|
||||||
|
EnsureTypeMatch(1, 1, .Float);
|
||||||
|
case typeof(float2):
|
||||||
|
EnsureTypeMatch(1, 2, .Float);
|
||||||
|
case typeof(float3):
|
||||||
|
EnsureTypeMatch(1, 3, .Float);
|
||||||
|
case typeof(float4):
|
||||||
|
EnsureTypeMatch(1, 4, .Float);
|
||||||
|
|
||||||
case typeof(Matrix4x3):
|
case typeof(Matrix4x3):
|
||||||
EnsureTypeMatch(4, 3, .Float);
|
EnsureTypeMatch(4, 3, .Float);
|
||||||
@@ -130,18 +142,24 @@ namespace GlitchyEngine.Renderer
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void SetData(bool value) => SetData<bool>(value);
|
public void SetData(bool value) => SetData<bool>(value);
|
||||||
|
public void SetData(bool2 value) => SetData<bool2>(value);
|
||||||
public void SetData(float value) => SetData<float>(value);
|
public void SetData(bool3 value) => SetData<bool3>(value);
|
||||||
public void SetData(Vector2 value) => SetData<Vector2>(value);
|
public void SetData(bool4 value) => SetData<bool4>(value);
|
||||||
public void SetData(Vector3 value) => SetData<Vector3>(value);
|
|
||||||
public void SetData(Vector4 value) => SetData<Vector4>(value);
|
|
||||||
|
|
||||||
public void SetData(int32 value) => SetData<int32>(value);
|
public void SetData(int32 value) => SetData<int32>(value);
|
||||||
public void SetData(Int2 value) => SetData<Int2>(value);
|
public void SetData(int2 value) => SetData<int2>(value);
|
||||||
public void SetData(Int3 value) => SetData<Int3>(value);
|
public void SetData(int3 value) => SetData<int3>(value);
|
||||||
public void SetData(Int4 value) => SetData<Int4>(value);
|
public void SetData(int4 value) => SetData<int4>(value);
|
||||||
|
|
||||||
public void SetData(uint32 value) => SetData<uint32>(value);
|
public void SetData(uint32 value) => SetData<uint32>(value);
|
||||||
|
public void SetData(uint2 value) => SetData<uint2>(value);
|
||||||
|
public void SetData(uint3 value) => SetData<uint3>(value);
|
||||||
|
public void SetData(uint4 value) => SetData<uint4>(value);
|
||||||
|
|
||||||
|
public void SetData(float value) => SetData<float>(value);
|
||||||
|
public void SetData(float2 value) => SetData<float2>(value);
|
||||||
|
public void SetData(float3 value) => SetData<float3>(value);
|
||||||
|
public void SetData(float4 value) => SetData<float4>(value);
|
||||||
|
|
||||||
public void SetData(ColorRGB value) => SetData<ColorRGB>(value);
|
public void SetData(ColorRGB value) => SetData<ColorRGB>(value);
|
||||||
public void SetData(ColorRGBA value) => SetData<ColorRGBA>(value);
|
public void SetData(ColorRGBA value) => SetData<ColorRGBA>(value);
|
||||||
|
|||||||
@@ -31,8 +31,8 @@ namespace GlitchyEngine.Renderer
|
|||||||
protected float _nearPlane;
|
protected float _nearPlane;
|
||||||
protected float _farPlane;
|
protected float _farPlane;
|
||||||
|
|
||||||
protected Vector3 _position;
|
protected float3 _position;
|
||||||
protected Vector3 _rotation;
|
protected float3 _rotation;
|
||||||
|
|
||||||
/// If true the transform matrix is outdated and needs to be recalculated.
|
/// If true the transform matrix is outdated and needs to be recalculated.
|
||||||
protected bool _transformOutdated = true;
|
protected bool _transformOutdated = true;
|
||||||
@@ -76,12 +76,12 @@ namespace GlitchyEngine.Renderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Position
|
public float3 Position
|
||||||
{
|
{
|
||||||
get => _position;
|
get => _position;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if(_position == value)
|
if(all(_position == value))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_position = value;
|
_position = value;
|
||||||
@@ -89,12 +89,12 @@ namespace GlitchyEngine.Renderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Vector3 Rotation
|
public float3 Rotation
|
||||||
{
|
{
|
||||||
get => _rotation;
|
get => _rotation;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if(_rotation == value)
|
if(all(_rotation == value))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_rotation = value;
|
_rotation = value;
|
||||||
|
|||||||
@@ -45,6 +45,11 @@ namespace GlitchyEngine.Renderer
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public bool TryGetVariable(String name, out BufferVariable variable)
|
||||||
|
{
|
||||||
|
return _nameToVariable.TryGetValue(name, out variable);
|
||||||
|
}
|
||||||
|
|
||||||
public BufferVariable this[String name] => _nameToVariable[name];
|
public BufferVariable this[String name] => _nameToVariable[name];
|
||||||
|
|
||||||
public List<BufferVariable>.Enumerator GetEnumerator()
|
public List<BufferVariable>.Enumerator GetEnumerator()
|
||||||
|
|||||||
@@ -39,9 +39,9 @@ namespace GlitchyEngine.Renderer
|
|||||||
|
|
||||||
if(length != 0.0f)
|
if(length != 0.0f)
|
||||||
{
|
{
|
||||||
transform.Columns[0]..Normalize() *= length;
|
transform.Columns[0] = normalize(transform.Columns[0]) * length;
|
||||||
transform.Columns[1]..Normalize() *= length;
|
transform.Columns[1] = normalize(transform.Columns[1]) * length;
|
||||||
transform.Columns[2]..Normalize() *= length;
|
transform.Columns[2] = normalize(transform.Columns[2]) * length;
|
||||||
}
|
}
|
||||||
|
|
||||||
Renderer.DrawLine(.Zero, .Right, .Red, transform);
|
Renderer.DrawLine(.Zero, .Right, .Red, transform);
|
||||||
@@ -66,7 +66,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
_frustumGeometry = new GeometryBinding();
|
_frustumGeometry = new GeometryBinding();
|
||||||
_frustumGeometry.SetPrimitiveTopology(.LineList);
|
_frustumGeometry.SetPrimitiveTopology(.LineList);
|
||||||
|
|
||||||
_frustumVertices = new VertexBuffer(typeof(Vector4), 8, .Dynamic, .Write);
|
_frustumVertices = new VertexBuffer(typeof(float4), 8, .Dynamic, .Write);
|
||||||
_frustumGeometry.SetVertexBufferSlot(_frustumVertices, 0);
|
_frustumGeometry.SetVertexBufferSlot(_frustumVertices, 0);
|
||||||
|
|
||||||
using (IndexBuffer indexBuffer = new IndexBuffer(24, .Immutable))
|
using (IndexBuffer indexBuffer = new IndexBuffer(24, .Immutable))
|
||||||
@@ -109,7 +109,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
2, 6,
|
2, 6,
|
||||||
3, 7);
|
3, 7);
|
||||||
|
|
||||||
Vector4[8] corners;
|
float4[8] corners;
|
||||||
// Perspective
|
// Perspective
|
||||||
if(projection._43 != 0.0f)
|
if(projection._43 != 0.0f)
|
||||||
{
|
{
|
||||||
@@ -121,7 +121,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
float gOverS = projection._11;
|
float gOverS = projection._11;
|
||||||
float g = projection._22;
|
float g = projection._22;
|
||||||
|
|
||||||
//var corners = //(Vector4*)&_vbFrustum.Data;
|
//var corners = //(float4*)&_vbFrustum.Data;
|
||||||
|
|
||||||
if(Math.Abs(d1) >= 10000)
|
if(Math.Abs(d1) >= 10000)
|
||||||
{
|
{
|
||||||
@@ -167,7 +167,7 @@ namespace GlitchyEngine.Renderer
|
|||||||
float n = -projection._34 / projection._33;
|
float n = -projection._34 / projection._33;
|
||||||
float f = (1 - projection._34) / projection._33;
|
float f = (1 - projection._34) / projection._33;
|
||||||
|
|
||||||
//var corners = (Vector4*)&_vbFrustum.Data;
|
//var corners = (float4*)&_vbFrustum.Data;
|
||||||
corners[0] = .(r, t, n, 1.0f);
|
corners[0] = .(r, t, n, 1.0f);
|
||||||
corners[1] = .(r, b, n, 1.0f);
|
corners[1] = .(r, b, n, 1.0f);
|
||||||
corners[2] = .(l, b, n, 1.0f);
|
corners[2] = .(l, b, n, 1.0f);
|
||||||
|
|||||||
@@ -104,6 +104,18 @@ public class EffectLibrary
|
|||||||
public bool Exists(String effectName) => _effects.ContainsKey(effectName);
|
public bool Exists(String effectName) => _effects.ContainsKey(effectName);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
|
public enum TextureDimension
|
||||||
|
{
|
||||||
|
Unknown,
|
||||||
|
Texture1D,
|
||||||
|
Texture1DArray,
|
||||||
|
Texture2D,
|
||||||
|
Texture2DArray,
|
||||||
|
Texture3D,
|
||||||
|
TextureCube,
|
||||||
|
TextureCubeArray
|
||||||
|
}
|
||||||
|
|
||||||
public class Effect : Asset
|
public class Effect : Asset
|
||||||
{
|
{
|
||||||
internal VertexShader _vs ~ _?.ReleaseRef();
|
internal VertexShader _vs ~ _?.ReleaseRef();
|
||||||
@@ -137,14 +149,16 @@ public class Effect : Asset
|
|||||||
public struct TextureEntry
|
public struct TextureEntry
|
||||||
{
|
{
|
||||||
public TextureViewBinding BoundTexture;
|
public TextureViewBinding BoundTexture;
|
||||||
|
public TextureDimension TextureDimension;
|
||||||
public ShaderTextureCollection.ResourceEntry* VsSlot;
|
public ShaderTextureCollection.ResourceEntry* VsSlot;
|
||||||
public ShaderTextureCollection.ResourceEntry* PsSlot;
|
public ShaderTextureCollection.ResourceEntry* PsSlot;
|
||||||
|
|
||||||
public this(TextureViewBinding boundTexture, ShaderTextureCollection.ResourceEntry* vsSlot, ShaderTextureCollection.ResourceEntry* psSlot)
|
public this(TextureViewBinding boundTexture, TextureDimension textureDimension, ShaderTextureCollection.ResourceEntry* vsSlot, ShaderTextureCollection.ResourceEntry* psSlot)
|
||||||
{
|
{
|
||||||
BoundTexture = boundTexture;
|
BoundTexture = boundTexture;
|
||||||
VsSlot = vsSlot;
|
VsSlot = vsSlot;
|
||||||
PsSlot = psSlot;
|
PsSlot = psSlot;
|
||||||
|
TextureDimension = textureDimension;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,7 +247,7 @@ public class Effect : Asset
|
|||||||
{
|
{
|
||||||
Debug.Profiler.ProfileRendererFunction!();
|
Debug.Profiler.ProfileRendererFunction!();
|
||||||
|
|
||||||
[Inline]InternalSetTexture(name, textureViewBinding..AddRef());
|
[Inline]InternalSetTexture(name, textureViewBinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InternalSetTexture(String name, TextureViewBinding textureViewBinding)
|
private void InternalSetTexture(String name, TextureViewBinding textureViewBinding)
|
||||||
@@ -242,29 +256,17 @@ public class Effect : Asset
|
|||||||
|
|
||||||
ref TextureEntry entry = ref _textures[name];
|
ref TextureEntry entry = ref _textures[name];
|
||||||
|
|
||||||
|
// TODO: Thats weird, we increment this reference somewhere... but WHERE?!
|
||||||
entry.BoundTexture.Release();
|
entry.BoundTexture.Release();
|
||||||
entry.BoundTexture = textureViewBinding;
|
entry.BoundTexture = textureViewBinding;
|
||||||
|
|
||||||
entry.VsSlot?.BoundTexture..Release() = entry.BoundTexture..AddRef();
|
if (entry.VsSlot != null)
|
||||||
entry.PsSlot?.BoundTexture..Release() = entry.BoundTexture..AddRef();
|
SetReferenceVar!(entry.VsSlot.BoundTexture, entry.BoundTexture);
|
||||||
|
|
||||||
|
if (entry.PsSlot != null)
|
||||||
|
SetReferenceVar!(entry.PsSlot.BoundTexture, entry.BoundTexture);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*private void ApplyTextures()
|
|
||||||
{
|
|
||||||
Debug.Profiler.ProfileRendererFunction!();
|
|
||||||
|
|
||||||
for(let (name, entry) in _textures)
|
|
||||||
{
|
|
||||||
entry.VsSlot?.BoundTexture.Release();
|
|
||||||
entry.VsSlot?.BoundTexture = entry.BoundTexture;
|
|
||||||
entry.VsSlot?.BoundTexture.AddRef();
|
|
||||||
|
|
||||||
entry.PsSlot?.BoundTexture.Release();
|
|
||||||
entry.PsSlot?.BoundTexture = entry.BoundTexture;
|
|
||||||
entry.PsSlot?.BoundTexture.AddRef();
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
public void ApplyChanges()
|
public void ApplyChanges()
|
||||||
{
|
{
|
||||||
Debug.Profiler.ProfileRendererFunction!();
|
Debug.Profiler.ProfileRendererFunction!();
|
||||||
@@ -602,11 +604,11 @@ public class Effect : Asset
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (numComponents == 2)
|
if (numComponents == 2)
|
||||||
return Variant.Create(*(Vector2*)floats.Ptr);
|
return Variant.Create(*(float2*)floats.Ptr);
|
||||||
else if (numComponents == 3)
|
else if (numComponents == 3)
|
||||||
return Variant.Create(*(Vector3*)floats.Ptr);
|
return Variant.Create(*(float3*)floats.Ptr);
|
||||||
else if (numComponents == 4)
|
else if (numComponents == 4)
|
||||||
return Variant.Create(*(Vector4*)floats.Ptr);
|
return Variant.Create(*(float4*)floats.Ptr);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -741,7 +743,7 @@ public class Effect : Asset
|
|||||||
// Get existing entry or create new
|
// Get existing entry or create new
|
||||||
if(!_textures.TryGetValue(shaderEntry.Name, out entry))
|
if(!_textures.TryGetValue(shaderEntry.Name, out entry))
|
||||||
{
|
{
|
||||||
entry = .(shaderEntry.BoundTexture, null, null);
|
entry = .(shaderEntry.BoundTexture, shaderEntry.Dimension, null, null);
|
||||||
entry.BoundTexture.AddRef();
|
entry.BoundTexture.AddRef();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,9 +11,9 @@ namespace GlitchyEngine.Renderer
|
|||||||
s_fullscreenQuadGeometry = new GeometryBinding();
|
s_fullscreenQuadGeometry = new GeometryBinding();
|
||||||
s_fullscreenQuadGeometry.SetPrimitiveTopology(.TriangleList);
|
s_fullscreenQuadGeometry.SetPrimitiveTopology(.TriangleList);
|
||||||
|
|
||||||
using(var quadVertices = new VertexBuffer(typeof(Vector4), 3, .Immutable))
|
using(var quadVertices = new VertexBuffer(typeof(float4), 3, .Immutable))
|
||||||
{
|
{
|
||||||
Vector4[4] vertices = .(
|
float4[4] vertices = .(
|
||||||
.(-1, 1, 0, 0),
|
.(-1, 1, 0, 0),
|
||||||
.( 3, 1, 2, 0),
|
.( 3, 1, 2, 0),
|
||||||
.(-1,-3, 0, 2),
|
.(-1,-3, 0, 2),
|
||||||
@@ -53,4 +53,57 @@ namespace GlitchyEngine.Renderer
|
|||||||
RenderCommand.DrawIndexed(s_fullscreenQuadGeometry);
|
RenderCommand.DrawIndexed(s_fullscreenQuadGeometry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static class Quad
|
||||||
|
{
|
||||||
|
static GeometryBinding s_quadGeometry;
|
||||||
|
|
||||||
|
public static void Init()
|
||||||
|
{
|
||||||
|
s_quadGeometry = new GeometryBinding();
|
||||||
|
s_quadGeometry.SetPrimitiveTopology(.TriangleList);
|
||||||
|
|
||||||
|
using(var quadVertices = new VertexBuffer(typeof(float4), 4, .Immutable))
|
||||||
|
{
|
||||||
|
float4[4] vertices = .(
|
||||||
|
.(-0.5f,-0.5f, 0, 1),
|
||||||
|
.(-0.5f, 0.5f, 0, 0),
|
||||||
|
.( 0.5f, 0.5f, 1, 0),
|
||||||
|
.( 0.5f,-0.5f, 1, 1)
|
||||||
|
);
|
||||||
|
|
||||||
|
quadVertices.SetData(vertices);
|
||||||
|
s_quadGeometry.SetVertexBufferSlot(quadVertices, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
using(var quadIndices = new IndexBuffer(6, .Immutable))
|
||||||
|
{
|
||||||
|
uint16[6] indices = .(0, 1, 2, 2, 3, 0);
|
||||||
|
|
||||||
|
quadIndices.SetData(indices);
|
||||||
|
s_quadGeometry.SetIndexBuffer(quadIndices);
|
||||||
|
}
|
||||||
|
|
||||||
|
VertexElement[] vertexElements = new .(
|
||||||
|
VertexElement(.R32G32_Float, "POSITION"),
|
||||||
|
VertexElement(.R32G32_Float, "TEXCOORD")
|
||||||
|
);
|
||||||
|
|
||||||
|
using (var quadBatchLayout = new VertexLayout(vertexElements, true))
|
||||||
|
{
|
||||||
|
s_quadGeometry.SetVertexLayout(quadBatchLayout);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Deinit()
|
||||||
|
{
|
||||||
|
s_quadGeometry.ReleaseRef();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Draw()
|
||||||
|
{
|
||||||
|
s_quadGeometry.Bind();
|
||||||
|
RenderCommand.DrawIndexed(s_quadGeometry);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -14,7 +14,7 @@ public class Material : Asset
|
|||||||
|
|
||||||
private uint8[] _rawVariables ~ delete _;
|
private uint8[] _rawVariables ~ delete _;
|
||||||
|
|
||||||
private Dictionary<String, AssetHandle<Texture>> _textures = new .() ~ delete _;
|
private Dictionary<String, (AssetHandle<Texture> Handle, TextureDimension Dimension)> _textures = new .() ~ delete _;
|
||||||
|
|
||||||
private Dictionary<String, (uint32 Offset, BufferVariable Variable)> _variables = new .() ~ delete _;
|
private Dictionary<String, (uint32 Offset, BufferVariable Variable)> _variables = new .() ~ delete _;
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ public class Material : Asset
|
|||||||
// At best whole paths. Shouldn't be that hard to do...
|
// At best whole paths. Shouldn't be that hard to do...
|
||||||
/*var texture = entry.BoundTexture;*/
|
/*var texture = entry.BoundTexture;*/
|
||||||
|
|
||||||
_textures.Add(name, .Invalid);
|
_textures.Add(name, (AssetHandle<Texture>.Invalid, entry.TextureDimension));
|
||||||
}
|
}
|
||||||
|
|
||||||
InitRawData();
|
InitRawData();
|
||||||
@@ -66,7 +66,19 @@ public class Material : Asset
|
|||||||
|
|
||||||
for(let (name, texture) in _textures)
|
for(let (name, texture) in _textures)
|
||||||
{
|
{
|
||||||
_effect.SetTexture(name, texture);
|
switch (texture.Dimension)
|
||||||
|
{
|
||||||
|
//case .Texture1D, .Texture1DArray:
|
||||||
|
case .Texture2D, .Texture2DArray:
|
||||||
|
AssetHandle<Texture2D> handle2D = .(texture.Handle);
|
||||||
|
_effect.SetTexture(name, handle2D);
|
||||||
|
case .TextureCube, .TextureCubeArray:
|
||||||
|
AssetHandle<TextureCube> cubeHandle = .(texture.Handle);
|
||||||
|
_effect.SetTexture(name, cubeHandle);
|
||||||
|
//case .Texture3D:
|
||||||
|
default:
|
||||||
|
Log.EngineLogger.Error("Tryied to bind undefined texture dimension!");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for(let (name, variable) in _variables)
|
for(let (name, variable) in _variables)
|
||||||
@@ -86,13 +98,27 @@ public class Material : Asset
|
|||||||
{
|
{
|
||||||
if(_textures.TryGetValue(name, var entry))
|
if(_textures.TryGetValue(name, var entry))
|
||||||
{
|
{
|
||||||
|
/*switch (texture.Get().GetType())
|
||||||
|
{
|
||||||
|
//case .Texture1D:
|
||||||
|
// _textures[name].Dimension = .Texture1D;
|
||||||
|
case typeof(Texture2D):
|
||||||
|
_textures[name].Dimension = .Texture2D;
|
||||||
|
case typeof(TextureCube):
|
||||||
|
_textures[name].Dimension = .TextureCube;
|
||||||
|
//case .Texture3D:
|
||||||
|
// _textures[name].Dimension = .Texture3D;
|
||||||
|
default:
|
||||||
|
_textures[name].Dimension = .Unknown;
|
||||||
|
}*/
|
||||||
//entry?.ReleaseRef();
|
//entry?.ReleaseRef();
|
||||||
_textures[name] = texture;
|
_textures[name].Handle = texture;
|
||||||
//texture?.AddRef();
|
//texture?.AddRef();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Log.EngineLogger.Assert(false);
|
Log.EngineLogger.Error($"Material doesn't have the texture slot \"{name}\"");
|
||||||
|
//Log.EngineLogger.Assert(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,17 +144,30 @@ public class Material : Asset
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetVariable(String name, float value) => SetVariable<float>(name, value);
|
public void SetVariable(String name, bool value) => SetVariable<bool>(name, value);
|
||||||
public void SetVariable(String name, Vector2 value) => SetVariable<Vector2>(name, value);
|
public void SetVariable(String name, bool2 value) => SetVariable<bool2>(name, value);
|
||||||
public void SetVariable(String name, Vector3 value) => SetVariable<Vector3>(name, value);
|
public void SetVariable(String name, bool3 value) => SetVariable<bool3>(name, value);
|
||||||
public void SetVariable(String name, Vector4 value) => SetVariable<Vector4>(name, value);
|
public void SetVariable(String name, bool4 value) => SetVariable<bool4>(name, value);
|
||||||
|
|
||||||
public void SetVariable(String name, int32 value) => SetVariable<int32>(name, value);
|
public void SetVariable(String name, int32 value) => SetVariable<int32>(name, value);
|
||||||
public void SetVariable(String name, Int2 value) => SetVariable<Int2>(name, value);
|
public void SetVariable(String name, int2 value) => SetVariable<int2>(name, value);
|
||||||
public void SetVariable(String name, Int3 value) => SetVariable<Int3>(name, value);
|
public void SetVariable(String name, int3 value) => SetVariable<int3>(name, value);
|
||||||
public void SetVariable(String name, Int4 value) => SetVariable<Int4>(name, value);
|
public void SetVariable(String name, int4 value) => SetVariable<int4>(name, value);
|
||||||
|
|
||||||
public void SetVariable(String name, uint32 value) => SetVariable<uint32>(name, value);
|
public void SetVariable(String name, uint32 value) => SetVariable<uint32>(name, value);
|
||||||
|
public void SetVariable(String name, uint2 value) => SetVariable<uint2>(name, value);
|
||||||
|
public void SetVariable(String name, uint3 value) => SetVariable<uint3>(name, value);
|
||||||
|
public void SetVariable(String name, uint4 value) => SetVariable<uint4>(name, value);
|
||||||
|
|
||||||
|
public void SetVariable(String name, float value) => SetVariable<float>(name, value);
|
||||||
|
public void SetVariable(String name, float2 value) => SetVariable<float2>(name, value);
|
||||||
|
public void SetVariable(String name, float3 value) => SetVariable<float3>(name, value);
|
||||||
|
public void SetVariable(String name, float4 value) => SetVariable<float4>(name, value);
|
||||||
|
|
||||||
|
/*public void SetVariable(String name, float value) => SetVariable<double>(name, value);
|
||||||
|
public void SetVariable(String name, float2 value) => SetVariable<float2>(name, value);
|
||||||
|
public void SetVariable(String name, float3 value) => SetVariable<float3>(name, value);
|
||||||
|
public void SetVariable(String name, float4 value) => SetVariable<float4>(name, value);*/
|
||||||
|
|
||||||
public void SetVariable(String name, Color value) => SetVariable<ColorRGBA>(name, (ColorRGBA)value);
|
public void SetVariable(String name, Color value) => SetVariable<ColorRGBA>(name, (ColorRGBA)value);
|
||||||
public void SetVariable(String name, ColorRGB value) => SetVariable<ColorRGB>(name, value);
|
public void SetVariable(String name, ColorRGB value) => SetVariable<ColorRGB>(name, value);
|
||||||
@@ -190,15 +229,14 @@ public class Material : Asset
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Supporeted types
|
// Supporeted types
|
||||||
// Float, Float2, Float3, Float4
|
// Bool, Bool2, Bool3, Bool4
|
||||||
|
// Int, int2, int3, int4
|
||||||
|
// UInt, UInt2, UInt3, UInt4
|
||||||
// Color, ColorRGB, ColorRGBA
|
// Color, ColorRGB, ColorRGBA
|
||||||
// Int, Int2, Int3, Int4
|
// Float, Float2, Float3, Float4
|
||||||
// UInt
|
|
||||||
// Matrix3x3, Matrix4x3, Matrix
|
// Matrix3x3, Matrix4x3, Matrix
|
||||||
|
|
||||||
// TODO: Add missing variable types
|
// TODO: Add missing variable types
|
||||||
// UInt2, UInt3, UInt4
|
|
||||||
// Bool, Bool2, Bool3, Bool4
|
|
||||||
// Half, Half2, Half3, Half4
|
// Half, Half2, Half3, Half4
|
||||||
// Byte, Byte2, Byte3, Byte4
|
// Byte, Byte2, Byte3, Byte4
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user