Animation* AnimationTarget::createAnimationFromBy(const char* id, int propertyId, float* from, float* by, Curve::InterpolationType type, unsigned long duration) { GP_ASSERT(from); GP_ASSERT(by); const unsigned int propertyComponentCount = getAnimationPropertyComponentCount(propertyId); GP_ASSERT(propertyComponentCount > 0); float* keyValues = new float[2 * propertyComponentCount]; memcpy(keyValues, from, sizeof(float) * propertyComponentCount); convertByValues(propertyId, propertyComponentCount, from, by); memcpy(keyValues + propertyComponentCount, by, sizeof(float) * propertyComponentCount); unsigned int* keyTimes = new unsigned int[2]; keyTimes[0] = 0; keyTimes[1] = (unsigned int)duration; Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type); SAFE_DELETE_ARRAY(keyValues); SAFE_DELETE_ARRAY(keyTimes); return animation; }
Animation* AnimationTarget::createAnimationFromTo(const char* id, int propertyId, float* from, float* to, Curve::InterpolationType type, unsigned long duration) { const unsigned int propertyComponentCount = getAnimationPropertyComponentCount(propertyId); float* keyValues = new float[2 * propertyComponentCount]; memcpy(keyValues, from, sizeof(float) * propertyComponentCount); memcpy(keyValues + propertyComponentCount, to, sizeof(float) * propertyComponentCount); unsigned long* keyTimes = new unsigned long[2]; keyTimes[0] = 0; keyTimes[1] = duration; Animation* animation = createAnimation(id, propertyId, 2, keyTimes, keyValues, type); SAFE_DELETE_ARRAY(keyValues); SAFE_DELETE_ARRAY(keyTimes); return animation; }
Animation* AnimationTarget::createAnimation(const char* id, Properties* animationProperties) { GP_ASSERT(animationProperties); if (std::strcmp(animationProperties->getNamespace(), "animation") != 0) { GP_ERROR("Invalid animation namespace '%s'.", animationProperties->getNamespace()); return NULL; } const char* propertyIdStr = animationProperties->getString("property"); if (propertyIdStr == NULL) { GP_ERROR("Attribute 'property' must be specified for an animation."); return NULL; } // Get animation target property id int propertyId = getPropertyId(_targetType, propertyIdStr); if (propertyId == -1) { GP_ERROR("Property ID is invalid."); return NULL; } unsigned int keyCount = animationProperties->getInt("keyCount"); if (keyCount == 0) { GP_ERROR("Attribute 'keyCount' must be specified for an animation."); return NULL; } const char* keyTimesStr = animationProperties->getString("keyTimes"); if (keyTimesStr == NULL) { GP_ERROR("Attribute 'keyTimes' must be specified for an animation."); return NULL; } const char* keyValuesStr = animationProperties->getString("keyValues"); if (keyValuesStr == NULL) { GP_ERROR("Attribute 'keyValues' must be specified for an animation."); return NULL; } const char* curveStr = animationProperties->getString("curve"); if (curveStr == NULL) { GP_ERROR("Attribute 'curve' must be specified for an animation."); return NULL; } char delimeter = ' '; size_t startOffset = 0; size_t endOffset = std::string::npos; unsigned int* keyTimes = new unsigned int[keyCount]; for (size_t i = 0; i < keyCount; i++) { endOffset = static_cast<std::string>(keyTimesStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, endOffset - startOffset).c_str(), NULL, 0); } else { keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, static_cast<std::string>(keyTimesStr).length()).c_str(), NULL, 0); } startOffset = endOffset + 1; } startOffset = 0; endOffset = std::string::npos; int componentCount = getAnimationPropertyComponentCount(propertyId); GP_ASSERT(componentCount > 0); unsigned int components = keyCount * componentCount; float* keyValues = new float[components]; for (unsigned int i = 0; i < components; i++) { endOffset = static_cast<std::string>(keyValuesStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, endOffset - startOffset).c_str()); } else { keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, static_cast<std::string>(keyValuesStr).length()).c_str()); } startOffset = endOffset + 1; } const char* keyInStr = animationProperties->getString("keyIn"); float* keyIn = NULL; if (keyInStr) { keyIn = new float[components]; startOffset = 0; endOffset = std::string::npos; for (unsigned int i = 0; i < components; i++) { endOffset = static_cast<std::string>(keyInStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, endOffset - startOffset).c_str()); } else { keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, static_cast<std::string>(keyInStr).length()).c_str()); } startOffset = endOffset + 1; } } const char* keyOutStr = animationProperties->getString("keyOut"); float* keyOut = NULL; if (keyOutStr) { keyOut = new float[components]; startOffset = 0; endOffset = std::string::npos; for (unsigned int i = 0; i < components; i++) { endOffset = static_cast<std::string>(keyOutStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, endOffset - startOffset).c_str()); } else { keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, static_cast<std::string>(keyOutStr).length()).c_str()); } startOffset = endOffset + 1; } } int curve = Curve::getInterpolationType(curveStr); Animation* animation = NULL; if (keyIn && keyOut) { animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, keyIn, keyOut, (Curve::InterpolationType)curve); } else { animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve); } const char* repeat = animationProperties->getString("repeatCount"); if (repeat) { if (strcmp(repeat, ANIMATION_TARGET_INDEFINITE_STR) == 0) { animation->getClip()->setRepeatCount(AnimationClip::REPEAT_INDEFINITE); } else { float value; sscanf(repeat, "%f", &value); animation->getClip()->setRepeatCount(value); } } SAFE_DELETE_ARRAY(keyOut); SAFE_DELETE_ARRAY(keyIn); SAFE_DELETE_ARRAY(keyValues); SAFE_DELETE_ARRAY(keyTimes); Properties* pClip = animationProperties->getNextNamespace(); if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0) { int frameCount = animationProperties->getInt("frameCount"); if (frameCount <= 0) { GP_ERROR("Frame count must be greater than zero for a clip."); return animation; } animation->createClips(animationProperties, (unsigned int) frameCount); } return animation; }
Animation* AnimationTarget::createAnimation(const char* id, Properties* animationProperties) { assert(animationProperties); assert(std::strcmp(animationProperties->getNamespace(), "animation") == 0); const char* propertyIdStr = animationProperties->getString("property"); assert(propertyIdStr); // Get animation target property id int propertyId = AnimationTarget::getPropertyId(_targetType, propertyIdStr); assert(propertyId != -1); unsigned int keyCount = animationProperties->getInt("keyCount"); assert(keyCount > 0); const char* keyTimesStr = animationProperties->getString("keyTimes"); assert(keyTimesStr); const char* keyValuesStr = animationProperties->getString("keyValues"); assert(keyValuesStr); const char* curveStr = animationProperties->getString("curve"); assert(curveStr); char delimeter = ' '; unsigned int startOffset = 0; unsigned int endOffset = (unsigned int)std::string::npos; unsigned long* keyTimes = new unsigned long[keyCount]; for (unsigned int i = 0; i < keyCount; i++) { endOffset = static_cast<std::string>(keyTimesStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, endOffset - startOffset).c_str(), NULL, 0); } else { keyTimes[i] = std::strtoul(static_cast<std::string>(keyTimesStr).substr(startOffset, static_cast<std::string>(keyTimesStr).length()).c_str(), NULL, 0); } startOffset = endOffset + 1; } startOffset = 0; endOffset = (unsigned int)std::string::npos; int componentCount = getAnimationPropertyComponentCount(propertyId); assert(componentCount > 0); unsigned int components = keyCount * componentCount; float* keyValues = new float[components]; for (unsigned int i = 0; i < components; i++) { endOffset = static_cast<std::string>(keyValuesStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, endOffset - startOffset).c_str()); } else { keyValues[i] = std::atof(static_cast<std::string>(keyValuesStr).substr(startOffset, static_cast<std::string>(keyValuesStr).length()).c_str()); } startOffset = endOffset + 1; } const char* keyInStr = animationProperties->getString("keyIn"); float* keyIn = NULL; if (keyInStr) { keyIn = new float[components]; startOffset = 0; endOffset = (unsigned int)std::string::npos; for (unsigned int i = 0; i < components; i++) { endOffset = static_cast<std::string>(keyInStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, endOffset - startOffset).c_str()); } else { keyIn[i] = std::atof(static_cast<std::string>(keyInStr).substr(startOffset, static_cast<std::string>(keyInStr).length()).c_str()); } startOffset = endOffset + 1; } } const char* keyOutStr = animationProperties->getString("keyOut"); float* keyOut = NULL; if (keyOutStr) { keyOut = new float[components]; startOffset = 0; endOffset = (unsigned int)std::string::npos; for (unsigned int i = 0; i < components; i++) { endOffset = static_cast<std::string>(keyOutStr).find_first_of(delimeter, startOffset); if (endOffset != std::string::npos) { keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, endOffset - startOffset).c_str()); } else { keyOut[i] = std::atof(static_cast<std::string>(keyOutStr).substr(startOffset, static_cast<std::string>(keyOutStr).length()).c_str()); } startOffset = endOffset + 1; } } int curve = Curve::getInterpolationType(curveStr); Animation* animation = NULL; if (keyIn && keyOut) { animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, keyIn, keyOut, (Curve::InterpolationType)curve); } else { animation = createAnimation(id, propertyId, keyCount, keyTimes, keyValues, (Curve::InterpolationType) curve); } SAFE_DELETE(keyOut); SAFE_DELETE(keyIn); SAFE_DELETE(keyValues); SAFE_DELETE(keyTimes); Properties* pClip = animationProperties->getNextNamespace(); if (pClip && std::strcmp(pClip->getNamespace(), "clip") == 0) { int frameCount = animationProperties->getInt("frameCount"); assert(frameCount > 0); animation->createClips(animationProperties, (unsigned int) frameCount); } return animation; }