void adddirtoscene(Scene *s,DirRec *dr,V3d pos,V3d up) { // printf("Adding directory %s\n",dr->fname); s->add(new Cylinder(pos+0.0*up,pos+1.0*up,0.05*up.mod())); pos=pos+up; // s->add(new TextRend(dr->fname,10,pos,0.3)); OrderedList<FileRec> ol; for (int i=1; i<=dr->fs.len; i++) { FileRec *r=dr->fs.num(i); ol.add(r,ordering(r)); } V3d x=V3d::normcross(up,V3d::k)*up.mod()*0.8; // Actually, want y=closest to real z V3d y=V3d::normcross(up,x)*up.mod()*0.8; for (int i=1; i<=ol.len; i++) { FileRec *r=ol.p2num(i); // printf(" %s\n",r->fname); float ang=((i%2)==0?1:-1)*(pi*(float)(i-1)/(float)(ol.len-1)); V3d d=up+x*mysin(ang)+y*mycos(ang); // Bad, should do rotation instead. if (Seq(r->type(),"file")) { //s->add(new Cylinder(pos+0.0*d,pos+0.2*d,0.05*up.mod())); s->add(new Sphere(pos+0.1*d,0.02*up.mod())); // s->add(new TextRend(r->fname,10,pos+d,0.1)); } else { DirRec *dr2=(DirRec *)r; adddirtoscene(s,dr2,pos,d.norm()*up.mod()*0.9); } } }
// scale is the width of the image in world space TexturedRectangle3d::TexturedRectangle3d(V3d cen,V3d r,V3d d,RGBmp *img,float s) { scale=s; textureimg=img; r=r.normalised()*scale; d=d.normalised()*scale*(float)img->height/(float)img->width; setupRectangle3d(cen-r/2.0-d/2.0,r,d); }
bool rayPassesNearOrThrough(const V3d& rayOrigin, const V3d& rayDir) const { const double diagRadius = 1.2*bbox.size().length()/2; // Sphere diameter is length of box diagonal const V3d o2c = bbox.center() - rayOrigin; // vector from rayOrigin to box center const double l = o2c.length(); if(l < diagRadius) return true; // rayOrigin lies within bounding sphere // rayOrigin lies outside of bounding sphere const double cosA = o2c.dot(rayDir)/l; // cosine of angle between rayDir and vector from origin to center if(cosA < DBL_MIN) return false; // rayDir points to side or behind with respect to direction from origin to center of box const double sinA = sqrt(1 - cosA*cosA); // sine of angle between rayDir and vector from origin to center return sinA/cosA < diagRadius/l; }
V3d *intersection(Line3d o) { //printf("\nTrying to find intersection %s-%s with %s-%s\n",a.toString(),b.toString(),o.a.toString(),o.b.toString()); Line2d la=Line2d(a.dropz(),b.dropz()); Line2d lb=Line2d(o.a.dropz(),o.b.dropz()); float f=la.findintersectionnum(lb); V3d lah=a+f*(b-a); float g=lb.findintersectionnum(la); V3d lbh=o.a+g*(o.b-o.a); //printf("Intersection (%f) %s == %s (%f) ?\n",f,lah.toString(),lbh.toString(),g); return new V3d(lah.x,lah.y,lah.z); if (lah==lbh) return new V3d(lah.x,lah.y,lah.z); //printf("Intersection failed.\n"); return NULL; }
void Corner::findnormal() { normal=V3d::o; for (int i=1;i<=gs.len;i++) normal=normal+gs.num(i)->normal(); if (gs.len>0) normal.normalise(); col=ucharchop(255*myabs(V3d::normdot(normal,V3d(-1,2,-1)))); // col=col*(float)gs.len/6.0; }
V3d Matrix::operator*(V3d u) { V3d n=V3d(0,0,0); float c; for (int i=0;i<=2;i++) { c=u.var(i); n.x=n.x+c*v[i][0]; n.y=n.y+c*v[i][1]; n.z=n.z+c*v[i][2]; } return n; }
void View3D::snapToPoint(const Imath::V3d & pos) { double snapScale = 0.025; QString pointInfo; V3d newPos(0.0,0.0,0.0); //init newPos to origin if (snapToGeometry(pos, snapScale, &newPos, &pointInfo)) { V3d posDiff = newPos - m_prevCursorSnap; g_logger.info("Selected Point Attributes:\n" "%s" "diff with previous = %.3f\n" "vector diff = %.3f", pointInfo, posDiff.length(), posDiff); // Snap cursor /and/ camera to new position // TODO: Decouple these, but in a sensible way m_cursorPos = newPos; m_camera.setCenter(newPos); m_prevCursorSnap = newPos; } }
float distAbove(V3d v) { // should be part of V3d! return v.distAbove(*this); }
float mod(V3d v) { return v.mod(); }
void main() { setuptriglookup(); allegrosetup(scrwid,scrhei); makepalette(&greypalette); mypalette(255,0,0,0); mypalette(0,0,0,0); mypalette(255,1,1,1); mypalette(128,0,0,0); for (int r=0;r<16;r++) { for (int g=0;g<16;g++) { int palc=r+g*16; mypalette(palc,(r==0?0:brightness+0.2+change*0.5*r/15.0),(g==0?0:brightness+change*0.1+0.2*g/15.0),(g==0?0:brightness+change*0.2+0.6*g/15.0)); // Groovy colours mypalette(palc,(r==0?0:0.1+0.6*r/15.0),(g==0?0:0.1+0.2*g/15.0),(g==0?0:0.1+0.7*g/15.0)); // Good colours: mypalette(palc,(r==0?0:0.3+0.4*r/15.0),(g==0?0:0.1+0.2*g/15.0),(g==0?0:0.3+0.5*g/15.0)); } } float pd=2.5; PPsetup(scrwid,scrhei,pd); V3d vel=V3d(0,0,0); V3d acc=V3d(0,0,0); float droll=0; float dyaw=0; float dpitch=0; int frame=0; // Set up track randomise(); for (int i=0;i<=15;i++) { waves+Wave(); // waves.num(i).display(); } for (float thru=0;thru<1.0;thru+=1.0/(float)numps) { V3d here=getpos(thru); V3d forward=getpos(thru+0.00001)-here; V3d up=V3d::normcross(V3d::crazy,forward); V3d right=V3d::normcross(forward,up); for (int i=0;i<tunnelps;i++) { float t=2*pi*(float)i/(float)tunnelps; float s=sin(t); float c=cos(t); V3d v=here+tunnelrad*(s*up+c*right); octree.add(v); } } for (int i=1;i<500;i++) { octree.add(8.0*V3d(floatrnd(-1,1),floatrnd(-1,1),floatrnd(-1,1))); } // Display track float t=0; do { t=t+0.03; V3d from=V3d::rotate(6.0*V3d::k,V3d::j,t); ori.forcez(from.neg()); pos=from; plotscene(); writescreen(); } while (!key[KEY_SPACE]); do { } while (key[KEY_SPACE]); // Race starttimer(); float thru=0; float marker=0; pos=getpos(marker); V3d *tail=new V3d[taillen]; int tailpos=0; do { thru+=0.001; // V3d last=V3d(pos.x,pos.y,pos.z); // V3d pos=getpos(thru); // V3d next=getpos(thru+0.00001); // V3d newz=next-pos; // ori.forcez(newz); frame++; // float pd=1.6+1.3*sin(2*pi*frame/1000.0); plotscene(); // Plot and move marker V3d m; for (int i=1;i<=15;i++) { m=V3d::disorientate(getpos(marker)-pos,ori); if (m.mod()<markerrange) marker+=0.0002; } float u=PPgetunitnoadd(m); bool plot=false; if (u) { int x,y; float rad=0.12*u; if (PPgetscrposnoadd(m,PPlefteye,&x,&y)) if (left.inimage(x,y)) { plot=true; left.opencircle(x,y,rad,15); left.opencircle(x,y,rad/2,15); } if (PPgetscrposnoadd(m,PPrighteye,&x,&y)) if (right.inimage(x,y)) { plot=true; right.opencircle(x,y,rad,15*16); right.opencircle(x,y,rad/2,15*16); } } if (!plot) { V2d v=scrwid*2*V2d(m.x,m.y).norm(); if (abs(v.x)>scrwid/2) { float change=(float)scrwid/2.0/abs(v.x); v=change*v; } if (abs(v.y)>scrhei/2) { float change=(float)scrhei/2.0/abs(v.y); v=change*v; } v=v+V2d(scrwid/2,scrhei/2); left.opencircle(v,5,15); right.opencircle(v,5,15*16); } // Pull player towards marker // if (m.mod()>markerrange+.1) { V3d pulldir=getpos(marker)-pos; // vel=vel+pulldir*0.02; // float amount=(V3d::normdot(ori.z(),pulldir)+5.0)/6.0; float amount=chop(0.99-(m.mod()-markerrange)/5.0,0,1); V3d newz=ori.z()*amount+(1.0-amount)*pulldir; ori.forcez(newz); // vel=vel*amount; // // // } // Draw and update tail V3d last=(tail[tailpos]-pos).disorientate(ori); for (int k=1;k<taillen;k++) { int j=mymod(tailpos+k,taillen); V3d next=(tail[j]-pos).disorientate(ori); plotline(last,next,(float)k/(float)taillen); last=next; } if ((frame % 2)==0) { tail[tailpos]=pos-ori.qz; tailpos=mymod(tailpos+1,taillen); } writescreen(); // acc=hang(acc,V3d::origin,0.95,0.01); // Movement float angvel=turnability; if (key[KEY_LCONTROL]) vel=vel+ori.z()*forcevel; else angvel=turnability*2.0; if (key[KEY_DOWN]) dpitch=dpitch+angvel; if (key[KEY_UP]) dpitch=dpitch-angvel; if (key[KEY_LEFT]) if (key[KEY_ALT]) droll=droll-angvel; else dyaw=dyaw-angvel; if (key[KEY_RIGHT]) if (key[KEY_ALT]) droll=droll+angvel; else dyaw=dyaw+angvel; vel=hang(vel,V3d::o,0.92,0); pos=pos+vel; droll=hang(droll,0,0.9,0); dyaw=hang(dyaw,0,0.9,0); dpitch=hang(dpitch,0,0.9,0); ori.roll(droll/5.0); ori.yaw(dyaw/5.0); ori.pitch(dpitch/5.0); framedone(); } while (!key[KEY_SPACE] && !key[KEY_ESC]); savetimer(); allegro_exit(); displayframespersecond(); }
void main() { allegrosetup(scrwid,scrhei); makepalette(&greypalette); mypalette(255,0,0,0); mypalette(0,0,0,0); mypalette(255,1,1,1); mypalette(128,0,0,0); randomise(); for (int i=0;i<=15;i++) { waves+Wave(); // waves.num(i).display(); } for (int r=0;r<16;r++) { for (int g=0;g<16;g++) { int palc=r+g*16; mypalette(palc,(r==0?0:brightness+0.2+change*0.5*r/15.0),(g==0?0:brightness+change*0.1+0.2*g/15.0),(g==0?0:brightness+change*0.2+0.6*g/15.0)); // Groovy colours mypalette(palc,(r==0?0:0.1+0.6*r/15.0),(g==0?0:0.1+0.2*g/15.0),(g==0?0:0.1+0.7*g/15.0)); // Good colours: mypalette(palc,(r==0?0:0.3+0.4*r/15.0),(g==0?0:0.1+0.2*g/15.0),(g==0?0:0.3+0.5*g/15.0)); } } V3d vel=V3d(0,0,0); V3d acc=V3d(0,0,0); Ori ori; float droll=0; float dyaw=0; float dpitch=0; int frame=0; List<V3d> particles=List<V3d>(gridsize*gridsize*gridsize); /* for (int i=1;i<gridsize*gridsize*gridsize;i++) { particles+gridsize*V3d(floatrnd(-1,1),floatrnd(-1,1),floatrnd(-1,1)); }*/ int ps=1; float rad=0; for (float thru=0;thru<1.0;thru+=0.0016) { V3d here=getpos(thru); V3d forward=getpos(thru+0.00001)-here; V3d up=V3d::normcross(V3d::crazy,forward); V3d right=V3d::normcross(forward,up); for (int i=0;i<ps;i++) { float t=2*pi*(float)i/(float)ps; float s=sin(t); float c=cos(t); particles+(here+rad*(s*up+c*right)); } // v.print(); } starttimer(); float thru=0; float marker=0; V3d pos=getpos(marker); V3d *tail=new V3d[taillen]; int tailpos=0; do { thru+=0.001; // V3d last=V3d(pos.x,pos.y,pos.z); // V3d pos=getpos(thru); // V3d next=getpos(thru+0.00001); // V3d newz=next-pos; // ori.forcez(newz); frame++; // float pd=1.6+1.3*sin(2*pi*frame/1000.0); float pd=2.0; PPsetup(scrwid,scrhei,pd); left.clear(0); right.clear(0); // b.fadeby(16); int ioff=-mydiv(pos.x,gjump); int joff=-mydiv(pos.y,gjump); int koff=-mydiv(pos.z,gjump); ori.quickorisetup(); // Need to find largest axis, and do loops with that one outside int ks=mysgn(ori.qz.z); int js=-mysgn(ori.qz.y); int is=-mysgn(ori.qz.x); for (int i=1;i<=particles.len;i++) { int x,y; V3d p=particles.num(i); V3d cen=p-pos+0.0*ori.y; cen=V3d::disorientate(cen,ori); int c=15.0-chop(14.0*(cen.z+gridsize)/(float)(gridsize*2),0,14); // int c=7.0-chop(6.0*(i/particles.len),0,6); plotsphere(cen,c); } // Plot and move marker V3d m; for (int i=1;i<=15;i++) { m=V3d::disorientate(getpos(marker)-pos,ori); if (m.mod()<markerrange) marker+=0.0002; } float u=PPgetunitnoadd(m); bool plot=false; if (u) { int x,y; float rad=0.08*u; PPgetscrposnoadd(m,PPlefteye,&x,&y); if (left.inimage(x,y)) { plot=true; left.opencircle(x,y,rad,15); } PPgetscrposnoadd(m,PPrighteye,&x,&y); if (right.inimage(x,y)) { plot=true; right.opencircle(x,y,rad,15*16); } } if (!plot) { V2d v=scrwid*2*V2d(m.x,m.y).norm(); if (abs(v.x)>scrwid/2) { float change=(float)scrwid/2.0/abs(v.x); v=change*v; } if (abs(v.y)>scrhei/2) { float change=(float)scrhei/2.0/abs(v.y); v=change*v; } v=v+V2d(scrwid/2,scrhei/2); left.opencircle(v,5,15); right.opencircle(v,5,15*16); } // Pull player towards marker // if (m.mod()>markerrange+.1) { V3d pulldir=getpos(marker)-pos; // vel=vel+pulldir*0.02; // float amount=(V3d::normdot(ori.z(),pulldir)+5.0)/6.0; float amount=chop(0.99-(m.mod()-markerrange)/5.0,0,1); V3d newz=ori.z()*amount+(1.0-amount)*pulldir; ori.forcez(newz); // vel=vel*amount; // //} // Draw and update tail V3d last=(tail[tailpos]-pos).disorientate(ori); for (int k=1;k<taillen;k++) { int j=mymod(tailpos+k,taillen); V3d next=(tail[j]-pos).disorientate(ori); plotline(last,next,(float)k/(float)taillen); last=next; } if ((frame % 5)==0) { tail[tailpos]=pos-ori.qz; tailpos=mymod(tailpos+1,taillen); } // Or screens for (int i=0;i<scrwid;i++) { for (int j=0;j<scrhei;j++) { b.bmp[j][i]=(left.bmp[j][i] | right.bmp[j][i]); } } b.writetoscreen(); // acc=hang(acc,V3d::origin,0.95,0.01); // Movement float angvel=turnability; if (key[KEY_LCONTROL]) vel=vel+ori.z()*forcevel; else angvel=turnability*2.0; if (key[KEY_UP]) dpitch=dpitch+angvel; if (key[KEY_DOWN]) dpitch=dpitch-angvel; if (key[KEY_LEFT]) if (key[KEY_ALT]) droll=droll-angvel; else dyaw=dyaw-angvel; if (key[KEY_RIGHT]) if (key[KEY_ALT]) droll=droll+angvel; else dyaw=dyaw+angvel; vel=hang(vel,V3d::o,0.91,0); pos=pos+vel; droll=hang(droll,0,0.9,0); dyaw=hang(dyaw,0,0.9,0); dpitch=hang(dpitch,0,0.9,0); ori.roll(droll/5.0); ori.yaw(dyaw/5.0); ori.pitch(dpitch/5.0); framedone(); } while (!key[KEY_SPACE] && !key[KEY_ESC]); savetimer(); allegro_exit(); displayframespersecond(); }
String toString() { return Sformat("%s-%s",a.toString(),b.toString()); }
static Matrix<double, 4, 4> _make_matrix( int x_axis, int y_axis, int z_axis ) { typedef Vector<double, 3> V3d; V3d x = (x_axis<0) ? -V3d::Unit(-x_axis) : V3d::Unit(x_axis); V3d y = (y_axis<0) ? -V3d::Unit(-y_axis) : V3d::Unit(y_axis); V3d z = (z_axis<0) ? -V3d::Unit(-z_axis) : V3d::Unit(z_axis); return Matrix<double, 4, 4>( x.x(), x.y(), x.z(), 0, y.x(), y.y(), y.z(), 0, z.x(), z.y(), z.z(), 0, 0, 0, 0, 1 ); }
void setupPlane(V3d a,V3d b) { pos=a; nor=b.normal(); }
String toString() { return Sformat(".%s^%s",pos.toString(),nor.toString()); }
void dispfn(V3d p) { p.print(); }
Renderable rotated(V3d ax,float ang) { return Triangle3d(a.rotated(ax,ang),b.rotated(ax,ang),c.rotated(ax,ang)); }
void Ori::forcez(V3d nz) { nz=nz.normalised(); y=V3d::normcross(x,nz).neg(); x=V3d::normcross(y,nz); qz=nz; }
Line3d orient(Viewpoint v) { return Line3d(a.orient(v),b.orient(v)); }
Plane orient(Viewpoint v) { return Plane(pos.orient(v),nor.orientate(v.ori)); }