// // SharedUtil.h // hifi // // Created by Stephen Birarda on 2/22/13. // Copyright (c) 2013 HighFidelity, Inc. All rights reserved. // #ifndef __hifi__SharedUtil__ #define __hifi__SharedUtil__ #include #include #include #include #include #include #ifdef _WIN32 #include "Systime.h" #else #include #endif typedef unsigned char rgbColor[3]; static const float ZERO = 0.0f; static const float ONE = 1.0f; static const float ONE_HALF = 0.5f; static const float ONE_THIRD = 0.333333f; static const float PIE = 3.141592f; static const float PI_TIMES_TWO = 3.141592f * 2.0f; static const float PI_OVER_180 = 3.141592f / 180.0f; static const float EPSILON = 0.000001f; //smallish positive number - used as margin of error for some computations static const float SQUARE_ROOT_OF_2 = (float)sqrt(2); static const float SQUARE_ROOT_OF_3 = (float)sqrt(3); static const float METER = 1.0f; static const float DECIMETER = 0.1f; static const float CENTIMETER = 0.01f; static const float MILLIIMETER = 0.001f; uint64_t usecTimestamp(const timeval *time); uint64_t usecTimestampNow(); float randFloat(); int randIntInRange (int min, int max); float randFloatInRange (float min,float max); unsigned char randomColorValue(int minimum); bool randomBoolean(); bool shouldDo(float desiredInterval, float deltaTime); void outputBufferBits(unsigned char* buffer, int length, bool withNewLine = true); void outputBits(unsigned char byte, bool withNewLine = true); void printVoxelCode(unsigned char* voxelCode); int numberOfOnes(unsigned char byte); bool oneAtBit(unsigned char byte, int bitIndex); void setAtBit(unsigned char& byte, int bitIndex); void clearAtBit(unsigned char& byte, int bitIndex); int getSemiNibbleAt(unsigned char& byte, int bitIndex); void setSemiNibbleAt(unsigned char& byte, int bitIndex, int value); int getNthBit(unsigned char byte, int ordinal); /// determines the bit placement 0-7 of the ordinal set bit bool isInEnvironment(const char* environment); void switchToResourcesParentIfRequired(); void loadRandomIdentifier(unsigned char* identifierBuffer, int numBytes); const char* getCmdOption(int argc, const char * argv[],const char* option); bool cmdOptionExists(int argc, const char * argv[],const char* option); void sharedMessageHandler(QtMsgType type, const QMessageLogContext& context, const QString &message); struct VoxelDetail { float x; float y; float z; float s; unsigned char red; unsigned char green; unsigned char blue; }; unsigned char* pointToVoxel(float x, float y, float z, float s, unsigned char r = 0, unsigned char g = 0, unsigned char b = 0); // Creates a full Voxel edit message, including command header, sequence, and details bool createVoxelEditMessage(unsigned char command, short int sequence, int voxelCount, VoxelDetail* voxelDetails, unsigned char*& bufferOut, int& sizeOut); /// encodes the voxel details portion of a voxel edit message bool encodeVoxelEditMessageDetails(unsigned char command, int voxelCount, VoxelDetail* voxelDetails, unsigned char* bufferOut, int sizeIn, int& sizeOut); #ifdef _WIN32 void usleep(int waitTime); #endif int insertIntoSortedArrays(void* value, float key, int originalIndex, void** valueArray, float* keyArray, int* originalIndexArray, int currentCount, int maxCount); int removeFromSortedArrays(void* value, void** valueArray, float* keyArray, int* originalIndexArray, int currentCount, int maxCount); // Helper Class for debugging class debug { public: static const char* valueOf(bool checkValue) { return checkValue ? "yes" : "no"; } }; bool isBetween(int64_t value, int64_t max, int64_t min); // These pack/unpack functions are designed to start specific known types in as efficient a manner // as possible. Taking advantage of the known characteristics of the semantic types. // Angles are known to be between 0 and 360deg, this allows us to encode in 16bits with great accuracy int packFloatAngleToTwoByte(unsigned char* buffer, float angle); int unpackFloatAngleFromTwoByte(uint16_t* byteAnglePointer, float* destinationPointer); // Orientation Quats are known to have 4 normalized components be between -1.0 and 1.0 // this allows us to encode each component in 16bits with great accuracy int packOrientationQuatToBytes(unsigned char* buffer, const glm::quat& quatInput); int unpackOrientationQuatFromBytes(unsigned char* buffer, glm::quat& quatOutput); // Ratios need the be highly accurate when less than 10, but not very accurate above 10, and they // are never greater than 1000 to 1, this allows us to encode each component in 16bits int packFloatRatioToTwoByte(unsigned char* buffer, float ratio); int unpackFloatRatioFromTwoByte(unsigned char* buffer, float& ratio); // Near/Far Clip values need the be highly accurate when less than 10, but only integer accuracy above 10 and // they are never greater than 16,000, this allows us to encode each component in 16bits int packClipValueToTwoByte(unsigned char* buffer, float clipValue); int unpackClipValueFromTwoByte(unsigned char* buffer, float& clipValue); // Positive floats that don't need to be very precise int packFloatToByte(unsigned char* buffer, float value, float scaleBy); int unpackFloatFromByte(unsigned char* buffer, float& value, float scaleBy); // Allows sending of fixed-point numbers: radix 1 makes 15.1 number, radix 8 makes 8.8 number, etc int packFloatScalarToSignedTwoByteFixed(unsigned char* buffer, float scalar, int radix); int unpackFloatScalarFromSignedTwoByteFixed(int16_t* byteFixedPointer, float* destinationPointer, int radix); // A convenience for sending vec3's as fixed-poimt floats int packFloatVec3ToSignedTwoByteFixed(unsigned char* destBuffer, const glm::vec3& srcVector, int radix); int unpackFloatVec3FromSignedTwoByteFixed(unsigned char* sourceBuffer, glm::vec3& destination, int radix); #endif /* defined(__hifi__SharedUtil__) */