/** * Calculate the end of the directonal marker line. * * This is done by calculating the scale we need to multiply the directional marker by to * reach each of the three sides of the bounding box, then take the smallest of these, * because that is the side it will intersect. Finally, multiply by an overall scale factor. */ CC3Vector CC3DirectionMarkerNode::calculateLineEnd() { CC3Box pbb = getParentBoundingBox(); CC3Vector md = getMarkerDirection(); CC3Vector pbbDirScale = cc3v(calcScale( md.x, pbb.minimum.x, pbb.maximum.x ), calcScale( md.y, pbb.minimum.y, pbb.maximum.y ), calcScale( md.z, pbb.minimum.z, pbb.maximum.z )); //CC3_PUSH_NOSHADOW GLfloat dirScale = MIN(pbbDirScale.x, MIN(pbbDirScale.y, pbbDirScale.z)); dirScale = dirScale * getDirectionMarkerScale(); //CC3_POP_NOSHADOW // Ensure that the direction marker has the minimum length specified by directionMarkerMinimumLength if (directionMarkerMinimumLength) { GLfloat gblUniScale = getGlobalScale().length() / CC3Vector::kCC3VectorUnitCubeLength; GLfloat minScale = directionMarkerMinimumLength / gblUniScale; dirScale = MAX(dirScale, minScale); } CC3Vector lineEnd = md.scaleUniform( dirScale ); //LogTrace(@"%@ calculated line end %@ from pbb scale %@ and dir scale %.3f and min global length: %.3f", self, // NSStringFromCC3Vector(lineEnd), NSStringFromCC3Vector(pbbDirScale), dirScale, directionMarkerMinimumLength); return lineEnd; }
mat4 Transform::getModelMatrix() { mat4 out = translate(glm::mat4(), getGlobalPosition()); out = rotate(out, getGlobalRotation().x, vec3(1.0f, 0.0f, 0.0f)); out = rotate(out, getGlobalRotation().y, vec3(0.0f, 1.0f, 0.0f)); out = rotate(out, getGlobalRotation().z, vec3(0.0f, 0.0f, 1.0f)); out = scale(out, getGlobalScale()); return out; }
//---------------------------------------- void ofNode::clearParent(bool bMaintainGlobalTransform) { if(parent){ parent->removeListener(*this); } if(bMaintainGlobalTransform && parent) { auto orientation = getGlobalOrientation(); auto position = getGlobalPosition(); auto scale = getGlobalScale(); this->parent = nullptr; setOrientation(orientation); setPosition(position); setScale(scale); }else{ this->parent = nullptr; } }
//---------------------------------------- glm::quat ofNode::getGlobalOrientation() const { auto rot = glm::scale(getGlobalTransformMatrix(), 1.f/getGlobalScale()); return glm::toQuat(rot); }
void Sprite::draw() { if (!_visible) { return; } //fix bug of transform of difference window size Vec2 windowSize = Director::getInstance()->getWindowSize(); auto originalSize = _texture2d->getRect(); Vec2 localAnchorPoint(originalSize.x*_anchor.x, originalSize.y*_anchor.y); Vec2 vertexes[4] = { -localAnchorPoint, { originalSize.x - localAnchorPoint.x, -localAnchorPoint.y }, originalSize - localAnchorPoint, { -localAnchorPoint.x, originalSize.y - localAnchorPoint.y } }; auto globalPosition = getGlobalPosition(); auto globalScale = getGlobalScale(); auto globalRotation = getGlobalRotation(); Vec2 _glScale{ 2 / windowSize.x, 2 / windowSize.y }; // init for rotating auto sin = Math::sin(globalRotation); auto cos = Math::cos(globalRotation); for (auto &vertex : vertexes) { // local transform // rotate { auto tempX = vertex.x; vertex.x = tempX*cos - vertex.y*sin; vertex.y = tempX*sin + vertex.y*cos; } vertex.x *= globalScale.x; vertex.y *= globalScale.y; // scale // global transform vertex.x += globalPosition.x; vertex.y += globalPosition.y; // gl transform vertex.x *= _glScale.x; vertex.y *= _glScale.y; vertex.x -= 1; vertex.y -= 1; } // draw float *_coord2f = _texture2d->getCoord2fPoints(); int _index_1 = 0; int _index_2 = 1; int _index_3 = 2; int _index_4 = 3; if (_is_flipx) { _index_1 = 2; _index_3 = 0; } if (_is_flipy) { _index_2 = 3; _index_4 = 1; } if (!cmd) { cmd = new RenderCmd_Quad; } cmd->_vertex[0] = vertexes[_index_1]; cmd->_vertex[1] = vertexes[_index_2]; cmd->_vertex[2] = vertexes[_index_3]; cmd->_vertex[3] = vertexes[_index_4]; cmd->_coord2f = _coord2f; cmd->tex = _texture2d; cmd->_opacity = _opactiy; Director::getInstance()->getRenderCmdQueue()->addRenderCmd(cmd); /* there are two methods to slove flip */ /* //method one int _index_1 = 0; int _index_2 = 1; int _index_3 = 2; int _index_4 = 3; if (_is_flipx) { _index_1 = 2; _index_3 = 0; } if (_is_flipy) { _index_2 = 3; _index_4 = 1; } glTexCoord2f(_coord2f[0], _coord2f[1]); glVertex2f(vertexes[_index_1].x, vertexes[_index_1].y); glTexCoord2f(_coord2f[2], _coord2f[3]); glVertex2f(vertexes[_index_2].x, vertexes[_index_2].y); glTexCoord2f(_coord2f[4], _coord2f[5]); glVertex2f(vertexes[_index_3].x, vertexes[_index_3].y); glTexCoord2f(_coord2f[6], _coord2f[7]); glVertex2f(vertexes[_index_4].x, vertexes[_index_4].y); // method two if (_is_flipx == false && _is_flipy == false) { glTexCoord2f(_coord2f[0], _coord2f[1]); glVertex2f(vertexes[0].x, vertexes[0].y); glTexCoord2f(_coord2f[2], _coord2f[3]); glVertex2f(vertexes[1].x, vertexes[1].y); glTexCoord2f(_coord2f[4], _coord2f[5]); glVertex2f(vertexes[2].x, vertexes[2].y); glTexCoord2f(_coord2f[6], _coord2f[7]); glVertex2f(vertexes[3].x, vertexes[3].y); } else if (_is_flipx == true && _is_flipy == false) { glTexCoord2f(_coord2f[0], _coord2f[1]); glVertex2f(vertexes[1].x, vertexes[1].y); glTexCoord2f(_coord2f[2], _coord2f[3]); glVertex2f(vertexes[0].x, vertexes[0].y); glTexCoord2f(_coord2f[4], _coord2f[5]); glVertex2f(vertexes[3].x, vertexes[3].y); glTexCoord2f(_coord2f[6], _coord2f[7]); glVertex2f(vertexes[2].x, vertexes[2].y); } else if (_is_flipx == false && _is_flipy == true) { glTexCoord2f(_coord2f[0], _coord2f[1]); glVertex2f(vertexes[3].x, vertexes[3].y); glTexCoord2f(_coord2f[2], _coord2f[3]); glVertex2f(vertexes[2].x, vertexes[2].y); glTexCoord2f(_coord2f[4], _coord2f[5]); glVertex2f(vertexes[1].x, vertexes[1].y); glTexCoord2f(_coord2f[6], _coord2f[7]); glVertex2f(vertexes[0].x, vertexes[0].y); } else if (_is_flipx == true && _is_flipy == true) { glTexCoord2f(_coord2f[0], _coord2f[1]); glVertex2f(vertexes[2].x, vertexes[2].y); glTexCoord2f(_coord2f[2], _coord2f[3]); glVertex2f(vertexes[3].x, vertexes[3].y); glTexCoord2f(_coord2f[4], _coord2f[5]); glVertex2f(vertexes[0].x, vertexes[0].y); glTexCoord2f(_coord2f[6], _coord2f[7]); glVertex2f(vertexes[1].x, vertexes[1].y); } */ Node::draw(); }
/** * Scaling the camera is a null operation because it scales everything, including the size * of objects, but also the distance from the camera to those objects. The effects cancel * out, and visually, it appears that nothing has changed. Therefore, the scale property * is not applied to the transform matrix of the camera. Instead it is used to adjust the * field of view to create a zooming effect. See the notes for the fieldOfView property. * * This implementation uses the globalScale property to unwind all scaling from the camera, * globally, because any inherited scaling will scale the frustum, and cause undesirable * clipping artifacts, particularly at the near clipping plane. * * For example, if the camera is mounted on another node that is scaled to ten times, the * near clipping plane of the camera will be scaled away from the camera by ten times, * resulting in unwanted clipping around the fringes of the view. For this reason, an inverse * scale of 1/10 is applied to the transform to counteract this effect. */ void CC3Camera::applyScalingTo( CC3Matrix* matrix ) { matrix->scaleBy( getGlobalScale().invert() ); }