Merge branch 'master' into vulkan

This commit is contained in:
Lynix
2017-08-20 21:35:51 +02:00
57 changed files with 904 additions and 197 deletions

View File

@@ -5,6 +5,7 @@
#include <Nazara/Core/AbstractHash.hpp>
#include <Nazara/Core/Error.hpp>
#include <Nazara/Core/Hash/CRC32.hpp>
#include <Nazara/Core/Hash/CRC64.hpp>
#include <Nazara/Core/Hash/Fletcher16.hpp>
#include <Nazara/Core/Hash/MD5.hpp>
#include <Nazara/Core/Hash/SHA1.hpp>
@@ -48,6 +49,9 @@ namespace Nz
case HashType_CRC32:
return std::make_unique<HashCRC32>();
case HashType_CRC64:
return std::make_unique<HashCRC64>();
case HashType_MD5:
return std::make_unique<HashMD5>();

View File

@@ -0,0 +1,115 @@
// Copyright (C) 2017 Jérôme Leclercq
// This file is part of the "Nazara Engine - Core module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/Core/Hash/CRC64.hpp>
#include <Nazara/Core/Endianness.hpp>
#include <Nazara/Core/Debug.hpp>
namespace Nz
{
struct HashCRC64_state
{
UInt64 crc;
};
namespace
{
static const UInt64 crc64_table[256] = {
0x0000000000000000ULL, 0x7ad870c830358979ULL, 0xf5b0e190606b12f2ULL, 0x8f689158505e9b8bULL,
0xc038e5739841b68fULL, 0xbae095bba8743ff6ULL, 0x358804e3f82aa47dULL, 0x4f50742bc81f2d04ULL,
0xab28ecb46814fe75ULL, 0xd1f09c7c5821770cULL, 0x5e980d24087fec87ULL, 0x24407dec384a65feULL,
0x6b1009c7f05548faULL, 0x11c8790fc060c183ULL, 0x9ea0e857903e5a08ULL, 0xe478989fa00bd371ULL,
0x7d08ff3b88be6f81ULL, 0x07d08ff3b88be6f8ULL, 0x88b81eabe8d57d73ULL, 0xf2606e63d8e0f40aULL,
0xbd301a4810ffd90eULL, 0xc7e86a8020ca5077ULL, 0x4880fbd87094cbfcULL, 0x32588b1040a14285ULL,
0xd620138fe0aa91f4ULL, 0xacf86347d09f188dULL, 0x2390f21f80c18306ULL, 0x594882d7b0f40a7fULL,
0x1618f6fc78eb277bULL, 0x6cc0863448deae02ULL, 0xe3a8176c18803589ULL, 0x997067a428b5bcf0ULL,
0xfa11fe77117cdf02ULL, 0x80c98ebf2149567bULL, 0x0fa11fe77117cdf0ULL, 0x75796f2f41224489ULL,
0x3a291b04893d698dULL, 0x40f16bccb908e0f4ULL, 0xcf99fa94e9567b7fULL, 0xb5418a5cd963f206ULL,
0x513912c379682177ULL, 0x2be1620b495da80eULL, 0xa489f35319033385ULL, 0xde51839b2936bafcULL,
0x9101f7b0e12997f8ULL, 0xebd98778d11c1e81ULL, 0x64b116208142850aULL, 0x1e6966e8b1770c73ULL,
0x8719014c99c2b083ULL, 0xfdc17184a9f739faULL, 0x72a9e0dcf9a9a271ULL, 0x08719014c99c2b08ULL,
0x4721e43f0183060cULL, 0x3df994f731b68f75ULL, 0xb29105af61e814feULL, 0xc849756751dd9d87ULL,
0x2c31edf8f1d64ef6ULL, 0x56e99d30c1e3c78fULL, 0xd9810c6891bd5c04ULL, 0xa3597ca0a188d57dULL,
0xec09088b6997f879ULL, 0x96d1784359a27100ULL, 0x19b9e91b09fcea8bULL, 0x636199d339c963f2ULL,
0xdf7adabd7a6e2d6fULL, 0xa5a2aa754a5ba416ULL, 0x2aca3b2d1a053f9dULL, 0x50124be52a30b6e4ULL,
0x1f423fcee22f9be0ULL, 0x659a4f06d21a1299ULL, 0xeaf2de5e82448912ULL, 0x902aae96b271006bULL,
0x74523609127ad31aULL, 0x0e8a46c1224f5a63ULL, 0x81e2d7997211c1e8ULL, 0xfb3aa75142244891ULL,
0xb46ad37a8a3b6595ULL, 0xceb2a3b2ba0eececULL, 0x41da32eaea507767ULL, 0x3b024222da65fe1eULL,
0xa2722586f2d042eeULL, 0xd8aa554ec2e5cb97ULL, 0x57c2c41692bb501cULL, 0x2d1ab4dea28ed965ULL,
0x624ac0f56a91f461ULL, 0x1892b03d5aa47d18ULL, 0x97fa21650afae693ULL, 0xed2251ad3acf6feaULL,
0x095ac9329ac4bc9bULL, 0x7382b9faaaf135e2ULL, 0xfcea28a2faafae69ULL, 0x8632586aca9a2710ULL,
0xc9622c4102850a14ULL, 0xb3ba5c8932b0836dULL, 0x3cd2cdd162ee18e6ULL, 0x460abd1952db919fULL,
0x256b24ca6b12f26dULL, 0x5fb354025b277b14ULL, 0xd0dbc55a0b79e09fULL, 0xaa03b5923b4c69e6ULL,
0xe553c1b9f35344e2ULL, 0x9f8bb171c366cd9bULL, 0x10e3202993385610ULL, 0x6a3b50e1a30ddf69ULL,
0x8e43c87e03060c18ULL, 0xf49bb8b633338561ULL, 0x7bf329ee636d1eeaULL, 0x012b592653589793ULL,
0x4e7b2d0d9b47ba97ULL, 0x34a35dc5ab7233eeULL, 0xbbcbcc9dfb2ca865ULL, 0xc113bc55cb19211cULL,
0x5863dbf1e3ac9decULL, 0x22bbab39d3991495ULL, 0xadd33a6183c78f1eULL, 0xd70b4aa9b3f20667ULL,
0x985b3e827bed2b63ULL, 0xe2834e4a4bd8a21aULL, 0x6debdf121b863991ULL, 0x1733afda2bb3b0e8ULL,
0xf34b37458bb86399ULL, 0x8993478dbb8deae0ULL, 0x06fbd6d5ebd3716bULL, 0x7c23a61ddbe6f812ULL,
0x3373d23613f9d516ULL, 0x49aba2fe23cc5c6fULL, 0xc6c333a67392c7e4ULL, 0xbc1b436e43a74e9dULL,
0x95ac9329ac4bc9b5ULL, 0xef74e3e19c7e40ccULL, 0x601c72b9cc20db47ULL, 0x1ac40271fc15523eULL,
0x5594765a340a7f3aULL, 0x2f4c0692043ff643ULL, 0xa02497ca54616dc8ULL, 0xdafce7026454e4b1ULL,
0x3e847f9dc45f37c0ULL, 0x445c0f55f46abeb9ULL, 0xcb349e0da4342532ULL, 0xb1eceec59401ac4bULL,
0xfebc9aee5c1e814fULL, 0x8464ea266c2b0836ULL, 0x0b0c7b7e3c7593bdULL, 0x71d40bb60c401ac4ULL,
0xe8a46c1224f5a634ULL, 0x927c1cda14c02f4dULL, 0x1d148d82449eb4c6ULL, 0x67ccfd4a74ab3dbfULL,
0x289c8961bcb410bbULL, 0x5244f9a98c8199c2ULL, 0xdd2c68f1dcdf0249ULL, 0xa7f41839ecea8b30ULL,
0x438c80a64ce15841ULL, 0x3954f06e7cd4d138ULL, 0xb63c61362c8a4ab3ULL, 0xcce411fe1cbfc3caULL,
0x83b465d5d4a0eeceULL, 0xf96c151de49567b7ULL, 0x76048445b4cbfc3cULL, 0x0cdcf48d84fe7545ULL,
0x6fbd6d5ebd3716b7ULL, 0x15651d968d029fceULL, 0x9a0d8ccedd5c0445ULL, 0xe0d5fc06ed698d3cULL,
0xaf85882d2576a038ULL, 0xd55df8e515432941ULL, 0x5a3569bd451db2caULL, 0x20ed197575283bb3ULL,
0xc49581ead523e8c2ULL, 0xbe4df122e51661bbULL, 0x3125607ab548fa30ULL, 0x4bfd10b2857d7349ULL,
0x04ad64994d625e4dULL, 0x7e7514517d57d734ULL, 0xf11d85092d094cbfULL, 0x8bc5f5c11d3cc5c6ULL,
0x12b5926535897936ULL, 0x686de2ad05bcf04fULL, 0xe70573f555e26bc4ULL, 0x9ddd033d65d7e2bdULL,
0xd28d7716adc8cfb9ULL, 0xa85507de9dfd46c0ULL, 0x273d9686cda3dd4bULL, 0x5de5e64efd965432ULL,
0xb99d7ed15d9d8743ULL, 0xc3450e196da80e3aULL, 0x4c2d9f413df695b1ULL, 0x36f5ef890dc31cc8ULL,
0x79a59ba2c5dc31ccULL, 0x037deb6af5e9b8b5ULL, 0x8c157a32a5b7233eULL, 0xf6cd0afa9582aa47ULL,
0x4ad64994d625e4daULL, 0x300e395ce6106da3ULL, 0xbf66a804b64ef628ULL, 0xc5bed8cc867b7f51ULL,
0x8aeeace74e645255ULL, 0xf036dc2f7e51db2cULL, 0x7f5e4d772e0f40a7ULL, 0x05863dbf1e3ac9deULL,
0xe1fea520be311aafULL, 0x9b26d5e88e0493d6ULL, 0x144e44b0de5a085dULL, 0x6e963478ee6f8124ULL,
0x21c640532670ac20ULL, 0x5b1e309b16452559ULL, 0xd476a1c3461bbed2ULL, 0xaeaed10b762e37abULL,
0x37deb6af5e9b8b5bULL, 0x4d06c6676eae0222ULL, 0xc26e573f3ef099a9ULL, 0xb8b627f70ec510d0ULL,
0xf7e653dcc6da3dd4ULL, 0x8d3e2314f6efb4adULL, 0x0256b24ca6b12f26ULL, 0x788ec2849684a65fULL,
0x9cf65a1b368f752eULL, 0xe62e2ad306bafc57ULL, 0x6946bb8b56e467dcULL, 0x139ecb4366d1eea5ULL,
0x5ccebf68aecec3a1ULL, 0x2616cfa09efb4ad8ULL, 0xa97e5ef8cea5d153ULL, 0xd3a62e30fe90582aULL,
0xb0c7b7e3c7593bd8ULL, 0xca1fc72bf76cb2a1ULL, 0x45775673a732292aULL, 0x3faf26bb9707a053ULL,
0x70ff52905f188d57ULL, 0x0a2722586f2d042eULL, 0x854fb3003f739fa5ULL, 0xff97c3c80f4616dcULL,
0x1bef5b57af4dc5adULL, 0x61372b9f9f784cd4ULL, 0xee5fbac7cf26d75fULL, 0x9487ca0fff135e26ULL,
0xdbd7be24370c7322ULL, 0xa10fceec0739fa5bULL, 0x2e675fb4576761d0ULL, 0x54bf2f7c6752e8a9ULL,
0xcdcf48d84fe75459ULL, 0xb71738107fd2dd20ULL, 0x387fa9482f8c46abULL, 0x42a7d9801fb9cfd2ULL,
0x0df7adabd7a6e2d6ULL, 0x772fdd63e7936bafULL, 0xf8474c3bb7cdf024ULL, 0x829f3cf387f8795dULL,
0x66e7a46c27f3aa2cULL, 0x1c3fd4a417c62355ULL, 0x935745fc4798b8deULL, 0xe98f353477ad31a7ULL,
0xa6df411fbfb21ca3ULL, 0xdc0731d78f8795daULL, 0x536fa08fdfd90e51ULL, 0x29b7d047efec8728ULL
};
}
void HashCRC64::Append(const UInt8* data, std::size_t len)
{
while (len--)
m_crc = crc64_table[(m_crc ^ *data++) & 0xFF] ^ (m_crc >> 8);
}
void HashCRC64::Begin()
{
m_crc = 0;
}
ByteArray HashCRC64::End()
{
#ifdef NAZARA_LITTLE_ENDIAN
SwapBytes(&m_crc, sizeof(UInt64));
#endif
return ByteArray(reinterpret_cast<UInt8*>(&m_crc), 8);
}
std::size_t HashCRC64::GetDigestLength() const
{
return 8;
}
const char* HashCRC64::GetHashName() const
{
return "CRC64";
}
}

