mirror of
https://github.com/overte-org/overte.git
synced 2025-04-18 00:26:33 +02:00
renamed "Head" to "Avatar" and did a bunch a cleanups, including removing the three-lined comments
This commit is contained in:
parent
a9ff483d3d
commit
e54fd0dd7d
9 changed files with 37 additions and 1664 deletions
|
@ -27,7 +27,6 @@ const float MAX_ITERATIONS_BETWEEN_AUDIO_SENDS = (MAX_AUDIO_SEND_INTERVAL_SECS *
|
|||
|
||||
bool stopReceiveAgentDataThread;
|
||||
bool injectAudioThreadRunning = false;
|
||||
int handStateTimer = 0;
|
||||
|
||||
int TEMP_AUDIO_LISTEN_PORT = 55439;
|
||||
// UDPSocket audioSocket(TEMP_AUDIO_LISTEN_PORT);
|
||||
|
@ -124,20 +123,7 @@ int main(int argc, const char* argv[]) {
|
|||
// put her hand out so somebody can shake it
|
||||
eve.setHandPosition(glm::vec3(eve.getPosition()[0] - 0.2,
|
||||
0.25,
|
||||
eve.getPosition()[2] + 0.1));
|
||||
|
||||
// simulate the effect of pressing and un-pressing the mouse button/pad
|
||||
handStateTimer ++;
|
||||
if ( handStateTimer == 100 ) {
|
||||
eve.setHandState(1);
|
||||
}
|
||||
if ( handStateTimer == 150 ) {
|
||||
eve.setHandState(0);
|
||||
}
|
||||
if ( handStateTimer >= 200 ) {
|
||||
handStateTimer = 0;
|
||||
}
|
||||
|
||||
eve.getPosition()[2] + 0.1));
|
||||
// read eve's audio data
|
||||
AudioInjector eveAudioInjector("eve.raw");
|
||||
|
||||
|
@ -152,6 +138,8 @@ int main(int argc, const char* argv[]) {
|
|||
// int numIterationsLeftBeforeAudioSend = 0;
|
||||
// pthread_t injectAudioThread;
|
||||
|
||||
int handStateTimer = 0;
|
||||
|
||||
while (true) {
|
||||
// update the thisSend timeval to the current time
|
||||
gettimeofday(&thisSend, NULL);
|
||||
|
@ -183,7 +171,19 @@ int main(int argc, const char* argv[]) {
|
|||
// sleep for the correct amount of time to have data send be consistently timed
|
||||
if ((numMicrosecondsSleep = (DATA_SEND_INTERVAL_MSECS * 1000) - (usecTimestampNow() - usecTimestamp(&thisSend))) > 0) {
|
||||
usleep(numMicrosecondsSleep);
|
||||
}
|
||||
}
|
||||
|
||||
// simulate the effect of pressing and un-pressing the mouse button/pad
|
||||
handStateTimer++;
|
||||
if ( handStateTimer == 100 ) {
|
||||
eve.setHandState(1);
|
||||
}
|
||||
if ( handStateTimer == 150 ) {
|
||||
eve.setHandState(0);
|
||||
}
|
||||
if ( handStateTimer >= 200 ) {
|
||||
handStateTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// stop the receive agent data thread
|
||||
|
|
|
@ -157,7 +157,7 @@ int audioCallback (const void *inputBuffer,
|
|||
|
||||
// memcpy the three float positions
|
||||
for (int p = 0; p < 3; p++) {
|
||||
memcpy(currentPacketPtr, &data->linkedHead->getPosition()[p], sizeof(float));
|
||||
memcpy(currentPacketPtr, &data->linkedAvatar->getPosition()[p], sizeof(float));
|
||||
currentPacketPtr += sizeof(float);
|
||||
}
|
||||
|
||||
|
@ -165,7 +165,7 @@ int audioCallback (const void *inputBuffer,
|
|||
*(currentPacketPtr++) = 255;
|
||||
|
||||
// memcpy the corrected render yaw
|
||||
float correctedYaw = fmodf(data->linkedHead->getRenderYaw(), 360);
|
||||
float correctedYaw = fmodf(data->linkedAvatar->getRenderYaw(), 360);
|
||||
|
||||
if (correctedYaw > 180) {
|
||||
correctedYaw -= 360;
|
||||
|
@ -259,7 +259,7 @@ int audioCallback (const void *inputBuffer,
|
|||
// rotation of the head relative to body, this may effect flange effect!
|
||||
//
|
||||
//
|
||||
int lastYawMeasured = fabsf(data->linkedHead->getLastMeasuredHeadYaw());
|
||||
int lastYawMeasured = fabsf(data->linkedAvatar->getLastMeasuredHeadYaw());
|
||||
|
||||
if (!samplesLeftForFlange && lastYawMeasured > MIN_FLANGE_EFFECT_THRESHOLD) {
|
||||
// we should flange for one second
|
||||
|
@ -448,7 +448,7 @@ void Audio::setWalkingState(bool newWalkState) {
|
|||
* @return Returns true if successful or false if an error occurred.
|
||||
Use Audio::getError() to retrieve the error code.
|
||||
*/
|
||||
Audio::Audio(Oscilloscope *s, Head *linkedHead)
|
||||
Audio::Audio(Oscilloscope *s, Avatar *linkedAvatar)
|
||||
{
|
||||
// read the walking sound from the raw file and store it
|
||||
// in the in memory array
|
||||
|
@ -472,7 +472,7 @@ Audio::Audio(Oscilloscope *s, Head *linkedHead)
|
|||
|
||||
audioData = new AudioData();
|
||||
|
||||
audioData->linkedHead = linkedHead;
|
||||
audioData->linkedAvatar = linkedAvatar;
|
||||
|
||||
// setup a UDPSocket
|
||||
audioData->audioSocket = new UDPSocket(AUDIO_UDP_LISTEN_PORT);
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
#include <portaudio.h>
|
||||
#include "AudioData.h"
|
||||
#include "Oscilloscope.h"
|
||||
#include "Head.h"
|
||||
#include "Avatar.h"
|
||||
|
||||
class Audio {
|
||||
public:
|
||||
// initializes audio I/O
|
||||
Audio(Oscilloscope *s, Head *linkedHead);
|
||||
Audio(Oscilloscope *s, Avatar *linkedAvatar);
|
||||
|
||||
void render();
|
||||
void render(int screenWidth, int screenHeight);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include "AudioRingBuffer.h"
|
||||
#include "UDPSocket.h"
|
||||
#include "Head.h"
|
||||
#include "Avatar.h"
|
||||
|
||||
class AudioData {
|
||||
public:
|
||||
|
@ -23,7 +23,7 @@ class AudioData {
|
|||
|
||||
UDPSocket *audioSocket;
|
||||
|
||||
Head *linkedHead;
|
||||
Avatar *linkedAvatar;
|
||||
|
||||
// store current mixer address and port
|
||||
in_addr_t mixerAddress;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,279 +0,0 @@
|
|||
//
|
||||
// Head.h
|
||||
// interface
|
||||
//
|
||||
// Created by Philip Rosedale on 9/11/12.
|
||||
// Copyright (c) 2012 High Fidelity, Inc. All rights reserved.
|
||||
//
|
||||
|
||||
#ifndef __interface__head__
|
||||
#define __interface__head__
|
||||
|
||||
#include <AvatarData.h>
|
||||
#include <Orientation.h>
|
||||
|
||||
#include "Field.h"
|
||||
#include "world.h"
|
||||
|
||||
#include "InterfaceConfig.h"
|
||||
#include "SerialInterface.h"
|
||||
|
||||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include <glm/gtx/quaternion.hpp> //looks like we might not need this
|
||||
|
||||
const bool AVATAR_GRAVITY = true;
|
||||
const float DECAY = 0.1;
|
||||
const float THRUST_MAG = 10.0;
|
||||
const float YAW_MAG = 300.0;
|
||||
const float TEST_YAW_DECAY = 5.0;
|
||||
const float LIN_VEL_DECAY = 5.0;
|
||||
|
||||
const float COLLISION_BODY_RADIUS = 0.1;
|
||||
const float COLLISION_HEIGHT = 1.5;
|
||||
|
||||
enum eyeContactTargets {LEFT_EYE, RIGHT_EYE, MOUTH};
|
||||
|
||||
#define FWD 0
|
||||
#define BACK 1
|
||||
#define LEFT 2
|
||||
#define RIGHT 3
|
||||
#define UP 4
|
||||
#define DOWN 5
|
||||
#define ROT_LEFT 6
|
||||
#define ROT_RIGHT 7
|
||||
#define MAX_DRIVE_KEYS 8
|
||||
|
||||
#define MAX_OTHER_AVATARS 10 // temporary - for testing purposes!
|
||||
|
||||
enum AvatarMode
|
||||
{
|
||||
AVATAR_MODE_STANDING = 0,
|
||||
AVATAR_MODE_WALKING,
|
||||
AVATAR_MODE_INTERACTING,
|
||||
NUM_AVATAR_MODES
|
||||
};
|
||||
|
||||
enum AvatarBoneID
|
||||
{
|
||||
AVATAR_BONE_NULL = -1,
|
||||
AVATAR_BONE_PELVIS_SPINE, // connects pelvis joint with torso joint (not supposed to be rotated)
|
||||
AVATAR_BONE_MID_SPINE, // connects torso joint with chest joint
|
||||
AVATAR_BONE_CHEST_SPINE, // connects chest joint with neckBase joint (not supposed to be rotated)
|
||||
AVATAR_BONE_NECK, // connects neckBase joint with headBase joint
|
||||
AVATAR_BONE_HEAD, // connects headBase joint with headTop joint
|
||||
AVATAR_BONE_LEFT_CHEST, // connects chest joint with left clavicle joint (not supposed to be rotated)
|
||||
AVATAR_BONE_LEFT_SHOULDER, // connects left clavicle joint with left shoulder joint
|
||||
AVATAR_BONE_LEFT_UPPER_ARM, // connects left shoulder joint with left elbow joint
|
||||
AVATAR_BONE_LEFT_FOREARM, // connects left elbow joint with left wrist joint
|
||||
AVATAR_BONE_LEFT_HAND, // connects left wrist joint with left fingertips joint
|
||||
AVATAR_BONE_RIGHT_CHEST, // connects chest joint with right clavicle joint (not supposed to be rotated)
|
||||
AVATAR_BONE_RIGHT_SHOULDER, // connects right clavicle joint with right shoulder joint
|
||||
AVATAR_BONE_RIGHT_UPPER_ARM, // connects right shoulder joint with right elbow joint
|
||||
AVATAR_BONE_RIGHT_FOREARM, // connects right elbow joint with right wrist joint
|
||||
AVATAR_BONE_RIGHT_HAND, // connects right wrist joint with right fingertips joint
|
||||
AVATAR_BONE_LEFT_PELVIS, // connects pelvis joint with left hip joint (not supposed to be rotated)
|
||||
AVATAR_BONE_LEFT_THIGH, // connects left hip joint with left knee joint
|
||||
AVATAR_BONE_LEFT_SHIN, // connects left knee joint with left heel joint
|
||||
AVATAR_BONE_LEFT_FOOT, // connects left heel joint with left toes joint
|
||||
AVATAR_BONE_RIGHT_PELVIS, // connects pelvis joint with right hip joint (not supposed to be rotated)
|
||||
AVATAR_BONE_RIGHT_THIGH, // connects right hip joint with right knee joint
|
||||
AVATAR_BONE_RIGHT_SHIN, // connects right knee joint with right heel joint
|
||||
AVATAR_BONE_RIGHT_FOOT, // connects right heel joint with right toes joint
|
||||
|
||||
NUM_AVATAR_BONES
|
||||
};
|
||||
|
||||
struct AvatarCollisionElipsoid
|
||||
{
|
||||
bool colliding;
|
||||
glm::vec3 position;
|
||||
float girth;
|
||||
float height;
|
||||
glm::vec3 upVector;
|
||||
};
|
||||
|
||||
struct AvatarHandHolding
|
||||
{
|
||||
glm::vec3 position;
|
||||
glm::vec3 velocity;
|
||||
float force;
|
||||
};
|
||||
|
||||
/*
|
||||
struct OtherAvatar
|
||||
{
|
||||
bool nearby;
|
||||
//glm::vec3 handPosition;
|
||||
//int handState;
|
||||
};
|
||||
*/
|
||||
|
||||
struct AvatarBone
|
||||
{
|
||||
AvatarBoneID parent; // which bone is this bone connected to?
|
||||
glm::vec3 position; // the position at the "end" of the bone
|
||||
glm::vec3 defaultPosePosition; // the parent relative position when the avatar is in the "T-pose"
|
||||
glm::vec3 springyPosition; // used for special effects (a 'flexible' variant of position)
|
||||
glm::dvec3 springyVelocity; // used for special effects ( the velocity of the springy position)
|
||||
float springBodyTightness; // how tightly the springy position tries to stay on the position
|
||||
glm::quat rotation; // this will eventually replace yaw, pitch and roll (and maybe orientation)
|
||||
float yaw; // the yaw Euler angle of the bone rotation off the parent
|
||||
float pitch; // the pitch Euler angle of the bone rotation off the parent
|
||||
float roll; // the roll Euler angle of the bone rotation off the parent
|
||||
Orientation orientation; // three orthogonal normals determined by yaw, pitch, roll
|
||||
float length; // the length of the bone
|
||||
float radius; // used for detecting collisions for certain physical effects
|
||||
};
|
||||
|
||||
struct AvatarHead
|
||||
{
|
||||
float pitchRate;
|
||||
float yawRate;
|
||||
float rollRate;
|
||||
float noise;
|
||||
float eyeballPitch[2];
|
||||
float eyeballYaw [2];
|
||||
float eyebrowPitch[2];
|
||||
float eyebrowRoll [2];
|
||||
float eyeballScaleX;
|
||||
float eyeballScaleY;
|
||||
float eyeballScaleZ;
|
||||
float interPupilDistance;
|
||||
float interBrowDistance;
|
||||
float nominalPupilSize;
|
||||
float pupilSize;
|
||||
float mouthPitch;
|
||||
float mouthYaw;
|
||||
float mouthWidth;
|
||||
float mouthHeight;
|
||||
float leanForward;
|
||||
float leanSideways;
|
||||
float pitchTarget;
|
||||
float yawTarget;
|
||||
float noiseEnvelope;
|
||||
float pupilConverge;
|
||||
float scale;
|
||||
int eyeContact;
|
||||
float browAudioLift;
|
||||
eyeContactTargets eyeContactTarget;
|
||||
|
||||
// Sound loudness information
|
||||
float lastLoudness;
|
||||
float averageLoudness;
|
||||
float audioAttack;
|
||||
};
|
||||
|
||||
|
||||
class Head : public AvatarData {
|
||||
public:
|
||||
Head(bool isMine);
|
||||
~Head();
|
||||
Head(const Head &otherHead);
|
||||
Head* clone() const;
|
||||
|
||||
void reset();
|
||||
void UpdateGyros(float frametime, SerialInterface * serialInterface, glm::vec3 * gravity);
|
||||
void setNoise (float mag) { _head.noise = mag; }
|
||||
void setScale(float s) {_head.scale = s; };
|
||||
void setRenderYaw(float y) {_renderYaw = y;}
|
||||
void setRenderPitch(float p) {_renderPitch = p;}
|
||||
float getRenderYaw() {return _renderYaw;}
|
||||
float getRenderPitch() {return _renderPitch;}
|
||||
void setLeanForward(float dist);
|
||||
void setLeanSideways(float dist);
|
||||
void addLean(float x, float z);
|
||||
float getLastMeasuredHeadYaw() const {return _head.yawRate;}
|
||||
float getBodyYaw() {return _bodyYaw;};
|
||||
void addBodyYaw(float y) {_bodyYaw += y;};
|
||||
|
||||
glm::vec3 getHeadLookatDirection();
|
||||
glm::vec3 getHeadLookatDirectionUp();
|
||||
glm::vec3 getHeadLookatDirectionRight();
|
||||
glm::vec3 getHeadPosition();
|
||||
glm::vec3 getBonePosition( AvatarBoneID b );
|
||||
glm::vec3 getBodyUpDirection();
|
||||
float getGirth();
|
||||
float getHeight();
|
||||
|
||||
AvatarMode getMode();
|
||||
|
||||
void setMousePressed( bool pressed );
|
||||
void render(bool lookingInMirror);
|
||||
void renderBody();
|
||||
void renderHead(bool lookingInMirror);
|
||||
void simulate(float);
|
||||
void startHandMovement();
|
||||
void stopHandMovement();
|
||||
void setHandMovementValues( glm::vec3 movement );
|
||||
void updateHandMovement( float deltaTime );
|
||||
void updateArmIKAndConstraints( float deltaTime );
|
||||
|
||||
float getAverageLoudness() {return _head.averageLoudness;};
|
||||
void setAverageLoudness(float al) {_head.averageLoudness = al;};
|
||||
|
||||
void SetNewHeadTarget(float, float);
|
||||
|
||||
// Set what driving keys are being pressed to control thrust levels
|
||||
void setDriveKeys(int key, bool val) { _driveKeys[key] = val; };
|
||||
bool getDriveKeys(int key) { return _driveKeys[key]; };
|
||||
|
||||
// Set/Get update the thrust that will move the avatar around
|
||||
void setThrust(glm::vec3 newThrust) { _thrust = newThrust; };
|
||||
void addThrust(glm::vec3 newThrust) { _thrust += newThrust; };
|
||||
glm::vec3 getThrust() { return _thrust; };
|
||||
|
||||
// Related to getting transmitter UDP data used to animate the avatar hand
|
||||
void processTransmitterData(unsigned char * packetData, int numBytes);
|
||||
float getTransmitterHz() { return _transmitterHz; };
|
||||
|
||||
private:
|
||||
AvatarHead _head;
|
||||
bool _isMine;
|
||||
glm::vec3 _TEST_bigSpherePosition;
|
||||
float _TEST_bigSphereRadius;
|
||||
bool _mousePressed;
|
||||
float _bodyYawDelta;
|
||||
bool _usingBodySprings;
|
||||
glm::vec3 _movedHandOffset;
|
||||
float _springVelocityDecay;
|
||||
float _springForce;
|
||||
glm::quat _rotation; // the rotation of the avatar body as a whole expressed as a quaternion
|
||||
AvatarBone _bone[ NUM_AVATAR_BONES ];
|
||||
AvatarMode _mode;
|
||||
AvatarHandHolding _handHolding;
|
||||
glm::dvec3 _velocity;
|
||||
glm::vec3 _thrust;
|
||||
float _maxArmLength;
|
||||
Orientation _orientation;
|
||||
int _driveKeys[MAX_DRIVE_KEYS];
|
||||
GLUquadric* _sphere;
|
||||
float _renderYaw;
|
||||
float _renderPitch; // Pitch from view frustum when this is own head
|
||||
timeval _transmitterTimer;
|
||||
float _transmitterHz;
|
||||
int _transmitterPackets;
|
||||
Head* _interactingOther;
|
||||
bool _interactingOtherIsNearby;
|
||||
|
||||
//-----------------------------
|
||||
// private methods...
|
||||
//-----------------------------
|
||||
void initializeSkeleton();
|
||||
void updateSkeleton();
|
||||
void initializeBodySprings();
|
||||
void updateBodySprings( float deltaTime );
|
||||
void calculateBoneLengths();
|
||||
void readSensors();
|
||||
void renderBoneAsBlock( AvatarBoneID b );
|
||||
void updateAvatarCollisionDetectionAndResponse
|
||||
(
|
||||
glm::vec3 collisionPosition,
|
||||
float collisionGirth,
|
||||
float collisionHeight,
|
||||
glm::vec3 collisionUpVector,
|
||||
float deltaTime
|
||||
);
|
||||
};
|
||||
|
||||
#endif
|
|
@ -60,8 +60,8 @@ VoxelSystem::~VoxelSystem() {
|
|||
pthread_mutex_destroy(&bufferWriteLock);
|
||||
}
|
||||
|
||||
void VoxelSystem::setViewerHead(Head *newViewerHead) {
|
||||
viewerHead = newViewerHead;
|
||||
void VoxelSystem::setViewerAvatar(Avatar *newViewerAvatar) {
|
||||
viewerAvatar = newViewerAvatar;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -187,7 +187,7 @@ int VoxelSystem::treeToArrays(VoxelNode *currentNode, const glm::vec3& nodePosi
|
|||
int voxelsAdded = 0;
|
||||
|
||||
float halfUnitForVoxel = powf(0.5, *currentNode->octalCode) * (0.5 * TREE_SCALE);
|
||||
glm::vec3 viewerPosition = viewerHead->getPosition();
|
||||
glm::vec3 viewerPosition = viewerAvatar->getPosition();
|
||||
|
||||
// debug LOD code
|
||||
glm::vec3 debugNodePosition;
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
#include <AgentData.h>
|
||||
#include <VoxelTree.h>
|
||||
#include <ViewFrustum.h>
|
||||
#include "Head.h"
|
||||
#include "Avatar.h"
|
||||
#include "Util.h"
|
||||
#include "world.h"
|
||||
|
||||
|
@ -34,7 +34,7 @@ public:
|
|||
void render();
|
||||
void setVoxelsRendered(int v) {voxelsRendered = v;};
|
||||
int getVoxelsRendered() {return voxelsRendered;};
|
||||
void setViewerHead(Head *newViewerHead);
|
||||
void setViewerAvatar(Avatar *newViewerAvatar);
|
||||
void loadVoxelsFile(const char* fileName,bool wantColorRandomizer);
|
||||
void createSphere(float r,float xc, float yc, float zc, float s, bool solid, bool wantColorRandomizer);
|
||||
|
||||
|
@ -67,7 +67,7 @@ private:
|
|||
static float _minDistance;
|
||||
|
||||
int voxelsRendered;
|
||||
Head *viewerHead;
|
||||
Avatar *viewerAvatar;
|
||||
VoxelTree *tree;
|
||||
GLfloat *readVerticesArray;
|
||||
GLubyte *readColorsArray;
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
#include "MenuColumn.h"
|
||||
#include "Menu.h"
|
||||
#include "Camera.h"
|
||||
#include "Head.h"
|
||||
#include "Avatar.h"
|
||||
#include "Particle.h"
|
||||
#include "Texture.h"
|
||||
#include "Cloud.h"
|
||||
|
@ -107,7 +107,7 @@ Oscilloscope audioScope(256,200,true);
|
|||
|
||||
ViewFrustum viewFrustum; // current state of view frustum, perspective, orientation, etc.
|
||||
|
||||
Head myAvatar(true); // The rendered avatar of oneself
|
||||
Avatar myAvatar(true); // The rendered avatar of oneself
|
||||
Camera myCamera; // My view onto the world (sometimes on myself :)
|
||||
Camera viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode
|
||||
|
||||
|
@ -382,7 +382,7 @@ void initDisplay(void)
|
|||
void init(void)
|
||||
{
|
||||
voxels.init();
|
||||
voxels.setViewerHead(&myAvatar);
|
||||
voxels.setViewerAvatar(&myAvatar);
|
||||
myAvatar.setRenderYaw(startYaw);
|
||||
|
||||
initializeHandController();
|
||||
|
@ -911,7 +911,7 @@ void display(void)
|
|||
agent != agentList->getAgents().end();
|
||||
agent++) {
|
||||
if (agent->getLinkedData() != NULL && agent->getType() == AGENT_TYPE_AVATAR) {
|
||||
Head *avatar = (Head *)agent->getLinkedData();
|
||||
Avatar *avatar = (Avatar *)agent->getLinkedData();
|
||||
avatar->render(0);
|
||||
}
|
||||
}
|
||||
|
@ -1493,7 +1493,7 @@ void idle(void) {
|
|||
{
|
||||
if (agent->getLinkedData() != NULL)
|
||||
{
|
||||
Head *avatar = (Head *)agent->getLinkedData();
|
||||
Avatar *avatar = (Avatar *)agent->getLinkedData();
|
||||
avatar->simulate(deltaTime);
|
||||
}
|
||||
}
|
||||
|
@ -1604,7 +1604,7 @@ void mouseoverFunc( int x, int y)
|
|||
|
||||
void attachNewHeadToAgent(Agent *newAgent) {
|
||||
if (newAgent->getLinkedData() == NULL) {
|
||||
newAgent->setLinkedData(new Head(false));
|
||||
newAgent->setLinkedData(new Avatar(false));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue