diff --git a/indra/llcharacter/llcharacter.cpp b/indra/llcharacter/llcharacter.cpp
index 6633c6531..dcdfe074e 100644
--- a/indra/llcharacter/llcharacter.cpp
+++ b/indra/llcharacter/llcharacter.cpp
@@ -55,7 +55,8 @@ LLCharacter::LLCharacter()
mPreferredPelvisHeight( 0.f ),
mSex( SEX_FEMALE ),
mAppearanceSerialNum( 0 ),
- mSkeletonSerialNum( 0 )
+ mSkeletonSerialNum( 0 ),
+ mInAppearance( false )
{
mMotionController.setCharacter( this );
sInstances.push_back(this);
diff --git a/indra/llcharacter/llcharacter.h b/indra/llcharacter/llcharacter.h
index 011278888..a7d9d348e 100644
--- a/indra/llcharacter/llcharacter.h
+++ b/indra/llcharacter/llcharacter.h
@@ -253,6 +253,10 @@ public:
ESex getSex() { return mSex; }
void setSex( ESex sex ) { mSex = sex; }
+ // set appearance flag
+ void setAppearanceFlag( bool flag ) { mInAppearance = flag; }
+ bool getAppearanceFlag() { return mInAppearance; }
+
U32 getAppearanceSerialNum() const { return mAppearanceSerialNum; }
void setAppearanceSerialNum( U32 num ) { mAppearanceSerialNum = num; }
@@ -272,7 +276,7 @@ protected:
U32 mAppearanceSerialNum;
U32 mSkeletonSerialNum;
LLAnimPauseRequest mPauseRequest;
-
+ BOOL mInAppearance;
private:
// visual parameter stuff
diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt
index 4ae918fa7..f464a5ea0 100644
--- a/indra/newview/CMakeLists.txt
+++ b/indra/newview/CMakeLists.txt
@@ -64,6 +64,10 @@ include_directories(
)
set(viewer_SOURCE_FILES
+ dhparam.cpp
+ dsaparam.cpp
+ emerald.cpp
+ emeraldboobutils.cpp
dofloaterhex.cpp
dohexeditor.cpp
floatersculptpreview.cpp
@@ -509,6 +513,8 @@ set(viewer_HEADER_FILES
CMakeLists.txt
ViewerInstall.cmake
+ emerald.h
+ emeraldboobutils.h
dofloaterhex.h
dohexeditor.h
floatersculptpreview.h
diff --git a/indra/newview/app_settings/client_definitions.xml b/indra/newview/app_settings/client_definitions.xml
new file mode 100644
index 000000000..004c63002
--- /dev/null
+++ b/indra/newview/app_settings/client_definitions.xml
@@ -0,0 +1,647 @@
+
+
+
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml
index 11a7afb9a..291e08e46 100644
--- a/indra/newview/app_settings/settings.xml
+++ b/indra/newview/app_settings/settings.xml
@@ -114,6 +114,94 @@
0
+ EmeraldBoobMass
+
+ Comment
+ Mass of boobs.
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 54.0
+
+ EmeraldBoobHardness
+
+ Comment
+ Hardness (dampening) of boobs.
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 51
+
+ EmeraldBreastPhysicsToggle
+
+ Comment
+ Enables/Disables breast physics
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 1
+
+ EmeraldBreastSportsBra
+
+ Comment
+ allows disabling the physics for 1 av, in case their outfit looks wrong with it on
+ Persist
+ 1
+ Type
+ Boolean
+ Value
+ 0
+
+ EmeraldBoobVelMax
+
+ Comment
+ Max amount of velocity boobs can have
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 64
+
+ EmeraldBoobFriction
+
+ Comment
+ Internal friction (brings boobs to rest). Shouldn't ever be above 1.
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 80
+
+ EmeraldBoobVelMin
+
+ Comment
+ Friction Fraction of FPS (used to keep friction uniform through FPS change).
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 24
+
+ EmeraldBoobXYInfluence
+
+ Comment
+ Amount of influence along the X and Y planes.
+ Persist
+ 1
+ Type
+ F32
+ Value
+ 0.1
+
AscentCmdLine
Comment
diff --git a/indra/newview/dhparam.cpp b/indra/newview/dhparam.cpp
new file mode 100644
index 000000000..917eb714d
--- /dev/null
+++ b/indra/newview/dhparam.cpp
@@ -0,0 +1,42 @@
+/* Generated using openssl */
+#include "llviewerprecompiledheaders.h"
+#include
+
+DH *get_dh2048()
+ {
+ static unsigned char dh2048_p[]={
+ 0xAC,0x31,0xAA,0xFD,0x76,0x1B,0x47,0x24,0x99,0x6D,0xF8,0xD5,
+ 0x5B,0x4B,0xD1,0x7E,0xF9,0x1A,0x41,0xF6,0x29,0xCC,0xA9,0x02,
+ 0x6B,0xED,0xFD,0xC9,0x37,0xCE,0xF6,0x11,0x78,0x6F,0x37,0x38,
+ 0x7D,0x49,0x3F,0x78,0x36,0x83,0x0A,0x6F,0xBA,0x6F,0x74,0xD9,
+ 0xB1,0xC1,0xC4,0x5A,0x7D,0x84,0x26,0x56,0x8B,0x53,0xF4,0xFE,
+ 0xD1,0x34,0xF1,0xE0,0x08,0x65,0xA6,0xFD,0xDB,0x5D,0xAC,0x14,
+ 0xCD,0xC9,0x7E,0x79,0xE9,0x3B,0xAF,0x92,0xC7,0x4D,0x91,0x15,
+ 0x0B,0x1E,0x2F,0x0A,0x56,0x4E,0x0D,0x3A,0x4D,0x9E,0xB0,0xB5,
+ 0xFC,0x0D,0xB1,0x55,0x40,0xC6,0x30,0x99,0xCD,0xE8,0x7E,0x72,
+ 0x08,0x93,0x9C,0x7F,0x55,0x23,0x27,0x09,0xF4,0x50,0xF2,0x96,
+ 0xB5,0x30,0x35,0x6A,0x99,0x4C,0xD6,0x85,0x72,0x8D,0x9C,0x19,
+ 0x70,0x9A,0x77,0x52,0xE8,0x33,0x03,0x7A,0x00,0xDA,0xFE,0xD7,
+ 0x98,0xD0,0x7B,0x26,0xBA,0xD7,0xFF,0xD1,0x49,0x61,0x27,0x3E,
+ 0xFC,0x12,0x81,0xC9,0xB0,0xAF,0x34,0x14,0x97,0x66,0xFB,0xEF,
+ 0xD3,0xFE,0xC9,0x01,0x25,0xEC,0xF4,0xE8,0xA8,0xD8,0x21,0x45,
+ 0x20,0x6F,0xFC,0xA8,0xB3,0xCE,0xCF,0x0D,0xA1,0x14,0xCC,0x38,
+ 0x81,0x74,0x6A,0x5E,0x36,0x09,0x1D,0xBE,0x4C,0x08,0x52,0x5E,
+ 0xC2,0x5F,0xA4,0x48,0x3A,0x71,0x85,0xF2,0x97,0x32,0xEC,0x3B,
+ 0xFB,0x1B,0x9A,0x8A,0x4B,0x20,0x32,0xFE,0x6A,0x94,0x4C,0x02,
+ 0xB2,0xD7,0xC3,0x1B,0xF8,0x90,0x54,0x76,0x70,0x49,0x81,0x86,
+ 0x30,0x12,0xD2,0x91,0xF0,0xFD,0x1B,0x53,0x2E,0x60,0x13,0x78,
+ 0x8B,0x3F,0x1B,0x13,
+ };
+ static unsigned char dh2048_g[]={
+ 0x05,
+ };
+ DH *dh;
+
+ if ((dh=DH_new()) == NULL) return(NULL);
+ dh->p=BN_bin2bn(dh2048_p,sizeof(dh2048_p),NULL);
+ dh->g=BN_bin2bn(dh2048_g,sizeof(dh2048_g),NULL);
+ if ((dh->p == NULL) || (dh->g == NULL))
+ { DH_free(dh); return(NULL); }
+ return(dh);
+ }
diff --git a/indra/newview/dsaparam.cpp b/indra/newview/dsaparam.cpp
new file mode 100644
index 000000000..e4c89d40e
--- /dev/null
+++ b/indra/newview/dsaparam.cpp
@@ -0,0 +1,69 @@
+/* Generated using openssl */
+#include "llviewerprecompiledheaders.h"
+#include
+
+static unsigned char dsa2048_p[]={
+ 0xD4,0x63,0x93,0xFA,0x69,0x87,0xDB,0x60,0x68,0xFB,0xCC,0x8F,
+ 0x55,0x85,0x7A,0xAC,0xAD,0x1F,0x8E,0xF0,0x2C,0x62,0x2F,0xE6,
+ 0xA6,0xA4,0xF3,0x57,0x42,0xDC,0xF0,0xE0,0x0E,0xC6,0x67,0x01,
+ 0x95,0x22,0x6F,0x03,0x00,0x2A,0xB4,0xBF,0x62,0x6D,0xA1,0xBD,
+ 0xB7,0x10,0x81,0xB4,0x20,0x1C,0x7D,0x41,0x75,0xCE,0x0F,0xCF,
+ 0x9D,0x03,0xEC,0xE6,0x7E,0xBC,0x76,0x97,0xBC,0x5C,0x70,0xFE,
+ 0xD5,0x64,0x15,0x20,0xD8,0xA8,0x25,0x73,0xD4,0xA2,0x77,0x99,
+ 0xC7,0x3B,0xF7,0x4E,0x20,0x40,0x43,0xD7,0x7C,0xFD,0xBC,0x2F,
+ 0x75,0xB5,0x18,0xA3,0x8C,0x85,0x79,0x86,0x53,0x62,0x73,0xBA,
+ 0x66,0x73,0xE2,0x48,0x15,0xAF,0x04,0x65,0xE2,0x4D,0x15,0x47,
+ 0x74,0x33,0x79,0xAE,0xBF,0x90,0xC0,0xF7,0x2F,0x04,0xFB,0xEE,
+ 0x29,0xEC,0x42,0xC7,0x36,0x14,0xAC,0xB2,0xBC,0xE1,0x71,0x13,
+ 0x65,0xBA,0x0D,0x61,0x11,0x89,0x49,0x41,0x5D,0xCC,0xE2,0x72,
+ 0x7B,0x93,0xF2,0x2E,0xD1,0x23,0x37,0xF9,0xFF,0x55,0x59,0xF6,
+ 0x41,0x78,0x87,0xC9,0xCD,0x95,0xD2,0xE5,0x1B,0x3A,0x25,0x7A,
+ 0xD8,0x16,0x2F,0x58,0xFE,0x3B,0xD5,0xB1,0x59,0x63,0x3C,0x90,
+ 0xA0,0xBF,0xA0,0x21,0x54,0xB0,0xB0,0x3F,0x9D,0xC6,0xB5,0x31,
+ 0xBA,0x86,0xDC,0x86,0x41,0xB7,0xBA,0xCE,0x58,0x09,0x8B,0xD9,
+ 0xD4,0xF1,0xD2,0x3B,0x5F,0x87,0xEE,0x66,0xFD,0x77,0x8C,0x2C,
+ 0x66,0x3E,0xC9,0xDA,0x3E,0x2A,0x38,0x03,0x23,0x71,0xC9,0x04,
+ 0x3E,0x9D,0x18,0x7F,0xBB,0x82,0x21,0x8E,0x5F,0xF0,0xAF,0xC8,
+ 0x08,0x2D,0xA6,0x3F,
+ };
+static unsigned char dsa2048_q[]={
+ 0xAE,0xCA,0x67,0x69,0x21,0x7A,0xE1,0x9B,0x64,0x74,0xED,0x58,
+ 0xF0,0x28,0xE0,0x45,0x2B,0x39,0xBC,0x79,
+ };
+static unsigned char dsa2048_g[]={
+ 0x51,0x1D,0xB0,0xF6,0x4E,0x8B,0xAF,0x1C,0x59,0x71,0x62,0x3C,
+ 0xC3,0xE2,0x44,0x35,0xCE,0x11,0xB4,0x49,0x04,0x41,0xA1,0x1C,
+ 0x22,0x59,0x47,0x8C,0x70,0x1D,0xA1,0x0C,0x51,0xFE,0x86,0x43,
+ 0x7B,0x75,0x5C,0xB7,0x68,0xA5,0xBE,0x81,0x9C,0x6F,0x6D,0x32,
+ 0x03,0xB0,0x28,0xA4,0x6B,0x5B,0x37,0xC3,0x35,0xCF,0xBD,0x92,
+ 0xC3,0x66,0x2E,0xAB,0xB4,0x13,0xEC,0x23,0xA3,0xE3,0x09,0x4E,
+ 0x47,0x7D,0xA5,0x90,0x33,0x80,0x5D,0x68,0xD6,0x39,0x54,0xBE,
+ 0x35,0xB0,0x61,0x5B,0x96,0x63,0x05,0x67,0xB7,0x3C,0x21,0x17,
+ 0x37,0x50,0x17,0x78,0xEA,0xC0,0x10,0x73,0xDF,0xE2,0x70,0x19,
+ 0x17,0xF7,0x11,0x82,0x73,0xDB,0xFF,0x3E,0x8D,0x98,0x2F,0x2F,
+ 0xA2,0x12,0xC3,0xB4,0x08,0xB2,0x2C,0x5B,0xA3,0x51,0xAA,0x7F,
+ 0x3D,0xE0,0x74,0x39,0xE5,0xAF,0x81,0x32,0xF8,0x45,0x75,0x11,
+ 0x35,0xD9,0x90,0xA1,0xA3,0x91,0x1A,0xEE,0xE9,0xAC,0x97,0x30,
+ 0x4C,0xD5,0x5B,0x38,0x49,0x12,0x3B,0xCC,0x0C,0x84,0xA2,0x59,
+ 0x78,0xB4,0xFD,0x46,0xAC,0x49,0x43,0x08,0xDB,0xF4,0x23,0xFF,
+ 0x23,0xF8,0x9A,0xFD,0x15,0xAF,0x6B,0x81,0xCE,0x15,0x22,0xEF,
+ 0x09,0x64,0x0A,0x1F,0x4D,0x6B,0xF1,0x9F,0x16,0x00,0x3E,0xE8,
+ 0xFC,0x9A,0x24,0x58,0x1C,0xB4,0x5F,0x56,0x3E,0x83,0x8C,0x0C,
+ 0x51,0x43,0x72,0x25,0xA8,0x1D,0x08,0x30,0x7E,0x17,0xC8,0xD6,
+ 0x66,0x57,0x0C,0x59,0x76,0xE4,0xA6,0x0C,0x05,0xA8,0x60,0x1D,
+ 0xA4,0x8F,0xBC,0xC4,0x67,0x55,0x0E,0x81,0x8F,0x66,0xED,0x1B,
+ 0x84,0xCD,0x02,0x9F,
+ };
+
+DSA *get_dsa2048()
+ {
+ DSA *dsa;
+
+ if ((dsa=DSA_new()) == NULL) return(NULL);
+ dsa->p=BN_bin2bn(dsa2048_p,sizeof(dsa2048_p),NULL);
+ dsa->q=BN_bin2bn(dsa2048_q,sizeof(dsa2048_q),NULL);
+ dsa->g=BN_bin2bn(dsa2048_g,sizeof(dsa2048_g),NULL);
+ if ((dsa->p == NULL) || (dsa->q == NULL) || (dsa->g == NULL))
+ { DSA_free(dsa); return(NULL); }
+ return(dsa);
+ }
\ No newline at end of file
diff --git a/indra/newview/emerald.cpp b/indra/newview/emerald.cpp
new file mode 100644
index 000000000..1d89381cf
--- /dev/null
+++ b/indra/newview/emerald.cpp
@@ -0,0 +1,593 @@
+// Copyright (c)2009 Thomas Shikami
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+#include "llviewerprecompiledheaders.h"
+#include "emerald.h"
+#include
+#include
+
+#include
+#include
+#include
+
+//-- Ascii85 encoder and decoder
+
+typedef unsigned int U32;
+
+static void encodeU32(unsigned int in, char *out)
+{
+ out[4] = char(in % 85) + char(33);
+ in /= 85;
+ out[3] = char(in % 85) + char(33);
+ in /= 85;
+ out[2] = char(in % 85) + char(33);
+ in /= 85;
+ out[1] = char(in % 85) + char(33);
+ in /= 85;
+ out[0] = char(in % 85) + char(33);
+}
+
+static unsigned int decodeU32(const char *in)
+{
+ U32 out;
+
+ out = U32(in[0] - 33);
+ out *= 85;
+ out += U32(in[1] - 33);
+ out *= 85;
+ out += U32(in[2] - 33);
+ out *= 85;
+ out += U32(in[3] - 33);
+ out *= 85;
+ out += U32(in[4] - 33);
+
+ return out;
+}
+
+// static
+std::string EAscii85::encode(const std::vector &in)
+{
+ std::ostringstream out;
+ U32 tuple;
+ int count;
+ char block[6];
+ block[5] = '\0';
+
+ out << "<~";
+
+ count = 0;
+ tuple = 0;
+ for(size_t i = 0; i < in.size(); i++)
+ {
+ tuple <<= 8;
+ tuple += in[i];
+ if(++count == 4)
+ {
+ if(tuple == 0)
+ {
+ out << "z";
+ }
+ else
+ {
+ encodeU32(tuple, block);
+ out << block;
+ }
+ count = 0;
+ }
+ }
+
+ switch(count)
+ {
+ case 1:
+ tuple <<= 8;
+ tuple += 255;
+ // pass through
+ case 2:
+ tuple <<= 8;
+ tuple += 255;
+ // pass through
+ case 3:
+ tuple <<= 8;
+ tuple += 255;
+ }
+
+ encodeU32(tuple, block);
+
+ switch(count)
+ {
+ case 1:
+ block[2] = '\0';
+ break;
+ case 2:
+ block[3] = '\0';
+ break;
+ case 3:
+ block[4] = '\0';
+ break;
+ }
+
+ if(count > 0)
+ out << block;
+
+ out << "~>";
+
+ return out.str();
+}
+
+// static
+std::vector EAscii85::decode(const std::string &in)
+{
+ std::vector out;
+ size_t len;
+ int count = 0;
+ char block[6];
+ block[5] = '\0';
+ U32 tuple;
+
+ // approximate length
+ len = in.length() / 5 * 4;
+
+ out.clear();
+
+ if(in.length() < 4) return out;
+
+ std::string::const_iterator i = in.begin();
+
+ if(*i != '<') return out;
+ i++;
+ if(*i != '~') return out;
+ i++;
+
+ out.reserve(len);
+
+ for(; i != in.end(); i++)
+ {
+ char c = *i;
+
+ if(c >= '!' && c < 'v')
+ {
+ block[count++] = c;
+ }
+
+ switch(c)
+ {
+ case 'z':
+ if(count == 1)
+ {
+ for(count = 0; count < 4; count++)
+ out.push_back(0);
+ count = 0;
+ }
+ break;
+ case '~':
+ if(count > 1)
+ {
+ switch(count)
+ {
+ case 2:
+ block[2] = 'u';
+ case 3:
+ block[3] = 'u';
+ case 4:
+ block[4] = 'u';
+ }
+ tuple = decodeU32(block);
+ for(;count > 1; count--)
+ {
+ out.push_back(char(tuple >> 24));
+ tuple <<= 8;
+ }
+ count = 0;
+ }
+ }
+
+ if(count == 5)
+ {
+ tuple = decodeU32(block);
+ for(count = 0; count < 4; count++)
+ {
+ out.push_back(char(tuple >> 24));
+ tuple <<= 8;
+ }
+ count = 0;
+ }
+ }
+
+ return out;
+}
+
+//-- AES wrapper
+
+class EAESEncrypt::EncryptImpl {
+public:
+ EncryptImpl(const unsigned char *key, const unsigned char *iv);
+ ~EncryptImpl();
+
+ std::vector encrypt(const std::string &in);
+
+ EVP_CIPHER_CTX ctx;
+};
+
+EAESEncrypt::EAESEncrypt(const unsigned char *key, const unsigned char *iv)
+{
+ mEncryptImpl = new EAESEncrypt::EncryptImpl(key, iv);
+}
+
+EAESEncrypt::EAESEncrypt(const std::vector &key, const std::vector &iv)
+{
+ mEncryptImpl = new EAESEncrypt::EncryptImpl(&key[0], &iv[0]);
+}
+
+EAESEncrypt::~EAESEncrypt()
+{
+ delete mEncryptImpl;
+}
+
+std::vector EAESEncrypt::encrypt(const std::string &in)
+{
+ return mEncryptImpl->encrypt(in);
+}
+
+EAESEncrypt::EncryptImpl::EncryptImpl(const unsigned char *key, const unsigned char *iv)
+{
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_EncryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
+}
+
+EAESEncrypt::EncryptImpl::~EncryptImpl()
+{
+ EVP_CIPHER_CTX_cleanup(&ctx);
+}
+
+std::vector EAESEncrypt::EncryptImpl::encrypt(const std::string &in)
+{
+ std::vector out;
+ int outlen;
+ int tmplen;
+
+ out.resize(in.length() + 32);
+
+ EVP_EncryptUpdate(&ctx, &out[0], &outlen, reinterpret_cast(in.c_str()), in.length());
+ EVP_EncryptFinal_ex(&ctx, &out[outlen], &tmplen);
+
+ out.resize(outlen + tmplen);
+
+ return out;
+}
+
+class EAESDecrypt::DecryptImpl {
+public:
+ DecryptImpl(const unsigned char *key, const unsigned char *iv);
+ ~DecryptImpl();
+
+ std::string decrypt(const std::vector &in);
+
+ EVP_CIPHER_CTX ctx;
+};
+
+EAESDecrypt::EAESDecrypt(const unsigned char *key, const unsigned char *iv)
+{
+ mDecryptImpl = new EAESDecrypt::DecryptImpl(key, iv);
+}
+
+EAESDecrypt::EAESDecrypt(const std::vector &key, const std::vector &iv)
+{
+ mDecryptImpl = new EAESDecrypt::DecryptImpl(&key[0], &iv[0]);
+}
+
+EAESDecrypt::~EAESDecrypt()
+{
+ delete mDecryptImpl;
+}
+
+EAESDecrypt::DecryptImpl::DecryptImpl(const unsigned char *key, const unsigned char *iv)
+{
+ EVP_CIPHER_CTX_init(&ctx);
+ EVP_DecryptInit_ex(&ctx, EVP_aes_128_cbc(), NULL, key, iv);
+}
+
+EAESDecrypt::DecryptImpl::~DecryptImpl()
+{
+ EVP_CIPHER_CTX_cleanup(&ctx);
+}
+
+std::string EAESDecrypt::decrypt(const std::vector &in)
+{
+ return mDecryptImpl->decrypt(in);
+}
+
+std::string EAESDecrypt::DecryptImpl::decrypt(const std::vector &in)
+{
+ std::vector out;
+ int outlen;
+ int tmplen;
+
+ if(in.size() == 0) return "";
+
+ out.resize(in.size() + 32);
+
+ EVP_DecryptUpdate(&ctx, &out[0], &outlen, &in[0], in.size());
+ EVP_DecryptFinal_ex(&ctx, &out[outlen], &tmplen);
+
+ out.resize(outlen + tmplen);
+
+ if(out.empty())
+ return "";
+
+ return std::string(reinterpret_cast(&out[0]), out.size());
+}
+
+EGenKey::EGenKey(const std::string &password, const unsigned char *salt)
+{
+ EVP_BytesToKey(EVP_aes_128_cbc(), EVP_sha1(), salt,
+ reinterpret_cast(password.c_str()), password.length(),
+ 1000, mKey, mIv);
+}
+
+EGenKey::~EGenKey()
+{
+ memset(mKey, 0, 16);
+ memset(mIv, 0, 16);
+}
+
+DH *get_dh2048();
+
+class BigNum
+{
+public:
+ BigNum(const std::vector &bin)
+ {
+ mBN = BN_bin2bn(&(bin[0]), bin.size(), NULL);
+ }
+
+ BigNum()
+ {
+ mBN = BN_new();
+ }
+
+ BigNum(const BigNum &other)
+ {
+ mBN = BN_dup(*other);
+ }
+
+ BigNum(BIGNUM *bn)
+ {
+ mBN = BN_dup(bn);
+ }
+
+ ~BigNum()
+ {
+ BN_clear_free(mBN);
+ mBN = NULL;
+ }
+
+ friend BIGNUM* operator*(const BigNum&);
+
+ BigNum& operator=(const std::vector &bin)
+ {
+ mBN = BN_bin2bn(&(bin[0]), bin.size(), mBN);
+ return *this;
+ }
+
+ BigNum& operator=(const BigNum& other)
+ {
+ BN_copy(mBN, *other);
+ return *this;
+ }
+
+ void to(std::vector &dest)
+ {
+ dest.resize(BN_num_bytes(mBN));
+ BN_bn2bin(mBN, &(dest[0]));
+ }
+
+ BIGNUM* to(BIGNUM *ret)
+ {
+ return BN_copy(ret, mBN);
+ }
+
+ BIGNUM* dup()
+ {
+ return BN_dup(mBN);
+ }
+
+ static BIGNUM* dup(const std::vector &bin)
+ {
+ return BN_bin2bn(&(bin[0]), bin.size(), NULL);
+ }
+
+private:
+ BIGNUM *mBN;
+};
+
+BIGNUM* operator*(const BigNum& o) { return o.mBN; }
+
+class EDH::DHImpl
+{
+public:
+ DH *mDH;
+};
+
+EDH::EDH(const std::vector &priv_key)
+{
+ mDHImpl = new DHImpl();
+
+ mDHImpl->mDH = get_dh2048();
+ mDHImpl->mDH->priv_key = BigNum::dup(priv_key);
+
+ DH_generate_key(mDHImpl->mDH);
+}
+
+EDH::EDH()
+{
+ mDHImpl = new DHImpl();
+
+ mDHImpl->mDH = get_dh2048();
+
+ DH_generate_key(mDHImpl->mDH);
+}
+
+EDH::~EDH()
+{
+ if(mDHImpl)
+ {
+ if(mDHImpl->mDH)
+ {
+ mDHImpl->mDH->priv_key = NULL;
+ mDHImpl->mDH->pub_key = NULL;
+ DH_free(mDHImpl->mDH);
+ mDHImpl->mDH = NULL;
+ }
+ delete mDHImpl;
+ mDHImpl = NULL;
+ }
+}
+
+void EDH::secretTo(std::vector &secret)
+{
+ BigNum(mDHImpl->mDH->priv_key).to(secret);
+}
+
+void EDH::publicTo(std::vector &pub)
+{
+ BigNum(mDHImpl->mDH->pub_key).to(pub);
+}
+
+std::vector EDH::computeKey(const std::vector &other_pub)
+{
+ std::vector temp;
+ BigNum pub(other_pub);
+ temp.resize(DH_size(mDHImpl->mDH));
+
+ DH_compute_key(&(temp[0]), *pub, mDHImpl->mDH);
+
+ return temp;
+}
+
+DSA *get_dsa2048();
+
+class EDSA::DSAImpl
+{
+public:
+ DSA *mDSA;
+};
+
+EDSA::EDSA()
+{
+ mDSAImpl = new DSAImpl();
+ mDSAImpl->mDSA = get_dsa2048();
+}
+
+EDSA::EDSA(const std::vector &secret)
+{
+ mDSAImpl = new DSAImpl();
+
+ const unsigned char *buf = &(secret[0]);
+
+ mDSAImpl->mDSA = d2i_DSAPrivateKey(NULL, &buf, secret.size());
+}
+
+std::vector EDSA::generateSecret()
+{
+ DSA_generate_key(mDSAImpl->mDSA);
+
+ std::vector temp;
+
+ int size = i2d_DSAPrivateKey(mDSAImpl->mDSA, NULL);
+
+ temp.resize(size);
+
+ unsigned char *buf = &(temp[0]);
+
+ i2d_DSAPrivateKey(mDSAImpl->mDSA, &buf);
+
+ return temp;
+}
+
+std::vector EDSA::getPublic()
+{
+ std::vector temp;
+
+ mDSAImpl->mDSA->write_params = 0;
+
+ int size = i2d_DSAPublicKey(mDSAImpl->mDSA, NULL);
+
+ temp.resize(size);
+
+ unsigned char *buf = &(temp[0]);
+
+ i2d_DSAPublicKey(mDSAImpl->mDSA, &buf);
+
+ return temp;
+}
+
+void EDSA::setPublic(const std::vector &pub)
+{
+ const unsigned char *buf = &(pub[0]);
+
+ d2i_DSAPublicKey(&mDSAImpl->mDSA, &buf, pub.size());
+}
+
+bool EDSA::verify(const std::vector &dgst, const std::vector &sig)
+{
+ bool result = false;
+
+ if(DSA_verify(0, &(dgst[0]), dgst.size(), &(sig[0]), sig.size(), mDSAImpl->mDSA) == 1)
+ {
+ result = true;
+ }
+
+ return result;
+}
+
+// static
+bool EDSA::verify(const std::vector &dgst, const std::vector &sig, const std::vector &pub)
+{
+ const unsigned char *buf = &(pub[0]);
+ DSA *dsa;
+ bool result = false;
+
+ dsa = get_dsa2048();
+
+ d2i_DSAPublicKey(&dsa, &buf, pub.size());
+
+ if(DSA_verify(0, &(dgst[0]), dgst.size(), &(sig[0]), sig.size(), dsa) == 1)
+ {
+ result = true;
+ }
+
+ DSA_free(dsa);
+
+ return result;
+}
+
+std::vector EDSA::sign(const std::vector &dgst)
+{
+ std::vector sig;
+ unsigned int size = DSA_size(mDSAImpl->mDSA);
+
+ sig.resize(size);
+
+ DSA_sign(0, &(dgst[0]), dgst.size(), &(sig[0]), &size, mDSAImpl->mDSA);
+
+ sig.resize(size);
+
+ return sig;
+}
+
+EDSA::~EDSA()
+{
+ delete mDSAImpl;
+ mDSAImpl = NULL;
+}
\ No newline at end of file
diff --git a/indra/newview/emerald.h b/indra/newview/emerald.h
new file mode 100644
index 000000000..a4d2126c6
--- /dev/null
+++ b/indra/newview/emerald.h
@@ -0,0 +1,107 @@
+// Copyright (c)2009 Thomas Shikami
+//
+// Permission to use, copy, modify, and/or distribute this software for any
+// purpose with or without fee is hereby granted, provided that the above
+// copyright notice and this permission notice appear in all copies.
+//
+// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+#include
+#include
+
+class EAscii85 {
+private:
+ EAscii85() { }
+public:
+ static std::string encode(const std::vector &in);
+ static std::vector decode(const std::string &in);
+};
+
+class EAESEncrypt {
+public:
+ EAESEncrypt(const unsigned char *key, const unsigned char *iv);
+ EAESEncrypt(const std::vector &key, const std::vector &iv);
+ ~EAESEncrypt();
+
+ std::vector encrypt(const std::string &in);
+
+private:
+ EAESEncrypt(const EAESEncrypt&) {}
+
+ class EncryptImpl;
+
+ EncryptImpl *mEncryptImpl;
+};
+
+class EAESDecrypt {
+public:
+ EAESDecrypt(const unsigned char *key, const unsigned char *iv);
+ EAESDecrypt(const std::vector &key, const std::vector &iv);
+ ~EAESDecrypt();
+
+ std::string decrypt(const std::vector &in);
+
+private:
+ EAESDecrypt(const EAESDecrypt&) {}
+ class DecryptImpl;
+
+ DecryptImpl *mDecryptImpl;
+};
+
+class EGenKey {
+public:
+ EGenKey(const std::string &password, const unsigned char *salt = 0);
+ ~EGenKey();
+
+ const unsigned char *key() const { return mKey; }
+ const unsigned char *iv() const { return mIv; }
+
+private:
+ unsigned char mKey[16];
+ unsigned char mIv[16];
+};
+
+class EDH {
+public:
+ EDH(const std::vector &secret);
+ EDH();
+ ~EDH();
+
+ void secretTo(std::vector &secret);
+ void publicTo(std::vector &pub);
+ std::vector computeKey(const std::vector &other_pub);
+
+private:
+ EDH(const EDH&) {}
+
+ class DHImpl;
+
+ DHImpl *mDHImpl;
+};
+
+class EDSA {
+public:
+ EDSA(const std::vector &secret);
+ EDSA();
+ ~EDSA();
+
+ std::vector getPublic();
+ void setPublic(const std::vector &pub);
+ std::vector generateSecret();
+ static bool verify(const std::vector &dgst, const std::vector &sig, const std::vector &pub);
+ bool verify(const std::vector &dgst, const std::vector &sig);
+ std::vector sign(const std::vector &dgst);
+
+private:
+ EDSA(const EDSA&) {}
+
+ class DSAImpl;
+
+ DSAImpl *mDSAImpl;
+};
diff --git a/indra/newview/emeraldboobutils.cpp b/indra/newview/emeraldboobutils.cpp
new file mode 100644
index 000000000..12b784a7e
--- /dev/null
+++ b/indra/newview/emeraldboobutils.cpp
@@ -0,0 +1,189 @@
+#include "llviewerprecompiledheaders.h"
+#include "emeraldboobutils.h"
+
+std::ostream &operator<<(std::ostream &os, const EmeraldGlobalBoobConfig &v)
+{
+ os << "EmeraldBoobConfig" << std::endl;
+ os << "enabled: " << v.enabled << std::endl;
+ os << "mass: " << v.mass << std::endl;
+ os << "hardness: " << v.hardness << std::endl;
+ os << "zMax: " << v.zMax << std::endl;
+ os << "velMin: " << v.velMin << std::endl;
+ os << "velMax: " << v.velMax << std::endl;
+ os << "zInfluence: " << v.zInfluence << std::endl;
+ os << "friction: " << v.friction << std::endl;
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, const EmeraldAvatarLocalBoobConfig &v)
+{
+ os << "EmeraldAvatarLocalBoobConfig" << std::endl;
+ os << "actualBoobGrav: " << v.actualBoobGrav << std::endl;
+ os << "boobSize: " << v.boobSize << std::endl;
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, const EmeraldBoobState &v)
+{
+ os << "EmeraldBoobState" << std::endl;
+ os << "boobGrav: " << v.boobGrav << std::endl;
+ os << "chestPosition: " << v.chestPosition << std::endl;
+ os << "chestRotation: " << v.chestRotation << std::endl;
+ os << "elapsedTime: " << v.elapsedTime << std::endl;
+ os << "frameDuration: " << v.frameDuration << std::endl;
+ os << "chestDisplacement: " << v.chestDisplacement << std::endl;
+ os << "localChestDisplacement: " << v.localChestDisplacement << std::endl;
+ os << "displacementForce: " << v.displacementForce << std::endl;
+ os << "mysteryValue: " << v.mysteryValue << std::endl;
+ os << "Number of bounceStates: " << v.bounceStates.size() << std::endl;
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, const EmeraldBoobInputs &v)
+{
+ os << "EmeraldBoobInputs" << std::endl;
+ os << "chestPosition: " << v.chestPosition << std::endl;
+ os << "chestRotation: " << v.chestRotation << std::endl;
+ os << "elapsedTime: " << v.elapsedTime << std::endl;
+ os << "appearanceFlag: " << v.appearanceFlag << std::endl;
+ os << "appearanceAnimating: " << v.appearanceAnimating << std::endl;
+ return os;
+}
+
+std::ostream &operator<<(std::ostream &os, const EmeraldBoobBounceState &v)
+{
+ os << "EmeraldBoobBounceState" << std::endl;
+ os << "bounceStart: " << v.bounceStart << std::endl;
+ os << "bounceStartAmplitude: " << v.bounceStartAmplitude << std::endl;
+ os << "bounceStartFrameDuration: " << v.bounceStartFrameDuration << std::endl;
+ return os;
+}
+
+F32 EmeraldBoobUtils::convertMass(F32 displayMass)
+{ return displayMass/100.f*150.f; };
+
+F32 EmeraldBoobUtils::convertHardness(F32 displayHardness)
+{ return displayHardness/100.f*50; };
+
+F32 EmeraldBoobUtils::convertVelMax(F32 displayVelMax)
+{ return displayVelMax/100.f*0.01f; };
+
+F32 EmeraldBoobUtils::convertFriction(F32 displayFriction)
+{ return displayFriction/100.f*1.0f; };
+
+F32 EmeraldBoobUtils::convertVelMin(F32 displayVelMin)
+{ return displayVelMin/100.f; };
+
+EmeraldBoobState EmeraldBoobUtils::idleUpdate(const EmeraldGlobalBoobConfig &config, const EmeraldAvatarLocalBoobConfig &localConfig, const EmeraldBoobState &oldState, const EmeraldBoobInputs &inputs)
+{
+ EmeraldBoobState newState;
+ F32 avatarLocalMass = 0.0f;
+ F32 partMod = 1.f;
+
+ if(!config.enabled || inputs.appearanceFlag || inputs.appearanceAnimating)
+ return newState;
+
+ if(inputs.type == 0)
+ {
+ newState.boobGrav = localConfig.actualBoobGrav;
+ avatarLocalMass = (llclamp(localConfig.boobSize, 0.0f, 0.5f) / 0.5f);
+ }
+ if(inputs.type == 1)
+ {
+ newState.boobGrav = localConfig.actualButtGrav;
+ partMod = 1.5f;
+ avatarLocalMass = llclamp(localConfig.actualButtGrav, 0.0f, 0.5f) / 0.5f;
+ }
+ if(inputs.type == 2)
+ {
+ newState.boobGrav = localConfig.actualFatGrav;
+ partMod = 1.3f;
+ avatarLocalMass = localConfig.actualFatGrav;
+ }
+
+
+ newState.elapsedTime = inputs.elapsedTime;
+ // seemed to create incorrect amounts of velocity when FPS varied
+ newState.frameDuration = inputs.elapsedTime - oldState.elapsedTime;
+ newState.chestPosition = inputs.chestPosition;
+ newState.chestRotation = inputs.chestRotation;
+ newState.chestDisplacement = inputs.chestPosition - oldState.chestPosition;
+ newState.localChestDisplacement = newState.chestDisplacement * ~inputs.chestRotation;
+
+
+ std::list bounceStates = oldState.bounceStates;
+
+ if(fabs(newState.localChestDisplacement.length()) > 0.f)
+ {
+ F32 boobVel = 0.f;
+ boobVel = newState.localChestDisplacement.mV[VZ];
+ boobVel += newState.localChestDisplacement[VX] * config.XYInfluence;
+ boobVel += newState.localChestDisplacement.mV[VY] * config.XYInfluence;
+ boobVel *= newState.frameDuration * 0.3f * 100.f;
+ boobVel = llclamp(boobVel, -config.velMax, config.velMax);
+ if(fabs(boobVel) <= config.velMax * config.velMin * newState.frameDuration * 100.f)
+ boobVel = 0.0f;
+ else
+ {
+ EmeraldBoobBounceState bounceState;
+ bounceState.bounceStart = inputs.elapsedTime;
+ bounceState.bounceStartFrameDuration = newState.frameDuration;
+ bounceState.bounceStartAmplitude = boobVel;
+ bounceState.bounceStartAmplitude *= avatarLocalMass;
+ bounceState.bounceStartAmplitude *= config.mass;
+ bounceStates.push_front(bounceState);
+ }
+ }
+
+ /*if(fabs(newState.localChestDisplacement.length()) >= 0.f) {
+ LLVector3 displacementInfluence = newState.localChestDisplacement;
+ displacementInfluence *= LLVector3(0.3f, 0.3f, 1.0f);
+ F32 clampedDisplacementInfluenceLength = llclamp(displacementInfluence.length(), 0.0f, config.velMax);
+ if(displacementInfluence[VZ]<0.f)
+ clampedDisplacementInfluenceLength= -clampedDisplacementInfluenceLength;
+ EmeraldBoobBounceState bounceState;
+ bounceState.bounceStart = inputs.elapsedTime;
+ bounceState.bounceStartFrameDuration = newState.frameDuration;
+ bounceState.bounceStartAmplitude = clampedDisplacementInfluenceLength;
+ if(fabs(bounceState.bounceStartAmplitude) < config.velMin * config.velMax)
+ bounceState.bounceStartAmplitude = 0.0f;
+ else
+ {
+ bounceState.bounceStartAmplitude *= config.mass;
+ bounceStates.push_front(bounceState);
+ }
+ }
+ */
+
+ F32 totalNewAmplitude = 0.0f;
+ //std::cout << "Beginning bounce State processing at time " << inputs.elapsedTime << std::endl;
+ while(!bounceStates.empty()) {
+ EmeraldBoobBounceState bounceState = bounceStates.front();
+ //std::cout << "Now processing " << bounceState;
+ bounceStates.pop_front();
+ F32 bounceTime = newState.elapsedTime-bounceState.bounceStart;
+ F32 newAmplitude = bounceState.bounceStartAmplitude*pow(60.f*config.friction, -bounceTime)*cos(config.hardness*partMod*bounceTime);
+ if(fabs(newAmplitude) < 0.005f) {
+ newAmplitude = 0.0f;
+ } else {
+ newState.bounceStates.push_front(bounceState);
+ }
+ totalNewAmplitude+=newAmplitude;
+ }
+ //std::cout << "Total new amplitude: " << totalNewAmplitude << std::endl;
+ /*
+ if(inputs.type == 0)
+ newState.boobGrav = localConfig.actualBoobGrav + totalNewAmplitude;
+ if(inputs.type == 1)
+ newState.boobGrav = localConfig.actualButtGrav + totalNewAmplitude;
+ if(inputs.type == 2)
+ newState.boobGrav = localConfig.actualFatGrav + totalNewAmplitude;
+ */
+
+ newState.boobGrav = totalNewAmplitude;
+
+
+ newState.boobGrav = llclamp(newState.boobGrav, -1.5f, 2.0f);
+
+ return newState;
+}
\ No newline at end of file
diff --git a/indra/newview/emeraldboobutils.h b/indra/newview/emeraldboobutils.h
new file mode 100644
index 000000000..26008f9de
--- /dev/null
+++ b/indra/newview/emeraldboobutils.h
@@ -0,0 +1,197 @@
+#ifndef __emeraldboobutils_h
+#define __emeraldboobutils_h
+
+#include
+#include
+
+#include "stdtypes.h"
+#include "v3math.h"
+#include "llquaternion.h"
+
+struct EmeraldGlobalBoobConfig
+{
+ bool enabled;
+ F32 mass;
+ F32 hardness;
+ F32 zMax;
+ F32 velMin;
+ F32 velMax;
+ F32 zInfluence;
+ F32 friction;
+ F32 XYInfluence;
+
+ EmeraldGlobalBoobConfig()
+ : enabled(false),
+ mass(6.4f),
+ hardness(0.67f),
+ zMax(1.29f),
+ velMin(0.0027f*0.017f),
+ velMax(0.0027f),
+ zInfluence(0.0f),
+ friction(0.35f),
+ XYInfluence(0.3f)
+ {
+ }
+
+ bool operator==(const EmeraldGlobalBoobConfig &other) const
+ {
+ return
+ enabled == other.enabled &&
+ mass == other.mass &&
+ zMax == other.zMax &&
+ velMax == other.velMax &&
+ velMin == other.velMin &&
+ zInfluence == other.zInfluence &&
+ XYInfluence == other.XYInfluence &&
+ friction == other.friction;
+ }
+};
+
+std::ostream &operator<<(std::ostream &os, const EmeraldGlobalBoobConfig &v);
+
+struct EmeraldAvatarLocalBoobConfig
+{
+ F32 actualBoobGrav;
+ F32 actualButtGrav;
+ F32 actualFatGrav;
+ F32 boobSize;
+
+ EmeraldAvatarLocalBoobConfig()
+ : actualBoobGrav(0.0f),
+ actualButtGrav(0.0f),
+ actualFatGrav(0.0f),
+ boobSize(0.0f)
+ {
+ }
+
+ bool operator==(const EmeraldAvatarLocalBoobConfig &other) const
+ {
+ return
+ actualBoobGrav == other.actualBoobGrav &&
+ actualButtGrav == other.actualButtGrav &&
+ actualFatGrav == other.actualFatGrav &&
+ boobSize == other.boobSize;
+ }
+
+};
+
+std::ostream &operator<<(std::ostream &os, const EmeraldAvatarLocalBoobConfig &v);
+
+struct EmeraldBoobBounceState;
+
+struct EmeraldBoobState
+{
+ F32 boobGrav;
+ LLVector3 chestPosition;
+ LLQuaternion chestRotation;
+ F32 elapsedTime;
+ F32 frameDuration;
+ LLVector3 chestDisplacement;
+ LLVector3 localChestDisplacement;
+ LLVector3 displacementForce;
+ F32 mysteryValue;
+ std::list bounceStates;
+
+ EmeraldBoobState()
+ : boobGrav(0.0f),
+ chestPosition(0.0f,0.0f,0.0f),
+ chestRotation(0.0f,0.0f,0.0f,1.0f),
+ elapsedTime(0.0f),
+ frameDuration(0.0f),
+ chestDisplacement(0.0f,0.0f,0.0f),
+ localChestDisplacement(0.0f,0.0f,0.0f),
+ displacementForce(0.0f,0.0f,0.0f),
+ mysteryValue(0.0f)
+ {
+ }
+
+ bool operator==(const EmeraldBoobState &other) const
+ {
+ return
+ boobGrav == other.boobGrav &&
+ chestPosition == other.chestPosition &&
+ chestRotation == other.chestRotation &&
+ elapsedTime == other.elapsedTime &&
+ frameDuration == other.frameDuration &&
+ chestDisplacement == other.chestDisplacement &&
+ localChestDisplacement == other.localChestDisplacement &&
+ displacementForce == other.displacementForce &&
+ mysteryValue == other.mysteryValue &&
+ bounceStates == other.bounceStates;
+ }
+};
+
+std::ostream &operator<<(std::ostream &os, const EmeraldBoobState &v);
+
+struct EmeraldBoobInputs
+{
+ LLVector3 chestPosition;
+ LLQuaternion chestRotation;
+ F32 elapsedTime;
+ bool appearanceFlag;
+ bool appearanceAnimating;
+ S32 type;
+
+ EmeraldBoobInputs()
+ : chestPosition(0.0f,0.0f,0.0f),
+ chestRotation(0.0f,0.0f,0.0f,1.0f),
+ elapsedTime(0.0f),
+ appearanceFlag(false),
+ appearanceAnimating(false),
+ type(0)
+ {
+ }
+
+ bool operator==(const EmeraldBoobInputs &other) const
+ {
+ return
+ chestPosition == other.chestPosition &&
+ chestRotation == other.chestRotation &&
+ elapsedTime == other.elapsedTime &&
+ appearanceFlag == other.appearanceFlag &&
+ appearanceAnimating == other.appearanceAnimating &&
+ type == other.type;
+ }
+};
+
+std::ostream &operator<<(std::ostream &os, const EmeraldBoobInputs &v);
+
+struct EmeraldBoobBounceState
+{
+ F32 bounceStart;
+ F32 bounceStartAmplitude;
+ F32 bounceStartFrameDuration;
+
+ EmeraldBoobBounceState()
+ : bounceStart(0.0f),
+ bounceStartAmplitude(0.0f),
+ bounceStartFrameDuration(0.0f)
+ {
+ };
+
+ bool operator==(const EmeraldBoobBounceState &other) const
+ {
+ return
+ bounceStart == other.bounceStart &&
+ bounceStartAmplitude == other.bounceStartAmplitude &&
+ bounceStartFrameDuration == other.bounceStartFrameDuration;
+ }
+};
+
+std::ostream &operator<<(std::ostream &os, const EmeraldBoobBounceState &v);
+
+
+struct EmeraldBoobUtils
+{
+public:
+ static EmeraldBoobState idleUpdate(const EmeraldGlobalBoobConfig &config, const EmeraldAvatarLocalBoobConfig &localConfig, const EmeraldBoobState &oldState, const EmeraldBoobInputs &inputs);
+
+ static F32 convertMass(F32 displayMass);
+ static F32 convertHardness(F32 displayHardness);
+ static F32 convertVelMax(F32 displayVelMax);
+ static F32 convertFriction(F32 displayFriction);
+ static F32 convertVelMin(F32 displayVelMin);
+};
+
+
+#endif
diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp
index 9c9a3f706..af8e5388f 100644
--- a/indra/newview/llviewercontrol.cpp
+++ b/indra/newview/llviewercontrol.cpp
@@ -71,6 +71,7 @@
#include "llvowlsky.h"
#include "llrender.h"
#include "llfloaterchat.h"
+#include "emeraldboobutils.h"
#ifdef TOGGLE_HACKED_GODLIKE_VIEWER
BOOL gHackGodmode = FALSE;
@@ -119,6 +120,49 @@ static bool handleSetShaderChanged(const LLSD& newvalue)
return true;
}
+static bool handleAvatarBoobMassChanged(const LLSD& newvalue)
+{
+ LLVOAvatar::sBoobConfig.mass = EmeraldBoobUtils::convertMass((F32) newvalue.asReal());
+ return true;
+}
+
+static bool handleAvatarBoobHardnessChanged(const LLSD& newvalue)
+{
+ LLVOAvatar::sBoobConfig.hardness = EmeraldBoobUtils::convertHardness((F32) newvalue.asReal());
+ return true;
+}
+
+static bool handleAvatarBoobVelMaxChanged(const LLSD& newvalue)
+{
+ LLVOAvatar::sBoobConfig.velMax = EmeraldBoobUtils::convertVelMax((F32) newvalue.asReal());
+ LLVOAvatar::sBoobConfig.velMin = LLVOAvatar::sBoobConfig.velMin*LLVOAvatar::sBoobConfig.velMax;
+ return true;
+}
+
+static bool handleAvatarBoobFrictionChanged(const LLSD& newvalue)
+{
+ LLVOAvatar::sBoobConfig.friction = EmeraldBoobUtils::convertFriction((F32) newvalue.asReal());
+ return true;
+}
+
+static bool handleAvatarBoobVelMinChanged(const LLSD& newvalue)
+{
+ LLVOAvatar::sBoobConfig.velMin = EmeraldBoobUtils::convertVelMin((F32) newvalue.asReal())*LLVOAvatar::sBoobConfig.velMax;
+ return true;
+}
+
+static bool handleAvatarBoobToggleChanged(const LLSD& newvalue)
+{
+ LLVOAvatar::sBoobConfig.enabled = (BOOL) newvalue.asReal();
+ return true;
+}
+
+static bool handleAvatarBoobXYInfluence(const LLSD& newvalue)
+{
+ LLVOAvatar::sBoobConfig.XYInfluence = (F32) newvalue.asReal();
+ return true;
+}
+
static bool handleSetSelfInvisible( const LLSD& newvalue)
{
LLVOAvatar::onChangeSelfInvisible( newvalue.asBoolean() );
@@ -468,6 +512,13 @@ void settings_setup_listeners()
gSavedSettings.getControl("RenderFlexTimeFactor")->getSignal()->connect(boost::bind(&handleFlexLODChanged, _1));
gSavedSettings.getControl("ThrottleBandwidthKBPS")->getSignal()->connect(boost::bind(&handleBandwidthChanged, _1));
gSavedSettings.getControl("RenderGamma")->getSignal()->connect(boost::bind(&handleGammaChanged, _1));
+ gSavedSettings.getControl("EmeraldBoobMass")->getSignal()->connect(boost::bind(&handleAvatarBoobMassChanged, _1));
+ gSavedSettings.getControl("EmeraldBoobHardness")->getSignal()->connect(boost::bind(&handleAvatarBoobHardnessChanged, _1));
+ gSavedSettings.getControl("EmeraldBoobVelMax")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMaxChanged, _1));
+ gSavedSettings.getControl("EmeraldBoobFriction")->getSignal()->connect(boost::bind(&handleAvatarBoobFrictionChanged, _1));
+ gSavedSettings.getControl("EmeraldBoobVelMin")->getSignal()->connect(boost::bind(&handleAvatarBoobVelMinChanged, _1));
+ gSavedSettings.getControl("EmeraldBreastPhysicsToggle")->getSignal()->connect(boost::bind(&handleAvatarBoobToggleChanged, _1));
+ gSavedSettings.getControl("EmeraldBoobXYInfluence")->getSignal()->connect(boost::bind(&handleAvatarBoobXYInfluence, _1));
gSavedSettings.getControl("RenderFogRatio")->getSignal()->connect(boost::bind(&handleFogRatioChanged, _1));
gSavedSettings.getControl("RenderMaxPartCount")->getSignal()->connect(boost::bind(&handleMaxPartCountChanged, _1));
gSavedSettings.getControl("RenderDynamicLOD")->getSignal()->connect(boost::bind(&handleRenderDynamicLODChanged, _1));
diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp
index a143d7815..aabb514ac 100644
--- a/indra/newview/llvoavatar.cpp
+++ b/indra/newview/llvoavatar.cpp
@@ -86,6 +86,7 @@
#include "llvoiceclient.h"
#include "llvoicevisualizer.h" // Ventrella
+
#include "llsdserialize.h"
//
#include "llfloaterexploreanimations.h"
@@ -707,16 +708,13 @@ F32 LLVOAvatar::sLODFactor = 1.f;
BOOL LLVOAvatar::sUseImpostors = FALSE;
BOOL LLVOAvatar::sJointDebug = FALSE;
-
-
-
-
+EmeraldGlobalBoobConfig LLVOAvatar::sBoobConfig;
F32 LLVOAvatar::sUnbakedTime = 0.f;
F32 LLVOAvatar::sUnbakedUpdateTime = 0.f;
F32 LLVOAvatar::sGreyTime = 0.f;
F32 LLVOAvatar::sGreyUpdateTime = 0.f;
-
+bool LLVOAvatar::sDoProperArc = true;
//-----------------------------------------------------------------------------
// Helper functions
@@ -768,7 +766,10 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mUpdatePeriod(1),
mFullyLoadedInitialized(FALSE),
mHasBakedHair( FALSE ),
- mSupportsAlphaLayers(FALSE)
+ mSupportsAlphaLayers(FALSE),
+ mFirstSetActualBoobGravRan( false )
+ //mFirstSetActualButtGravRan( false ),
+ //mFirstSetActualFatGravRan( false )
//
// mNametagSaysIdle(false),
// mIdleForever(true),
@@ -996,6 +997,16 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
}
+ // grab the boob savedparams (prob a better place for this)
+ sBoobConfig.mass = EmeraldBoobUtils::convertMass(gSavedSettings.getF32("EmeraldBoobMass"));
+ sBoobConfig.hardness = EmeraldBoobUtils::convertHardness(gSavedSettings.getF32("EmeraldBoobHardness"));
+ sBoobConfig.velMax = EmeraldBoobUtils::convertVelMax(gSavedSettings.getF32("EmeraldBoobVelMax"));
+ sBoobConfig.velMin = EmeraldBoobUtils::convertVelMin(gSavedSettings.getF32("EmeraldBoobVelMin"));
+ sBoobConfig.friction = EmeraldBoobUtils::convertFriction(gSavedSettings.getF32("EmeraldBoobFriction"));
+ sBoobConfig.enabled = gSavedSettings.getBOOL("EmeraldBreastPhysicsToggle");
+ sBoobConfig.XYInfluence = gSavedSettings.getF32("EmeraldBoobXYInfluence");
+ sDoProperArc = (bool)gSavedSettings.getBOOL("EmeraldUseProperArc");
+
if (gNoRender)
{
return;
@@ -2712,7 +2723,7 @@ BOOL LLVOAvatar::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
idleUpdateVoiceVisualizer( voice_enabled );
idleUpdateMisc( detailed_update );
idleUpdateAppearanceAnimation();
-
+ idleUpdateBoobEffect();
idleUpdateLipSync( voice_enabled );
idleUpdateLoadingEffect();
idleUpdateBelowWater(); // wind effect uses this
@@ -2994,105 +3005,105 @@ void LLVOAvatar::idleUpdateAppearanceAnimation()
}
}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+// ------------------------------------------------------------
+// Danny: ZOMG Boob Phsyics go!
+// ------------------------------------------------------------
+void LLVOAvatar::idleUpdateBoobEffect()
+{
+ if(mFirstSetActualBoobGravRan)
+ {
+ // should probably be moved somewhere where it is only called when boobsize changes
+ LLVisualParam *param;
+
+ // BOOBS
+ param = getVisualParam(105); //boob size
+ mLocalBoobConfig.boobSize = param->getCurrentWeight();
+ EmeraldBoobInputs boobInputs;
+ boobInputs.type = 0;
+ boobInputs.chestPosition = mChestp->getWorldPosition();
+ boobInputs.chestRotation = mChestp->getWorldRotation();
+ boobInputs.elapsedTime = mBoobBounceTimer.getElapsedTimeF32();
+ boobInputs.appearanceFlag = getAppearanceFlag();
+
+
+ EmeraldBoobState newBoobState = EmeraldBoobUtils::idleUpdate(sBoobConfig, mLocalBoobConfig, mBoobState, boobInputs);
+
+ if(mBoobState.boobGrav != newBoobState.boobGrav)
+ {
+ LLVisualParam *param;
+ param = getVisualParam(507);
+
+ ESex avatar_sex = getSex();
+
+ param->stopAnimating(FALSE);
+ param->setWeight(llclamp(newBoobState.boobGrav+getActualBoobGrav(), -1.5f, 2.f), FALSE);
+ param->apply(avatar_sex);
+ updateVisualParams();
+ }
+
+ mBoobState = newBoobState;
+ }
+ /*
+ if(mFirstSetActualButtGravRan)
+ {
+ // BUTT
+ EmeraldBoobInputs buttInputs;
+ buttInputs.type = 1;
+ buttInputs.chestPosition = mPelvisp->getWorldPosition();
+ buttInputs.chestRotation = mPelvisp->getWorldRotation();
+ buttInputs.elapsedTime = mBoobBounceTimer.getElapsedTimeF32();
+ buttInputs.appearanceFlag = getAppearanceFlag();
+
+
+ EmeraldBoobState newButtState = EmeraldBoobUtils::idleUpdate(sBoobConfig, mLocalBoobConfig, mButtState, buttInputs);
+
+ if(mButtState.boobGrav != newButtState.boobGrav)
+ {
+ LLVisualParam *param;
+ param = getVisualParam(795);
+
+ ESex avatar_sex = getSex();
+
+ param->stopAnimating(FALSE);
+ param->setWeight(newButtState.boobGrav*0.3f+getActualButtGrav(), FALSE);
+ param->apply(avatar_sex);
+ updateVisualParams();
+ }
+
+ mButtState = newButtState;
+ }
+
+ if(mFirstSetActualFatGravRan)
+ {
+ // FAT
+ EmeraldBoobInputs fatInputs;
+ fatInputs.type = 2;
+ fatInputs.chestPosition = mPelvisp->getWorldPosition();
+ fatInputs.chestRotation = mPelvisp->getWorldRotation();
+ fatInputs.elapsedTime = mBoobBounceTimer.getElapsedTimeF32();
+ fatInputs.appearanceFlag = getAppearanceFlag();
+
+
+ EmeraldBoobState newFatState = EmeraldBoobUtils::idleUpdate(sBoobConfig, mLocalBoobConfig, mFatState, fatInputs);
+
+ if(mFatState.boobGrav != newFatState.boobGrav)
+ {
+ LLVisualParam *param;
+ param = getVisualParam(157);
+
+ ESex avatar_sex = getSex();
+
+ param->stopAnimating(FALSE);
+ param->setWeight(newFatState.boobGrav*0.3f+getActualFatGrav(), FALSE);
+ param->apply(avatar_sex);
+ updateVisualParams();
+ }
+
+ mFatState = newFatState;
+ }
+ */
+
+}
void LLVOAvatar::idleUpdateLipSync(bool voice_enabled)
{
@@ -10419,11 +10430,33 @@ void LLVOAvatar::idleUpdateRenderCost()
}
}
+ if(sDoProperArc)
+ {
+ std::set::const_iterator tex_iter;
+ for(tex_iter = textures.begin();tex_iter != textures.end();++tex_iter)
+ {
+ LLViewerImage* img = gImageList.getImage(*tex_iter);
+ if(img)
+ {
+ shame += (img->getHeight() * img->getWidth()) >> 4;
+ }
+ }
+ }
shame += textures.size() * 5;
setDebugText(llformat("%d", shame));
F32 green = 1.f-llclamp(((F32) shame-1024.f)/1024.f, 0.f, 1.f);
F32 red = llmin((F32) shame/1024.f, 1.f);
+ if(sDoProperArc)
+ {
+ green = 1.f-llclamp(((F32)shame-1000000.f)/1000000.f, 0.f, 1.f);
+ red = llmin((F32)shame/1000000.f, 1.f);
+ }
+ else
+ {
+ green = 1.f-llclamp(((F32)shame-1024.f)/1024.f, 0.f, 1.f);
+ red = llmin((F32)shame/1024.f, 1.f);
+ }
mText->setColor(LLColor4(red,green,0,1));
}
diff --git a/indra/newview/llvoavatar.h b/indra/newview/llvoavatar.h
index a98629d90..a01ccd855 100644
--- a/indra/newview/llvoavatar.h
+++ b/indra/newview/llvoavatar.h
@@ -49,7 +49,7 @@
#include "llrendertarget.h"
#include "llwearable.h"
#include "llvoavatardefines.h"
-
+#include "emeraldboobutils.h"
extern const LLUUID ANIM_AGENT_BODY_NOISE;
@@ -118,7 +118,7 @@ public:
void idleUpdateLipSync(bool voice_enabled);
void idleUpdateLoadingEffect();
void idleUpdateWindEffect();
-
+ void idleUpdateBoobEffect();
void idleUpdateNameTag(const LLVector3& root_pos_last);
void idleUpdateRenderCost();
void idleUpdateTractorBeam();
@@ -525,58 +525,57 @@ private:
BOOL mAppearanceAnimSetByUser;
F32 mLastAppearanceBlendTime;
+ //--------------------------------------------------------------------
+ // boob bounce stuff
+ //--------------------------------------------------------------------
+private:
+ bool mFirstSetActualBoobGravRan;
+ //bool mFirstSetActualButtGravRan;
+ //bool mFirstSetActualFatGravRan;
+ LLFrameTimer mBoobBounceTimer;
+ EmeraldAvatarLocalBoobConfig mLocalBoobConfig;
+ EmeraldBoobState mBoobState;
+ //EmeraldBoobState mButtState;
+ //EmeraldBoobState mFatState;
+public:
+ //boob
+ F32 getActualBoobGrav() { return mLocalBoobConfig.actualBoobGrav; }
+ void setActualBoobGrav(F32 grav)
+ {
+ mLocalBoobConfig.actualBoobGrav = grav;
+ if(!mFirstSetActualBoobGravRan)
+ {
+ mBoobState.boobGrav = grav;
+ mFirstSetActualBoobGravRan = true;
+ }
+ }
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ //butt
+ /*F32 getActualButtGrav() { return mLocalBoobConfig.actualButtGrav; }
+ void setActualButtGrav(F32 grav)
+ {
+ mLocalBoobConfig.actualButtGrav = grav;
+ if(!mFirstSetActualButtGravRan)
+ {
+ mButtState.boobGrav = grav;
+ mFirstSetActualButtGravRan = true;
+ }
+ }
+ //fat
+ F32 getActualFatGrav() { return mLocalBoobConfig.actualFatGrav; }
+ void setActualFatGrav(F32 grav)
+ {
+ mLocalBoobConfig.actualFatGrav = grav;
+ if(!mFirstSetActualFatGravRan)
+ {
+ mFatState.boobGrav = grav;
+ mFirstSetActualFatGravRan = true;
+ }
+ }
+ */
+ static EmeraldGlobalBoobConfig sBoobConfig;
//--------------------------------------------------------------------
// Attachments
@@ -870,6 +869,7 @@ public:
static F32 sUnbakedUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)
static F32 sGreyTime; // Total seconds with >=1 grey avatars
static F32 sGreyUpdateTime; // Last time stats were updated (to prevent multiple updates per frame)
+ static bool sDoProperArc;
const std::string getBakedStatusForPrintout() const;
};
diff --git a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_vanity.xml b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_vanity.xml
index da2abed87..8e8fe8e3c 100644
--- a/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_vanity.xml
+++ b/indra/newview/skins/default/xui/en-us/panel_preferences_ascent_vanity.xml
@@ -3,15 +3,38 @@
border="true" label="Ascent Vanity" name="ascvan" enabled="true" mouse_opaque="true">
-
-
-
+
+
+
+
+
+
+