View File

@@ -697,7 +697,7 @@ namespace Nz
auto it = layers.find(i);
if (it == layers.end())
it = layers.insert(std::make_pair(i, Layer())).first;
Layer& layer = it->second;
layer.clearCount = 0;
@@ -729,7 +729,6 @@ namespace Nz
void ForwardRenderQueue::SortForOrthographic(const AbstractViewer * viewer)
{
Planef nearPlane = viewer->GetFrustum().GetPlane(FrustumPlane_Near);
Vector3f viewerPos = viewer->GetEyePosition();
for (auto& pair : layers)
{

View File

@@ -128,13 +128,18 @@ namespace Nz
if (!result.address)
continue;
if (result.socketType != SocketType_UDP)
continue;
hostnameAddress = result.address;
break; //< Take first valid address
}
if (!hostnameAddress.IsValid())
{
if (error)
*error = ResolveError_NotFound;
return nullptr;
}
return Connect(hostnameAddress, channelCount, data);
}

View File

@@ -139,7 +139,7 @@ namespace Nz
m_packetsLost = 0;
m_packetLoss = 0;
m_packetLossVariance = 0;
m_packetThrottle = ENetConstants::ENetProtocol_MaximumWindowSize;
m_packetThrottle = ENetConstants::ENetPeer_DefaultPacketThrottle;
m_packetThrottleLimit = ENetConstants::ENetPeer_PacketThrottleScale;
m_packetThrottleCounter = 0;
m_packetThrottleEpoch = 0;
@@ -1330,7 +1330,7 @@ namespace Nz
{
if (rtt < m_lastRoundTripTime)
{
m_packetThrottle = std::max(m_packetThrottle + m_packetThrottleAcceleration, m_packetThrottleLimit);
m_packetThrottle = std::min(m_packetThrottle + m_packetThrottleAcceleration, m_packetThrottleLimit);
return 1;
}
else if (rtt > m_lastRoundTripTime + 2 * m_lastRoundTripTimeVariance)

View File

@@ -80,7 +80,7 @@ namespace Nz
NazaraWarning("An error occured while removing socket from epoll structure (errno " + String::Number(errno) + ": " + Error::GetLastSystemError() + ')');
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
int SocketPollerImpl::Wait(int msTimeout, SocketError* error)
{
int activeSockets;

View File

@@ -30,7 +30,7 @@ namespace Nz
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
int Wait(int msTimeout, SocketError* error);
private:
std::unordered_set<SocketHandle> m_readyToReadSockets;

View File

@@ -509,12 +509,12 @@ namespace Nz
NazaraAssert(buffer && length > 0, "Invalid buffer");
IpAddressImpl::SockAddrBuffer nameBuffer;
socklen_t bufferLength = sizeof(sockaddr_in);
socklen_t bufferLength = static_cast<socklen_t>(nameBuffer.size());
IpAddress senderIp;
int byteRead = recvfrom(handle, buffer, length, 0, reinterpret_cast<sockaddr*>(&nameBuffer), &bufferLength);
if (byteRead == SOCKET_ERROR)
if (byteRead == -1)
{
int errorCode = GetLastErrorCode();
if (errorCode == EAGAIN)
@@ -549,6 +549,92 @@ namespace Nz
else // else we received something
senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
if (from)
*from = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
if (read)
*read = byteRead;
if (error)
*error = SocketError_NoError;
return true;
}
bool SocketImpl::ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error)
{
NazaraAssert(handle != InvalidHandle, "Invalid handle");
NazaraAssert(buffers && bufferCount > 0, "Invalid buffers");
StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(iovec));
struct iovec* sysBuffers = static_cast<struct iovec*>(memory.GetPtr());
for (std::size_t i = 0; i < bufferCount; ++i)
{
sysBuffers[i].iov_base = buffers[i].data;
sysBuffers[i].iov_len = buffers[i].dataLength;
}
struct msghdr msgHdr;
std::memset(&msgHdr, 0, sizeof(msgHdr));
msgHdr.msg_iov = sysBuffers;
msgHdr.msg_iovlen = static_cast<int>(bufferCount);
IpAddressImpl::SockAddrBuffer nameBuffer;
if (from)
{
msgHdr.msg_name = nameBuffer.data();
msgHdr.msg_namelen = static_cast<socklen_t>(nameBuffer.size());
}
IpAddress senderIp;
int byteRead = recvmsg(handle, &msgHdr, MSG_NOSIGNAL);
if (byteRead == -1)
{
int errorCode = GetLastErrorCode();
if (errorCode == EAGAIN)
errorCode = EWOULDBLOCK;
switch (errorCode)
{
case EWOULDBLOCK:
{
// If we have no data and are not blocking, return true with 0 byte read
byteRead = 0;
senderIp = IpAddress::Invalid;
break;
}
default:
{
if (error)
*error = TranslateErrnoToResolveError(errorCode);
return false; //< Error
}
}
}
else if (byteRead == 0)
{
if (error)
*error = SocketError_ConnectionClosed;
return false; //< Connection closed
}
else // else we received something
senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(nameBuffer.data()));
#ifdef HAS_MSGHDR_FLAGS
if (msgHdr.msg_flags & MSG_TRUNC)
{
if (error)
*error = SocketError_DatagramSize;
return false;
}
#endif
if (from)
*from = senderIp;

