예제 #1
0
/* Variables::set: set value */
void Variables::set(const char *alias, const char *str1, const char *str2)
{
   Value *val;

   float max, min, tmp;

   if(MMDAgent_strlen(alias) <= 0) return;

   /* check the same alias */
   for(val = m_head; val; val = val->next) {
      if(MMDAgent_strequal(val->name, alias))
         break;
   }

   /* push */
   if(val == NULL) {
      val = (Value *) malloc(sizeof(Value));
      val->name = MMDAgent_strdup(alias);
      val->next = NULL;
      if(m_tail == NULL) {
         m_head = val;
         val->prev = NULL;
      } else {
         m_tail->next = val;
         val->prev = m_tail;
      }
      m_tail = val;
   } else {
      free(val->sval);
   }

   /* set string */
   if(str2 == NULL) {
      val->sval = MMDAgent_strdup(str1);
   } else {
      val->sval = (char *) malloc(sizeof(char) * (MMDAgent_strlen(str1) + 1 + MMDAgent_strlen(str2) + 1));
      sprintf(val->sval, "%s|%s", str1, str2);
   }

   /* set float */
   if(str2 == NULL) {
      val->fval = MMDAgent_str2float(str1);
   } else {
      min = MMDAgent_str2float(str1);
      max = MMDAgent_str2float(str2);
      if(max < min) {
         tmp = max;
         max = min;
         min = tmp;
      }
      val->fval = min + (max - min) * (rand() - 0.0f) * (1.0f / (RAND_MAX - 0.0f)); /* 0.0f is RAND_MIN */
   }

   m_mmdagent->sendEventMessage(VARIABLES_VALUESETEVENT, alias); /* send message */
}
예제 #2
0
/* Variables::evaluate: evaluate value */
void Variables::evaluate(const char *alias, const char *mode, const char *str)
{
   Value *val;
   float f1, f2;
   bool ret;

   /* get value 1 */
   for(val = m_head; val; val = val->next) {
      if(MMDAgent_strequal(val->name, alias) == true) {
         f1 = val->fval;
         break;
      }
   }
   if(val == NULL)
      return;

   /* get value 2 */
   f2 = MMDAgent_str2float(str);

   /* evaluate */
   if(MMDAgent_strequal(mode, VARIABLES_EQ) == true) {
      if(f1 == f2)
         ret = true;
      else
         ret = false;
   } else if(MMDAgent_strequal(mode, VARIABLES_NE) == true) {
      if(f1 != f2)
         ret = true;
      else
         ret = false;
   } else if(MMDAgent_strequal(mode, VARIABLES_LE) == true) {
      if(f1 <= f2)
         ret = true;
      else
         ret = false;
   } else if(MMDAgent_strequal(mode, VARIABLES_LT) == true) {
      if(f1 < f2)
         ret = true;
      else
         ret = false;
   } else if(MMDAgent_strequal(mode, VARIABLES_GE) == true) {
      if(f1 >= f2)
         ret = true;
      else
         ret = false;
   } else if(MMDAgent_strequal(mode, VARIABLES_GT) == true) {
      if(f1 > f2)
         ret = true;
      else
         ret = false;
   } else {
      /* unknown mode */
      return;
   }

   if(ret == true)
      m_mmdagent->sendEventMessage(VARIABLES_VALUEEVALEVENT, "%s|%s|%s|%s", alias, mode, str, VARIABLES_TRUE);
   else
      m_mmdagent->sendEventMessage(VARIABLES_VALUEEVALEVENT, "%s|%s|%s|%s", alias, mode, str, VARIABLES_FALSE);
}
예제 #3
0
/* LipSync::load: initialize and load lip setting */
bool LipSync::load(const char *file)
{
   int i, j;
   FILE *fp;
   int len;
   char buff[LIPSYNC_MAXBUFLEN];
   bool err = false;

   fp = MMDAgent_fopen(file, "r");
   if(fp == NULL)
      return false;

   /* number of expression */
   len = MMDAgent_fgettoken(fp, buff);
   if(len <= 0) {
      fclose(fp);
      return false;
   }
   m_numMotion = MMDAgent_str2int(buff);
   if(m_numMotion <= 0) {
      fclose(fp);
      clear();
      return false;
   }

   /* motion name */
   m_motion = (char **) malloc(sizeof(char *) * m_numMotion);
   for(i = 0; i < m_numMotion; i++) {
      len = MMDAgent_fgettoken(fp, buff);
      if(len <= 0) err = true;
      m_motion[i] = MMDAgent_strdup(buff);
   }
   if(err == true) {
      fclose(fp);
      clear();
      return false;
   }

   /* number of phone */
   len = MMDAgent_fgettoken(fp, buff);
   if(len <= 0) {
      fclose(fp);
      clear();
      return false;
   }
   m_numPhone = MMDAgent_str2int(buff);
   if(m_numPhone <= 0) {
      fclose(fp);
      clear();
      return false;
   }

   /* phone name, type, and blend rate */
   m_phone = (char **) malloc(sizeof(char *) * m_numPhone);
   m_blendRate = (float **) malloc(sizeof(float *) * m_numPhone);
   for(i = 0; i < m_numPhone; i++) {
      len = MMDAgent_fgettoken(fp, buff);
      if(len <= 0) err = true;
      m_phone[i] = MMDAgent_strdup(buff);
      m_blendRate[i] = (float *) malloc(sizeof(float) * m_numMotion);
      for(j = 0; j < m_numMotion; j++) {
         len = MMDAgent_fgettoken(fp, buff);
         if(len <= 0) err = true;
         m_blendRate[i][j] = MMDAgent_str2float(buff);
         if(m_blendRate[i][j] < 0.0f) err = true;
      }
   }
   if(err == true) {
      fclose(fp);
      clear();
      return false;
   }

   fclose(fp);
   return true;
}
예제 #4
0
/* LipSync::createMotion: create motion from phoneme sequence */
bool LipSync::createMotion(const char *str, unsigned char **rawData, unsigned long *rawSize)
{
   int i, j, k;
   int len;
   char *buf, *p, *save;

   LipKeyFrame *head, *tail, *tmp1, *tmp2;
   float f, diff;

   int totalNumKey;
   unsigned long currentFrame;
   unsigned char *data;
   VMDFile_Header *header;
   unsigned long *numBoneKeyFrames;
   unsigned long *numFaceKeyFrames;
   VMDFile_FaceFrame *face;

   /* check */
   if(str == NULL || m_numMotion <= 0 || m_numPhone <= 0)
      return false;

   /* initialize */
   (*rawData) = NULL;
   (*rawSize) = 0;

   /* get phone index and duration */
   buf = MMDAgent_strdup(str);
   head = NULL;
   tail = NULL;
   diff = 0.0f;
   for(i = 0, k = 0, p = MMDAgent_strtok(buf, LIPSYNC_SEPARATOR, &save); p; i++, p = MMDAgent_strtok(NULL, LIPSYNC_SEPARATOR, &save)) {
      if(i % 2 == 0) {
         for(j = 0; j < m_numPhone; j++) {
            if(MMDAgent_strequal(m_phone[j], p)) {
               k = j;
               break;
            }
         }
         if(m_numPhone <= j)
            k = 0;
      } else {
         tmp1 = (LipKeyFrame *) malloc(sizeof(LipKeyFrame));
         tmp1->phone = k;
         f = 0.03f * MMDAgent_str2float(p) + diff; /* convert ms to frame */
         tmp1->duration = (int) (f + 0.5);
         if(tmp1->duration < 1)
            tmp1->duration = 1;
         diff = f - tmp1->duration;
         tmp1->rate = 1.0f;
         tmp1->next = NULL;
         if(head == NULL)
            head = tmp1;
         else
            tail->next = tmp1;
         tail = tmp1;
      }
   }

   /* add final closed lip */
   tmp1 = (LipKeyFrame *) malloc(sizeof(LipKeyFrame));
   tmp1->phone = 0;
   tmp1->duration = 1;
   tmp1->rate = 0.0f;
   tmp1->next = NULL;
   if(head == NULL)
      head = tmp1;
   else
      tail->next = tmp1;
   tail = tmp1;

   /* insert interpolation lip motion */
   for(tmp1 = head; tmp1; tmp1 = tmp1->next) {
      if(tmp1->next && tmp1->duration > LIPSYNC_INTERPOLATIONMARGIN) {
         tmp2 = (LipKeyFrame *) malloc(sizeof(LipKeyFrame));
         tmp2->phone = tmp1->phone;
         tmp2->duration = LIPSYNC_INTERPOLATIONMARGIN;
         tmp2->rate = tmp1->rate * LIPSYNC_INTERPOLATIONRATE;
         tmp2->next = tmp1->next;
         tmp1->duration -= LIPSYNC_INTERPOLATIONMARGIN;
         tmp1->next = tmp2;
         tmp2 = tmp1;
      }
   }

   /* count length of key frame */
   len = 0;
   for(tmp1 = head; tmp1; tmp1 = tmp1->next)
      len++;

   totalNumKey = m_numMotion * len;

   /* create memories */
   (*rawSize) = sizeof(VMDFile_Header) + sizeof(unsigned long) + sizeof(unsigned long) + sizeof(VMDFile_FaceFrame) * totalNumKey;
   i = (*rawSize);
   i = sizeof(unsigned char) * (*rawSize);
   (*rawData) = (unsigned char *) malloc(i);

   data = (*rawData);
   /* header */
   header = (VMDFile_Header *) data;
   strncpy(header->header, "Vocaloid Motion Data 0002", 30);
   data += sizeof(VMDFile_Header);
   /* number of key frame for bone */
   numBoneKeyFrames = (unsigned long *) data;
   (*numBoneKeyFrames) = 0;
   data += sizeof(unsigned long);
   /* number of key frame for expression */
   numFaceKeyFrames = (unsigned long *) data;
   (*numFaceKeyFrames) = totalNumKey;
   data += sizeof(unsigned long);
   /* set key frame */
   for (i = 0; i < m_numMotion; i++) {
      currentFrame = 0;
      for(tmp1 = head; tmp1; tmp1 = tmp1->next) {
         face = (VMDFile_FaceFrame *) data;
         strncpy(face->name, m_motion[i], 15);
         face->keyFrame = currentFrame;
         face->weight = m_blendRate[tmp1->phone][i] * tmp1->rate;
         data += sizeof(VMDFile_FaceFrame);
         currentFrame += tmp1->duration;
      }
   }

   /* free */
   free(buf);
   for(tmp1 = head; tmp1; tmp1 = tmp2) {
      tmp2 = tmp1->next;
      free(tmp1);
   }
   return true;
}
/* Option::load: load options from config file */
bool Option::load(const char *file)
{
   FILE *fp;
   char buf[OPTION_MAXBUFLEN];
   int len;
   char *p1;

   int ivec2[2];
   float fvec3[3];
   float fvec4[4];

   fp = MMDAgent_fopen(file, "r");
   if (fp == NULL)
      return false;

   while (fgets(buf, OPTION_MAXBUFLEN, fp)) {
      len = MMDAgent_strlen(buf);
      if(len <= 0) continue;
      p1 = &(buf[len - 1]);
      while (p1 >= &(buf[0]) && (*p1 == '\n' || *p1 == '\r' || *p1 == '\t' || *p1 == ' ')) {
         *p1 = L'\0';
         p1--;
      }
      p1 = &(buf[0]);
      if (*p1 == '#') continue;
      while (*p1 != L'=' && *p1 != L'\0') p1++;
      if (*p1 == L'\0') continue;
      *p1 = L'\0';
      p1++;

      /* overwrite option values */
      if(MMDAgent_strequal(buf, OPTION_USECARTOONRENDERING_STR)) {
         setUseCartoonRendering(MMDAgent_str2bool(p1));
      } else if(MMDAgent_strequal(buf, OPTION_USEMMDLIKECARTOON_STR)) {
         setUseMMDLikeCartoon(MMDAgent_str2bool(p1));
      } else if(MMDAgent_strequal(buf, OPTION_CARTOONEDGEWIDTH_STR)) {
         setCartoonEdgeWidth(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_CARTOONEDGESTEP_STR)) {
         setCartoonEdgeStep(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_CARTOONEDGESELECTEDCOLOR_STR)) {
         if(MMDAgent_str2fvec(p1, fvec4, 4))
            setCartoonEdgeSelectedColor(fvec4);
      } else if(MMDAgent_strequal(buf, OPTION_CAMERAROTATION_STR)) {
         if(MMDAgent_str2fvec(p1, fvec3, 3))
            setCameraRotation(fvec3);
      } else if(MMDAgent_strequal(buf, OPTION_CAMERATRANSITION_STR)) {
         if(MMDAgent_str2fvec(p1, fvec3, 3))
            setCameraTransition(fvec3);
      } else if(MMDAgent_strequal(buf, OPTION_CAMERADISTANCE_STR)) {
         setCameraDistance(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_CAMERAFOVY_STR)) {
         setCameraFovy(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_STAGESIZE_STR)) {
         if(MMDAgent_str2fvec(p1, fvec3, 3))
            setStageSize(fvec3);
      } else if(MMDAgent_strequal(buf, OPTION_SHOWFPS_STR)) {
         setShowFps(MMDAgent_str2bool(p1));
      } else if(MMDAgent_strequal(buf, OPTION_FPSPOSITION_STR)) {
         if(MMDAgent_str2fvec(p1, fvec3, 3))
            setFpsPosition(fvec3);
      } else if(MMDAgent_strequal(buf, OPTION_WINDOWSIZE_STR)) {
         if(MMDAgent_str2ivec(p1, ivec2, 2))
            setWindowSize(ivec2);
      } else if(MMDAgent_strequal(buf, OPTION_FULLSCREEN_STR)) {
         setFullScreen(MMDAgent_str2bool(p1));
      } else if(MMDAgent_strequal(buf, OPTION_LOGSIZE_STR)) {
         if(MMDAgent_str2ivec(p1, ivec2, 2))
            setLogSize(ivec2);
      } else if(MMDAgent_strequal(buf, OPTION_LOGPOSITION_STR)) {
         if(MMDAgent_str2fvec(p1, fvec3, 3))
            setLogPosition(fvec3);
      } else if(MMDAgent_strequal(buf, OPTION_LOGSCALE_STR)) {
         setLogScale(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_LIGHTDIRECTION_STR)) {
         if(MMDAgent_str2fvec(p1, fvec4, 4))
            setLightDirection(fvec4);
      } else if(MMDAgent_strequal(buf, OPTION_LIGHTINTENSITY_STR)) {
         setLightIntensity(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_LIGHTCOLOR_STR)) {
         if(MMDAgent_str2fvec(p1, fvec3, 3))
            setLightColor(fvec3);
      } else if(MMDAgent_strequal(buf, OPTION_CAMPUSCOLOR_STR)) {
         if(MMDAgent_str2fvec(p1, fvec3, 3))
            setCampusColor(fvec3);
      } else if(MMDAgent_strequal(buf, OPTION_MAXMULTISAMPLING_STR)) {
         setMaxMultiSampling(MMDAgent_str2int(p1));
      } else if(MMDAgent_strequal(buf, OPTION_MOTIONADJUSTTIME_STR)) {
         setMotionAdjustTime(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_LIPSYNCPRIORITY_STR)) {
         setLipsyncPriority(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_BULLETFPS_STR)) {
         setBulletFps(MMDAgent_str2int(p1));
      } else if(MMDAgent_strequal(buf, OPTION_GRAVITYFACTOR_STR)) {
         setGravityFactor(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_ROTATESTEP_STR)) {
         setRotateStep(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_TRANSLATESTEP_STR)) {
         setTranslateStep(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_DISTANCESTEP_STR)) {
         setDistanceStep(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_FOVYSTEP_STR)) {
         setFovyStep(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_USESHADOWMAPPING_STR)) {
         setUseShadowMapping(MMDAgent_str2bool(p1));
      } else if(MMDAgent_strequal(buf, OPTION_SHADOWMAPPINGTEXTURESIZE_STR)) {
         setShadowMappingTextureSize(MMDAgent_str2int(p1));
      } else if(MMDAgent_strequal(buf, OPTION_SHADOWMAPPINGSELFDENSITY_STR)) {
         setShadowMappingSelfDensity(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_SHADOWMAPPINGFLOORDENSITY_STR)) {
         setShadowMappingFloorDensity(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_SHADOWMAPPINGLIGHTFIRST_STR)) {
         setShadowMappingLightFirst(MMDAgent_str2bool(p1));
      } else if(MMDAgent_strequal(buf, OPTION_DISPLAYCOMMENTTIME_STR)) {
         setDisplayCommentTime(MMDAgent_str2float(p1));
      } else if(MMDAgent_strequal(buf, OPTION_MAXNUMMODEL_STR)) {
         setMaxNumModel(MMDAgent_str2int(p1));
      }
   }
   fclose(fp);

   return true;
}