/* ============ Select_SetTexture Timo : bFitScale to compute scale on the plane and counteract plane / axial plane snapping Timo : brush primitive texturing the brushprimit_texdef given must be understood as a qtexture_t width=2 height=2 ( HiRes ) Timo : texture plugin, added an IPluginTexdef* parameter must be casted to an IPluginTexdef! if not NULL, get ->Copy() of it into each face or brush ( and remember to hook ) if NULL, means we have no information, ask for a default ============ */ void WINAPI Select_SetTexture( texdef_t* texdef, brushprimit_texdef_s* brushprimit_texdef, bool bFitScale, void* pPlugTexdef ) { brush_s* b; int nCount = g_ptrSelectedFaces.GetSize(); if ( nCount > 0 ) { Undo_Start( "set face textures" ); ASSERT( g_ptrSelectedFaces.GetSize() == g_ptrSelectedFaceBrushes.GetSize() ); for ( int i = 0; i < nCount; i++ ) { face_s* selFace = reinterpret_cast<face_s*>( g_ptrSelectedFaces.GetAt( i ) ); brush_s* selBrush = reinterpret_cast<brush_s*>( g_ptrSelectedFaceBrushes.GetAt( i ) ); Undo_AddBrush( selBrush ); SetFaceTexdef( selBrush, selFace, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef*>( pPlugTexdef ) ); Brush_Build( selBrush, bFitScale ); Undo_EndBrush( selBrush ); } Undo_End(); } else if ( selected_brushes.next != &selected_brushes ) { Undo_Start( "set brush textures" ); for ( b = selected_brushes.next ; b != &selected_brushes ; b = b->next ) if ( !b->owner->eclass->fixedsize ) { Undo_AddBrush( b ); Brush_SetTexture( b, texdef, brushprimit_texdef, bFitScale, static_cast<IPluginTexdef*>( pPlugTexdef ) ); Undo_EndBrush( b ); } Undo_End(); } Sys_UpdateWindows( W_ALL ); }
void Select_SetTexture (texdef_t *texdef) { brush_t *b; if (selected_face) { selected_face->texdef = *texdef; Brush_Build(selected_face_brush); } else { for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) if (!b->owner->eclass->fixedsize) Brush_SetTexture (b, texdef); } Sys_UpdateWindows (W_ALL); }
/* ============ Select_SetTexture bool bFitScale = compute scale on the plane and counteract plane->axial snapping ============ */ void Select_SetTexture (texdef_t *texdef, bool bFitScale/*=false*/, bool bNoSystemTextureOverwrite/*=false*/) { brush_t *b; if (selected_face) { SetFaceTexdef (selected_face_brush, selected_face, texdef, bFitScale, bNoSystemTextureOverwrite); Brush_Build(selected_face_brush, bFitScale); } else { for (b=selected_brushes.next ; b != &selected_brushes ; b=b->next) if (!b->owner->eclass->fixedsize) Brush_SetTexture (b, texdef, bFitScale, bNoSystemTextureOverwrite); } Sys_UpdateWindows (W_ALL); }
/* ================ Drag_Begin ================ */ void Drag_Begin( int x, int y, int buttons, const idVec3 &xaxis, const idVec3 &yaxis, const idVec3 &origin, const idVec3 &dir ) { qertrace_t t; drag_ok = false; VectorCopy(vec3_origin, pressdelta); VectorCopy(vec3_origin, vPressStart); drag_first = true; // shift LBUTTON = select entire brush if (buttons == (MK_LBUTTON | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { int nFlag = ( ::GetAsyncKeyState( VK_MENU ) != 0 ) ? SF_CYCLE : 0; if (dir[0] == 0 || dir[1] == 0 || dir[2] == 0) { // extremely low chance of this happening from camera Select_Ray(origin, dir, nFlag | SF_ENTITIES_FIRST); // hack for XY } else { Select_Ray(origin, dir, nFlag); } return; } // ctrl-shift LBUTTON = select single face if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { if ( radiant_entityMode.GetBool() ) { return; } // _D3XP disabled //Select_Deselect( ( ::GetAsyncKeyState( VK_MENU ) == 0 ) ); Select_Ray(origin, dir, SF_SINGLEFACE); return; } // LBUTTON + all other modifiers = manipulate selection if (buttons & MK_LBUTTON) { Drag_Setup(x, y, buttons, xaxis, yaxis, origin, dir); return; } if ( radiant_entityMode.GetBool() ) { return; } int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; // middle button = grab texture if (buttons == nMouseButton) { t = Test_Ray(origin, dir, false); if (t.face) { g_qeglobals.d_new_brush_bottom = t.brush->mins; g_qeglobals.d_new_brush_top = t.brush->maxs; // use a local brushprimit_texdef fitted to a default 2x2 texture brushprimit_texdef_t bp_local; if (t.brush && t.brush->pPatch) { texdef_t localtd; memset(&bp_local.coords, 0, sizeof(bp_local.coords)); bp_local.coords[0][0] = 1.0f; bp_local.coords[1][1] = 1.0f; localtd.SetName(t.brush->pPatch->d_texture->GetName()); Texture_SetTexture(&localtd, &bp_local, false, true); Select_CopyPatchTextureCoords ( t.brush->pPatch ); } else { Select_ProjectFaceOntoPatch( t.face ); ConvertTexMatWithQTexture(&t.face->brushprimit_texdef, t.face->d_texture, &bp_local, NULL); Texture_SetTexture(&t.face->texdef, &bp_local, false, true); } UpdateSurfaceDialog(); UpdatePatchInspector(); UpdateLightInspector(); } else { Sys_Status("Did not select a texture\n"); } return; } // ctrl-middle button = set entire brush to texture if (buttons == (nMouseButton | MK_CONTROL)) { t = Test_Ray(origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') { Sys_Status("Can't change an entity texture\n"); } else { Brush_SetTexture ( t.brush, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false ); Sys_UpdateWindows(W_ALL); } } else { Sys_Status("Didn't hit a btrush\n"); } return; } // ctrl-shift-middle button = set single face to texture if (buttons == (nMouseButton | MK_SHIFT | MK_CONTROL)) { t = Test_Ray(origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') { Sys_Status("Can't change an entity texture\n"); } else { SetFaceTexdef ( t.brush, t.face, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef ); Brush_Build(t.brush); Sys_UpdateWindows(W_ALL); } } else { Sys_Status("Didn't hit a btrush\n"); } return; } if (buttons == (nMouseButton | MK_SHIFT)) { Sys_Status("Set brush face texture info\n"); t = Test_Ray(origin, dir, false); if (t.brush && !t.brush->owner->eclass->fixedsize) { /* if (t.brush->brush_faces->texdef.name[0] == '(') { if (t.brush->owner->eclass->nShowFlags & ECLASS_LIGHT) { CString strBuff; idMaterial *pTex = declManager->FindMaterial(g_qeglobals.d_texturewin.texdef.name); if (pTex) { idVec3 vColor = pTex->getColor(); float fLargest = 0.0f; for (int i = 0; i < 3; i++) { if (vColor[i] > fLargest) { fLargest = vColor[i]; } } if (fLargest == 0.0f) { vColor[0] = vColor[1] = vColor[2] = 1.0f; } else { float fScale = 1.0f / fLargest; for (int i = 0; i < 3; i++) { vColor[i] *= fScale; } } strBuff.Format("%f %f %f", pTex->getColor().x, pTex->getColor().y, pTex->getColor().z); SetKeyValue(t.brush->owner, "_color", strBuff.GetBuffer(0)); Sys_UpdateWindows(W_ALL); } } else { Sys_Status("Can't select an entity brush face\n"); } } else { */ // strcpy(t.face->texdef.name,g_qeglobals.d_texturewin.texdef.name); t.face->texdef.SetName(g_qeglobals.d_texturewin.texdef.name); Brush_Build(t.brush); Sys_UpdateWindows(W_ALL); // } } else { Sys_Status("Didn't hit a brush\n"); } return; } }
entity_t *Entity_PostParse(entity_t *ent, brush_t *pList) { bool has_brushes; eclass_t *e; brush_t *b; idVec3 mins, maxs, zero; idBounds bo; zero.Zero(); Entity_SetCurveData( ent ); if (ent->brushes.onext == &ent->brushes) { has_brushes = false; } else { has_brushes = true; } bool needsOrigin = !GetVectorForKey(ent, "origin", ent->origin); const char *pModel = ValueForKey(ent, "model"); const char *cp = ValueForKey(ent, "classname"); if (strlen(cp)) { e = Eclass_ForName(cp, has_brushes); } else { const char *cp2 = ValueForKey(ent, "name"); if (strlen(cp2)) { char buff[1024]; strcpy(buff, cp2); int len = strlen(buff); while ((isdigit(buff[len-1]) || buff[len-1] == '_') && len > 0) { buff[len-1] = '\0'; len--; } e = Eclass_ForName(buff, has_brushes); SetKeyValue(ent, "classname", buff, false); } else { e = Eclass_ForName("", has_brushes); } } idStr str; if (e->defArgs.GetString("model", "", str) && e->entityModel == NULL) { e->entityModel = gameEdit->ANIM_GetModelFromEntityDef( &e->defArgs ); } ent->eclass = e; bool hasModel = EntityHasModel(ent); if (hasModel) { ent->eclass->defArgs.GetString("model", "", str); if (str.Length()) { hasModel = false; ent->epairs.Delete("model"); } } if (e->nShowFlags & ECLASS_WORLDSPAWN) { ent->origin.Zero(); needsOrigin = false; ent->epairs.Delete( "model" ); } else if (e->nShowFlags & ECLASS_LIGHT) { if (GetVectorForKey(ent, "light_origin", ent->lightOrigin)) { GetMatrixForKey(ent, "light_rotation", ent->lightRotation); ent->trackLightOrigin = true; } else if (hasModel) { SetKeyValue(ent, "light_origin", ValueForKey(ent, "origin")); ent->lightOrigin = ent->origin; if (GetMatrixForKey(ent, "rotation", ent->lightRotation)) { SetKeyValue(ent, "light_rotation", ValueForKey(ent, "rotation")); } ent->trackLightOrigin = true; } } else if ( e->nShowFlags & ECLASS_ENV ) { // need to create an origin from the bones here idVec3 org; idAngles ang; bo.Clear(); bool hasBody = false; const idKeyValue *arg = ent->epairs.MatchPrefix( "body ", NULL ); while ( arg ) { sscanf( arg->GetValue(), "%f %f %f %f %f %f", &org.x, &org.y, &org.z, &ang.pitch, &ang.yaw, &ang.roll ); bo.AddPoint( org ); arg = ent->epairs.MatchPrefix( "body ", arg ); hasBody = true; } if (hasBody) { ent->origin = bo.GetCenter(); } } if (e->fixedsize || hasModel) // fixed size entity { if (ent->brushes.onext != &ent->brushes) { for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { b->entityModel = true; } } if (hasModel) { // model entity idRenderModel *modelHandle = renderModelManager->FindModel( pModel ); if ( dynamic_cast<idRenderModelPrt*>( modelHandle ) || dynamic_cast<idRenderModelLiquid*>( modelHandle ) ) { bo.Zero(); bo.ExpandSelf( 12.0f ); } else { bo = modelHandle->Bounds( NULL ); } VectorCopy(bo[0], mins); VectorCopy(bo[1], maxs); for (int i = 0; i < 3; i++) { if (mins[i] == maxs[i]) { mins[i]--; maxs[i]++; } } VectorAdd(mins, ent->origin, mins); VectorAdd(maxs, ent->origin, maxs); b = Brush_Create(mins, maxs, &e->texdef); b->modelHandle = modelHandle; float yaw = 0; bool convertAngles = GetFloatForKey(ent, "angle", &yaw); extern void Brush_Rotate(brush_t *b, idMat3 matrix, idVec3 origin, bool bBuild); extern void Brush_Rotate(brush_t *b, idVec3 rot, idVec3 origin, bool bBuild); if (convertAngles) { idVec3 rot(0, 0, yaw); Brush_Rotate(b, rot, ent->origin, false); } if (GetMatrixForKey(ent, "rotation", ent->rotation)) { idBounds bo2; bo2.FromTransformedBounds(bo, ent->origin, ent->rotation); b->owner = ent; Brush_Resize(b, bo2[0], bo2[1]); } Entity_LinkBrush(ent, b); } if (!hasModel || (ent->eclass->nShowFlags & ECLASS_LIGHT && hasModel)) { // create a custom brush if (ent->trackLightOrigin) { mins = e->mins + ent->lightOrigin; maxs = e->maxs + ent->lightOrigin; } else { mins = e->mins + ent->origin; maxs = e->maxs + ent->origin; } b = Brush_Create(mins, maxs, &e->texdef); GetMatrixForKey(ent, "rotation", ent->rotation); Entity_LinkBrush(ent, b); b->trackLightOrigin = ent->trackLightOrigin; if ( e->texdef.name == NULL ) { brushprimit_texdef_t bp; texdef_t td; td.SetName( ent->eclass->defMaterial ); Brush_SetTexture( b, &td, &bp, false ); } } } else // brush entity { if (ent->brushes.next == &ent->brushes) { printf("Warning: Brush entity with no brushes\n"); } if (!needsOrigin) { idStr cn = ValueForKey(ent, "classname"); idStr name = ValueForKey(ent, "name"); idStr model = ValueForKey(ent, "model"); if (cn.Icmp("func_static") == 0) { if (name.Icmp(model) == 0) { needsOrigin = true; } } } if (needsOrigin) { idVec3 mins, maxs, mid; int i; char text[32]; mins[0] = mins[1] = mins[2] = 999999; maxs[0] = maxs[1] = maxs[2] = -999999; // add in the origin for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { Brush_Build(b, true, false, false); for (i = 0; i < 3; i++) { if (b->mins[i] < mins[i]) { mins[i] = b->mins[i]; } if (b->maxs[i] > maxs[i]) { maxs[i] = b->maxs[i]; } } } for (i = 0; i < 3; i++) { ent->origin[i] = (mins[i] + ((maxs[i] - mins[i]) / 2)); } sprintf(text, "%i %i %i", (int)ent->origin[0], (int)ent->origin[1], (int)ent->origin[2]); SetKeyValue(ent, "origin", text); } if (!(e->nShowFlags & ECLASS_WORLDSPAWN)) { if (e->defArgs.FindKey("model") == NULL && (pModel == NULL || (pModel && strlen(pModel) == 0))) { SetKeyValue(ent, "model", ValueForKey(ent, "name")); } } else { DeleteKey(ent, "origin"); } } // add all the brushes to the main list if (pList) { for (b = ent->brushes.onext; b != &ent->brushes; b = b->onext) { b->next = pList->next; pList->next->prev = b; b->prev = pList; pList->next = b; } } FixFloats(&ent->epairs); return ent; }
/* ======================================================================================================================= Entity_Create Creates a new entity out of the selected_brushes list. If the entity class is fixed size, the brushes are only used to find a midpoint. Otherwise, the brushes have their ownership transfered to the new entity. ======================================================================================================================= */ entity_t *Entity_Create(eclass_t *c, bool forceFixed) { entity_t *e; brush_t *b; idVec3 mins, maxs, origin; char text[32]; texdef_t td; brushprimit_texdef_t bp; // check to make sure the brushes are ok for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { if (b->owner != world_entity) { Sys_Status("Entity NOT created, brushes not all from world\n"); Sys_Beep(); return NULL; } } idStr str; if (c->defArgs.GetString("model", "", str) && c->entityModel == NULL) { c->entityModel = gameEdit->ANIM_GetModelFromEntityDef( &c->defArgs ); } // create it e = Entity_New(); e->brushes.onext = e->brushes.oprev = &e->brushes; e->eclass = c; e->epairs.Copy(c->args); SetKeyValue(e, "classname", c->name); Entity_Name(e, false); // add the entity to the entity list Entity_AddToList(e, &entities); if (c->fixedsize) { // // just use the selection for positioning b = selected_brushes.next; for (i=0 ; // i<3 ; i++) { e->origin[i] = b->mins[i] - c->mins[i]; } // Select_GetMid(e->origin); VectorCopy(e->origin, origin); // create a custom brush VectorAdd(c->mins, e->origin, mins); VectorAdd(c->maxs, e->origin, maxs); b = Brush_Create(mins, maxs, &c->texdef); Entity_LinkBrush(e, b); if (c->defMaterial.Length()) { td.SetName(c->defMaterial); Brush_SetTexture(b, &td, &bp, false); } // delete the current selection Select_Delete(); // select the new brush b->next = b->prev = &selected_brushes; selected_brushes.next = selected_brushes.prev = b; Brush_Build(b); } else { Select_GetMid(origin); // change the selected brushes over to the new entity for (b = selected_brushes.next; b != &selected_brushes; b = b->next) { Entity_UnlinkBrush(b); Entity_LinkBrush(e, b); Brush_Build(b); // so the key brush gets a name if (c->defMaterial.Length()) { td.SetName(c->defMaterial); Brush_SetTexture(b, &td, &bp, false); } } //for (int i = 0; i < 3; i++) { // origin[i] = vMin[i] + vMax[i] * 0.5; //} if (!forceFixed) { SetKeyValue(e, "model", ValueForKey(e, "name")); } } sprintf(text, "%i %i %i", (int)origin[0], (int)origin[1], (int)origin[2]); SetKeyValue(e, "origin", text); VectorCopy(origin, e->origin); Sys_UpdateWindows(W_ALL); return e; }
/* =========== Drag_Begin //++timo test three button mouse and three button emulation here ? =========== */ void Drag_Begin (int x, int y, int buttons, vec3_t xaxis, vec3_t yaxis, vec3_t origin, vec3_t dir) { trace_t t; drag_ok = false; VectorCopy (vec3_origin, pressdelta); VectorCopy (vec3_origin, vPressStart); drag_first = true; peLink = NULL; // shift LBUTTON = select entire brush if (buttons == (MK_LBUTTON | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { int nFlag = (static_cast<bool>(::GetAsyncKeyState(VK_MENU))) ? SF_CYCLE : 0; if (dir[0] == 0 || dir[1] == 0 || dir[2] == 0) // extremely low chance of this happening from camera Select_Ray (origin, dir, nFlag | SF_ENTITIES_FIRST); // hack for XY else Select_Ray (origin, dir, nFlag); return; } // ctrl-shift LBUTTON = select single face if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { Sys_Printf ("Face Selection?\n"); Select_Deselect (!static_cast<bool>(::GetAsyncKeyState(VK_MENU))); Select_Ray (origin, dir, SF_SINGLEFACE); return; } // LBUTTON + all other modifiers = manipulate selection if (buttons & MK_LBUTTON) { // Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir); return; } // JONATHAN: stuff to add here int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; // middle button = grab texture if (buttons == nMouseButton) { t = Test_Ray (origin, dir, false); if (t.face) { //++timo clean #if 0 // g_qeglobals.d_new_brush_bottom_z = t.brush->mins[2]; // g_qeglobals.d_new_brush_top_z = t.brush->maxs[2]; // g_pParentWnd->ActiveXY()->GetViewType() // cf VIEWTYPE definition: enum VIEWTYPE {YZ, XZ, XY}; // we fit our work zone to the brush int nViewType = g_pParentWnd->ActiveXY()->GetViewType(); int nDim1 = (nViewType == YZ) ? 1 : 0; int nDim2 = (nViewType == XY) ? 1 : 2; g_qeglobals.d_work_min[nDim1] = t.brush->mins[nDim1]; g_qeglobals.d_work_max[nDim1] = t.brush->maxs[nDim1]; g_qeglobals.d_work_min[nDim2] = t.brush->mins[nDim2]; g_qeglobals.d_work_max[nDim2] = t.brush->maxs[nDim2]; #endif // JONATHAN:: On ALT-Middle mouse // Fit texture to face SHORT altdown = (GetKeyState(VK_MENU) & 0x8000); if (altdown) { // Fit Texture to brush face Face_FitTexture(t.face, 1, 1); // Build Brush to apply update Brush_Build(t.brush); //? // Update Camera View Sys_UpdateWindows (W_CAMERA); } else { UpdateWorkzone_ForBrush( t.brush ); // use a local brushprimit_texdef fitted to a default 2x2 texture brushprimit_texdef_t bp_local; ConvertTexMatWithQTexture( &t.face->brushprimit_texdef, t.face->d_texture, &bp_local, NULL ); Texture_SetTexture ( &t.face->texdef, &bp_local, false, GETPLUGINTEXDEF(t.face)); UpdateSurfaceDialog(); UpdatePatchInspector(); } } else Sys_Printf ("Did not select a texture\n"); return; } // ctrl-middle button = set entire brush to texture if (buttons == (nMouseButton|MK_CONTROL) ) { t = Test_Ray (origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') Sys_Printf ("Can't change an entity texture\n"); else { Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef, false, static_cast<IPluginTexdef *>( g_qeglobals.d_texturewin.pTexdef ) ); Sys_UpdateWindows (W_ALL); } } else Sys_Printf ("Didn't hit a btrush\n"); return; } // JONATHAN:HERE // ctrl-shift-middle button = set single face to texture if (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL) ) { t = Test_Ray (origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') Sys_Printf ("Can't change an entity texture\n"); else { SetFaceTexdef (t.brush, t.face, &g_qeglobals.d_texturewin.texdef, &g_qeglobals.d_texturewin.brushprimit_texdef); Brush_Build( t.brush ); Sys_UpdateWindows (W_ALL); } } else Sys_Printf ("Didn't hit a btrush\n"); return; } if (buttons == (nMouseButton | MK_SHIFT)) { Sys_Printf("Set brush face texture info\n"); t = Test_Ray (origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') { if (t.brush->owner->eclass->nShowFlags & ECLASS_LIGHT) { CString strBuff; qtexture_t* pTex = g_qeglobals.d_texturewin.pShader->getTexture(); if (pTex) { vec3_t vColor; VectorCopy(pTex->color, vColor); float fLargest = 0.0f; for (int i = 0; i < 3; i++) { if (vColor[i] > fLargest) fLargest = vColor[i]; } if (fLargest == 0.0f) { vColor[0] = vColor[1] = vColor[2] = 1.0f; } else { float fScale = 1.0f / fLargest; for (int i = 0; i < 3; i++) { vColor[i] *= fScale; } } strBuff.Format("%f %f %f",pTex->color[0], pTex->color[1], pTex->color[2]); SetKeyValue(t.brush->owner, "_color", strBuff.GetBuffer(0)); Sys_UpdateWindows (W_ALL); } } else { Sys_Printf ("Can't select an entity brush face\n"); } } else { //strcpy(t.face->texdef.name,g_qeglobals.d_texturewin.texdef.name); t.face->texdef.SetName(g_qeglobals.d_texturewin.texdef.name); Brush_Build(t.brush); Sys_UpdateWindows (W_ALL); } } else Sys_Printf ("Didn't hit a brush\n"); return; } }
/* =========== Drag_Begin =========== */ void Drag_Begin (int x, int y, int buttons, vec3_t xaxis, vec3_t yaxis, vec3_t origin, vec3_t dir) { trace_t t; drag_ok = false; VectorCopy (vec3_origin, pressdelta); VectorCopy (vec3_origin, vPressStart); drag_first = true; peLink = NULL; // shift LBUTTON = select entire brush if (buttons == (MK_LBUTTON | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { int nFlag = (static_cast<bool>(::GetAsyncKeyState(VK_MENU))) ? SF_CYCLE : 0; if (dir[0] == 0 || dir[1] == 0 || dir[2] == 0) // extremely low chance of this happening from camera Select_Ray (origin, dir, nFlag | SF_ENTITIES_FIRST); // hack for XY else Select_Ray (origin, dir, nFlag); return; } // ctrl-shift LBUTTON = select single face if (buttons == (MK_LBUTTON | MK_CONTROL | MK_SHIFT) && g_qeglobals.d_select_mode != sel_curvepoint) { Select_Deselect (); Select_Ray (origin, dir, SF_SINGLEFACE); return; } // LBUTTON + all other modifiers = manipulate selection if (buttons & MK_LBUTTON) { Drag_Setup (x, y, buttons, xaxis, yaxis, origin, dir); return; } int nMouseButton = g_PrefsDlg.m_nMouseButtons == 2 ? MK_RBUTTON : MK_MBUTTON; // middle button = grab texture if (buttons == nMouseButton) { t = Test_Ray (origin, dir, false); if (t.face) { g_qeglobals.d_new_brush_bottom_z = t.brush->mins[2]; g_qeglobals.d_new_brush_top_z = t.brush->maxs[2]; Texture_SetTexture (&t.face->texdef); UpdateSurfaceDialog(); UpdatePatchInspector(); } else Sys_Printf ("Did not select a texture\n"); return; } // ctrl-middle button = set entire brush to texture if (buttons == (nMouseButton|MK_CONTROL) ) { t = Test_Ray (origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') Sys_Printf ("Can't change an entity texture\n"); else { Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef, false, false); Sys_UpdateWindows (W_ALL); } } else Sys_Printf ("Didn't hit a btrush\n"); return; } // ctrl-shift-middle button = set single face to texture if (buttons == (nMouseButton|MK_SHIFT|MK_CONTROL) ) { t = Test_Ray (origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') Sys_Printf ("Can't change an entity texture\n"); else { SetFaceTexdef (t.brush, t.face, &g_qeglobals.d_texturewin.texdef, false, false); Brush_Build( t.brush ); Sys_UpdateWindows (W_ALL); } } else Sys_Printf ("Didn't hit a btrush\n"); return; } // shift-middle = (if light) // set face texture info (err...whatever), // else // set brush to texture but preserve any system faces // if (buttons == (nMouseButton | MK_SHIFT)) { Sys_Printf("Set brush face texture info\n"); t = Test_Ray (origin, dir, false); if (t.brush) { if (t.brush->brush_faces->texdef.name[0] == '(') { if (strcmpi(t.brush->owner->eclass->name, "light") == 0) { CString strBuff; qtexture_t* pTex = Texture_ForName(g_qeglobals.d_texturewin.texdef.name); if (pTex) { vec3_t vColor; VectorCopy(pTex->color, vColor); float fLargest = 0.0f; for (int i = 0; i < 3; i++) { if (vColor[i] > fLargest) fLargest = vColor[i]; } if (fLargest == 0.0f) { vColor[0] = vColor[1] = vColor[2] = 1.0f; } else { float fScale = 1.0f / fLargest; for (int i = 0; i < 3; i++) { vColor[i] *= fScale; } } strBuff.Format("%f %f %f",pTex->color[0], pTex->color[1], pTex->color[2]); SetKeyValue(t.brush->owner, "_color", strBuff.GetBuffer(0)); Sys_UpdateWindows (W_ALL); } } else { Sys_Printf ("Can't select an entity brush face\n"); } } else { Brush_SetTexture (t.brush, &g_qeglobals.d_texturewin.texdef, false, true); Sys_UpdateWindows (W_ALL); } } else Sys_Printf ("Didn't hit a brush\n"); return; } }