View File

@@ -63,6 +63,7 @@ namespace Nz
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
static bool ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error);
static bool Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error);
static bool SendMultiple(SocketHandle handle, const NetBuffer* buffers, std::size_t bufferCount, const IpAddress& to, int* sent, SocketError* error);

View File

@@ -76,7 +76,7 @@ namespace Nz
m_readyToWriteSockets.erase(socket);
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
int SocketPollerImpl::Wait(int msTimeout, SocketError* error)
{
int activeSockets;

View File

@@ -30,7 +30,7 @@ namespace Nz
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
int Wait(int msTimeout, SocketError* error);
private:
std::unordered_set<SocketHandle> m_readyToReadSockets;

View File

@@ -170,7 +170,7 @@ namespace Nz
* Waits a specific/undetermined amount of time until at least one socket part of the SocketPoller becomes ready.
* To query the ready state of the registered socket, use the IsReadyToRead or IsReadyToWrite functions.
*
* \param msTimeout Maximum time to wait in milliseconds, 0 for infinity
* \param msTimeout Maximum time to wait in milliseconds, 0 will returns immediately and -1 will block indefinitely
*
* \return True if at least one socket registered to the poller is ready.
*
@@ -179,7 +179,7 @@ namespace Nz
* \see IsReady
* \see RegisterSocket
*/
bool SocketPoller::Wait(UInt64 msTimeout)
bool SocketPoller::Wait(int msTimeout)
{
SocketError error;

View File

@@ -118,6 +118,42 @@ namespace Nz
return true;
}
/*!
* \brief Receive multiple datagram from one peer
* \return true If data were sent
*
* \param to Destination IpAddress (must match socket protocol)
* \param buffers A pointer to an array of NetBuffer containing buffers and size data
* \param bufferCount Number of buffers available
* \param from IpAddress of the peer
* \param received Optional argument to get the number of bytes received
*/
bool UdpSocket::ReceiveMultiple(NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, std::size_t* received)
{
NazaraAssert(m_handle != SocketImpl::InvalidHandle, "Socket hasn't been created");
NazaraAssert(buffers && bufferCount > 0, "Invalid buffer");
int read;
if (!SocketImpl::ReceiveMultiple(m_handle, buffers, bufferCount, from, &read, &m_lastError))
{
switch (m_lastError)
{
case SocketError_ConnectionClosed:
m_lastError = SocketError_NoError;
read = 0;
break;
default:
return false;
}
}
if (received)
*received = read;
return true;
}
/*!
* \brief Receives the packet available
* \return true If packet received

View File

@@ -586,6 +586,72 @@ namespace Nz
return true;
}
bool SocketImpl::ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error)
{
NazaraAssert(handle != InvalidHandle, "Invalid handle");
NazaraAssert(buffers && bufferCount > 0, "Invalid buffers");
IpAddressImpl::SockAddrBuffer nameBuffer;
int bufferLength = static_cast<int>(nameBuffer.size());
IpAddress senderIp;
StackAllocation memory = NazaraStackAllocation(bufferCount * sizeof(WSABUF));
WSABUF* winBuffers = static_cast<WSABUF*>(memory.GetPtr());
for (std::size_t i = 0; i < bufferCount; ++i)
{
winBuffers[i].buf = static_cast<CHAR*>(buffers[i].data);
winBuffers[i].len = static_cast<ULONG>(buffers[i].dataLength);
}
DWORD flags = 0;
DWORD byteRead;
if (WSARecvFrom(handle, winBuffers, static_cast<DWORD>(bufferCount), &byteRead, &flags, reinterpret_cast<sockaddr*>(nameBuffer.data()), &bufferLength, nullptr, nullptr) == SOCKET_ERROR)
{
int errorCode = WSAGetLastError();
switch (errorCode)
{
case WSAECONNRESET:
case WSAEWOULDBLOCK:
{
// If we have no data and are not blocking, return true with 0 byte read
byteRead = 0;
senderIp = IpAddress::Invalid;
break;
}
default:
{
if (error)
*error = TranslateWSAErrorToSocketError(errorCode);
return false; //< Error
}
}
}
else
senderIp = IpAddressImpl::FromSockAddr(reinterpret_cast<const sockaddr*>(&nameBuffer));
if (flags & MSG_PARTIAL)
{
if (error)
*error = SocketError_DatagramSize;
return false;
}
if (from)
*from = senderIp;
if (read)
*read = byteRead;
if (error)
*error = SocketError_NoError;
return true;
}
bool SocketImpl::Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error)
{
NazaraAssert(handle != InvalidHandle, "Invalid handle");

View File

@@ -64,6 +64,7 @@ namespace Nz
static bool Receive(SocketHandle handle, void* buffer, int length, int* read, SocketError* error);
static bool ReceiveFrom(SocketHandle handle, void* buffer, int length, IpAddress* from, int* read, SocketError* error);
static bool ReceiveMultiple(SocketHandle handle, NetBuffer* buffers, std::size_t bufferCount, IpAddress* from, int* read, SocketError* error);
static bool Send(SocketHandle handle, const void* buffer, int length, int* sent, SocketError* error);
static bool SendMultiple(SocketHandle handle, const NetBuffer* buffers, std::size_t bufferCount, const IpAddress& to, int* sent, SocketError* error);

View File

@@ -129,7 +129,7 @@ namespace Nz
#endif
}
int SocketPollerImpl::Wait(UInt64 msTimeout, SocketError* error)
int SocketPollerImpl::Wait(int msTimeout, SocketError* error)
{
int activeSockets;
@@ -179,7 +179,7 @@ namespace Nz
tv.tv_sec = static_cast<long>(msTimeout / 1000ULL);
tv.tv_usec = static_cast<long>((msTimeout % 1000ULL) * 1000ULL);
activeSockets = ::select(0xDEADBEEF, readSet, writeSet, nullptr, (msTimeout > 0) ? &tv : nullptr); //< The first argument is ignored on Windows
activeSockets = ::select(0xDEADBEEF, readSet, writeSet, nullptr, (msTimeout >= 0) ? &tv : nullptr); //< The first argument is ignored on Windows
if (activeSockets == SOCKET_ERROR)
{
if (error)

View File

@@ -32,7 +32,7 @@ namespace Nz
bool RegisterSocket(SocketHandle socket, SocketPollEventFlags eventFlags);
void UnregisterSocket(SocketHandle socket);
int Wait(UInt64 msTimeout, SocketError* error);
int Wait(int msTimeout, SocketError* error);
private:
#if NAZARA_NETWORK_POLL_SUPPORT

View File

@@ -15,7 +15,9 @@ namespace Nz
{
cpShapeFilter filter = cpShapeFilterNew(m_collisionGroup, m_categoryMask, m_collisionMask);
std::vector<cpShape*> shapes = CreateShapes(body);
std::vector<cpShape*> shapes;
CreateShapes(body, shapes);
for (cpShape* shape : shapes)
{
cpShapeSetFilter(shape, filter);
@@ -39,9 +41,9 @@ namespace Nz
{
}
float BoxCollider2D::ComputeInertialMatrix(float mass) const
float BoxCollider2D::ComputeMomentOfInertia(float mass) const
{
return static_cast<float>(cpMomentForBox2(mass, cpBBNew(m_rect.x, m_rect.y + m_rect.height, m_rect.x + m_rect.width, m_rect.y)));
return static_cast<float>(cpMomentForBox2(mass, cpBBNew(m_rect.x, m_rect.y, m_rect.x + m_rect.width, m_rect.y + m_rect.height)));
}
ColliderType2D BoxCollider2D::GetType() const
@@ -49,12 +51,9 @@ namespace Nz
return ColliderType2D_Box;
}
std::vector<cpShape*> BoxCollider2D::CreateShapes(RigidBody2D* body) const
void BoxCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
{
std::vector<cpShape*> shapes;
shapes.push_back(cpBoxShapeNew2(body->GetHandle(), cpBBNew(m_rect.x, m_rect.y + m_rect.height, m_rect.x + m_rect.width, m_rect.y), m_radius));
return shapes;
shapes.push_back(cpBoxShapeNew2(body->GetHandle(), cpBBNew(m_rect.x, m_rect.y, m_rect.x + m_rect.width, m_rect.y + m_rect.height), m_radius));
}
/******************************** CircleCollider2D *********************************/
@@ -65,7 +64,7 @@ namespace Nz
{
}
float CircleCollider2D::ComputeInertialMatrix(float mass) const
float CircleCollider2D::ComputeMomentOfInertia(float mass) const
{
return static_cast<float>(cpMomentForCircle(mass, 0.f, m_radius, cpv(m_offset.x, m_offset.y)));
}
@@ -75,12 +74,66 @@ namespace Nz
return ColliderType2D_Circle;
}
std::vector<cpShape*> CircleCollider2D::CreateShapes(RigidBody2D* body) const
void CircleCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
{
std::vector<cpShape*> shapes;
shapes.push_back(cpCircleShapeNew(body->GetHandle(), m_radius, cpv(m_offset.x, m_offset.y)));
}
return shapes;
/******************************** CompoundCollider2D *********************************/
CompoundCollider2D::CompoundCollider2D(std::vector<Collider2DRef> geoms) :
m_geoms(std::move(geoms))
{
}
float CompoundCollider2D::ComputeMomentOfInertia(float mass) const
{
///TODO: Correctly compute moment using parallel axis theorem:
/// https://chipmunk-physics.net/forum/viewtopic.php?t=1056
float momentOfInertia = 0.f;
for (const auto& geom : m_geoms)
momentOfInertia += geom->ComputeMomentOfInertia(mass); //< Eeeer
return momentOfInertia;
}
ColliderType2D CompoundCollider2D::GetType() const
{
return ColliderType2D_Compound;
}
void CompoundCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
{
// Since C++ does not allow protected call from other objects, we have to be a friend of Collider2D, yay
for (const auto& geom : m_geoms)
geom->CreateShapes(body, shapes);
}
/******************************** ConvexCollider2D *********************************/
ConvexCollider2D::ConvexCollider2D(SparsePtr<const Vector2f> vertices, std::size_t vertexCount, float radius) :
m_radius(radius)
{
m_vertices.resize(vertexCount);
for (std::size_t i = 0; i < vertexCount; ++i)
m_vertices[i].Set(*vertices++);
}
float ConvexCollider2D::ComputeMomentOfInertia(float mass) const
{
static_assert(sizeof(cpVect) == sizeof(Vector2d), "Chipmunk vector is not equivalent to Vector2d");
return static_cast<float>(cpMomentForPoly(mass, int(m_vertices.size()), reinterpret_cast<const cpVect*>(m_vertices.data()), cpv(0.0, 0.0), m_radius));
}
ColliderType2D ConvexCollider2D::GetType() const
{
return ColliderType2D_Convex;
}
void ConvexCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
{
shapes.push_back(cpPolyShapeNew(body->GetHandle(), int(m_vertices.size()), reinterpret_cast<const cpVect*>(m_vertices.data()), cpTransformIdentity, m_radius));
}
/********************************* NullCollider2D **********************************/
@@ -90,19 +143,18 @@ namespace Nz
return ColliderType2D_Null;
}
float NullCollider2D::ComputeInertialMatrix(float /*mass*/) const
float NullCollider2D::ComputeMomentOfInertia(float /*mass*/) const
{
return 0.f;
}
std::vector<cpShape*> NullCollider2D::CreateShapes(RigidBody2D* /*body*/) const
void NullCollider2D::CreateShapes(RigidBody2D* /*body*/, std::vector<cpShape*>& /*shapes*/) const
{
return std::vector<cpShape*>();
}
/******************************** SegmentCollider2D *********************************/
float SegmentCollider2D::ComputeInertialMatrix(float mass) const
float SegmentCollider2D::ComputeMomentOfInertia(float mass) const
{
return static_cast<float>(cpMomentForSegment(mass, cpv(m_first.x, m_first.y), cpv(m_second.x, m_second.y), m_thickness));
}
@@ -112,12 +164,8 @@ namespace Nz
return ColliderType2D_Segment;
}
std::vector<cpShape*> SegmentCollider2D::CreateShapes(RigidBody2D* body) const
void SegmentCollider2D::CreateShapes(RigidBody2D* body, std::vector<cpShape*>& shapes) const
{
std::vector<cpShape*> shapes;
shapes.push_back(cpSegmentShapeNew(body->GetHandle(), cpv(m_first.x, m_first.y), cpv(m_second.x, m_second.y), m_thickness));
return shapes;
}
}

