Fixed font atlas, feature completed garbage collection, and fix math.
This commit is contained in:
parent
f030ac62ae
commit
0b298c6130
@ -42,7 +42,7 @@ set(EHS_SOURCES
|
|||||||
src/EHS.cpp include/ehs/EHS.h
|
src/EHS.cpp include/ehs/EHS.h
|
||||||
src/Type.cpp include/ehs/Type.h
|
src/Type.cpp include/ehs/Type.h
|
||||||
src/BaseObj.cpp include/ehs/BaseObj.h
|
src/BaseObj.cpp include/ehs/BaseObj.h
|
||||||
src/GarbageCollector.cpp include/ehs/GarbageCollector.h
|
src/GC.cpp include/ehs/GC.h
|
||||||
src/Log.cpp include/ehs/Log.h
|
src/Log.cpp include/ehs/Log.h
|
||||||
src/URI.cpp include/ehs/URI.h
|
src/URI.cpp include/ehs/URI.h
|
||||||
src/Math.cpp include/ehs/Math.h
|
src/Math.cpp include/ehs/Math.h
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "EHS.h"
|
|
||||||
#include "Vector.h"
|
#include "Vector.h"
|
||||||
#include "BaseObj.h"
|
#include "BaseObj.h"
|
||||||
#include "ehs/system/Mutex.h"
|
#include "ehs/system/Mutex.h"
|
||||||
@ -10,10 +9,10 @@ namespace ehs
|
|||||||
{
|
{
|
||||||
typedef bool (*GcLogic)(BaseObj*);
|
typedef bool (*GcLogic)(BaseObj*);
|
||||||
|
|
||||||
class GarbageCollector
|
class GC
|
||||||
{
|
{
|
||||||
private:
|
private:
|
||||||
static Vector<GcLogic>* logic;
|
static Array<GcLogic> logic;
|
||||||
static Vector<BaseObj*> garbage;
|
static Vector<BaseObj*> garbage;
|
||||||
static UInt_64 max;
|
static UInt_64 max;
|
||||||
static Thread thread;
|
static Thread thread;
|
||||||
@ -27,6 +26,10 @@ namespace ehs
|
|||||||
|
|
||||||
static void Stop();
|
static void Stop();
|
||||||
|
|
||||||
|
static bool HasLogic(GcLogic logicCb);
|
||||||
|
|
||||||
|
static bool AddLogic(GcLogic logicCb);
|
||||||
|
|
||||||
/// Adds an object to the garbage pile to be deleted.
|
/// Adds an object to the garbage pile to be deleted.
|
||||||
/// @param[in] obj The object to be deleted.
|
/// @param[in] obj The object to be deleted.
|
||||||
static void Add(BaseObj* obj);
|
static void Add(BaseObj* obj);
|
||||||
@ -59,5 +62,8 @@ namespace ehs
|
|||||||
static void Dump();
|
static void Dump();
|
||||||
|
|
||||||
static bool IsRunning();
|
static bool IsRunning();
|
||||||
|
|
||||||
|
private:
|
||||||
|
static bool ShouldDelete(BaseObj *obj);
|
||||||
};
|
};
|
||||||
}
|
}
|
@ -116,20 +116,51 @@ namespace ehs
|
|||||||
return sum;
|
return sum;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T = float>
|
||||||
|
static T Ln_Taylor(T x)
|
||||||
|
{
|
||||||
|
T result = 0;
|
||||||
|
T term = (x - 1) / (x + 1);
|
||||||
|
T term_squared = term * term;
|
||||||
|
T denominator = 1;
|
||||||
|
T current_term = term;
|
||||||
|
|
||||||
|
for (int n = 0; n < 100; ++n)
|
||||||
|
{
|
||||||
|
result += current_term / denominator;
|
||||||
|
current_term *= term_squared;
|
||||||
|
denominator += 2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 2 * result;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T = float>
|
template <typename T = float>
|
||||||
static T Ln(T x)
|
static T Ln(T x)
|
||||||
{
|
{
|
||||||
if (x <= 0)
|
if (x <= 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
T result = 0;
|
if (x == 1)
|
||||||
|
return 0;
|
||||||
|
|
||||||
x = (x - 1) / (x + 1);
|
SSize exp = 0;
|
||||||
|
while (x > 2)
|
||||||
|
{
|
||||||
|
x /= 2;
|
||||||
|
exp++;
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 1; i <= 19; i += 2)
|
while (x < 0.5)
|
||||||
result += (1 / i) * Exp<T>(x * i);
|
{
|
||||||
|
x *= 2;
|
||||||
|
exp--;
|
||||||
|
}
|
||||||
|
|
||||||
return 2 * result;
|
T result = Ln_Taylor<T>(x);
|
||||||
|
result += exp * Ln_Taylor<T>(2);
|
||||||
|
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A method for use of exponents.
|
/// A method for use of exponents.
|
||||||
@ -142,26 +173,35 @@ namespace ehs
|
|||||||
static T Pow(const T base, const I exponent)
|
static T Pow(const T base, const I exponent)
|
||||||
{
|
{
|
||||||
if (base == 0)
|
if (base == 0)
|
||||||
return 0;
|
return (exponent == 0) ? 1 : 0;
|
||||||
|
|
||||||
if (exponent == 0)
|
if (exponent == 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
UInt_32 exponentIsInteger = exponent == (UInt_32)exponent;
|
SSize intExp = (SSize)exponent;
|
||||||
UInt_32 baseIsNegative = base < 0;
|
bool isInteger = exponent == intExp;
|
||||||
|
bool isNeg = base < 0;
|
||||||
|
|
||||||
if (baseIsNegative && exponentIsInteger)
|
if (isNeg && isInteger)
|
||||||
{
|
{
|
||||||
T result = Exp<T>(exponent * Ln<T>(-base));
|
T result = Exp<T>(exponent * Ln<T>(-base));
|
||||||
if (Mod((float)exponent, 2.0f) != 0)
|
if ((SSize)exponent % 2)
|
||||||
result = -result;
|
result = -result;
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
else if (!baseIsNegative)
|
|
||||||
return Exp<T>(exponent * Ln<T>(base));
|
|
||||||
|
|
||||||
return 0;
|
if (isNeg && !isInteger)
|
||||||
|
{
|
||||||
|
T magnitude = Exp<T>(exponent * Ln<T>(-base));
|
||||||
|
T angle = exponent * Pi<T>();
|
||||||
|
T realPart = magnitude * Cos<T>(angle);
|
||||||
|
T imagPart = magnitude * Sin<T>(angle);
|
||||||
|
|
||||||
|
return realPart;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Exp<T>(exponent * Ln<T>(base));
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T = float>
|
template <typename T = float>
|
||||||
|
@ -62,7 +62,9 @@ namespace ehs
|
|||||||
|
|
||||||
#if defined(EHS_64_BIT)
|
#if defined(EHS_64_BIT)
|
||||||
typedef UInt_64 Size;
|
typedef UInt_64 Size;
|
||||||
|
typedef SInt_64 SSize;
|
||||||
#elif defined(EHS_32_BIT)
|
#elif defined(EHS_32_BIT)
|
||||||
typedef UInt_32 Size;
|
typedef UInt_32 Size;
|
||||||
|
typedef SInt_32 SSize;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
@ -2,7 +2,7 @@
|
|||||||
#include "ehs/Log.h"
|
#include "ehs/Log.h"
|
||||||
#include "ehs/Version.h"
|
#include "ehs/Version.h"
|
||||||
#include "ehs/io/Console.h"
|
#include "ehs/io/Console.h"
|
||||||
#include "ehs/GarbageCollector.h"
|
#include "ehs/GC.h"
|
||||||
#include "ehs/io/audio/Audio.h"
|
#include "ehs/io/audio/Audio.h"
|
||||||
#include "ehs/io/img/Img.h"
|
#include "ehs/io/img/Img.h"
|
||||||
#include "ehs/io/img/PNG.h"
|
#include "ehs/io/img/PNG.h"
|
||||||
@ -141,13 +141,13 @@ int main()
|
|||||||
ehs::DecodeEHM
|
ehs::DecodeEHM
|
||||||
});
|
});
|
||||||
|
|
||||||
ehs::GarbageCollector::Start();
|
ehs::GC::Start();
|
||||||
|
|
||||||
const ehs::SInt_32 code = Main(&ehs::appName, &ehs::appVerId, &ehs::appVer);
|
const ehs::SInt_32 code = Main(&ehs::appName, &ehs::appVerId, &ehs::appVer);
|
||||||
if (code)
|
if (code)
|
||||||
EHS_LOG_INT(ehs::LogType::WARN, 0, "Executable exited with code #" + ehs::Str_8::FromNum(code) + ".");
|
EHS_LOG_INT(ehs::LogType::WARN, 0, "Executable exited with code #" + ehs::Str_8::FromNum(code) + ".");
|
||||||
|
|
||||||
ehs::GarbageCollector::Stop();
|
ehs::GC::Stop();
|
||||||
|
|
||||||
ehs::Log::OnExit();
|
ehs::Log::OnExit();
|
||||||
|
|
||||||
|
180
src/GC.cpp
Normal file
180
src/GC.cpp
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
#include "ehs/GC.h"
|
||||||
|
|
||||||
|
namespace ehs
|
||||||
|
{
|
||||||
|
UInt_32 GarbageCollectionThread(void* params)
|
||||||
|
{
|
||||||
|
while (GC::IsRunning())
|
||||||
|
{
|
||||||
|
GC::Poll();
|
||||||
|
Thread::SleepFor(50);
|
||||||
|
}
|
||||||
|
|
||||||
|
GC::Dump();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
Array<GcLogic> GC::logic;
|
||||||
|
Vector<BaseObj*> GC::garbage(0, 1000);
|
||||||
|
UInt_64 GC::max = 10;
|
||||||
|
Thread GC::thread;
|
||||||
|
Mutex GC::mutex;
|
||||||
|
bool GC::running = false;
|
||||||
|
|
||||||
|
bool GC::Has(const BaseObj* obj)
|
||||||
|
{
|
||||||
|
for (UInt_64 i = 0; i < garbage.Size(); ++i)
|
||||||
|
if (garbage[i] == obj)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GC::Start()
|
||||||
|
{
|
||||||
|
if (running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
mutex.Initialize();
|
||||||
|
|
||||||
|
thread.Start(GarbageCollectionThread, nullptr);
|
||||||
|
|
||||||
|
running = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GC::Stop()
|
||||||
|
{
|
||||||
|
if (!running)
|
||||||
|
return;
|
||||||
|
|
||||||
|
running = false;
|
||||||
|
|
||||||
|
thread.Join();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GC::HasLogic(GcLogic logicCb)
|
||||||
|
{
|
||||||
|
for (UInt_64 i = 0; i < logic.Size(); ++i)
|
||||||
|
if (logic[i] == logicCb)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GC::AddLogic(GcLogic logicCb)
|
||||||
|
{
|
||||||
|
if (HasLogic(logicCb))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (running)
|
||||||
|
mutex.Lock();
|
||||||
|
|
||||||
|
logic.Push(logicCb);
|
||||||
|
|
||||||
|
if (running)
|
||||||
|
mutex.Unlock();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GC::Add(BaseObj* obj)
|
||||||
|
{
|
||||||
|
if (!obj)
|
||||||
|
return;
|
||||||
|
|
||||||
|
#ifdef EHS_DEBUG
|
||||||
|
if (Has(obj))
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 1, Str_8(obj->GetTypeId(), obj->GetTypeIdSize()) +
|
||||||
|
" object with address of, \"" + Str_8::FromNum((ehs::Size)obj) + "\" is already in garbage.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
garbage.Push(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
void GC::SetMax(const UInt_64 newMax)
|
||||||
|
{
|
||||||
|
max = newMax;
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_64 GC::GetMax()
|
||||||
|
{
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
|
void GC::SetStride(const UInt_64 newStride)
|
||||||
|
{
|
||||||
|
Dump();
|
||||||
|
|
||||||
|
garbage = Vector<BaseObj*>(0, newStride);
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_64 GC::GetStride()
|
||||||
|
{
|
||||||
|
return garbage.Stride();
|
||||||
|
}
|
||||||
|
|
||||||
|
UInt_64 GC::Size()
|
||||||
|
{
|
||||||
|
return garbage.Size();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GC::Poll()
|
||||||
|
{
|
||||||
|
if (running)
|
||||||
|
mutex.Lock();
|
||||||
|
|
||||||
|
UInt_64 i = 0;
|
||||||
|
UInt_64 o = 0;
|
||||||
|
|
||||||
|
while (garbage.Size() && i < max && o < garbage.Size())
|
||||||
|
{
|
||||||
|
if (!ShouldDelete(garbage[o]))
|
||||||
|
{
|
||||||
|
o++;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (o != garbage.Size() - 1)
|
||||||
|
garbage.Swap(o, garbage.End());
|
||||||
|
|
||||||
|
delete garbage.Pop();
|
||||||
|
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (running)
|
||||||
|
mutex.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
void GC::Dump()
|
||||||
|
{
|
||||||
|
if (running)
|
||||||
|
mutex.Lock();
|
||||||
|
|
||||||
|
for (UInt_64 i = 0; i < garbage.Size(); ++i)
|
||||||
|
delete garbage[i];
|
||||||
|
|
||||||
|
garbage.Clear();
|
||||||
|
|
||||||
|
if (running)
|
||||||
|
mutex.Unlock();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GC::IsRunning()
|
||||||
|
{
|
||||||
|
return running;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GC::ShouldDelete(BaseObj *obj)
|
||||||
|
{
|
||||||
|
for (UInt_64 l = 0; l < logic.Size(); ++l)
|
||||||
|
if (!logic[l](obj))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
@ -1,133 +0,0 @@
|
|||||||
#include "ehs/GarbageCollector.h"
|
|
||||||
|
|
||||||
namespace ehs
|
|
||||||
{
|
|
||||||
UInt_32 GarbageCollectionThread(void* params)
|
|
||||||
{
|
|
||||||
while (GarbageCollector::IsRunning())
|
|
||||||
{
|
|
||||||
GarbageCollector::Poll();
|
|
||||||
Thread::SleepFor(50);
|
|
||||||
}
|
|
||||||
|
|
||||||
GarbageCollector::Dump();
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Vector<BaseObj*> GarbageCollector::garbage(0, 1000);
|
|
||||||
UInt_64 GarbageCollector::max = 10;
|
|
||||||
Thread GarbageCollector::thread;
|
|
||||||
Mutex GarbageCollector::mutex;
|
|
||||||
bool GarbageCollector::running = false;
|
|
||||||
|
|
||||||
bool GarbageCollector::Has(const BaseObj* obj)
|
|
||||||
{
|
|
||||||
for (UInt_64 i = 0; i < garbage.Size(); ++i)
|
|
||||||
if (garbage[i] == obj)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GarbageCollector::Start()
|
|
||||||
{
|
|
||||||
if (running)
|
|
||||||
return;
|
|
||||||
|
|
||||||
mutex.Initialize();
|
|
||||||
|
|
||||||
thread.Start(GarbageCollectionThread, nullptr);
|
|
||||||
|
|
||||||
running = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GarbageCollector::Stop()
|
|
||||||
{
|
|
||||||
if (!running)
|
|
||||||
return;
|
|
||||||
|
|
||||||
running = false;
|
|
||||||
|
|
||||||
thread.Join();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GarbageCollector::Add(BaseObj* obj)
|
|
||||||
{
|
|
||||||
if (!obj)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (Has(obj))
|
|
||||||
{
|
|
||||||
EHS_LOG_INT(LogType::WARN, 1, obj->GetTypeId() + " object with address of, \"" + Str_8::FromNum<USize>((USize)obj) + "\" is already in garbage.");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
garbage.Push(obj);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GarbageCollector::SetMax(const UInt_64 newMax)
|
|
||||||
{
|
|
||||||
max = newMax;
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt_64 GarbageCollector::GetMax()
|
|
||||||
{
|
|
||||||
return max;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GarbageCollector::SetStride(const UInt_64 newStride)
|
|
||||||
{
|
|
||||||
Dump();
|
|
||||||
|
|
||||||
garbage = Vector<BaseObj*>(0, newStride);
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt_64 GarbageCollector::GetStride()
|
|
||||||
{
|
|
||||||
return garbage.Stride();
|
|
||||||
}
|
|
||||||
|
|
||||||
UInt_64 GarbageCollector::Size()
|
|
||||||
{
|
|
||||||
return garbage.Size();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GarbageCollector::Poll()
|
|
||||||
{
|
|
||||||
if (running)
|
|
||||||
mutex.Lock();
|
|
||||||
|
|
||||||
UInt_64 i = 0;
|
|
||||||
|
|
||||||
while (i < garbage.Size())
|
|
||||||
{
|
|
||||||
garbage.Swap(i, garbage.End());
|
|
||||||
delete garbage.Pop();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (running)
|
|
||||||
mutex.Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
void GarbageCollector::Dump()
|
|
||||||
{
|
|
||||||
if (running)
|
|
||||||
mutex.Lock();
|
|
||||||
|
|
||||||
for (UInt_64 i = 0; i < garbage.Size(); ++i)
|
|
||||||
delete garbage[i];
|
|
||||||
|
|
||||||
garbage.Clear();
|
|
||||||
|
|
||||||
if (running)
|
|
||||||
mutex.Unlock();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool GarbageCollector::IsRunning()
|
|
||||||
{
|
|
||||||
return running;
|
|
||||||
}
|
|
||||||
}
|
|
@ -43,6 +43,7 @@ namespace ehs
|
|||||||
atlas = new Byte[resolution.x * resolution.y];
|
atlas = new Byte[resolution.x * resolution.y];
|
||||||
size = 0;
|
size = 0;
|
||||||
fData.ReadArray(atlas, &size);
|
fData.ReadArray(atlas, &size);
|
||||||
|
fData.ReadArray(atlas, &size);
|
||||||
}
|
}
|
||||||
|
|
||||||
FontAtlas::FontAtlas(FontAtlas&& fa) noexcept
|
FontAtlas::FontAtlas(FontAtlas&& fa) noexcept
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
#include "ehs/io/audio/AudioDevice_ALSA.h"
|
#include "ehs/io/audio/AudioDevice_ALSA.h"
|
||||||
#include "ehs/EHS.h"
|
#include "ehs/EHS.h"
|
||||||
#include "ehs/Log.h"
|
#include "ehs/Log.h"
|
||||||
|
#include "ehs/io/Console.h"
|
||||||
|
|
||||||
namespace ehs
|
namespace ehs
|
||||||
{
|
{
|
||||||
@ -366,13 +367,21 @@ namespace ehs
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
EHS_LOG_INT(LogType::ERR, 0, "Wrong value for the audio device type.");
|
EHS_LOG_INT(LogType::ERR, 1, "Wrong value for the audio device type.");
|
||||||
|
return {};
|
||||||
|
}
|
||||||
|
|
||||||
|
int err = snd_pcm_open(&result.hdl, "default", rType, SND_PCM_NONBLOCK);
|
||||||
|
if (err < 0)
|
||||||
|
{
|
||||||
|
EHS_LOG_INT(LogType::ERR, 2, "Failed to retrieve default audio device with error #" + Str_8::FromNum(err) + ".");
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
snd_pcm_open(&result.hdl, "default", rType, SND_PCM_NONBLOCK);
|
|
||||||
result.type = AudioDeviceType::OUTPUT;
|
result.type = AudioDeviceType::OUTPUT;
|
||||||
|
|
||||||
|
EHS_LOG_SUCCESS();
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -275,7 +275,6 @@ namespace ehs
|
|||||||
|
|
||||||
meshes[i].SetIndices(data.ReadArray<UInt_32, UInt_64>());
|
meshes[i].SetIndices(data.ReadArray<UInt_32, UInt_64>());
|
||||||
|
|
||||||
/*
|
|
||||||
Bone& skeleton = mdl->GetSkeleton();
|
Bone& skeleton = mdl->GetSkeleton();
|
||||||
UInt_8 boneCount = data.Read<UInt_8>();
|
UInt_8 boneCount = data.Read<UInt_8>();
|
||||||
for (UInt_8 b = 0; b < boneCount; ++b)
|
for (UInt_8 b = 0; b < boneCount; ++b)
|
||||||
@ -329,7 +328,6 @@ namespace ehs
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -29,7 +29,7 @@ namespace ehs
|
|||||||
}
|
}
|
||||||
|
|
||||||
Mesh::Mesh(const Mesh& mesh)
|
Mesh::Mesh(const Mesh& mesh)
|
||||||
: BaseObj((BaseObj&&)mesh), hashId(mesh.hashId), id(mesh.id), vertices(mesh.vertices), indices(mesh.indices)
|
: BaseObj(mesh), hashId(mesh.hashId), id(mesh.id), vertices(mesh.vertices), indices(mesh.indices)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user