Widget::Widget(const std::string& name, point_type w, point_type h): _parent (0), _index (0), _layer (LAYER_LOW), _padLeft (0.0f), _padRight (0.0f), _padTop (0.0f), _padBottom (0.0f), _valign (VA_CENTER), _halign (HA_CENTER), _coordMode (CM_ABSOLUTE), _canFill (false), _canClone (true), _isManaged (false), _isStyled (false), _minWidth (0.0f), _minHeight (0.0f) { _name = name.size() ? name : generateRandomName("Widget"); if(!_norms.valid()) { _norms = new PointArray(1); (*_norms)[0].set(0.0f, 0.0f, 1.0f); (*_norms)[0].normalize(); } TexCoordArray* texs = new TexCoordArray(4); // Fill our texture coordinates with null stuff for now, since we aren't using them // until an Image is set at some later point. std::fill(texs->begin(), texs->end(), osg::Vec2(0.0f, 0.0f)); setUseDisplayList(false); setDataVariance(osg::Object::DYNAMIC); setVertexArray(new PointArray(4)); setColorArray(new ColorArray(4)); setNormalArray(_norms.get()); setTexCoordArray(0, texs); setNormalBinding(osg::Geometry::BIND_OVERALL); setColorBinding(osg::Geometry::BIND_PER_VERTEX); addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUADS, 0, 4)); setDimensions(0.0f, 0.0f, w, h); setColor(1.0f, 1.0f, 1.0f, 1.0f); }
WidgetBorder::WidgetBorder(const Widget & widget) : widget(widget) { if (osg::Vec3Array * data = new osg::Vec3Array(4)) { const Rect & rect = widget.getRect(); const int padding = widget.getBorderPadding(); const float z = widget.getZ(); spdlog::get("log")->info("initializing WidgetBorder with rect {}, {}, {}, {}", rect.x1, rect.y1, rect.x2, rect.y2); (*data)[0].set(rect.x1 - padding, rect.y2 + padding, z); (*data)[1].set(rect.x1 - padding, rect.y1 - padding, z); (*data)[2].set(rect.x2 + padding, rect.y1 - padding, z); (*data)[3].set(rect.x2 + padding, rect.y2 + padding, z); setVertexArray(data); } if (osg::Vec3Array * data = new osg::Vec3Array(1)) { (*data)[0].set(0.f, 0.f, 1.f); setNormalArray(data, osg::Array::BIND_OVERALL); } if (osg::Vec4Array * data = new osg::Vec4Array(1)) { /* const osg::Color & color = widget.getBorderColor(); (*data)[0].set(widget.getBorderColor().r, widget.getBorderColor().g, widget.getBorderColor().b, widget.getBorderColor().a); */ (*data)[0].set(1.f, 1.f, 1.f, 1.f); setColorArray(data, osg::Array::BIND_OVERALL); } addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::LINE_LOOP, 0, 4)); // TODO: getOrCreateStateSet()->setAttribute(new osg::LineWidth(widget.getBorderPadding())); }
void HeightmapShapeDrawable<S>::refresh(bool /*firstTime*/) { if (mHeightmapShape->getDataVariance() == dynamics::Shape::STATIC) setDataVariance(::osg::Object::STATIC); else setDataVariance(::osg::Object::DYNAMIC); // Row major matrix where top left corner is the height at (0, 0), and bottom // right corner is the height at (rows, -cols) in (x, y) coordinates. const auto& heightmap = mHeightmapShape->getHeightField(); // This function is called whenever the heightmap version is increased, and // the heightmap could be updated in the version up. So we always update the // heightmap. { assert(mElements); assert(mNormals); setVertices<S>( heightmap, *mVertices, *mElements, *mNormals, mHeightmapShape->getScale()); addPrimitiveSet(mElements); setVertexArray(mVertices); setNormalArray(mNormals, ::osg::Array::BIND_PER_VERTEX); } // This function is called whenever the heightmap version is increased, and // the color could be updated in the version up. So we always update the // color. { if (mColors->size() != 1) mColors->resize(1); (*mColors)[0] = eigToOsgVec4d(mVisualAspect->getRGBA()); setColorArray(mColors, ::osg::Array::BIND_OVERALL); } }
void Ellipsoid::subDraw() { computeAssistVar(); getPrimitiveSetList().clear(); osg::ref_ptr<osg::Vec3Array> vertexArr = new osg::Vec3Array; osg::ref_ptr<osg::Vec3Array> normalArr = new osg::Vec3Array; setVertexArray(vertexArr); setNormalArray(normalArr, osg::Array::BIND_PER_VERTEX); osg::ref_ptr<osg::Vec4Array> colArr = new osg::Vec4Array(); colArr->push_back(m_color); setColorArray(colArr, osg::Array::BIND_OVERALL); bool isFull = osg::equivalent(m_angle, 2 * M_PI, GetEpsilon()); if (isFull) { m_angle = 2 * M_PI; } osg::Vec3 bottomNormal = -m_aLen; bottomNormal.normalize(); osg::Quat localToWold; localToWold.makeRotate(osg::Z_AXIS, -bottomNormal); osg::Vec3 xVec = localToWold * osg::X_AXIS; osg::Vec3 yVec = xVec ^ bottomNormal; int hCount = m_bDivision; double hIncAng = 2 * M_PI / hCount; osg::Quat hQuat(hIncAng, bottomNormal); int vCount = (int)ceil(m_angle / (2 * M_PI / m_aDivision)); if (vCount & 1) // 如果是奇数,则变成偶数 ++vCount; double vIncAng = m_angle / vCount; double currAngle = m_angle / 2.0; double b = m_bRadius; double a = m_aLen.length(); osg::Vec3 vec1(b * sin(currAngle), 0, a * cos(currAngle)); vec1 = localToWold * vec1; osg::Vec3 normal1(sin(currAngle) / b, 0, cos(currAngle) / a); normal1 = localToWold * normal1; normal1.normalize(); currAngle -= vIncAng; osg::Vec3 vec2(b * sin(currAngle), 0, a * cos(currAngle)); vec2 = localToWold * vec2; osg::Vec3 normal2(sin(currAngle) / b, 0, cos(currAngle) / a); normal2 = localToWold * normal2; normal2.normalize(); const GLint first = vertexArr->size(); for (int i = 0; i < vCount / 2; ++i) { osg::Vec3 hVec1 = vec1; osg::Vec3 hVec2 = vec2; osg::Vec3 hNormal1 = normal1; osg::Vec3 hNormal2 = normal2; const size_t hFirst = vertexArr->size(); for (int j = 0; j < hCount; ++j) { vertexArr->push_back(m_center + hVec1); vertexArr->push_back(m_center + hVec2); normalArr->push_back(hNormal1); normalArr->push_back(hNormal2); hVec1 = hQuat * hVec1; hVec2 = hQuat * hVec2; hNormal1 = hQuat * hNormal1; hNormal2 = hQuat * hNormal2; } vertexArr->push_back((*vertexArr)[hFirst]); vertexArr->push_back((*vertexArr)[hFirst + 1]); normalArr->push_back((*normalArr)[hFirst]); normalArr->push_back((*normalArr)[hFirst + 1]); vec1 = vec2; currAngle -= vIncAng; vec2.set(b * sin(currAngle), 0, a * cos(currAngle)); vec2 = localToWold * vec2; normal1 = normal2; normal2.set(sin(currAngle) / b, 0, cos(currAngle) / a); normal2 = localToWold * normal2; normal2.normalize(); } addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::QUAD_STRIP, first, vertexArr->size() - first)); if (!isFull && m_bottomVis) { const GLint first = vertexArr->size(); currAngle = m_angle / 2.0; osg::Vec3 vec1(b * sin(currAngle), 0, a * cos(currAngle)); vec1 = localToWold * vec1; osg::Vec3 vec2(0, 0, a * cos(currAngle)); vec2 = localToWold * vec2; vertexArr->push_back(m_center + vec2); normalArr->push_back(bottomNormal); for (int i = 0; i < hCount; ++i) { vertexArr->push_back(m_center + vec1); normalArr->push_back(bottomNormal); vec1 = hQuat * vec1; } vertexArr->push_back((*vertexArr)[first + 1]); normalArr->push_back(bottomNormal); addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, first, vertexArr->size() - first)); } }
void SCylinder::subDraw() { getPrimitiveSetList().clear(); osg::ref_ptr<osg::Vec3Array> vertexArr = new osg::Vec3Array; osg::ref_ptr<osg::Vec3Array> normalArr = new osg::Vec3Array; setVertexArray(vertexArr); setNormalArray(normalArr, osg::Array::BIND_PER_VERTEX); osg::ref_ptr<osg::Vec4Array> colArr = new osg::Vec4Array(); colArr->push_back(m_color); setColorArray(colArr, osg::Array::BIND_OVERALL); int count = (int)getDivision(); double incAng = 2 * M_PI / count; osg::Vec3 topNormal = m_height; topNormal.normalize(); double angleCos = m_bottomNormal * (-topNormal) / m_bottomNormal.length() / topNormal.length(); double angle = acos(angleCos); double a = m_radius; double b = m_radius / sin(M_PI_2 - angle); osg::Vec3 vec = m_bottomNormal ^ topNormal; vec.normalize(); osg::Quat bottomQuat(incAng, m_bottomNormal); double currAngle = 0; osg::Quat localToWorldQuat; localToWorldQuat.makeRotate(osg::Z_AXIS, m_bottomNormal); osg::Vec3 yAxis = localToWorldQuat * osg::Y_AXIS; osg::Quat localToWorldQuat2; localToWorldQuat2.makeRotate(yAxis, vec); localToWorldQuat *= localToWorldQuat2; osg::Vec3 bottomVec(b * sin(currAngle), a * cos(currAngle), 0); bottomVec = localToWorldQuat * bottomVec; //bottomVec = localToWorldQuat2 * bottomVec; osg::Quat topQuat(incAng, topNormal); osg::Vec3 topVec = vec * m_radius; osg::Vec3 topCenter = m_org + m_height; size_t first = vertexArr->size(); for (int i = 0; i < count; ++i) { vertexArr->push_back(topCenter + topVec); vertexArr->push_back(m_org + bottomVec); normalArr->push_back(topVec); normalArr->back().normalize(); normalArr->push_back(normalArr->back()); currAngle += incAng; bottomVec.set(b * sin(currAngle), a * cos(currAngle), 0); bottomVec = localToWorldQuat * bottomVec; //bottomVec = localToWorldQuat2 * bottomVec; topVec = topQuat * topVec; } vertexArr->push_back((*vertexArr)[first]); vertexArr->push_back((*vertexArr)[first + 1]); normalArr->push_back((*normalArr)[first]); normalArr->push_back((*normalArr)[first + 1]); addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_STRIP, first, vertexArr->size() - first)); if (m_bottomVis) { first = vertexArr->size(); vertexArr->push_back(m_org); normalArr->push_back(m_bottomNormal); for (int i = count; i >= 0; --i) { vertexArr->push_back((*vertexArr)[i * 2 + 1]); normalArr->push_back(m_bottomNormal); } addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, first, vertexArr->size() - first)); } if (m_topVis) { first = vertexArr->size(); vertexArr->push_back(topCenter); normalArr->push_back(topNormal); for (int i = 0; i < count + 1; ++i) { vertexArr->push_back((*vertexArr)[i * 2]); normalArr->push_back(topNormal); } addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::TRIANGLE_FAN, first, vertexArr->size() - first)); } }
osgToy::Polyhedron::Polyhedron() { setVertexArray( new osg::Vec3Array ); setNormalArray( new osg::Vec3Array ); setColorArray( new osg::Vec4Array ); }