View File

@@ -60,12 +60,12 @@ namespace Nz
{
cpPointQueryInfo queryInfo;
if (cpShape* shape = cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, &queryInfo))
if (cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, &queryInfo))
{
result->closestPoint.Set(Nz::Vector2<cpFloat>(queryInfo.point.x, queryInfo.point.y));
result->distance = float(queryInfo.distance);
result->fraction.Set(Nz::Vector2<cpFloat>(queryInfo.gradient.x, queryInfo.gradient.y));
result->nearestBody = static_cast<Nz::RigidBody2D*>(cpShapeGetUserData(shape));
result->nearestBody = static_cast<Nz::RigidBody2D*>(cpShapeGetUserData(queryInfo.shape));
return true;
}
@@ -74,7 +74,7 @@ namespace Nz
}
else
{
if (cpShape* shape = cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, nullptr))
if (cpSpacePointQueryNearest(m_handle, { from.x, from.y }, maxDistance, filter, nullptr))
return true;
else
return false;
@@ -114,7 +114,7 @@ namespace Nz
{
cpSegmentQueryInfo queryInfo;
if (cpShape* shape = cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, &queryInfo))
if (cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, &queryInfo))
{
hitInfo->fraction = float(queryInfo.alpha);
hitInfo->hitNormal.Set(Nz::Vector2<cpFloat>(queryInfo.normal.x, queryInfo.normal.y));
@@ -128,7 +128,7 @@ namespace Nz
}
else
{
if (cpShape* shape = cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, nullptr))
if (cpSpaceSegmentQueryFirst(m_handle, { from.x, from.y }, { to.x, to.y }, radius, filter, nullptr))
return true;
else
return false;
@@ -146,7 +146,7 @@ namespace Nz
};
cpShapeFilter filter = cpShapeFilterNew(collisionGroup, categoryMask, collisionMask);
cpSpaceBBQuery(m_handle, cpBBNew(boundingBox.x, boundingBox.y + boundingBox.height, boundingBox.x + boundingBox.width, boundingBox.y), filter, callback, bodies);
cpSpaceBBQuery(m_handle, cpBBNew(boundingBox.x, boundingBox.y, boundingBox.x + boundingBox.width, boundingBox.y + boundingBox.height), filter, callback, bodies);
}
void PhysWorld2D::RegisterCallbacks(unsigned int collisionId, const Callback& callbacks)

