353
353
return v3Sub(par, per);
356
matrix_t mRotationFromTo(vector_t a, vector_t b)
356
matrix_t mRotationFromTo(vector_t a, vector_t b, vmfloat_t f)
358
358
double rdot = vDot(a, b);
359
359
vector_t rcross = vCross(a, b);
360
360
vector_t raxis = vSetLength(rcross, 1.0);
361
361
double angle = atan2(vLength(rcross), (rdot));
362
matrix_t rm = mRotationMatrixAxisAngle(raxis, angle);
362
matrix_t rm = mRotationMatrixAxisAngle(raxis, angle*f);
367
matrix_t mRotationFromToOnAxis(vector_t a, vector_t b, vector_t c, vmfloat_t f)
369
a = v3Sub(a, vProjectAOnB(a, c));
370
b = v3Sub(b, vProjectAOnB(b, c));
372
return mRotationFromTo(a,b, f);
367
376
- (void) computeRotationForCursorPos: (vector_t) newCursorNorm
369
378
// vector_t newCursorNorm = v3Add(cursorPosNorm, cursorDeltaNorm);
381
390
vector_t camPos = mvMatrixInv.varr[3];
383
vector_t oldCursorBegin = vUnW(mTransformPos(fullMatrixInv, vCreatePos(cursorPosNorm.farr[0], cursorPosNorm.farr[1], 0.0)));
384
vector_t oldCursorEnd = vUnW(mTransformPos(fullMatrixInv, vCreatePos(cursorPosNorm.farr[0], cursorPosNorm.farr[1], 1.0)));
392
// vector_t oldCursorBegin = vUnW(mTransformPos(fullMatrixInv, vCreatePos(cursorPosNorm.farr[0], cursorPosNorm.farr[1], 0.0)));
393
// vector_t oldCursorEnd = vUnW(mTransformPos(fullMatrixInv, vCreatePos(cursorPosNorm.farr[0], cursorPosNorm.farr[1], 1.0)));
385
394
vector_t newCursorBegin = vUnW(mTransformPos(fullMatrixInv, vCreatePos(newCursorNorm.farr[0], newCursorNorm.farr[1], 0.0)));
386
395
vector_t newCursorEnd = vUnW(mTransformPos(fullMatrixInv, vCreatePos(newCursorNorm.farr[0], newCursorNorm.farr[1], 1.0)));
387
396
vector_t newCursorRay = v3Sub(newCursorEnd, newCursorBegin);
388
vector_t oldCursorRay = v3Sub(oldCursorEnd, oldCursorBegin);
397
// vector_t oldCursorRay = v3Sub(oldCursorEnd, oldCursorBegin);
389
398
double t = INFINITY, t1 = INFINITY;
390
399
vector_t shit = vZero();
391
400
int isInSphere = SphereRayIntersect(camLookAt, rr, newCursorBegin, newCursorRay, &t, &t1);
424
433
vector_t h2 = v3Add(newCursorBegin, v3MulScalar(newCursorRay, frontSideRotation ? t1 : t));
425
434
vector_t R2 = v3Sub(h2, camLookAt);
426
matrix_t rm = mRotationFromTo(R, R2);
435
matrix_t rm = mRotationFromTo(R, R2, 1.0);
427
436
camRotationMatrix = mTransform(camRotationMatrix, rm);
428
437
camRotationMatrix = mOrthonormalize(camRotationMatrix);
466
matrix_t rm = mRotationFromTo(R, shit);
476
matrix_t rm = mRotationFromTo(R, shit, 1.0);
467
477
camRotationMatrix = mTransform(camRotationMatrix, rm);
468
478
camRotationMatrix = mOrthonormalize(camRotationMatrix);
482
// make the camera upright (a bit)
484
matrix_t CT = mTranspose(camRotationMatrix);
485
vector_t camUp = CT.varr[1];
486
vector_t camForward = CT.varr[2];
487
vector_t worldUp = vCreateDir(0.0,0.0,1.0);
489
matrix_t rm2 = mRotationFromToOnAxis(worldUp, camUp, camForward, 0.01);
490
camRotationMatrix = mTransform(camRotationMatrix, rm2);
491
camRotationMatrix = mOrthonormalize(camRotationMatrix);
509
typedef struct TerrainIndex
514
- (TerrainIndex) indexOfTriangle: (MeshTriangle*) tri
517
return (TerrainIndex){-1,-1};
518
CityDocument* doc = [windowController document];
519
long cityWidth = [doc cityWidth];
520
long cityLength = [doc cityLength];
522
size_t numGridVertices = (cityWidth+1)*(cityLength+1);
524
size_t cellVertexIndex = triAtCursor->vertices[0] - numGridVertices;
525
size_t xi = cellVertexIndex % cityWidth;
526
size_t yi = cellVertexIndex / cityLength;
528
return (TerrainIndex){xi,yi};
531
- (void) drawCellHighlight: (TerrainIndex) ti withColor: (vector_t) color
533
if ((ti.x == -1) || (ti.y == -1))
536
CityDocument* doc = [windowController document];
537
long cityWidth = [doc cityWidth];
544
uint32_t indices[4] = { yi*(cityWidth+1) + xi,
545
yi*(cityWidth+1) + xi + 1,
546
(yi+1)*(cityWidth+1) + xi + 1,
547
(yi+1)*(cityWidth+1) + xi};
550
glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_INT, indices);
489
553
- (void) drawTerrainGrid
533
597
[gridMesh justDraw];
605
[terrainMesh setupArrays];
606
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
608
[self drawCellHighlight: (TerrainIndex){roadToolState.x0, roadToolState.y0} withColor: vCreate(0.5,0.0,0.0,0.5)];
609
[self drawCellHighlight: (TerrainIndex){roadToolState.x1, roadToolState.y1} withColor: vCreate(0.0,0.5,0.0,0.5)];
611
[terrainMesh cleanupArrays];
541
CityDocument* doc = [windowController document];
542
long cityWidth = [doc cityWidth];
543
long cityLength = [doc cityLength];
545
size_t numGridVertices = (cityWidth+1)*(cityLength+1);
546
//size_t numCellVertices = (cityWidth)*(cityLength);
548
vector_t v0 = terrainOctree->vertices[triAtCursor->vertices[0]];
549
vector_t v1 = terrainOctree->vertices[triAtCursor->vertices[1]];
550
vector_t v2 = terrainOctree->vertices[triAtCursor->vertices[2]];
552
size_t cellVertexIndex = triAtCursor->vertices[0] - numGridVertices;
553
size_t xi = cellVertexIndex % cityWidth;
554
size_t yi = cellVertexIndex / cityLength;
556
glColor4d(1.0,0.0,0.0,1.0);
558
uint32_t indices[4] = { yi*(cityWidth+1) + xi,
559
yi*(cityWidth+1) + xi + 1,
560
(yi+1)*(cityWidth+1) + xi + 1,
561
(yi+1)*(cityWidth+1) + xi};
564
621
[terrainMesh setupArrays];
565
622
glBindBufferARB(GL_ELEMENT_ARRAY_BUFFER, 0);
566
glDrawElements(GL_LINE_LOOP, 4, GL_UNSIGNED_INT, indices);
624
[self drawCellHighlight: [self indexOfTriangle: triAtCursor] withColor: vCreate(0.5,0.5,0.0,0.5)];
568
626
[terrainMesh cleanupArrays];
709
767
NSPoint p = [self convertPoint: [event locationInWindow] fromView: nil];
710
768
NSRect b = [self bounds];
769
NSUInteger flags = [event modifierFlags] & (NSAlphaShiftKeyMask|NSShiftKeyMask|NSControlKeyMask|NSAlternateKeyMask|NSCommandKeyMask);
712
771
vector_t newCursorPos = vZero();
713
772
newCursorPos.farr[0] = (p.x - b.origin.x)/b.size.width*2.0 - 1.0;
720
779
switch (toolMode)
787
[self findTerrainTriUnderCursor];
788
if (!roadToolState.startMarked)
790
roadToolState.x0 = -1;
791
roadToolState.y0 = -1;
793
roadToolState.x1 = -1;
794
roadToolState.y1 = -1;
798
TerrainIndex ti = [self indexOfTriangle: triAtCursor];
799
if (!roadToolState.startMarked)
801
roadToolState.x0 = ti.x;
802
roadToolState.y0 = ti.y;
803
roadToolState.startMarked = 1;
807
roadToolState.x1 = ti.x;
808
roadToolState.y1 = ti.y;
724
818
startingCamRotationMatrix = camRotationMatrix;