diff --git a/models/test/face-eyes.png b/models/test/face-eyes.png index 218153c..0d71201 100644 Binary files a/models/test/face-eyes.png and b/models/test/face-eyes.png differ diff --git a/models/test/face-iris.png b/models/test/face-iris.png new file mode 100644 index 0000000..0b01c66 Binary files /dev/null and b/models/test/face-iris.png differ diff --git a/models/test/model.toml b/models/test/model.toml index 1557b8f..6338d35 100644 --- a/models/test/model.toml +++ b/models/test/model.toml @@ -17,6 +17,14 @@ bind = "head" follow = "face" factor = 0.85 +[[part]] +texture = "face-iris.png" +bind = "head" +follow = "face" +factor = 0.85 +offset_bind = "offset-eyes" +offset_factor = 0.03 + [[part]] bind = "head" follow = "face" diff --git a/src/cv.cpp b/src/cv.cpp index df49863..2ad7d48 100644 --- a/src/cv.cpp +++ b/src/cv.cpp @@ -137,6 +137,7 @@ void cvFrame() { landmarks[biggestFace][30].x * 2 / (float)frame.cols - 1, landmarks[biggestFace][30].y * 2 / (float)frame.rows - 1 ); + faceData.positions[OFFSET_EYES] = eyeVector; faceData.triggers[TRIGGER_NULL] = false; faceData.triggers[TRIGGER_MOUTH_OPEN] = diff --git a/src/model.cpp b/src/model.cpp index 4b0e876..de0ba3f 100644 --- a/src/model.cpp +++ b/src/model.cpp @@ -122,6 +122,7 @@ Model::Model(const char* path) { // rotation and scale factor auto rotFacResult = partsVec[i].getDouble("rot_factor"); auto scaleFacResult = partsVec[i].getDouble("scale_factor"); + auto offsetFacResult = partsVec[i].getDouble("offset_factor"); if (rotFacResult.first) { newPart.rotFactor = (float)rotFacResult.second; @@ -129,6 +130,10 @@ Model::Model(const char* path) { if (scaleFacResult.first) { newPart.scaleFactor = (float)scaleFacResult.second; } + if (offsetFacResult.first) { + newPart.offsetFactor = (float)offsetFacResult.second; + } + // origin auto originArray = partsVec[i].getArray("origin"); @@ -154,6 +159,13 @@ Model::Model(const char* path) { newPart.scaleOffset = glm::vec2((float)offsetVec[0], (float)offsetVec[1]); } + // offset bind + auto offsetBindResult = partsVec[i].getString("offset_bind"); + if (offsetBindResult.first) { + newPart.setOffsetBind(offsetBindResult.second); + } + + // texture auto textureSingle = partsVec[i].getString("texture"); diff --git a/src/modelpart.cpp b/src/modelpart.cpp index d5001b6..7073771 100644 --- a/src/modelpart.cpp +++ b/src/modelpart.cpp @@ -11,6 +11,7 @@ std::map bindStringToNum { {"null", BIND_NULL}, {"head", BIND_HEAD}, {"face", BIND_FACE}, + {"offset-eyes", OFFSET_EYES}, }; std::map triggerStringToNum { @@ -40,6 +41,10 @@ void ModelPart::setFollowTarget(std::string followTarget) { follow = bindStringToNum[followTarget]; } +void ModelPart::setOffsetBind(std::string bindName) { + offsetBind = bindStringToNum[bindName]; +} + void ModelPart::smoothTransform(glm::vec2 position, float rotation, float scale) { histPositions[histI] = position; histRotations[histI] = rotation; @@ -78,7 +83,8 @@ void ModelPart::processFaceData(struct FaceData faceData) { glm::vec2 bindPosition = faceData.positions[bind]; glm::vec2 followPosition = faceData.positions[follow]; glm::vec2 followDirection = followPosition - bindPosition; - glm::vec2 newPosition = bindPosition + (followDirection * factor); + glm::vec2 offset = faceData.positions[offsetBind] * offsetFactor; + glm::vec2 newPosition = bindPosition + offset + (followDirection * factor); smoothTransform(newPosition, faceData.headRotation, faceData.scale); diff --git a/src/modelpart.hpp b/src/modelpart.hpp index 63db13e..9f5a6a0 100644 --- a/src/modelpart.hpp +++ b/src/modelpart.hpp @@ -11,6 +11,9 @@ #define BIND_HEAD 0x01 #define BIND_FACE 0x02 +#define OFFSET_EYES 0x10 + + #define TRIGGER_NULL 0x00 #define TRIGGER_MOUTH_OPEN 0x01 @@ -38,6 +41,8 @@ class ModelPart { int bind = BIND_NULL; int follow = BIND_NULL; float factor = 0.0f; //default factor of 0 so part will not follow a null by default + int offsetBind = BIND_NULL; + float offsetFactor = 0.0f; float rotFactor = 1.0f; float scaleFactor = 1.0f; @@ -54,6 +59,7 @@ class ModelPart { void setBind(std::string bindName); void setFollowTarget(std::string followTarget); + void setOffsetBind(std::string bindName); void smoothTransform(glm::vec2 position, float rotation, float scale); void setTransform(glm::vec2 position, float rotation, float scale);