View File

@@ -191,6 +191,11 @@ namespace Nz
return Vector2f(static_cast<float>(vel.x), static_cast<float>(vel.y));
}
PhysWorld2D* RigidBody2D::GetWorld() const
{
return m_world;
}
bool RigidBody2D::IsMoveable() const
{
return m_mass > 0.f;
@@ -240,7 +245,7 @@ namespace Nz
cpSpaceAddShape(space, shape);
}
cpBodySetMoment(m_handle, m_geom->ComputeInertialMatrix(m_mass));
cpBodySetMoment(m_handle, m_geom->ComputeMomentOfInertia(m_mass));
}
void RigidBody2D::SetMass(float mass)
@@ -252,7 +257,7 @@ namespace Nz
m_world->RegisterPostStep(this, [mass](Nz::RigidBody2D* body)
{
cpBodySetMass(body->GetHandle(), mass);
cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeInertialMatrix(mass));
cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeMomentOfInertia(mass));
});
}
else
@@ -266,7 +271,7 @@ namespace Nz
{
cpBodySetType(body->GetHandle(), CP_BODY_TYPE_DYNAMIC);
cpBodySetMass(body->GetHandle(), mass);
cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeInertialMatrix(mass));
cpBodySetMoment(body->GetHandle(), body->GetGeom()->ComputeMomentOfInertia(mass));
}
});
}
@@ -280,6 +285,14 @@ namespace Nz
cpBodySetCenterOfGravity(m_handle, cpv(center.x, center.y));
}
void RigidBody2D::SetMomentOfInertia(float moment)
{
m_world->RegisterPostStep(this, [moment] (Nz::RigidBody2D* body)
{
cpBodySetMoment(body->GetHandle(), moment);
});
}
void RigidBody2D::SetPosition(const Vector2f& position)
{
cpBodySetPosition(m_handle, cpv(position.x, position.y));

View File

@@ -128,12 +128,12 @@ namespace Nz
std::size_t primitiveCount = list.GetSize();
if (primitiveCount > 1)
{
std::vector<Collider3D*> geoms(primitiveCount);
std::vector<Collider3DRef> geoms(primitiveCount);
for (unsigned int i = 0; i < primitiveCount; ++i)
geoms[i] = CreateGeomFromPrimitive(list.GetPrimitive(i));
return CompoundCollider3D::New(&geoms[0], primitiveCount);
return CompoundCollider3D::New(std::move(geoms));
}
else if (primitiveCount > 0)
return CreateGeomFromPrimitive(list.GetPrimitive(0));
@@ -239,11 +239,9 @@ namespace Nz
/******************************* CompoundCollider3D ********************************/
CompoundCollider3D::CompoundCollider3D(Collider3D** geoms, std::size_t geomCount)
CompoundCollider3D::CompoundCollider3D(std::vector<Collider3DRef> geoms) :
m_geoms(std::move(geoms))
{
m_geoms.reserve(geomCount);
for (std::size_t i = 0; i < geomCount; ++i)
m_geoms.emplace_back(geoms[i]);
}
const std::vector<Collider3DRef>& CompoundCollider3D::GetGeoms() const

View File

@@ -204,6 +204,11 @@ namespace Nz
return velocity;
}
PhysWorld3D* RigidBody3D::GetWorld() const
{
return m_world;
}
bool RigidBody3D::IsAutoSleepEnabled() const
{
return NewtonBodyGetAutoSleep(m_body) != 0;
@@ -314,7 +319,7 @@ namespace Nz
NazaraUnused(userData);
NewtonBodySetSleepState(body, 0);
return 1;
},
},
nullptr);
}
}

