aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llhudeffectlookat.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llhudeffectlookat.cpp')
-rw-r--r--linden/indra/newview/llhudeffectlookat.cpp239
1 files changed, 182 insertions, 57 deletions
diff --git a/linden/indra/newview/llhudeffectlookat.cpp b/linden/indra/newview/llhudeffectlookat.cpp
index da0ec60..6922f29 100644
--- a/linden/indra/newview/llhudeffectlookat.cpp
+++ b/linden/indra/newview/llhudeffectlookat.cpp
@@ -39,6 +39,10 @@
39#include "llselectmgr.h" 39#include "llselectmgr.h"
40#include "llglheaders.h" 40#include "llglheaders.h"
41 41
42
43#include "llxmltree.h"
44
45
42BOOL LLHUDEffectLookAt::sDebugLookAt = FALSE; 46BOOL LLHUDEffectLookAt::sDebugLookAt = FALSE;
43 47
44// packet layout 48// packet layout
@@ -54,69 +58,179 @@ const F32 MAX_SENDS_PER_SEC = 4.f;
54const F32 MIN_DELTAPOS_FOR_UPDATE = 0.05f; 58const F32 MIN_DELTAPOS_FOR_UPDATE = 0.05f;
55const F32 MIN_TARGET_OFFSET_SQUARED = 0.0001f; 59const F32 MIN_TARGET_OFFSET_SQUARED = 0.0001f;
56 60
57// timeouts 61
58// can't use actual F32_MAX, because we add this to the current frametime 62// can't use actual F32_MAX, because we add this to the current frametime
59const F32 MAX_TIMEOUT = F32_MAX / 2.f; 63const F32 MAX_TIMEOUT = F32_MAX / 2.f;
60 64
61const F32 LOOKAT_TIMEOUTS[LOOKAT_NUM_TARGETS] = 65/**
66 * Simple data class holding values for a particular type of attention.
67 */
68class LLAttention
62{ 69{
63 MAX_TIMEOUT, //LOOKAT_TARGET_NONE 70public:
64 3.f, //LOOKAT_TARGET_IDLE 71 LLAttention(){}
65 4.f, //LOOKAT_TARGET_AUTO_LISTEN 72 LLAttention(F32 timeout, F32 priority, char *name, LLColor3 color) :
66 2.f, //LOOKAT_TARGET_FREELOOK 73 mTimeout(timeout), mPriority(priority), mName(name), mColor(color)
67 4.f, //LOOKAT_TARGET_RESPOND 74 {
68 1.f, //LOOKAT_TARGET_HOVER 75 }
69 MAX_TIMEOUT, //LOOKAT_TARGET_CONVERSATION 76 F32 mTimeout, mPriority;
70 MAX_TIMEOUT, //LOOKAT_TARGET_SELECT 77 LLString mName;
71 MAX_TIMEOUT, //LOOKAT_TARGET_FOCUS 78 LLColor3 mColor;
72 MAX_TIMEOUT, //LOOKAT_TARGET_MOUSELOOK
73 0.f, //LOOKAT_TARGET_CLEAR
74}; 79};
75 80
76const S32 LOOKAT_PRIORITIES[LOOKAT_NUM_TARGETS] = 81/**
82 * Simple data class holding a list of attentions, one for every type.
83 */
84class LLAttentionSet
77{ 85{
78 0, //LOOKAT_TARGET_NONE 86public:
79 1, //LOOKAT_TARGET_IDLE 87 LLAttentionSet(const LLAttention attentions[])
80 3, //LOOKAT_TARGET_AUTO_LISTEN 88 {
81 2, //LOOKAT_TARGET_FREELOOK 89 for(int i=0; i<LOOKAT_NUM_TARGETS; i++)
82 3, //LOOKAT_TARGET_RESPOND 90 {
83 4, //LOOKAT_TARGET_HOVER 91 mAttentions[i] = attentions[i];
84 5, //LOOKAT_TARGET_CONVERSATION 92 }
85 6, //LOOKAT_TARGET_SELECT 93 }
86 6, //LOOKAT_TARGET_FOCUS 94 LLAttention mAttentions[LOOKAT_NUM_TARGETS];
87 7, //LOOKAT_TARGET_MOUSELOOK 95 LLAttention& operator[](int idx) { return mAttentions[idx]; }
88 8, //LOOKAT_TARGET_CLEAR
89}; 96};
90 97
91const char *LOOKAT_STRINGS[] = 98// Default attribute set data.
99// Used to initialize the global attribute set objects, one of which will be
100// refered to by the hud object at any given time.
101// Note that the values below are only the default values and that any or all of them
102// can be overwritten with customizing data from the XML file. The actual values below
103// are those that will give exactly the same look-at behavior as before the ability
104// to customize was added. - MG
105static const
106 LLAttention
107 BOY_ATTS[] = { // default set of masculine attentions
108 LLAttention(MAX_TIMEOUT, 0, "None", LLColor3(0.3f, 0.3f, 0.3f)), // LOOKAT_TARGET_NONE
109 LLAttention(3.f, 1, "Idle", LLColor3(0.5f, 0.5f, 0.5f)), // LOOKAT_TARGET_IDLE
110 LLAttention(4.f, 3, "AutoListen", LLColor3(0.5f, 0.5f, 0.5f)), // LOOKAT_TARGET_AUTO_LISTEN
111 LLAttention(2.f, 2, "FreeLook", LLColor3(0.5f, 0.5f, 0.9f)), // LOOKAT_TARGET_FREELOOK
112 LLAttention(4.f, 3, "Respond", LLColor3(0.0f, 0.0f, 0.0f)), // LOOKAT_TARGET_RESPOND
113 LLAttention(1.f, 4, "Hover", LLColor3(0.5f, 0.9f, 0.5f)), // LOOKAT_TARGET_HOVER
114 LLAttention(MAX_TIMEOUT, 0, "Conversation", LLColor3(0.1f, 0.1f, 0.5f)), // LOOKAT_TARGET_CONVERSATION
115 LLAttention(MAX_TIMEOUT, 6, "Select", LLColor3(0.9f, 0.5f, 0.5f)), // LOOKAT_TARGET_SELECT
116 LLAttention(MAX_TIMEOUT, 6, "Focus", LLColor3(0.9f, 0.5f, 0.9f)), // LOOKAT_TARGET_FOCUS
117 LLAttention(MAX_TIMEOUT, 7, "Mouselook", LLColor3(0.9f, 0.9f, 0.5f)), // LOOKAT_TARGET_MOUSELOOK
118 LLAttention(0.f, 8, "Clear", LLColor3(1.0f, 1.0f, 1.0f)), // LOOKAT_TARGET_CLEAR
119 },
120 GIRL_ATTS[] = { // default set of feminine attentions
121 LLAttention(MAX_TIMEOUT, 0, "None", LLColor3(0.3f, 0.3f, 0.3f)), // LOOKAT_TARGET_NONE
122 LLAttention(3.f, 1, "Idle", LLColor3(0.5f, 0.5f, 0.5f)), // LOOKAT_TARGET_IDLE
123 LLAttention(4.f, 3, "AutoListen", LLColor3(0.5f, 0.5f, 0.5f)), // LOOKAT_TARGET_AUTO_LISTEN
124 LLAttention(2.f, 2, "FreeLook", LLColor3(0.5f, 0.5f, 0.9f)), // LOOKAT_TARGET_FREELOOK
125 LLAttention(4.f, 3, "Respond", LLColor3(0.0f, 0.0f, 0.0f)), // LOOKAT_TARGET_RESPOND
126 LLAttention(1.f, 4, "Hover", LLColor3(0.5f, 0.9f, 0.5f)), // LOOKAT_TARGET_HOVER
127 LLAttention(MAX_TIMEOUT, 0, "Conversation", LLColor3(0.1f, 0.1f, 0.5f)), // LOOKAT_TARGET_CONVERSATION
128 LLAttention(MAX_TIMEOUT, 6, "Select", LLColor3(0.9f, 0.5f, 0.5f)), // LOOKAT_TARGET_SELECT
129 LLAttention(MAX_TIMEOUT, 6, "Focus", LLColor3(0.9f, 0.5f, 0.9f)), // LOOKAT_TARGET_FOCUS
130 LLAttention(MAX_TIMEOUT, 7, "Mouselook", LLColor3(0.9f, 0.9f, 0.5f)), // LOOKAT_TARGET_MOUSELOOK
131 LLAttention(0.f, 8, "Clear", LLColor3(1.0f, 1.0f, 1.0f)), // LOOKAT_TARGET_CLEAR
132 };
133
134static LLAttentionSet
135 gBoyAttentions(BOY_ATTS),
136 gGirlAttentions(GIRL_ATTS);
137
138
139static BOOL loadGender(LLXmlTreeNode* gender)
92{ 140{
93 "None", //LOOKAT_TARGET_NONE 141 if( !gender)
94 "Idle", //LOOKAT_TARGET_IDLE 142 {
95 "AutoListen", //LOOKAT_TARGET_AUTO_LISTEN 143 return FALSE;
96 "FreeLook", //LOOKAT_TARGET_FREELOOK 144 }
97 "Respond", //LOOKAT_TARGET_RESPOND 145 LLString str;
98 "Hover", //LOOKAT_TARGET_HOVER 146 gender->getAttributeString("name", str);
99 "Conversation", //LOOKAT_TARGET_CONVERSATION 147 LLAttentionSet& attentions = (str.compare("Masculine") == 0) ? gBoyAttentions : gGirlAttentions;
100 "Select", //LOOKAT_TARGET_SELECT 148 for (LLXmlTreeNode* attention_node = gender->getChildByName( "param" );
101 "Focus", //LOOKAT_TARGET_FOCUS 149 attention_node;
102 "Mouselook", //LOOKAT_TARGET_MOUSELOOK 150 attention_node = gender->getNextNamedChild())
103 "Clear", //LOOKAT_TARGET_CLEAR 151 {
104}; 152 attention_node->getAttributeString("attention", str);
153 LLAttention* attention;
154 if (str == "idle") attention = &attentions[LOOKAT_TARGET_IDLE];
155 else if(str == "auto_listen") attention = &attentions[LOOKAT_TARGET_AUTO_LISTEN];
156 else if(str == "freelook") attention = &attentions[LOOKAT_TARGET_FREELOOK];
157 else if(str == "respond") attention = &attentions[LOOKAT_TARGET_RESPOND];
158 else if(str == "hover") attention = &attentions[LOOKAT_TARGET_HOVER];
159 else if(str == "conversation") attention = &attentions[LOOKAT_TARGET_CONVERSATION];
160 else if(str == "select") attention = &attentions[LOOKAT_TARGET_SELECT];
161 else if(str == "focus") attention = &attentions[LOOKAT_TARGET_FOCUS];
162 else if(str == "mouselook") attention = &attentions[LOOKAT_TARGET_MOUSELOOK];
163 else return FALSE;
164
165 F32 priority, timeout;
166 attention_node->getAttributeF32("priority", priority);
167 attention_node->getAttributeF32("timeout", timeout);
168 if(timeout < 0) timeout = MAX_TIMEOUT;
169 attention->mPriority = priority;
170 attention->mTimeout = timeout;
171 }
172 return TRUE;
173}
105 174
106const LLColor3 LOOKAT_COLORS[LOOKAT_NUM_TARGETS] = 175static BOOL loadAttentions()
107{ 176{
108 LLColor3(0.3f, 0.3f, 0.3f), //LOOKAT_TARGET_NONE 177 static BOOL first_time = TRUE;
109 LLColor3(0.5f, 0.5f, 0.5f), //LOOKAT_TARGET_IDLE 178 if( ! first_time)
110 LLColor3(0.5f, 0.5f, 0.5f), //LOOKAT_TARGET_AUTO_LISTEN 179 {
111 LLColor3(0.5f, 0.5f, 0.9f), //LOOKAT_TARGET_FREELOOK 180 return TRUE; // maybe not ideal but otherwise it can continue to fail forever.
112 LLColor3(0.f, 0.f, 0.f), //LOOKAT_TARGET_RESPOND 181 }
113 LLColor3(0.5f, 0.9f, 0.5f), //LOOKAT_TARGET_HOVER 182 first_time = FALSE;
114 LLColor3(0.1f, 0.1f, 0.5f), //LOOKAT_TARGET_CONVERSATION 183
115 LLColor3(0.9f, 0.5f, 0.5f), //LOOKAT_TARGET_SELECT 184 char filename[MAX_PATH]; /*Flawfinder: ignore*/
116 LLColor3(0.9f, 0.5f, 0.9f), //LOOKAT_TARGET_FOCUS 185 strncpy(filename,gDirUtilp->getExpandedFilename(LL_PATH_CHARACTER,"attentions.xml").c_str(), sizeof(filename) -1); /*Flawfinder: ignore*/
117 LLColor3(0.9f, 0.9f, 0.5f), //LOOKAT_TARGET_MOUSELOOK 186 filename[sizeof(filename) -1] = '\0';
118 LLColor3(1.f, 1.f, 1.f), //LOOKAT_TARGET_CLEAR 187 LLXmlTree xml_tree;
119}; 188 BOOL success = xml_tree.parseFile( filename, FALSE );
189 if( !success )
190 {
191 return FALSE;
192 }
193 LLXmlTreeNode* root = xml_tree.getRoot();
194 if( !root )
195 {
196 return FALSE;
197 }
198
199 //-------------------------------------------------------------------------
200 // <linden_attentions version="1.0"> (root)
201 //-------------------------------------------------------------------------
202 if( !root->hasName( "linden_attentions" ) )
203 {
204 llwarns << "Invalid linden_attentions file header: " << filename << llendl;
205 return FALSE;
206 }
207
208 LLString version;
209 static LLStdStringHandle version_string = LLXmlTree::addAttributeString("version");
210 if( !root->getFastAttributeString( version_string, version ) || (version != "1.0") )
211 {
212 llwarns << "Invalid linden_attentions file version: " << version << llendl;
213 return FALSE;
214 }
215
216 //-------------------------------------------------------------------------
217 // <gender>
218 //-------------------------------------------------------------------------
219 for (LLXmlTreeNode* child = root->getChildByName( "gender" );
220 child;
221 child = root->getNextNamedChild())
222 {
223 if( !loadGender( child ) )
224 {
225 return FALSE;
226 }
227 }
228
229 return TRUE;
230}
231
232
233
120 234
121//----------------------------------------------------------------------------- 235//-----------------------------------------------------------------------------
122// LLHUDEffectLookAt() 236// LLHUDEffectLookAt()
@@ -127,6 +241,10 @@ LLHUDEffectLookAt::LLHUDEffectLookAt(const U8 type) :
127 mLastSendTime(0.f) 241 mLastSendTime(0.f)
128{ 242{
129 clearLookAtTarget(); 243 clearLookAtTarget();
244 // parse the default sets
245 loadAttentions();
246 // initialize current attention set. switches when avatar sex changes.
247 mAttentions = &gGirlAttentions;
130} 248}
131 249
132//----------------------------------------------------------------------------- 250//-----------------------------------------------------------------------------
@@ -280,7 +398,7 @@ BOOL LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *objec
280 llassert(target_type < LOOKAT_NUM_TARGETS); 398 llassert(target_type < LOOKAT_NUM_TARGETS);
281 399
282 // must be same or higher priority than existing effect 400 // must be same or higher priority than existing effect
283 if (LOOKAT_PRIORITIES[target_type] < LOOKAT_PRIORITIES[mTargetType]) 401 if ((*mAttentions)[target_type].mPriority < (*mAttentions)[mTargetType].mPriority)
284 { 402 {
285 return FALSE; 403 return FALSE;
286 } 404 }
@@ -288,8 +406,7 @@ BOOL LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *objec
288 F32 current_time = mTimer.getElapsedTimeF32(); 406 F32 current_time = mTimer.getElapsedTimeF32();
289 407
290 // type of lookat behavior or target object has changed 408 // type of lookat behavior or target object has changed
291 BOOL lookAtChanged = (target_type != mTargetType) || 409 BOOL lookAtChanged = (target_type != mTargetType) || (object != mTargetObject);
292 (object != mTargetObject);
293 410
294 // lookat position has moved a certain amount and we haven't just sent an update 411 // lookat position has moved a certain amount and we haven't just sent an update
295 lookAtChanged = lookAtChanged || (dist_vec(position, mLastSentOffsetGlobal) > MIN_DELTAPOS_FOR_UPDATE) && 412 lookAtChanged = lookAtChanged || (dist_vec(position, mLastSentOffsetGlobal) > MIN_DELTAPOS_FOR_UPDATE) &&
@@ -298,7 +415,8 @@ BOOL LLHUDEffectLookAt::setLookAt(ELookAtType target_type, LLViewerObject *objec
298 if (lookAtChanged) 415 if (lookAtChanged)
299 { 416 {
300 mLastSentOffsetGlobal = position; 417 mLastSentOffsetGlobal = position;
301 setDuration(LOOKAT_TIMEOUTS[target_type]); 418 F32 timeout = (*mAttentions)[target_type].mTimeout;
419 setDuration(timeout);
302 setNeedsSendToSim(TRUE); 420 setNeedsSendToSim(TRUE);
303 } 421 }
304 422
@@ -379,7 +497,7 @@ void LLHUDEffectLookAt::render()
379 glScalef(0.3f, 0.3f, 0.3f); 497 glScalef(0.3f, 0.3f, 0.3f);
380 glBegin(GL_LINES); 498 glBegin(GL_LINES);
381 { 499 {
382 LLColor3 color = LOOKAT_COLORS[mTargetType]; 500 LLColor3 color = (*mAttentions)[mTargetType].mColor;
383 glColor3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]); 501 glColor3f(color.mV[VRED], color.mV[VGREEN], color.mV[VBLUE]);
384 glVertex3f(-1.f, 0.f, 0.f); 502 glVertex3f(-1.f, 0.f, 0.f);
385 glVertex3f(1.f, 0.f, 0.f); 503 glVertex3f(1.f, 0.f, 0.f);
@@ -412,6 +530,13 @@ void LLHUDEffectLookAt::update()
412 return; 530 return;
413 } 531 }
414 532
533 // make sure the proper set of avatar attention are currently being used.
534 LLVOAvatar* source_avatar = (LLVOAvatar*)(LLViewerObject*)mSourceObject;
535 // for now the first cut will just switch on sex. future development could adjust
536 // timeouts according to avatar age and/or other features.
537 mAttentions = (source_avatar->getSex() == SEX_MALE) ? &gBoyAttentions : &gGirlAttentions;
538 //printf("updated to %s\n", (source_avatar->getSex() == SEX_MALE) ? "male" : "female");
539
415 F32 time = mTimer.getElapsedTimeF32(); 540 F32 time = mTimer.getElapsedTimeF32();
416 541
417 // clear out the effect if time is up 542 // clear out the effect if time is up
@@ -438,7 +563,7 @@ void LLHUDEffectLookAt::update()
438 563
439 if (sDebugLookAt) 564 if (sDebugLookAt)
440 { 565 {
441 ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->addDebugText(LOOKAT_STRINGS[mTargetType]); 566 ((LLVOAvatar*)(LLViewerObject*)mSourceObject)->addDebugText((*mAttentions)[mTargetType].mName);
442 } 567 }
443} 568}
444 569