void Terrain_SelectPointByRay( vec3_t org, vec3_t dir, int buttons ) { float bestd; terrainFace_t *face; terrainFace_t *bestface; brush_t *pb; float dist; vec3_t vec; // find the point closest to the ray bestface = NULL; bestd = WORLD_SIZE * 4; for( pb = selected_brushes.next; pb != &selected_brushes; pb = pb->next ) { if ( pb->terrainBrush ) { face = Terrain_Ray( org, dir, pb, &dist ); if ( face && ( dist < bestd ) ) { bestface = face; bestd = dist; } } } for( pb = active_brushes .next; pb != &active_brushes; pb = pb->next ) { if ( pb->terrainBrush ) { face = Terrain_Ray( org, dir, pb, &dist ); if ( face && ( dist < bestd ) ) { bestface = face; bestd = dist; } } } if ( !bestface ) { return; } VectorMA( org, bestd, dir, vec ); Terrain_AddMovePoint( vec, buttons & MK_CONTROL, buttons & MK_SHIFT, buttons ); }
void CCamWnd::Cam_ChangeFloor (qboolean up) { brush_t *b; float d, bestd, current; vec3_t start, dir; start[0] = m_Camera.origin[0]; start[1] = m_Camera.origin[1]; start[2] = 8192; dir[0] = dir[1] = 0; dir[2] = -1; current = 8192 - (m_Camera.origin[2] - 48); if (up) bestd = 0; else bestd = 16384; for (b=active_brushes.next ; b != &active_brushes ; b=b->next) { if ( b->pTerrain && !Terrain_Ray( start, dir, b, &d ) ) continue; if ( !b->pTerrain && !Brush_Ray (start, dir, b, &d) ) continue; if (up && d < current && d > bestd) bestd = d; if (!up && d > current && d < bestd) bestd = d; } if (bestd == 0 || bestd == 16384) return; m_Camera.origin[2] += current - bestd; Sys_UpdateWindows (W_CAMERA|W_Z_OVERLAY); }
trace_t Test_Ray (vec3_t origin, vec3_t dir, int flags) { brush_t *brush; face_t *face; float dist; trace_t t; memset (&t, 0, sizeof(t)); t.dist = DIST_START; if (flags & SF_CYCLE) { CPtrArray array; brush_t *pToSelect = (selected_brushes.next != &selected_brushes) ? selected_brushes.next : NULL; Select_Deselect(); // go through active brushes and accumulate all "hit" brushes for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) { //if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) // continue; if (FilterBrush (brush)) continue; if (!g_PrefsDlg.m_bSelectCurves && brush->patchBrush) continue; if( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush ) continue; //if (!g_bShowPatchBounds && brush->patchBrush) // continue; face = Brush_Ray (origin, dir, brush, &dist); if (face) { if ( brush->terrainBrush ) { Terrain_Ray( origin, dir, brush, &dist ); if( dist == 0 ) { // didn't actually hit the terrain continue; } } array.Add(brush); } } int nSize = array.GetSize(); if (nSize > 0) { bool bFound = false; for (int i = 0; i < nSize; i++) { brush_t *b = reinterpret_cast<brush_t*>(array.GetAt(i)); // did we hit the last one selected yet ? if (b == pToSelect) { // yes we want to select the next one in the list int n = (i > 0) ? i-1 : nSize-1; pToSelect = reinterpret_cast<brush_t*>(array.GetAt(n)); bFound = true; break; } } if (!bFound) pToSelect = reinterpret_cast<brush_t*>(array.GetAt(0)); } if (pToSelect) { face = Brush_Ray (origin, dir, pToSelect, &dist); if ( pToSelect->terrainBrush ) { t.terraface = Terrain_Ray( origin, dir, pToSelect, &dist ); } t.dist = dist; t.brush = pToSelect; t.face = face; t.selected = false; return t; } } if (! (flags & SF_SELECTED_ONLY) ) { for (brush = active_brushes.next ; brush != &active_brushes ; brush=brush->next) { if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) continue; if (FilterBrush (brush)) continue; if (!g_PrefsDlg.m_bSelectCurves && brush->patchBrush) continue; if( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush ) continue; //if (!g_bShowPatchBounds && brush->patchBrush) // continue; face = Brush_Ray (origin, dir, brush, &dist); if ( face ) { if ( brush->terrainBrush ) { t.terraface = Terrain_Ray( origin, dir, brush, &dist ); } } if (dist > 0 && dist < t.dist) { t.dist = dist; t.brush = brush; t.face = face; t.selected = false; } } } for (brush = selected_brushes.next ; brush != &selected_brushes ; brush=brush->next) { if ( (flags & SF_ENTITIES_FIRST) && brush->owner == world_entity) continue; if (FilterBrush (brush)) continue; if (!g_PrefsDlg.m_bSelectCurves && brush->patchBrush) continue; if( !g_PrefsDlg.m_bSelectTerrain && brush->terrainBrush ) continue; face = Brush_Ray (origin, dir, brush, &dist); if ( face ) { if ( brush->terrainBrush ) { t.terraface = Terrain_Ray( origin, dir, brush, &dist ); } } if (dist > 0 && dist < t.dist) { t.dist = dist; t.brush = brush; t.face = face; t.selected = true; } } // if entites first, but didn't find any, check regular if ( (flags & SF_ENTITIES_FIRST) && t.brush == NULL) return Test_Ray (origin, dir, flags - SF_ENTITIES_FIRST); return t; }