View File

@@ -105,11 +105,10 @@ namespace Nz
const AbstractTextDrawer::Line& SimpleTextDrawer::GetLine(std::size_t index) const
{
NazaraAssert(index < m_lines.size(), "Line index out of range");
if (!m_glyphUpdated)
UpdateGlyphs();
NazaraAssert(index < m_lines.size(), "Line index out of range");
return m_lines[index];
}
@@ -319,6 +318,10 @@ namespace Nz
glyph.color = m_color;
glyph.flipped = fontGlyph.flipped;
glyph.bounds.Set(fontGlyph.aabb);
glyph.bounds.x += m_drawPos.x;
glyph.bounds.y += m_drawPos.y;
if (fontGlyph.requireFauxBold)
{
// Let's simulate bold by enlarging the glyph (not a neat idea, but should work)
@@ -330,16 +333,13 @@ namespace Nz
// Replace it at the correct height
Vector2f offset(glyph.bounds.GetCenter() - center);
glyph.bounds.x -= offset.x;
glyph.bounds.y -= offset.y;
// Adjust advance (+10%)
advance += advance / 10;
}
glyph.bounds.Set(fontGlyph.aabb);
glyph.bounds.x += m_drawPos.x;
glyph.bounds.y += m_drawPos.y;
// We "lean" the glyph to simulate italics style
float italic = (fontGlyph.requireFauxItalic) ? 0.208f : 0.f;
float italicTop = italic * glyph.bounds.y;