void DPatch::LoadFromPatch( scene::Instance& patch ){ QER_entity = patch.path().parent().get_pointer(); QER_brush = patch.path().top().get_pointer(); PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints( patch.path().top() ); width = static_cast<int>( matrix.x() ); height = static_cast<int>( matrix.y() ); for ( int x = 0; x < width; x++ ) { for ( int y = 0; y < height; y++ ) { PatchControl& p = matrix( x, y ); points[x][y].xyz[0] = p.m_vertex[0]; points[x][y].xyz[1] = p.m_vertex[1]; points[x][y].xyz[2] = p.m_vertex[2]; points[x][y].st[0] = p.m_texcoord[0]; points[x][y].st[1] = p.m_texcoord[1]; } } SetTexture( GlobalPatchCreator().Patch_getShader( patch.path().top() ) ); #if 0 SetTexture( brush->pPatch->GetShader() ); width = brush->pPatch->getWidth(); height = brush->pPatch->getHeight(); for ( int x = 0; x < height; x++ ) { for ( int y = 0; y < width; y++ ) { float *p = brush->pPatch->ctrlAt( ROW,x,y ); p[0] = points[x][y].xyz[0]; p[1] = points[x][y].xyz[1]; p[2] = points[x][y].xyz[2]; p[3] = points[x][y].st[0]; p[4] = points[x][y].st[1]; } } #endif }
ScriptSceneNode PatchInterface::createPatchDef3() { // Create a new patch and return the script scene node scene::INodePtr node = GlobalPatchCreator(DEF3).createPatch(); // Add the node to the buffer otherwise it will be deleted immediately, // as ScriptSceneNodes are using weak_ptrs. SceneNodeBuffer::Instance().push_back(node); return ScriptSceneNode(node); }
scene::Node& createPrimitive( const char* name ){ if ( string_equal( name, "brush" ) ) { return GlobalBrushCreator().createBrush(); } else if ( string_equal( name, "patch" ) ) { return GlobalPatchCreator().createPatch(); } ASSERT_MESSAGE( 0, PARSE_ERROR << ": primitive type not supported: \"" << name << "\"\n" ); scene::Node* node = 0; return *node; }
void MakeBevel(vec3_t vMin, vec3_t vMax) { NodeSmartReference patch(GlobalPatchCreator().createPatch()); GlobalPatchCreator().Patch_resize(patch, 3, 3); GlobalPatchCreator().Patch_setShader(patch, "textures/common/caulk"); PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints(patch); vec3_t x_3, y_3, z_3; x_3[0] = vMin[0]; x_3[1] = vMin[0]; x_3[2] = vMax[0]; y_3[0] = vMin[1]; y_3[1] = vMax[1]; y_3[2] = vMax[1]; z_3[0] = vMin[2]; z_3[1] = (vMax[2] + vMin[2])/2; z_3[2] = vMax[2]; /* x_3[0] = 0; x_3[1] = 0; x_3[2] = 64; y_3[0] = 0; y_3[1] = 64; y_3[2] = 64; z_3[0] = 0; z_3[1] = 32; z_3[2] = 64;*/ for(int i = 0; i < 3; i++) { for(int j = 0; j < 3; j++) { PatchControl& p = matrix(i, j); p.m_vertex[0] = x_3[i]; p.m_vertex[1] = y_3[i]; p.m_vertex[2] = z_3[j]; } } //does invert the matrix, else the patch face is on wrong side. for(int i = 0 ; i < 3 ; i++ ) { for(int j = 0; j < 1; j++) { PatchControl& p = matrix(i,2- j); PatchControl& q = matrix(i, j); std::swap(p.m_vertex, q.m_vertex); //std::swap(p.m_texcoord, q.m_texcoord); } } GlobalPatchCreator().Patch_controlPointsChanged(patch); //TODO - the patch has textures weird, patchmanip.h has all function it needs.. lots of duplicate code.. //NaturalTexture(patch); Node_getTraversable(GlobalRadiant().getMapWorldEntity())->insert(patch); }
void constructPrefab(const AABB& aabb, const std::string& shader, EPatchPrefab eType, EViewType viewType, std::size_t width, std::size_t height) { GlobalSelectionSystem().setSelectedAll(false); scene::INodePtr node(GlobalPatchCreator(DEF2).createPatch()); GlobalMap().findOrInsertWorldspawn()->addChildNode(node); Patch* patch = Node_getPatch(node); patch->setShader(shader); patch->ConstructPrefab(aabb, eType, viewType, width, height); patch->controlPointsChanged(); Node_setSelected(node, true); }
/* // Example Primitive { patchDef2 { "textures/darkmod/stone/brick/rough_big_blocks03" ( 5 3 0 0 0 ) ( ( ( 64 -88 108 0 0 ) ( 64 -88 184 0 -1.484375 ) ( 64 -88 184 0 -1.484375 ) ) ( ( 64 -88 184 1.484375 0 ) ( 64 -88 184 1.484375 -1.484375 ) ( 64 -88 184 1.484375 -1.484375 ) ) ( ( 112 -88 184 2.421875 0 ) ( 112 -88 184 2.421875 -1.484375 ) ( 112 -88 184 2.421875 -1.484375 ) ) ( ( 160 -88 184 3.359375 0 ) ( 160 -88 184 3.359375 -1.484375 ) ( 160 -88 184 3.359375 -1.484375 ) ) ( ( 160 -88 108 4.84375 0 ) ( 160 -88 184 4.84375 -1.484375 ) ( 160 -88 184 4.84375 -1.484375 ) ) ) } } */ scene::INodePtr PatchDef2Parser::parse(parser::DefTokeniser& tok) const { scene::INodePtr node = GlobalPatchCreator(DEF2).createPatch(); IPatchNodePtr patchNode = boost::dynamic_pointer_cast<IPatchNode>(node); assert(patchNode != NULL); IPatch& patch = patchNode->getPatch(); tok.assertNextToken("{"); // Parse shader patch.setShader(tok.nextToken()); // Parse parameters tok.assertNextToken("("); // parse matrix dimensions std::size_t cols = string::convert<std::size_t>(tok.nextToken()); std::size_t rows = string::convert<std::size_t>(tok.nextToken()); patch.setDims(cols, rows); // ignore contents/flags values tok.skipTokens(3); tok.assertNextToken(")"); // Parse Patch Matrix parseMatrix(tok, patch); // Parse Footer tok.assertNextToken("}"); tok.assertNextToken("}"); patch.controlPointsChanged(); return node; }
void createCaps(Patch& patch, const scene::INodePtr& parent, EPatchCap type, const std::string& shader) { if ((type == eCapEndCap || type == eCapIEndCap) && patch.getWidth() != 5) { rError() << "cannot create end-cap - patch width != 5" << std::endl; gtkutil::MessageBox::ShowError(_("Cannot create end-cap, patch must have a width of 5."), GlobalMainFrame().getTopLevelWindow()); return; } if ((type == eCapBevel || type == eCapIBevel) && patch.getWidth() != 3) { gtkutil::MessageBox::ShowError(_("Cannot create bevel-cap, patch must have a width of 3."), GlobalMainFrame().getTopLevelWindow()); rError() << "cannot create bevel-cap - patch width != 3" << std::endl; return; } if (type == eCapCylinder && patch.getWidth() != 9) { gtkutil::MessageBox::ShowError(_("Cannot create cylinder-cap, patch must have a width of 9."), GlobalMainFrame().getTopLevelWindow()); rError() << "cannot create cylinder-cap - patch width != 9" << std::endl; return; } assert(parent != NULL); { scene::INodePtr cap(GlobalPatchCreator(DEF2).createPatch()); parent->addChildNode(cap); Patch* capPatch = Node_getPatch(cap); assert(capPatch != NULL); patch.MakeCap(capPatch, type, ROW, true); capPatch->setShader(shader); // greebo: Avoid creating "degenerate" patches (all vertices merged in one 3D point) if (!capPatch->isDegenerate()) { Node_setSelected(cap, true); } else { parent->removeChildNode(cap); rWarning() << "Prevented insertion of degenerate patch." << std::endl; } } { scene::INodePtr cap(GlobalPatchCreator(DEF2).createPatch()); parent->addChildNode(cap); Patch* capPatch = Node_getPatch(cap); assert(capPatch != NULL); patch.MakeCap(capPatch, type, ROW, false); capPatch->setShader(shader); // greebo: Avoid creating "degenerate" patches (all vertices merged in one 3D point) if (!capPatch->isDegenerate()) { Node_setSelected(cap, true); } else { parent->removeChildNode(cap); rWarning() << "Prevented insertion of degenerate patch." << std::endl; } } }
void thicken(const PatchNodePtr& sourcePatch, float thickness, bool createSeams, int axis) { // Get a shortcut to the patchcreator PatchCreator& patchCreator = GlobalPatchCreator(DEF2); // Create a new patch node scene::INodePtr node(patchCreator.createPatch()); scene::INodePtr parent = sourcePatch->getParent(); assert(parent != NULL); // Insert the node into the same parent as the existing patch parent->addChildNode(node); // Retrieve the contained patch from the node Patch* targetPatch = Node_getPatch(node); // Create the opposite patch with the given thickness = distance targetPatch->createThickenedOpposite(sourcePatch->getPatchInternal(), thickness, axis); // Select the newly created patch Node_setSelected(node, true); if (createSeams && thickness > 0.0f) { // Allocate four new patches scene::INodePtr nodes[4] = { patchCreator.createPatch(), patchCreator.createPatch(), patchCreator.createPatch(), patchCreator.createPatch() }; // Now create the four walls for (int i = 0; i < 4; i++) { // Insert each node into the same parent as the existing patch // It's vital to do this first, otherwise these patches won't have valid shaders parent->addChildNode(nodes[i]); // Retrieve the contained patch from the node Patch* wallPatch = Node_getPatch(nodes[i]); // Create the wall patch by passing i as wallIndex wallPatch->createThickenedWall(sourcePatch->getPatchInternal(), *targetPatch, i); if (!wallPatch->isDegenerate()) { // Now select the newly created patch Node_setSelected(nodes[i], true); } else { rMessage() << "Thicken: Discarding degenerate patch." << std::endl; // Remove again parent->removeChildNode(nodes[i]); } } } // Invert the target patch so that it faces the opposite direction targetPatch->InvertMatrix(); }
void createDecals() { for (FaceInstanceList::iterator i = _faceInstances.begin(); i != _faceInstances.end(); ++i) { // Get the winding const Winding& winding = (*i)->getFace().getWinding(); // Create a new decal patch scene::INodePtr patchNode = GlobalPatchCreator(DEF3).createPatch(); if (patchNode == NULL) { gtkutil::errorDialog(_("Could not create patch."), GlobalMainFrame().getTopLevelWindow()); return; } Patch* patch = Node_getPatch(patchNode); assert(patch != NULL); // must not fail // Set the tesselation of that 3x3 patch patch->setDims(3,3); patch->setFixedSubdivisions(true, Subdivisions(1,1)); // Set the coordinates patch->ctrlAt(0,0).vertex = winding[0].vertex; patch->ctrlAt(2,0).vertex = winding[1].vertex; patch->ctrlAt(1,0).vertex = (patch->ctrlAt(0,0).vertex + patch->ctrlAt(2,0).vertex)/2; patch->ctrlAt(0,1).vertex = (winding[0].vertex + winding[3].vertex)/2; patch->ctrlAt(2,1).vertex = (winding[1].vertex + winding[2].vertex)/2; patch->ctrlAt(1,1).vertex = (patch->ctrlAt(0,1).vertex + patch->ctrlAt(2,1).vertex)/2; patch->ctrlAt(2,2).vertex = winding[2].vertex; patch->ctrlAt(0,2).vertex = winding[3].vertex; patch->ctrlAt(1,2).vertex = (patch->ctrlAt(2,2).vertex + patch->ctrlAt(0,2).vertex)/2; // Use the texture in the clipboard, if it's a decal texture Texturable& clipboard = GlobalShaderClipboard().getSource(); if (!clipboard.empty()) { if (clipboard.getShader().find("decals") != std::string::npos) { patch->setShader(clipboard.getShader()); } } // Fit the texture on it patch->SetTextureRepeat(1,1); patch->FlipTexture(1); // Insert the patch into worldspawn scene::INodePtr worldSpawnNode = GlobalMap().getWorldspawn(); assert(worldSpawnNode != NULL); // This must be non-NULL, otherwise we won't have faces worldSpawnNode->addChildNode(patchNode); // Deselect the face instance (*i)->setSelected(SelectionSystem::eFace, false); // Select the patch Node_setSelected(patchNode, true); } }
void DPatch::BuildInRadiant( scene::Node* entity ){ NodeSmartReference patch( GlobalPatchCreator().createPatch() ); scene::Node& parent = entity != 0 ? *entity : GlobalRadiant().getMapWorldEntity(); Node_getTraversable( parent )->insert( patch ); GlobalPatchCreator().Patch_setShader( patch, texture ); GlobalPatchCreator().Patch_resize( patch, height, width ); PatchControlMatrix matrix = GlobalPatchCreator().Patch_getControlPoints( patch ); for ( int x = 0; x < width; x++ ) { for ( int y = 0; y < height; y++ ) { PatchControl& p = matrix( x, y ); p.m_vertex[0] = points[x][y].xyz[0]; p.m_vertex[1] = points[x][y].xyz[1]; p.m_vertex[2] = points[x][y].xyz[2]; p.m_texcoord[0] = points[x][y].st[0]; p.m_texcoord[1] = points[x][y].st[1]; } } GlobalPatchCreator().Patch_controlPointsChanged( patch ); QER_entity = entity; QER_brush = patch.get_pointer(); #if 0 int nIndex = g_FuncTable.m_pfnCreatePatchHandle(); //$ FIXME: m_pfnGetPatchHandle patchMesh_t* pm = g_FuncTable.m_pfnGetPatchData( nIndex ); b->patchBrush = true; b->pPatch = Patch_Alloc(); b->pPatch->setDims( width,height ); for ( int x = 0; x < width; x++ ) for ( int y = 0; y < height; y++ ) CopyDrawVert( &points[x][y], &pm->ctrl[x][y] ); /* if(entity) { // strcpy(pm->d_texture->name, texture); brush_t* brush = (brush_t*)g_FuncTable.m_pfnCreateBrushHandle(); brush->patchBrush = true; brush->pPatch = pm; pm->pSymbiot = brush; pm->bSelected = false; pm->bOverlay = false; // bleh, f*cks up, just have to wait for a proper function pm->bDirty = true; // or get my own patch out.... pm->nListID = -1; g_FuncTable.m_pfnCommitBrushHandleToEntity(brush, entity); } else*/ // patch to entity just plain dont work atm if ( entity ) { g_FuncTable.m_pfnCommitPatchHandleToEntity( nIndex, pm, texture, entity ); } else{ g_FuncTable.m_pfnCommitPatchHandleToMap( nIndex, pm, texture ); } QER_brush = pm->pSymbiot; #endif }