void Camera::update_following(double dt) { ActorPtr following_actor = following_actor_.lock(); if(following_actor) { kmQuaternion actor_rotation = following_actor->absolute_rotation(); kmVec3 actor_position = following_actor->absolute_position(); kmVec3 actor_forward; kmQuaternionGetForwardVec3RH(&actor_forward, &actor_rotation); kmQuaternion initial_rotation; kmQuaternionAssign(&initial_rotation, &rotation_); float t = ((following_lag_ == 0) ? 1.0 : dt * (1.0 / following_lag_)); kmQuaternionSlerp(&rotation_, &initial_rotation, &actor_rotation, t); kmVec3 rotated_offset; kmQuaternionMultiplyVec3(&rotated_offset, &rotation_, &following_offset_); //kmMat4RotationQuaternion(&new_rotation_matrix, &rotation_); //kmVec3MultiplyMat4(&rotated_offset, &following_offset_, &new_rotation_matrix); kmVec3Add(&position_, &rotated_offset, &actor_position); update_from_parent(); } else { //The actor was destroyed, so reset following_actor_ = ActorRef(); } }
kmBool kmRay3IntersectPlane(kmVec3* pOut, const kmRay3* ray, const kmPlane* plane) { //t = - (A*org.x + B*org.y + C*org.z + D) / (A*dir.x + B*dir.y + C*dir.z ) kmScalar d = (plane->a * ray->dir.x + plane->b * ray->dir.y + plane->c * ray->dir.z); if(d == 0) { return KM_FALSE; } kmScalar t = -(plane->a * ray->start.x + plane->b * ray->start.y + plane->c * ray->start.z + plane->d) / d; if(t < 0) { return KM_FALSE; } kmVec3 scaled_dir; kmVec3Scale(&scaled_dir, &ray->dir, t); kmVec3Add(pOut, &ray->start, &scaled_dir); return KM_TRUE; }
kmBool kmRay3IntersectAABB3(const kmRay3* ray, const kmAABB3* aabb, kmVec3* intersection, kmScalar* distance) { //http://gamedev.stackexchange.com/a/18459/15125 kmVec3 rdir, dirfrac, diff; kmVec3Normalize(&rdir, &ray->dir); kmVec3Fill(&dirfrac, 1.0 / rdir.x, 1.0 / rdir.y, 1.0 / rdir.z); kmScalar t1 = (aabb->min.x - ray->start.x) * dirfrac.x; kmScalar t2 = (aabb->max.x - ray->start.x) * dirfrac.x; kmScalar t3 = (aabb->min.y - ray->start.y) * dirfrac.y; kmScalar t4 = (aabb->max.y - ray->start.y) * dirfrac.y; kmScalar t5 = (aabb->min.z - ray->start.z) * dirfrac.z; kmScalar t6 = (aabb->max.z - ray->start.z) * dirfrac.z; kmScalar tmin = kmMax(kmMax(kmMin(t1, t2), kmMin(t3, t4)), kmMin(t5, t6)); kmScalar tmax = kmMin(kmMin(kmMax(t1, t2), kmMax(t3, t4)), kmMax(t5, t6)); // if tmax < 0, ray (line) is intersecting AABB, but whole AABB is behind us if(tmax < 0) { return KM_FALSE; } // if tmin > tmax, ray doesn't intersect AABB if (tmin > tmax) { return KM_FALSE; } if(distance) *distance = tmin; if(intersection) { kmVec3Scale(&diff, &rdir, tmin); kmVec3Add(intersection, &ray->start, &diff); } return KM_TRUE; }
lite3d_scene_node *lite3d_scene_node_move(lite3d_scene_node *node, const kmVec3 *position) { SDL_assert(node && position); kmVec3Add(&node->position, &node->position, position); node->recalc = LITE3D_TRUE; return node; }
kmVec3 AABB::getCenter() const { kmVec3 result; kmVec3Add(&result, &_min, &_max); kmVec3Scale(&result, &result, 0.5f); return result; }
kmVec3* kmVec3ProjectOnToPlane(kmVec3* pOut, const kmVec3* point, const struct kmPlane* plane) { kmVec3 N; kmVec3Fill(&N, plane->a, plane->b, plane->c); kmVec3Normalize(&N, &N); kmScalar distance = -kmVec3Dot(&N, point); kmVec3Scale(&N, &N, distance); kmVec3Add(pOut, point, &N); return pOut; }
kmVec3* kmQuaternionMultiplyVec3(kmVec3* pOut, const kmQuaternion* q, const kmVec3* v) { kmVec3 uv, uuv, qvec; qvec.x = q->x; qvec.y = q->y; qvec.z = q->z; kmVec3Cross(&uv, &qvec, v); kmVec3Cross(&uuv, &qvec, &uv); kmVec3Scale(&uv, &uv, (2.0f * q->w)); kmVec3Scale(&uuv, &uuv, 2.0f); kmVec3Add(pOut, v, &uv); kmVec3Add(pOut, pOut, &uuv); return pOut; }
/* Move camera */ void dlMoveCamera( dlCamera *object, kmVec3 *move ) { CALL("%p, vec3[%f, %f, %f]", object, move->x, move->y, move->z); if(!object) return; kmVec3Add( &object->translation, &object->translation, move ); object->transform_changed = 1; }
void BoundingBox::getCenter(kmVec3* dst) const { GP_ASSERT(dst); kmVec3Subtract(dst, &max, &min); //dst->set(min, max); //dst->scale(0.5f); kmVec3Scale(dst, dst, 0.5f); //dst->add(min); kmVec3Add(dst, dst, &min); return; }
/* move sceneobject */ void dlMoveObject( dlObject *object, kmVec3 *move ) { unsigned int i; CALL("%p, vec3[%f, %f, %f]", object, move->x, move->y, move->z); kmVec3Add( &object->translation, &object->translation, move ); object->transform_changed = 1; i = 0; for(; i != object->num_childs; ++i) dlMoveObject( object->child[i], move ); }
kmBool kmRay3IntersectTriangle(const kmRay3* ray, const kmVec3* v0, const kmVec3* v1, const kmVec3* v2, kmVec3* intersection, kmVec3* normal, kmScalar* distance) { kmVec3 e1, e2, pvec, tvec, qvec, dir; kmScalar det, inv_det, u, v, t; kmVec3Normalize(&dir, &ray->dir); kmVec3Subtract(&e1, v1, v0); kmVec3Subtract(&e2, v2, v0); kmVec3Cross(&pvec, &dir, &e2); det = kmVec3Dot(&e1, &pvec); /* Backfacing, discard. */ if(det < kmEpsilon) { return KM_FALSE; } if(kmAlmostEqual(det, 0)) { return KM_FALSE; } inv_det = 1.0 / det; kmVec3Subtract(&tvec, &ray->start, v0); u = inv_det * kmVec3Dot(&tvec, &pvec); if(u < 0.0 || u > 1.0) { return KM_FALSE; } kmVec3Cross(&qvec, &tvec, &e1); v = inv_det * kmVec3Dot(&dir, &qvec); if(v < 0.0 || (u + v) > 1.0) { return KM_FALSE; } t = inv_det * kmVec3Dot(&e2, &qvec); if(t > kmEpsilon && (t*t) <= kmVec3LengthSq(&ray->dir)) { kmVec3 scaled; *distance = t; /* Distance */ kmVec3Cross(normal, &e1, &e2); /* Surface normal of collision */ kmVec3Normalize(normal, normal); kmVec3Normalize(&scaled, &dir); kmVec3Scale(&scaled, &scaled, *distance); kmVec3Add(intersection, &ray->start, &scaled); return KM_TRUE; } return KM_FALSE; }
void lite3d_bounding_vol_setup(struct lite3d_bounding_vol *vol, const kmVec3 *vmin, const kmVec3 *vmax) { float l, w, h; kmVec3 center; SDL_assert(vmin); SDL_assert(vmax); SDL_assert(vol); l = vmax->x - vmin->x; w = vmax->y - vmin->y; h = vmax->z - vmin->z; vol->box[0] = *vmin; vol->box[1].x = vmin->x; vol->box[1].y = vmin->y; vol->box[1].z = vmin->z + h; vol->box[2].x = vmin->x; vol->box[2].y = vmin->y + w; vol->box[2].z = vmin->z + h; vol->box[3].x = vmin->x; vol->box[3].y = vmin->y + w; vol->box[3].z = vmin->z; vol->box[4].x = vmin->x + l; vol->box[4].y = vmin->y; vol->box[4].z = vmin->z; vol->box[5].x = vmin->x + l; vol->box[5].y = vmin->y; vol->box[5].z = vmin->z + h; vol->box[6].x = vmin->x + l; vol->box[6].y = vmin->y + w; vol->box[6].z = vmin->z; vol->box[7] = *vmax; /* calc center vector */ center.x = l / 2; center.y = w / 2; center.z = h / 2; kmVec3Add(&vol->sphereCenter, vmin, ¢er); vol->radius = kmVec3Length(¢er); }
/* \brief cast a ray from camera at specified relative coordinate */ GLHCKAPI kmRay3* glhckCameraCastRayFromPoint(glhckCamera *object, kmRay3 *pOut, const kmVec2 *point) { CALL(2, "%p, "VEC2S, pOut, VEC2(point)); glhckFrustum *frustum = glhckCameraGetFrustum(object); kmVec3 nu, nv, fu, fv; kmVec3Subtract(&nu, &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_RIGHT], &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_LEFT]); kmVec3Subtract(&nv, &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_TOP_LEFT], &frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_LEFT]); kmVec3Subtract(&fu, &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_RIGHT], &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_LEFT]); kmVec3Subtract(&fv, &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_TOP_LEFT], &frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_LEFT]); kmVec3Scale(&nu, &nu, point->x); kmVec3Scale(&nv, &nv, point->y); kmVec3Scale(&fu, &fu, point->x); kmVec3Scale(&fv, &fv, point->y); pOut->start = frustum->corners[GLHCK_FRUSTUM_CORNER_NEAR_BOTTOM_LEFT]; pOut->dir = frustum->corners[GLHCK_FRUSTUM_CORNER_FAR_BOTTOM_LEFT]; kmVec3Add(&pOut->start, &pOut->start, &nu); kmVec3Add(&pOut->start, &pOut->start, &nv); kmVec3Add(&pOut->dir, &pOut->dir, &fu); kmVec3Add(&pOut->dir, &pOut->dir, &fv); kmVec3Subtract(&pOut->dir, &pOut->dir, &pOut->start); RET(2, "%p", pOut); return pOut; }
kmVec3* kmRay3IntersectPlane(kmVec3* pOut, const kmRay3* ray, const kmPlane* plane) { //t = - (A*org.x + B*org.y + C*org.z + D) / (A*dir.x + B*dir.y + C*dir.z ) double t = -(plane->a * ray->start.x + plane->b * ray->start.y + plane->c * ray->start.z + plane->d) / ( plane->a * ray->dir.x + plane->b * ray->dir.y + plane->c * ray->dir.z); kmVec3 scaled_dir; kmVec3Scale(&scaled_dir, &ray->dir, t); kmVec3Add(pOut, &ray->start, &scaled_dir); return pOut; }
void Mesh::enable_debug(bool value) { if(value) { if(normal_debug_mesh_) return; //This maintains a lock on the material MaterialID mid = resource_manager().new_material(); resource_manager().window->loader_for( "material_loader", Material::BuiltIns::DIFFUSE_ONLY )->into(resource_manager().material(mid)); normal_debug_mesh_ = new_submesh_with_material("__debug__", mid, MESH_ARRANGEMENT_LINES, VERTEX_SHARING_MODE_INDEPENDENT); //Go through the submeshes, and for each index draw a normal line each([=](const std::string& name, SubMesh* mesh) { for(uint16_t idx: mesh->index_data->all()) { Vec3 pos1 = mesh->vertex_data->position_at<Vec3>(idx); Vec3 n; mesh->vertex_data->normal_at(idx, n); kmVec3Scale(&n, &n, 10.0); kmVec3 pos2; kmVec3Add(&pos2, &pos1, &n); normal_debug_mesh_->vertex_data->position(pos1); normal_debug_mesh_->vertex_data->diffuse(smlt::Colour::RED); int16_t next_index = normal_debug_mesh_->vertex_data->move_next(); normal_debug_mesh_->index_data->index(next_index - 1); normal_debug_mesh_->vertex_data->position(pos2); normal_debug_mesh_->vertex_data->diffuse(smlt::Colour::RED); next_index = normal_debug_mesh_->vertex_data->move_next(); normal_debug_mesh_->index_data->index(next_index - 1); } }); normal_debug_mesh_->vertex_data->done(); normal_debug_mesh_->index_data->done(); } else { if(normal_debug_mesh_) { delete_submesh(normal_debug_mesh_->name()); normal_debug_mesh_ = nullptr; } } }
/* Rotate camera */ void dlRotateCamera( dlCamera *object, kmVec3 *rotation ) { kmVec3 rotToDir, forwards; CALL("%p, vec3[%f, %f, %f]", object, rotation->x, rotation->y, rotation->z); forwards.x = 0; forwards.y = 0; forwards.z = 1; if(!object) return; object->rotation = *rotation; /* update target */ kmVec3RotationToDirection( &rotToDir, &object->rotation, &forwards ); kmVec3Add( &object->target, &object->translation, &rotToDir ); object->transform_changed = 1; }
kmVec3* kmAABB3Centre(const kmAABB3* aabb, kmVec3* pOut) { kmVec3Add(pOut, &aabb->min, &aabb->max); kmVec3Scale(pOut, pOut, 0.5); return pOut; }
void Frustum::setupProjectionPerspective(const ViewTransform& view, float left, float right, float top, float bottom, float nearPlane, float farPlane) { kmVec3 cc = view.getPosition(); kmVec3 cDir = view.getDirection(); kmVec3 cRight = view.getRight(); kmVec3 cUp = view.getUp(); kmVec3Normalize(&cDir, &cDir); kmVec3Normalize(&cRight, &cRight); kmVec3Normalize(&cUp, &cUp); kmVec3 nearCenter; kmVec3 farCenter; kmVec3Scale(&nearCenter, &cDir, nearPlane); kmVec3Add(&nearCenter, &nearCenter, &cc); kmVec3Scale(&farCenter, &cDir, farPlane); kmVec3Add(&farCenter, &farCenter, &cc); //near { kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &nearCenter, &cDir); } //far { kmVec3 normal; kmVec3Scale(&normal, &cDir, -1); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &farCenter, &normal); } //left { kmVec3 point; kmVec3Scale(&point, &cRight, left); kmVec3Add(&point, &point, &nearCenter); kmVec3 normal; kmVec3Subtract(&normal, &point, &cc); kmVec3Cross(&normal, &normal, &cUp); kmVec3Normalize(&normal, &normal); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal); } //right { kmVec3 point; kmVec3Scale(&point, &cRight, right); kmVec3Add(&point, &point, &nearCenter); kmVec3 normal; kmVec3Subtract(&normal, &point, &cc); kmVec3Cross(&normal, &cUp, &normal); kmVec3Normalize(&normal, &normal); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal); } //bottom { kmVec3 point; kmVec3Scale(&point, &cUp, bottom); kmVec3Add(&point, &point, &nearCenter); kmVec3 normal; kmVec3Subtract(&normal, &point, &cc); kmVec3Cross(&normal, &cRight, &normal); kmVec3Normalize(&normal, &normal); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal); } //top { kmVec3 point; kmVec3Scale(&point, &cUp, top); kmVec3Add(&point, &point, &nearCenter); kmVec3 normal; kmVec3Subtract(&normal, &point, &cc); kmVec3Cross(&normal, &normal, &cRight); kmVec3Normalize(&normal, &normal); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal); } }
void Frustum::setupProjectionOrthogonal(const cocos2d::ViewTransform &view, float width, float height, float nearPlane, float farPlane) { kmVec3 cc = view.getPosition(); kmVec3 cDir = view.getDirection(); kmVec3 cRight = view.getRight(); kmVec3 cUp = view.getUp(); kmVec3Normalize(&cDir, &cDir); kmVec3Normalize(&cRight, &cRight); kmVec3Normalize(&cUp, &cUp); //near { kmVec3 point; kmVec3 normal; normal = cDir; kmVec3Scale(&point, &cDir, nearPlane); kmVec3Add(&point, &point, &cc); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_NEAR], &point, &normal); } //far { kmVec3 point; kmVec3 normal; kmVec3Scale(&normal, &cDir, -1); kmVec3Scale(&point, &cDir, farPlane); kmVec3Add(&point, &point, &cc); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_FAR], &point, &normal); } //left { kmVec3 point; kmVec3 normal; normal = cRight; kmVec3Scale(&point, &cRight, -width * 0.5); kmVec3Add(&point, &point, &cc); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_LEFT], &point, &normal); } //right { kmVec3 point; kmVec3 normal; kmVec3Scale(&normal, &cRight, -1); kmVec3Scale(&point, &cRight, width * 0.5); kmVec3Add(&point, &point, &cc); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_RIGHT], &point, &normal); } //bottom { kmVec3 point; kmVec3 normal; normal = cUp; kmVec3Scale(&point, &cUp, -height * 0.5); kmVec3Add(&point, &point, &cc); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_BOTTOM], &point, &normal); } //top { kmVec3 point; kmVec3 normal; kmVec3Scale(&normal, &cUp, -1); kmVec3Scale(&point, &cUp, height * 0.5); kmVec3Add(&point, &point, &cc); kmPlaneFromPointAndNormal(&_frustumPlanes[FrustumPlane::FRUSTUM_TOP], &point, &normal); } }
int process_inputs() { // Get mouse position double xpos, ypos; glfwGetCursorPos(mainWindow, &xpos, &ypos); // Reset mouse position for next frame glfwSetCursorPos(mainWindow, SCREEN_WIDTH/2, SCREEN_HEIGHT/2); // Compute new orientation horizontalAngle += mouseSpeed * (float)( SCREEN_WIDTH/2 - xpos ); verticalAngle += mouseSpeed * (float)( SCREEN_HEIGHT/2 - ypos ); /* If F1, reload */ if (glfwGetKey(mainWindow, GLFW_KEY_F1)) { Engine_Reload(); } /* If F2, reset view */ if (glfwGetKey(mainWindow, GLFW_KEY_F2)) { printf("Camera reset.\n"); Camera_Reset(); } /* If tab, change lookat to next mesh */ if (glfwGetKey(mainWindow, GLFW_KEY_TAB)) { //Camera_LookAtNext(); } /* Move closer */ //if (glfwGetKey(mainWindow, GLFW_KEY_W)) { // ypos = 100; //} /* Move further */ //if (glfwGetKey(mainWindow, GLFW_KEY_S)) { // ypos = -100; //} /* Move left */ //if (glfwGetKey(mainWindow, GLFW_KEY_A)) { // xpos = 100; //} /* Move right */ //if (glfwGetKey(mainWindow, GLFW_KEY_D)) { // xpos = -100; //} // Compute new orientation //horizontalAngle += mouseSpeed * (float)(1024/2 - xpos ); //verticalAngle += mouseSpeed * (float)( 768/2 - ypos ); horizontalAngle += mouseSpeed * xpos; verticalAngle += mouseSpeed * ypos; //printf("horizontalAngle is %f, and verticalAngle is %f.\n", horizontalAngle, verticalAngle); // Direction : Spherical coordinates to Cartesian coordinates conversion float temp1 = cos(verticalAngle) * sin(horizontalAngle); float temp2 = sin(verticalAngle); float temp3 = cos(verticalAngle) * cos(horizontalAngle); kmVec3 direction = {temp1, temp2, temp3}; // Right vector kmVec3 right = { sin(horizontalAngle - 3.14f/2.0f), 0, cos(horizontalAngle - 3.14f/2.0f) }; // Up vector kmVec3 up = *kmVec3Cross(&up, &right, &direction ); // Move forward if (glfwGetKey( mainWindow, GLFW_KEY_UP ) == GLFW_PRESS){ kmVec3Add(&position, &position, kmVec3Scale(&position, &direction, deltaTime * speed)); } // Move backward if (glfwGetKey( mainWindow, GLFW_KEY_DOWN ) == GLFW_PRESS){ kmVec3Subtract(&position, &position, kmVec3Scale(&position, &direction, deltaTime * speed)); } // Strafe right if (glfwGetKey( mainWindow, GLFW_KEY_RIGHT ) == GLFW_PRESS){ kmVec3Add(&position, &position, kmVec3Scale(&position, &right, deltaTime * speed)); } // Strafe left if (glfwGetKey( mainWindow, GLFW_KEY_LEFT ) == GLFW_PRESS){ kmVec3Subtract(&position, &position, kmVec3Scale(&position, &right, deltaTime * speed)); } float FoV = initialFoV; kmMat4PerspectiveProjection(&ProjectionMatrix, FoV, (16.0f / 8.0f), 0.1f, 100.0f); // Camera matrix //ViewMatrix = glm::lookAt( // position, // Camera is here // position+direction, // and looks here : at the same position, plus "direction" // up // Head is up (set to 0,-1,0 to look upside-down) // ); kmVec3 p_eye; p_eye = position; kmVec3 p_ctr; p_ctr = *kmVec3Add(&p_ctr, &position, &direction); kmVec3 p_up; p_up = up; kmMat4LookAt(&ViewMatrix, &p_eye, &p_ctr, &p_up); kmMat4Identity(&ModelMatrix); kmMat4 temp_mat; kmMat4Multiply(&temp_mat, &ViewMatrix, &ModelMatrix); kmMat4Multiply(&MVP, &ProjectionMatrix, &temp_mat ); //printf("Matrix contains:\n"); //printf("%f, %f, %f, %f\n", MVP.mat[0], MVP.mat[1], MVP.mat[2], MVP.mat[3]); //printf("%f, %f, %f, %f\n", MVP.mat[4], MVP.mat[5], MVP.mat[6], MVP.mat[7]); //printf("%f, %f, %f, %f\n", MVP.mat[8], MVP.mat[9], MVP.mat[10], MVP.mat[11]); //printf("%f, %f, %f, %f\n", MVP.mat[12], MVP.mat[13], MVP.mat[14], MVP.mat[15]); return 0; }
void CSkin::CalcSkelAnim(const CAnimationController::BoneMatrixMap &matrices) { CVertexPT *vertices = new CVertexPT[m_uVertexCount]; for(size_t i = 0; i < m_uVertexCount; ++i) { const CVertexPTB &vertex = m_vertices[i]; CVertexPT &vertex1 = vertices[i]; if(matrices.empty()) { vertex1.position = vertex.position; vertex1.tex = vertex.tex; continue; } kmVec3 pos; kmVec3Fill(&pos,vertex.position.x,vertex.position.y, vertex.position.z); kmVec3 finalpos; kmMat4 mat, mat2, mat3, mat4; if(vertex.bones.x >= 0) { auto itr = matrices.find(static_cast<ESkeletonBoneType>(vertex.bones.x)); BEATS_ASSERT(itr != matrices.end()); mat = itr->second; kmVec3 postmp; kmVec3Transform(&postmp,&pos,&mat); kmVec3Scale(&postmp, &postmp, vertex.weights.x); finalpos = postmp; } if(vertex.bones.y >= 0) { auto itr = matrices.find(static_cast<ESkeletonBoneType>(vertex.bones.y)); BEATS_ASSERT(itr != matrices.end()); mat2 = itr->second; kmVec3 postmp; kmVec3Transform(&postmp,&pos,&mat2); kmVec3Scale(&postmp, &postmp, vertex.weights.y); kmVec3Add(&finalpos,&finalpos,&postmp); } if(vertex.bones.z >= 0) { auto itr = matrices.find(static_cast<ESkeletonBoneType>(vertex.bones.z)); BEATS_ASSERT(itr != matrices.end()); mat3 = itr->second; kmVec3 postmp; kmVec3Transform(&postmp,&pos,&mat3); kmVec3Scale(&postmp, &postmp, vertex.weights.z); kmVec3Add(&finalpos,&finalpos,&postmp); } if(vertex.bones.w >= 0) { auto itr = matrices.find(static_cast<ESkeletonBoneType>(vertex.bones.w)); BEATS_ASSERT(itr != matrices.end()); mat4 = itr->second; kmVec3 postmp; kmVec3Transform(&postmp,&pos,&mat4); kmVec3Scale(&postmp, &postmp, vertex.weights.w); kmVec3Add(&finalpos,&finalpos,&postmp); } vertex1.position = finalpos; vertex1.tex = vertex.tex; } buildVBOVertex(vertices, m_uVertexCount*sizeof(CVertexPT)); BEATS_SAFE_DELETE_ARRAY(vertices); }