20 #include "renderworld.h"
21 #include "physphere.h"
22 #include "phyellipsoid.h"
24 #include "phycylinder.h"
27 #include "phycompoundobject.h"
29 #include "graphicalwobject.h"
30 #include "private/renderwobjecthierarchy.h"
44 # include <GLUT/glut.h>
51 #define GLMultMatrix glMultMatrixf
66 virtual void render( QGLContext* gw ) {
69 const wMatrix& m = obj->matrix();
70 GLMultMatrix(&m[0][0]);
79 calculateAABB( minpoint, maxpoint, obj->matrix() );
84 minPoint = tm.w_pos - rds;
85 maxPoint = tm.w_pos + rds;
89 dimension[0] = rad*2.0;
90 dimension[1] = rad*2.0;
91 dimension[2] = rad*2.0;
103 wmesh =
dynamic_cast<WMesh*
>(wobj);
104 Q_ASSERT_X(wmesh != NULL,
"RenderWMesh",
"The WObject is not a WMesh!!!");
107 virtual void render( QGLContext* gw ) {
110 if ( wmesh->attachedTo() ) {
111 m = m * wmesh->attachedTo()->matrix();
113 GLMultMatrix(&m[0][0]);
114 int m_numMeshes = wmesh->meshesCount();
122 for (
int i = 0; i < m_numMeshes; i++ ) {
123 int materialIndex = m_pMeshes[i].m_materialIndex;
124 if ( materialIndex >= 0 ) {
125 glMaterialfv( GL_FRONT, GL_AMBIENT, m_pMaterials[materialIndex].m_ambient );
126 glMaterialfv( GL_FRONT, GL_DIFFUSE, m_pMaterials[materialIndex].m_diffuse );
127 glMaterialfv( GL_FRONT, GL_SPECULAR, m_pMaterials[materialIndex].m_specular );
128 glMaterialfv( GL_FRONT, GL_EMISSION, m_pMaterials[materialIndex].m_emissive );
129 glMaterialf( GL_FRONT, GL_SHININESS, m_pMaterials[materialIndex].m_shininess );
133 glBegin( GL_TRIANGLES );
134 for (
int j = 0; j < m_pMeshes[i].m_numTriangles; j++ ) {
135 int triangleIndex = m_pMeshes[i].m_pTriangleIndices[j];
137 for (
int k = 0; k < 3; k++ ) {
138 int index = pTri->m_vertexIndices[k];
139 glNormal3fv( pTri->m_vertexNormals[k] );
140 glTexCoord2f( pTri->m_s[k], pTri->m_t[k] );
141 glVertex3fv( m_pVertices[index].m_location );
165 box =
dynamic_cast<PhyBox*
>(wobj);
166 Q_ASSERT_X(box != NULL,
"RenderPhyBox",
"The WObject is not a PhyBox!!!");
172 virtual void render( QGLContext* gw ) {
175 const wMatrix& m = box->matrix();
176 GLMultMatrix(&m[0][0]);
182 float hdx = (dx/2.0);
183 float hdy = (dy/2.0);
184 float hdz = (dz/2.0);
186 glNormal3f(0.0, 0.0, 1.0);
187 glTexCoord2f(0.0, 0.0); glVertex3f(-hdx, -hdy, hdz);
188 glTexCoord2f(1.0, 0.0); glVertex3f( hdx, -hdy, hdz);
189 glTexCoord2f(1.0, 1.0); glVertex3f( hdx, hdy, hdz);
190 glTexCoord2f(0.0, 1.0); glVertex3f(-hdx, hdy, hdz);
193 glNormal3f(0.0, 0.0, -1.0);
194 glTexCoord2f(0.0, 0.0); glVertex3f( hdx, -hdy, -hdz);
195 glTexCoord2f(1.0, 0.0); glVertex3f(-hdx, -hdy, -hdz);
196 glTexCoord2f(1.0, 1.0); glVertex3f(-hdx, hdy, -hdz);
197 glTexCoord2f(0.0, 1.0); glVertex3f( hdx, hdy, -hdz);
200 glNormal3f(0.0, 1.0, 0.0);
201 glTexCoord2f(0.0, 0.0); glVertex3f(-hdx, hdy, hdz);
202 glTexCoord2f(1.0, 0.0); glVertex3f( hdx, hdy, hdz);
203 glTexCoord2f(1.0, 1.0); glVertex3f( hdx, hdy, -hdz);
204 glTexCoord2f(0.0, 1.0); glVertex3f(-hdx, hdy, -hdz);
207 glNormal3f(0.0, -1.0, 0.0);
208 glTexCoord2f(0.0, 0.0); glVertex3f(-hdx, -hdy, -hdz);
209 glTexCoord2f(1.0, 0.0); glVertex3f( hdx, -hdy, -hdz);
210 glTexCoord2f(1.0, 1.0); glVertex3f( hdx, -hdy, hdz);
211 glTexCoord2f(0.0, 1.0); glVertex3f(-hdx, -hdy, hdz);
214 glNormal3f(-1.0, 0.0, 0.0);
215 glTexCoord2f(0.0, 0.0); glVertex3f(-hdx, -hdy, -hdz);
216 glTexCoord2f(1.0, 0.0); glVertex3f(-hdx, -hdy, hdz);
217 glTexCoord2f(1.0, 1.0); glVertex3f(-hdx, hdy, hdz);
218 glTexCoord2f(0.0, 1.0); glVertex3f(-hdx, hdy, -hdz);
221 glNormal3f(1.0, 0.0, 0.0);
222 glTexCoord2f(0.0, 0.0); glVertex3f( hdx, -hdy, hdz);
223 glTexCoord2f(1.0, 0.0); glVertex3f( hdx, -hdy, -hdz);
224 glTexCoord2f(1.0, 1.0); glVertex3f( hdx, hdy, -hdz);
225 glTexCoord2f(0.0, 1.0); glVertex3f( hdx, hdy, hdz);
230 if (box->localAxesDrawn()) {
231 const float radius =
min(dx,
min(dy, dz)) * 0.1;
233 RenderWObjectContainer::drawArrow(
wVector(dx, 0.0, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::red);
234 RenderWObjectContainer::drawArrow(
wVector(0.0, dy, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::green);
235 RenderWObjectContainer::drawArrow(
wVector(0.0, 0.0, dz),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::blue);
245 calculateAABB( minpoint, maxpoint, obj->matrix() );
249 real tdx = fabs(tm.x_ax[0]*dx) + fabs(tm.y_ax[0]*dy) + fabs(tm.z_ax[0]*dz);
250 real tdy = fabs(tm.x_ax[1]*dx) + fabs(tm.y_ax[1]*dy) + fabs(tm.z_ax[1]*dz);
251 real tdz = fabs(tm.x_ax[2]*dx) + fabs(tm.y_ax[2]*dy) + fabs(tm.z_ax[2]*dz);
253 wVector hds( tdx/2.0, tdy/2.0, tdz/2.0 );
254 minPoint = tm.w_pos - hds;
255 maxPoint = tm.w_pos + hds;
262 wVector hds( dx/2.0, dy/2.0, dz/2.0 );
276 Q_ASSERT_X(sph != NULL,
"RenderPhySphere",
"The WObject is not a PhySphere!!!");
280 virtual void render( QGLContext* gw ) {
288 GLMultMatrix(&mat[0][0]);
291 pObj = gluNewQuadric();
293 gluQuadricTexture(pObj,
true);
294 gluSphere(pObj, rad, 20, 20);
295 gluDeleteQuadric(pObj);
298 if (sph->localAxesDrawn()) {
299 const float radius = rad * 0.1;
301 RenderWObjectContainer::drawArrow(
wVector(2.0 * rad, 0.0, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::red);
302 RenderWObjectContainer::drawArrow(
wVector(0.0, 2.0 * rad, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::green);
303 RenderWObjectContainer::drawArrow(
wVector(0.0, 0.0, 2.0 * rad),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::blue);
313 calculateAABB( minpoint, maxpoint, obj->matrix() );
318 minPoint = tm.w_pos - rds;
319 maxPoint = tm.w_pos + rds;
323 dimension[0] = rad*2.0;
324 dimension[1] = rad*2.0;
325 dimension[2] = rad*2.0;
339 Q_ASSERT_X(sph != NULL,
"RenderPhyEllipsoid",
"The WObject is not a PhyEllipsoid!!!");
340 radx = sph->radiusX();
341 rady = sph->radiusY();
342 radz = sph->radiusZ();
345 virtual void render( QGLContext* gw ) {
350 mat.x_ax = mat.x_ax.
scale( radx );
351 mat.y_ax = mat.y_ax.
scale( rady );
352 mat.z_ax = mat.z_ax.
scale( radz );
353 GLMultMatrix(&mat[0][0]);
356 pObj = gluNewQuadric();
358 gluQuadricTexture(pObj,
true);
359 gluSphere(pObj, 1, 20, 20);
360 gluDeleteQuadric(pObj);
363 if (sph->localAxesDrawn()) {
364 const float radius = qMax( qMax(radx, rady), radz ) * 0.1;
366 RenderWObjectContainer::drawArrow(
wVector(2.0 * radx, 0.0, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::red);
367 RenderWObjectContainer::drawArrow(
wVector(0.0, 2.0 * rady, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::green);
368 RenderWObjectContainer::drawArrow(
wVector(0.0, 0.0, 2.0 * radz),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::blue);
378 calculateAABB( minpoint, maxpoint, obj->matrix() );
382 wVector rds( radx, rady, radz );
383 minPoint = tm.w_pos - rds;
384 maxPoint = tm.w_pos + rds;
388 dimension[0] = radx*2.0;
389 dimension[1] = rady*2.0;
390 dimension[2] = radz*2.0;
486 m_height(m_cylinder->height()),
487 m_radius(m_cylinder->radius()),
488 m_cylinderVertexes(),
491 m_cylinderTextureCoords(),
492 m_upperBaseVertexes(),
493 m_upperBaseNormals(),
495 m_upperBaseTextureCoords(),
496 m_upperBaseSegmentsLength(),
497 m_lowerBaseVertexes(),
498 m_lowerBaseNormals(),
500 m_lowerBaseTextureCoords(),
501 m_lowerBaseSegmentsLength()
503 Q_ASSERT_X(m_cylinder != NULL,
"RenderPhyCylinder",
"The WObject is not a PhyCylinder!!!");
523 if (m_cylinder->graphicalRepresentationNeedsUpdate(
this)) {
524 updateRepresentation();
528 container()->setupColorTexture(gw,
this);
529 GLMultMatrix(&(m_cylinder->matrix()[0][0]));
533 glEnableClientState(GL_NORMAL_ARRAY);
534 glEnableClientState(GL_COLOR_ARRAY);
535 glEnableClientState(GL_VERTEX_ARRAY);
536 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
538 glNormalPointer(GL_FLOAT, 0, m_cylinderNormals.data());
539 glColorPointer(3, GL_FLOAT, 0, m_cylinderColors.data());
540 glVertexPointer(3, GL_FLOAT, 0, m_cylinderVertexes.data());
541 glTexCoordPointer(2, GL_FLOAT, 0, m_cylinderTextureCoords.data());
543 glDrawArrays(GL_TRIANGLE_STRIP, 0, m_cylinderVertexes.size() / 3);
546 glNormalPointer(GL_FLOAT, 0, m_upperBaseNormals.data());
547 glColorPointer(3, GL_FLOAT, 0, m_upperBaseColors.data());
548 glVertexPointer(3, GL_FLOAT, 0, m_upperBaseVertexes.data());
549 glTexCoordPointer(2, GL_FLOAT, 0, m_upperBaseTextureCoords.data());
551 unsigned int startIndex = 0;
552 foreach (
unsigned int curLength, m_upperBaseSegmentsLength) {
553 glDrawArrays(GL_TRIANGLE_FAN, startIndex, curLength);
554 startIndex += curLength;
558 glNormalPointer(GL_FLOAT, 0, m_lowerBaseNormals.data());
559 glColorPointer(3, GL_FLOAT, 0, m_lowerBaseColors.data());
560 glVertexPointer(3, GL_FLOAT, 0, m_lowerBaseVertexes.data());
561 glTexCoordPointer(2, GL_FLOAT, 0, m_lowerBaseTextureCoords.data());
564 foreach (
unsigned int curLength, m_lowerBaseSegmentsLength) {
565 glDrawArrays(GL_TRIANGLE_FAN, startIndex, curLength);
566 startIndex += curLength;
569 glDisableClientState(GL_VERTEX_ARRAY);
570 glDisableClientState(GL_COLOR_ARRAY);
571 glDisableClientState(GL_NORMAL_ARRAY);
572 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
575 if (m_cylinder->localAxesDrawn()) {
576 const float radius =
min(m_radius, m_height) * 0.1;
578 RenderWObjectContainer::drawArrow(
wVector(m_height, 0.0, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::red);
579 RenderWObjectContainer::drawArrow(
wVector(0.0, 2.0 * m_radius, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::green);
580 RenderWObjectContainer::drawArrow(
wVector(0.0, 0.0, 2.0 * m_radius),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::blue);
597 if (m_cylinder->graphicalRepresentationNeedsUpdate()) {
598 updateRepresentation();
602 calculateAABB(minpoint, maxpoint, obj->matrix());
616 if (m_cylinder->graphicalRepresentationNeedsUpdate()) {
617 updateRepresentation();
620 const real h2 = m_height / 2.0;
621 const real tdx = fabs(tm.x_ax[0] * h2) + fabs(tm.y_ax[0] * m_radius) + fabs(tm.z_ax[0] * m_radius);
622 const real tdy = fabs(tm.x_ax[1] * h2) + fabs(tm.y_ax[1] * m_radius) + fabs(tm.z_ax[1] * m_radius);
623 const real tdz = fabs(tm.x_ax[2] * h2) + fabs(tm.y_ax[2] * m_radius) + fabs(tm.z_ax[2] * m_radius);
624 const wVector hds(tdx, tdy, tdz);
625 minPoint = tm.w_pos - hds;
626 maxPoint = tm.w_pos + hds;
639 if (m_cylinder->graphicalRepresentationNeedsUpdate()) {
640 updateRepresentation();
643 dimension[0] = m_height;
644 dimension[1] = m_radius * 2.0;
645 dimension[2] = m_radius * 2.0;
646 const wVector rds(m_height / 2.0, m_radius, m_radius);
660 const int numDivs = 20;
661 const float anglePerDiv = (2 * M_PI) /
float(numDivs);
662 const float lowerBaseX = -m_height / 2.0;
663 const float upperBaseX = +m_height / 2.0;
666 m_cylinderVertexes.clear();
667 m_cylinderNormals.clear();
668 m_cylinderColors.clear();
669 m_cylinderTextureCoords.clear();
670 m_upperBaseVertexes.clear();
671 m_upperBaseNormals.clear();
672 m_upperBaseColors.clear();
673 m_upperBaseTextureCoords.clear();
674 m_upperBaseSegmentsLength.clear();
675 m_lowerBaseVertexes.clear();
676 m_lowerBaseNormals.clear();
677 m_lowerBaseColors.clear();
678 m_lowerBaseTextureCoords.clear();
679 m_lowerBaseSegmentsLength.clear();
682 QColor cylinderColor;
683 if (m_cylinder->useColorTextureOfOwner()) {
694 cylinderColor = obj->
color();
696 cylinderColor = m_cylinder->color();
702 QList<PhyCylinder::SegmentColor> tmpCylinderColors;
703 if (cylinderColor.isValid()){
707 tmpCylinderColors = m_cylinder->segmentsColor();
710 QList<PhyCylinder::SegmentColor> cylinderColors;
711 for (
int i = 0; i < tmpCylinderColors.size(); ++i) {
712 if (tmpCylinderColors[i].intervals.length() < anglePerDiv) {
713 cylinderColors << tmpCylinderColors[i];
716 const int numDivisions = int(ceil(tmpCylinderColors[i].intervals.length() / anglePerDiv));
717 if (numDivisions == 0) {
720 const real divisionsLength = tmpCylinderColors[i].intervals.length() /
real(numDivisions);
723 if (numDivisions == 1) {
724 cylinderColors << tmpCylinderColors[i];
727 const real firstIntervalStart = tmpCylinderColors[i].intervals.begin()->start;
729 for (
int j = 1; j < numDivisions - 1; j++) {
730 const real curIntervalStart = cylinderColors.last().intervals.begin()->end;
731 cylinderColors << PhyCylinder::SegmentColor(
SimpleInterval(curIntervalStart, curIntervalStart + divisionsLength), tmpCylinderColors[i].color);
734 const real lastIntervalStart = cylinderColors.last().intervals.begin()->end;
735 const real lastIntervalEnd = tmpCylinderColors[i].intervals.begin()->end;
736 cylinderColors << PhyCylinder::SegmentColor(
SimpleInterval(lastIntervalStart, lastIntervalEnd), tmpCylinderColors[i].color);
743 const QColor color = cylinderColors[0].color;
744 const float normY = cos(-PI_GRECO);
745 const float normZ = sin(-PI_GRECO);
746 const float y = m_radius * normY;
747 const float z = m_radius * normZ;
748 m_cylinderVertexes.append(lowerBaseX);
749 m_cylinderVertexes.append(y);
750 m_cylinderVertexes.append(z);
751 m_cylinderNormals.append(0.0);
752 m_cylinderNormals.append(normY);
753 m_cylinderNormals.append(normZ);
754 m_cylinderColors.append(color.redF());
755 m_cylinderColors.append(color.greenF());
756 m_cylinderColors.append(color.blueF());
757 m_cylinderTextureCoords.append(0.0);
758 m_cylinderTextureCoords.append(0.0);
759 m_cylinderVertexes.append(upperBaseX);
760 m_cylinderVertexes.append(y);
761 m_cylinderVertexes.append(z);
762 m_cylinderNormals.append(0.0);
763 m_cylinderNormals.append(normY);
764 m_cylinderNormals.append(normZ);
765 m_cylinderColors.append(color.redF());
766 m_cylinderColors.append(color.greenF());
767 m_cylinderColors.append(color.blueF());
768 m_cylinderTextureCoords.append(1.0);
769 m_cylinderTextureCoords.append(0.0);
772 QColor prevColor = cylinderColors[0].color;
773 for (
int i = 0; i < cylinderColors.size(); ++i) {
774 const QColor color = cylinderColors[i].color;
776 if (prevColor != color) {
779 const real prevAngle = cylinderColors[i].intervals.begin()->start;
780 const float normY = cos(prevAngle);
781 const float normZ = sin(prevAngle);
782 const float y = m_radius * normY;
783 const float z = m_radius * normZ;
785 m_cylinderVertexes.append(lowerBaseX);
786 m_cylinderVertexes.append(y);
787 m_cylinderVertexes.append(z);
788 m_cylinderNormals.append(0.0);
789 m_cylinderNormals.append(normY);
790 m_cylinderNormals.append(normZ);
791 m_cylinderColors.append(color.redF());
792 m_cylinderColors.append(color.greenF());
793 m_cylinderColors.append(color.blueF());
794 m_cylinderTextureCoords.append(0.0);
795 m_cylinderTextureCoords.append((prevAngle + PI_GRECO) / (2.0 * PI_GRECO));
796 m_cylinderVertexes.append(upperBaseX);
797 m_cylinderVertexes.append(y);
798 m_cylinderVertexes.append(z);
799 m_cylinderNormals.append(0.0);
800 m_cylinderNormals.append(normY);
801 m_cylinderNormals.append(normZ);
802 m_cylinderColors.append(color.redF());
803 m_cylinderColors.append(color.greenF());
804 m_cylinderColors.append(color.blueF());
805 m_cylinderTextureCoords.append(1.0);
806 m_cylinderTextureCoords.append((prevAngle + PI_GRECO) / (2.0 * PI_GRECO));
809 const real curAngle = cylinderColors[i].intervals.begin()->end;
810 const float normY = cos(curAngle);
811 const float normZ = sin(curAngle);
812 const float y = m_radius * normY;
813 const float z = m_radius * normZ;
816 m_cylinderVertexes.append(lowerBaseX);
817 m_cylinderVertexes.append(y);
818 m_cylinderVertexes.append(z);
819 m_cylinderNormals.append(0.0);
820 m_cylinderNormals.append(normY);
821 m_cylinderNormals.append(normZ);
822 m_cylinderColors.append(color.redF());
823 m_cylinderColors.append(color.greenF());
824 m_cylinderColors.append(color.blueF());
825 m_cylinderTextureCoords.append(0.0);
826 m_cylinderTextureCoords.append((curAngle + PI_GRECO) / (2.0 * PI_GRECO));
827 m_cylinderVertexes.append(upperBaseX);
828 m_cylinderVertexes.append(y);
829 m_cylinderVertexes.append(z);
830 m_cylinderNormals.append(0.0);
831 m_cylinderNormals.append(normY);
832 m_cylinderNormals.append(normZ);
833 m_cylinderColors.append(color.redF());
834 m_cylinderColors.append(color.greenF());
835 m_cylinderColors.append(color.blueF());
836 m_cylinderTextureCoords.append(1.0);
837 m_cylinderTextureCoords.append((curAngle + PI_GRECO) / (2.0 * PI_GRECO));
839 prevColor = cylinderColors[i].color;
845 QList<PhyCylinder::SegmentColor> upperBaseColor;
846 QColor colorForUpperBase;
847 if (cylinderColor.isValid()) {
849 colorForUpperBase = cylinderColor;
850 }
else if (m_cylinder->upperBaseColor().isValid()) {
852 colorForUpperBase = m_cylinder->upperBaseColor();
854 if (colorForUpperBase.isValid()) {
855 for (
int i = 0; i < cylinderColors.size(); i++) {
857 s.
color = colorForUpperBase;
861 upperBaseColor = cylinderColors;
866 unsigned int numVertexesCurSegment = 0;
871 const QColor color = upperBaseColor[0].color;
872 m_upperBaseVertexes.append(upperBaseX);
873 m_upperBaseVertexes.append(0.0);
874 m_upperBaseVertexes.append(0.0);
875 m_upperBaseNormals.append(1.0);
876 m_upperBaseNormals.append(0.0);
877 m_upperBaseNormals.append(0.0);
878 m_upperBaseColors.append(color.redF());
879 m_upperBaseColors.append(color.greenF());
880 m_upperBaseColors.append(color.blueF());
881 m_upperBaseTextureCoords.append(0.5);
882 m_upperBaseTextureCoords.append(0.5);
883 ++numVertexesCurSegment;
885 const real curAngle = upperBaseColor[0].intervals.begin()->start;
886 const float normY = cos(curAngle);
887 const float normZ = sin(curAngle);
888 const float y = m_radius * normY;
889 const float z = m_radius * normZ;
891 m_upperBaseVertexes.append(upperBaseX);
892 m_upperBaseVertexes.append(y);
893 m_upperBaseVertexes.append(z);
894 m_upperBaseNormals.append(1.0);
895 m_upperBaseNormals.append(0.0);
896 m_upperBaseNormals.append(0.0);
897 m_upperBaseColors.append(color.redF());
898 m_upperBaseColors.append(color.greenF());
899 m_upperBaseColors.append(color.blueF());
900 m_upperBaseTextureCoords.append((normY + 1.0) / 2.0);
901 m_upperBaseTextureCoords.append((normZ + 1.0) / 2.0);
902 ++numVertexesCurSegment;
905 prevColor = upperBaseColor[0].color;
906 for (
int i = 0; i < upperBaseColor.size(); ++i) {
907 const QColor color = upperBaseColor[i].color;
909 if (prevColor != color) {
911 m_upperBaseSegmentsLength.append(numVertexesCurSegment);
912 numVertexesCurSegment = 0;
916 const real prevAngle = upperBaseColor[i].intervals.begin()->start;
917 const float normY = cos(prevAngle);
918 const float normZ = sin(prevAngle);
919 const float y = m_radius * normY;
920 const float z = m_radius * normZ;
921 m_upperBaseVertexes.append(upperBaseX);
922 m_upperBaseVertexes.append(0.0);
923 m_upperBaseVertexes.append(0.0);
924 m_upperBaseNormals.append(1.0);
925 m_upperBaseNormals.append(0.0);
926 m_upperBaseNormals.append(0.0);
927 m_upperBaseColors.append(color.redF());
928 m_upperBaseColors.append(color.greenF());
929 m_upperBaseColors.append(color.blueF());
930 m_upperBaseTextureCoords.append(0.5);
931 m_upperBaseTextureCoords.append(0.5);
932 ++numVertexesCurSegment;
933 m_upperBaseVertexes.append(upperBaseX);
934 m_upperBaseVertexes.append(y);
935 m_upperBaseVertexes.append(z);
936 m_upperBaseNormals.append(1.0);
937 m_upperBaseNormals.append(0.0);
938 m_upperBaseNormals.append(0.0);
939 m_upperBaseColors.append(color.redF());
940 m_upperBaseColors.append(color.greenF());
941 m_upperBaseColors.append(color.blueF());
942 m_upperBaseTextureCoords.append((normY + 1.0) / 2.0);
943 m_upperBaseTextureCoords.append((normZ + 1.0) / 2.0);
944 ++numVertexesCurSegment;
947 const real curAngle = upperBaseColor[i].intervals.begin()->end;
948 const float normY = cos(curAngle);
949 const float normZ = sin(curAngle);
950 const float y = m_radius * normY;
951 const float z = m_radius * normZ;
953 m_upperBaseVertexes.append(upperBaseX);
954 m_upperBaseVertexes.append(y);
955 m_upperBaseVertexes.append(z);
956 m_upperBaseNormals.append(1.0);
957 m_upperBaseNormals.append(0.0);
958 m_upperBaseNormals.append(0.0);
959 m_upperBaseColors.append(color.redF());
960 m_upperBaseColors.append(color.greenF());
961 m_upperBaseColors.append(color.blueF());
962 m_upperBaseTextureCoords.append((normY + 1.0) / 2.0);
963 m_upperBaseTextureCoords.append((normZ + 1.0) / 2.0);
964 ++numVertexesCurSegment;
966 prevColor = upperBaseColor[i].color;
969 m_upperBaseSegmentsLength.append(numVertexesCurSegment);
972 QList<PhyCylinder::SegmentColor> lowerBaseColor;
973 QColor colorForLowerBase;
974 if (cylinderColor.isValid()) {
976 colorForLowerBase = cylinderColor;
977 }
else if (m_cylinder->lowerBaseColor().isValid()) {
979 colorForLowerBase = m_cylinder->lowerBaseColor();
981 if (colorForLowerBase.isValid()) {
982 for (
int i = 0; i < cylinderColors.size(); i++) {
984 s.
color = colorForLowerBase;
988 lowerBaseColor = cylinderColors;
991 numVertexesCurSegment = 0;
994 const QColor color = lowerBaseColor[0].color;
995 m_lowerBaseVertexes.append(lowerBaseX);
996 m_lowerBaseVertexes.append(0.0);
997 m_lowerBaseVertexes.append(0.0);
998 m_lowerBaseNormals.append(-1.0);
999 m_lowerBaseNormals.append(0.0);
1000 m_lowerBaseNormals.append(0.0);
1001 m_lowerBaseColors.append(color.redF());
1002 m_lowerBaseColors.append(color.greenF());
1003 m_lowerBaseColors.append(color.blueF());
1004 m_lowerBaseTextureCoords.append(0.5);
1005 m_lowerBaseTextureCoords.append(0.5);
1006 ++numVertexesCurSegment;
1008 const real curAngle = lowerBaseColor[0].intervals.begin()->start;
1009 const float normY = cos(curAngle);
1010 const float normZ = sin(curAngle);
1011 const float y = m_radius * normY;
1012 const float z = m_radius * normZ;
1014 m_lowerBaseVertexes.append(lowerBaseX);
1015 m_lowerBaseVertexes.append(y);
1016 m_lowerBaseVertexes.append(z);
1017 m_lowerBaseNormals.append(-1.0);
1018 m_lowerBaseNormals.append(0.0);
1019 m_lowerBaseNormals.append(0.0);
1020 m_lowerBaseColors.append(color.redF());
1021 m_lowerBaseColors.append(color.greenF());
1022 m_lowerBaseColors.append(color.blueF());
1023 m_lowerBaseTextureCoords.append((normY + 1.0) / 2.0);
1024 m_lowerBaseTextureCoords.append((normZ + 1.0) / 2.0);
1025 ++numVertexesCurSegment;
1028 prevColor = lowerBaseColor[0].color;
1029 for (
int i = 0; i < lowerBaseColor.size(); ++i) {
1030 const QColor color = lowerBaseColor[i].color;
1032 if (prevColor != color) {
1034 m_lowerBaseSegmentsLength.append(numVertexesCurSegment);
1035 numVertexesCurSegment = 0;
1039 const real prevAngle = lowerBaseColor[i].intervals.begin()->start;
1040 const float normY = cos(prevAngle);
1041 const float normZ = sin(prevAngle);
1042 const float y = m_radius * normY;
1043 const float z = m_radius * normZ;
1044 m_lowerBaseVertexes.append(lowerBaseX);
1045 m_lowerBaseVertexes.append(0.0);
1046 m_lowerBaseVertexes.append(0.0);
1047 m_lowerBaseNormals.append(-1.0);
1048 m_lowerBaseNormals.append(0.0);
1049 m_lowerBaseNormals.append(0.0);
1050 m_lowerBaseColors.append(color.redF());
1051 m_lowerBaseColors.append(color.greenF());
1052 m_lowerBaseColors.append(color.blueF());
1053 m_lowerBaseTextureCoords.append(0.5);
1054 m_lowerBaseTextureCoords.append(0.5);
1055 ++numVertexesCurSegment;
1056 m_lowerBaseVertexes.append(lowerBaseX);
1057 m_lowerBaseVertexes.append(y);
1058 m_lowerBaseVertexes.append(z);
1059 m_lowerBaseNormals.append(-1.0);
1060 m_lowerBaseNormals.append(0.0);
1061 m_lowerBaseNormals.append(0.0);
1062 m_lowerBaseColors.append(color.redF());
1063 m_lowerBaseColors.append(color.greenF());
1064 m_lowerBaseColors.append(color.blueF());
1065 m_lowerBaseTextureCoords.append((normY + 1.0) / 2.0);
1066 m_lowerBaseTextureCoords.append((normZ + 1.0) / 2.0);
1067 ++numVertexesCurSegment;
1070 const real curAngle = lowerBaseColor[i].intervals.begin()->end;
1071 const float normY = cos(curAngle);
1072 const float normZ = sin(curAngle);
1073 const float y = m_radius * normY;
1074 const float z = m_radius * normZ;
1076 m_lowerBaseVertexes.append(lowerBaseX);
1077 m_lowerBaseVertexes.append(y);
1078 m_lowerBaseVertexes.append(z);
1079 m_lowerBaseNormals.append(-1.0);
1080 m_lowerBaseNormals.append(0.0);
1081 m_lowerBaseNormals.append(0.0);
1082 m_lowerBaseColors.append(color.redF());
1083 m_lowerBaseColors.append(color.greenF());
1084 m_lowerBaseColors.append(color.blueF());
1085 m_lowerBaseTextureCoords.append((normY + 1.0) / 2.0);
1086 m_lowerBaseTextureCoords.append((normZ + 1.0) / 2.0);
1087 ++numVertexesCurSegment;
1089 prevColor = lowerBaseColor[i].color;
1092 m_lowerBaseSegmentsLength.append(numVertexesCurSegment);
1216 cone =
dynamic_cast<PhyCone*
>(wobj);
1217 Q_ASSERT_X(cone != NULL,
"RenderPhyCone",
"The WObject is not a PhyCone!!!");
1218 rad = cone->radius();
1219 hei = cone->height();
1222 virtual void render( QGLContext* gw ) {
1224 GLUquadricObj *pObj;
1229 wMatrix matrix = wMatrix::yaw( PI_GRECO * 0.5 );
1231 matrix = matrix * cone->matrix();
1232 GLMultMatrix(&matrix[0][0]);
1235 pObj = gluNewQuadric();
1236 gluQuadricTexture(pObj,
true);
1237 gluCylinder(pObj, rad, 0, hei, 20, 2);
1240 gluQuadricOrientation(pObj, GLU_INSIDE);
1241 gluDisk(pObj, 0.0f, rad, 20, 1);
1243 gluDeleteQuadric(pObj);
1246 if (cone->localAxesDrawn()) {
1247 const float radius =
min(rad, hei) * 0.1;
1249 RenderWObjectContainer::drawArrow(
wVector(hei, 0.0, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::red);
1250 RenderWObjectContainer::drawArrow(
wVector(0.0, 2.0 * rad, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::green);
1251 RenderWObjectContainer::drawArrow(
wVector(0.0, 0.0, 2.0 * rad),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::blue);
1261 calculateAABB( minpoint, maxpoint, obj->matrix() );
1266 real tdx = fabs(tm.x_ax[0]*h2) + fabs(tm.y_ax[0]*rad) + fabs(tm.z_ax[0]*rad);
1267 real tdy = fabs(tm.x_ax[1]*h2) + fabs(tm.y_ax[1]*rad) + fabs(tm.z_ax[1]*rad);
1268 real tdz = fabs(tm.x_ax[2]*h2) + fabs(tm.y_ax[2]*rad) + fabs(tm.z_ax[2]*rad);
1270 minPoint = tm.w_pos - hds;
1271 maxPoint = tm.w_pos + hds;
1276 dimension[1] = rad*2.0;
1277 dimension[2] = rad*2.0;
1382 Q_ASSERT_X(co != NULL,
"RenderCompoundObject",
"The WObject is not a PhyCompoundObject!!!");
1383 initRobjv( container );
1390 virtual void render( QGLContext* gw ) {
1393 wMatrix matrix = co->matrix();
1394 GLMultMatrix(&matrix[0][0]);
1400 if (co->localAxesDrawn()) {
1405 calculateOBB(dimension, minPoint, maxPoint);
1406 const float radius =
min(dimension.x,
min(dimension.y, dimension.z)) * 0.1;
1408 RenderWObjectContainer::drawArrow(
wVector(dimension.x, 0.0, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::red);
1409 RenderWObjectContainer::drawArrow(
wVector(0.0, dimension.y, 0.0),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::green);
1410 RenderWObjectContainer::drawArrow(
wVector(0.0, 0.0, dimension.z),
wVector(0.0, 0.0, 0.0), radius, 2.0 * radius, 2.0 * radius, Qt::blue);
1420 calculateAABB( minpoint, maxpoint, obj->matrix() );
1424 robjv[0]->calculateAABB( minPoint, maxPoint, robjv[0]->
object()->matrix()*tm );
1426 for(
int i=1; i<robjv.size(); i++ ) {
1427 robjv[i]->calculateAABB( minP, maxP, robjv[i]->
object()->matrix()*tm );
1428 mergeAABB( minPoint, maxPoint, minP, maxP );
1435 if ( robjv.size() == 0 ) {
1436 qWarning(
"== this point should never reached: renderwobjecthierarchy.cpp:435" );
1439 robjv[0]->calculateAABB( minPoint, maxPoint, robjv[0]->
object()->matrix() );
1440 for(
int i=1; i<robjv.size(); i++ ) {
1441 robjv[i]->calculateAABB( minP, maxP, robjv[i]->
object()->matrix() );
1442 mergeAABB( minPoint, maxPoint, minP, maxP );
1444 dimension[0] = fabs( maxPoint[0] - minPoint[0] );
1445 dimension[1] = fabs( maxPoint[1] - minPoint[1] );
1446 dimension[2] = fabs( maxPoint[2] - minPoint[2] );
1450 QVector<RenderWObject*> robjv;
1454 robjv << RenderWObjectContainer::createRenderWObjectFor( obj, container );
1457 void mergeAABB( wVector& minPointA, wVector& maxPointA,
const wVector& minPointB,
const wVector& maxPointB ) {
1458 minPointA[0] =
min( minPointA[0], minPointB[0] );
1459 minPointA[1] =
min( minPointA[1], minPointB[1] );
1460 minPointA[2] =
min( minPointA[2], minPointB[2] );
1461 maxPointA[0] =
max( maxPointA[0], maxPointB[0] );
1462 maxPointA[1] =
max( maxPointA[1], maxPointB[1] );
1463 maxPointA[2] =
max( maxPointA[2], maxPointB[2] );
1474 m_graphicalWObject(dynamic_cast<GraphicalWObject*>(obj))
1476 Q_ASSERT_X(m_graphicalWObject != NULL,
"GraphicalWObjectRenderer",
"The WObject is not a GraphicalWObject!!!");
1483 virtual void render(QGLContext *gw)
1485 m_graphicalWObject->updateAndRender(
this, gw);
1490 m_graphicalWObject->updateAndRenderAABB(
this, gw);
1495 m_graphicalWObject->updateAndCalculateAABB(minPoint, maxPoint, tm);
1500 m_graphicalWObject->updateAndCalculateOBB(dimension, minPoint, maxPoint);
1507 bool RenderWObjectContainer::facInited =
false;
1508 QMap<QString, WAbstractCreator*>* RenderWObjectContainer::fac;
1509 void RenderWObjectContainer::initFactory() {
1510 if ( facInited )
return;
1512 fac =
new QMap<QString, WAbstractCreator*>();
1514 (*fac)[
"farsa::WMesh"] =
new WCreator<RenderWMesh>();
1515 (*fac)[
"farsa::PhyBox"] =
new WCreator<RenderPhyBox>();
1516 (*fac)[
"farsa::PhySphere"] =
new WCreator<RenderPhySphere>();
1517 (*fac)[
"farsa::PhyEllipsoid"] =
new WCreator<RenderPhyEllipsoid>();
1518 (*fac)[
"farsa::PhyCylinder"] =
new WCreator<RenderPhyCylinder>();
1519 (*fac)[
"farsa::PhyCone"] =
new WCreator<RenderPhyCone>();
1521 (*fac)[
"farsa::PhyCompoundObject"] =
new WCreator<RenderCompoundObject>();
1522 (*fac)[
"farsa::GraphicalWObject"] =
new WCreator<GraphicalWObjectRenderer>();
1525 (*fac)[
"farsa::WObject"] =
new WCreator<RenderGenericObject>();
1526 (*fac)[
"farsa::WorldController"] =
new WCreator<RenderGenericObject>();
QVector< GLfloat > m_cylinderVertexes
The array of vertexes of the cylinder.
virtual void calculateOBB(wVector &dimension, wVector &minPoint, wVector &maxPoint)
Returns the dimension of the Oriented Bounding Box (OBB) in the object local frame.
virtual void calculateOBB(wVector &dimension, wVector &minPoint, wVector &maxPoint)
Returns the dimension of the Oriented Bounding Box (OBB) in the object local frame.
virtual void calculateAABB(wVector &minPoint, wVector &maxPoint, const wMatrix tm)
Computes and returns the AABB of the object.
QVector< GLfloat > m_cylinderColors
The array of colors of vertexes of the cylinder.
virtual void calculateAABB(wVector &minPoint, wVector &maxPoint, const wMatrix tm)
Returns the min and max points of the Axis-Aligned Bounding Box (AABB)
QVector< GLfloat > m_lowerBaseTextureCoords
The arrayof texture coordinates for each vertex of the lower base.
QVector< GLfloat > m_upperBaseTextureCoords
The arrayof texture coordinates for each vertex of the upper base.
virtual void render(QGLContext *gw)
The function performing the actual rendering.
RenderPhyCylinder(WObject *wobj, RenderWObjectContainer *container)
Constructor.
virtual void renderAABB(RenderWorld *gw)
The function rendering the Axis-Aligned Bounding Box (AABB)
void updateRepresentation()
Updates the representation of the cylinder.
QColor color() const
return the color of this object
virtual void calculateAABB(wVector &minPoint, wVector &maxPoint, const wMatrix tm)
Returns the min and max points of the Axis-Aligned Bounding Box (AABB)
virtual ~RenderPhyCylinder()
Destructor.
virtual void calculateOBB(wVector &dimension, wVector &minPoint, wVector &maxPoint)
Returns the dimension of the Oriented Bounding Box (OBB) in the object local frame.
virtual void calculateAABB(wVector &minPoint, wVector &maxPoint, const wMatrix tm)
Returns the min and max points of the Axis-Aligned Bounding Box (AABB)
virtual void calculateAABB(wVector &minPoint, wVector &maxPoint, const wMatrix tm)
Returns the min and max points of the Axis-Aligned Bounding Box (AABB)
const real m_radius
The radius of the cylinder.
QVector< unsigned int > m_lowerBaseSegmentsLength
The array with the number of vertexes for each segment of the lower base (each segment has a differen...
FARSA_UTIL_TEMPLATE const T max(const T &t1, const U &t2)
virtual void renderAABB(RenderWorld *gw)
The function rendering the Axis-Aligned Bounding Box (AABB)
This file contains the implementation of some RenderWObject for drawing object and also the initializ...
virtual void calculateOBB(wVector &dimension, wVector &minPoint, wVector &maxPoint)
Returns the dimension of the Oriented Bounding Box (OBB) in the object local frame.
PhyCylinder *const m_cylinder
The cylinder we have to render.
The structure used to define the color of intervals of the cylinder.
QVector< GLfloat > m_upperBaseColors
The array of colors of vertexes of the upper base.
virtual void renderAABB(RenderWorld *gw)
The function rendering the Axis-Aligned Bounding Box (AABB)
QVector< GLfloat > m_cylinderTextureCoords
The arrayof texture coordinates for each vertex of the cylinder.
virtual void renderAABB(RenderWorld *gw)
Renders only the AABB of the object.
virtual void calculateOBB(wVector &dimension, wVector &minPoint, wVector &maxPoint)
Computes and returns the OBB of the object.
An helper class to draw stuffs in the world.
const QVector< PhyObject * > bodies()
return PhyObject composing this object
QVector< GLfloat > m_upperBaseVertexes
The array of vertexes of the upper base.
QVector< GLfloat > m_lowerBaseVertexes
The array of vertexes of the lower base.
virtual void renderAABB(RenderWorld *gw)
The function rendering the Axis-Aligned Bounding Box (AABB)
QVector< GLfloat > m_upperBaseNormals
The array of normals to vertexes of the upper base.
wVector rotateVector(const wVector &v) const
rotate the vector v, it doesn't apply position transformation
bool useColorTextureOfOwner() const
if true, we will use color and texture of our owner (if we have one)
QVector< GLfloat > m_lowerBaseNormals
The array of normals to vertexes of the lower base.
wVectorT< false > scale(real s) const
return a new wVectorT with element scaled by s
virtual void calculateAABB(wVector &, wVector &, const wMatrix)
Returns the min and max points of the Axis-Aligned Bounding Box (AABB)
virtual void renderAABB(RenderWorld *gw)
The function rendering the Axis-Aligned Bounding Box (AABB)
QVector< unsigned int > m_upperBaseSegmentsLength
The array with the number of vertexes for each segment of the upper base (each segment has a differen...
virtual void calculateOBB(wVector &dimension, wVector &minPoint, wVector &maxPoint)
Returns the dimension of the Oriented Bounding Box (OBB) in the object local frame.
virtual void calculateAABB(wVector &minPoint, wVector &maxPoint, const wMatrix tm)
Returns the min and max points of the Axis-Aligned Bounding Box (AABB)
The class rendering a PhyCylinder.
virtual void calculateOBB(wVector &, wVector &, wVector &)
Returns the dimension of the Oriented Bounding Box (OBB) in the object local frame.
const real m_height
The height of the cylinder.
QVector< GLfloat > m_lowerBaseColors
The array of colors of vertexes of the lower base.
FARSA_UTIL_TEMPLATE const T min(const T &t1, const U &t2)
virtual void renderAABB(RenderWorld *gw)
The function rendering the Axis-Aligned Bounding Box (AABB)
QVector< GLfloat > m_cylinderNormals
The array of normals to vertexes of the cylinder.
virtual void calculateAABB(wVector &minPoint, wVector &maxPoint, const wMatrix tm)
Returns the min and max points of the Axis-Aligned Bounding Box (AABB)
Ownable * owner() const
Returns the owner of this object.
static void drawWireBox(wVector dims, wMatrix matrix)
draw a wireframe Box
RenderWObjectContainer class.
virtual void renderAABB(RenderWorld *gw)
The function rendering the Axis-Aligned Bounding Box (AABB)
virtual void calculateAABB(wVector &minPoint, wVector &maxPoint, const wMatrix tm)
Returns the min and max points of the Axis-Aligned Bounding Box (AABB)
virtual void calculateOBB(wVector &dimension, wVector &minPoint, wVector &maxPoint)
Returns the dimension of the Oriented Bounding Box (OBB) in the object local frame.
void setupColorTexture(QGLContext *, RenderWObject *obj)
Setup the Color and Texture into the OpenGL Context for RenderWObject passed.
virtual void renderAABB(RenderWorld *)
The function rendering the Axis-Aligned Bounding Box (AABB)
virtual void calculateOBB(wVector &dimension, wVector &minPoint, wVector &maxPoint)
Returns the dimension of the Oriented Bounding Box (OBB) in the object local frame.
QColor color
The color of the segment.