2015-11-25 53 views
17

मैं टाइल्स के साथ काम नहीं करता लेकिन एसएफ :: वर्टेक्स के साथ खींचे गए क्यूब्स। प्रत्येक क्यूब्स में 6 अंक होते हैं जिनमें प्रत्येक 4 अंक होते हैं। enter image description here2 डी आइसोमेट्रिक - एसएफएमएल - सही सूत्र, गलत समन्वय रेंज

तो मुझे एक पक्ष चुनने के लिए बस cubes[numCube].sides()[numSide].... होना है।

for(int J = 0; J < mapSize; J++) 
    { 
     for(int I = 0; I < mapSize; I++) 
     { 
      x = (J - I) * (cubeSize/2); 
      y = (J + I) * (cubeSize/4); 

      c = new cube(cubeSize, x, y, z, I, J); 
      cs.push_back(*c); 
     } 
    } 

cube.cpp में मैं बनाने के पक्ष है, तो, sides.cpp में, मैं प्रत्येक अंक 'निर्देशांकों के इस तरह calcul:

switch(typeSide) 
{ 
    case 0://DOWN_SIDE 
     light = 1; 

     tmp_x = x + (size/2); 
     tmp_y = y + (size/2); 
     p0 = new point(tmp_x, tmp_y, tmp_z); 

     tmp_x = x + size; 
     tmp_y = y + (3 * (size/4)); 
     p1 = new point(tmp_x, tmp_y, tmp_z); 

     tmp_x = x + (size/2); 
     tmp_y = y + size; 
     p2 = new point(tmp_x, tmp_y, tmp_z); 

     tmp_x = x; 
     tmp_y = y + (3 * (size/4)); 
     p3 = new point(tmp_x, tmp_y, tmp_z); 
     break; 

    case 1://BACK_LEFT_SIDE 

//ETC. .... 

प्वाइंट

मैं क्यूब्स layer.cpp बनाने सीपीपी:

/* 
* point.cpp 
* 
* Created on: 21 nov. 2015 
*  Author: user 
*/ 

#include "point.h" 

point::point(float tx, float ty, float tz) 
{ 
    coords* dummyVar = new coords(tx, ty, tz); 
    coordinates = dummyVar; 
} 

std::vector<float> point::position()//Use : myPoint.getPosition[0] //get the x 
{ 
    std::vector<float> dummyVar; 

    dummyVar.push_back(coordinates->getX()); 
    dummyVar.push_back(coordinates->getY() - coordinates->getZ()); 

    return dummyVar; 
} 

void point::move(float tx, float ty, float tz) 
{ 
    coordinates->setX(tx); 
    coordinates->setY(ty); 
    coordinates->setZ(tz); 
} 

मेरे समस्या समारोह मैं पता लगाने के लिए उपयोग करने से आते क्लिक:

012,351,
if (event.type == sf::Event::MouseMoved) 
{ 
      currentSelectedCube = maps[currentMapID].getCubeIDAt(event.mouseMove.x, event.mouseMove.y, offsetLeft, offsetTop, enableOffset); 
} 

समारोह (टिप्पणियों के साथ परेशान नहीं है):

मैं 'पाश के लिए' बिना मेरे घन वेक्टर में एक घन के प्रवेश प्राप्त करने की कोशिश। क्यों? जब मैं क्लिक करता हूं तो कम CPU का उपयोग करने के लिए।

int map::getCubeIDAt(float x, float y, int offsetLeft, int offsetTop, bool enableOffset)//WIP ! //USED FOR CLICK DETECTION ON CUBES 
    { 
    //----------------------------------------------------------------// 
     int unsigned entry = -1; 

     int I = 0; 
     int J = 0; 
    //----------------------------------------------------------------// 

     if(currentLayerId() > -1)//If there is any layers 
     { 
      //IF CHECK IN MAP BOUDING BOX + ROTATION TO GOT DIAMOND SHAPE AREA(LAYER + OFFSETS)---------------------------------- 
      //{ 

       if(!enableOffset)//With offsets disabled 
       { 
        I = (y * 2 - x)/cubeSize; 
        J = (y * 2 + x)/cubeSize; 
       } 
       else //With offsets enabled 
       { 
        I = (((y-offsetTop)+(currentLayerId()*(cubeSize/2))) * 2 - (x-offsetLeft))/cubeSize; 
        J = (((y-offsetTop)+(currentLayerId()*(cubeSize/2))) * 2 + (x-offsetLeft))/cubeSize; 
       } 

       entry = I + J * size; 

       if (entry < 0 || entry >= layers()[currentLayerId()].cubes().size()) 
       { 
        entry = -1; 
       } 
       else//DEBUG - DISPLAYING VALUES FOR TEST 
       { 
        std::cout << "Entry n°" << entry << " - "; 
        std::cout << "[" << I << "; " << J << "]" << std::endl; 
       } 
      //} 
      //END IF CHECK IN MAP BOUDING BOX + ROTATION TO GOT DIAMOND SHAPE AREA(LAYER + OFFSETS)---------------------------------- 
     } 

     return entry; 
    } 

मैं-जम्मू और entryNumber ठीक हैं। मेरा मतलब है, उदाहरण के लिए, घन 0 के लिए, मेरे पास I = 0 है; जे = 0; आदि ... यह काम कर रहा है।

मुझे समझ नहीं आता क्यों समन्वय रेंज लाल हिस्सा की तरह है इस तस्वीर में (100% पर सही नहीं, मैं एक पेंट प्रतिभाशाली हा हा नहीं कर रहा हूँ):

enter image description here

लेकिन मैं उसे प्राप्त करना चाहिए (दूसरी तस्वीर - लाल भाग वह जगह है जहां मैं क्लिक करता हूं):

लेकिन कुछ चेक के बाद, आईजे और प्रविष्टि मुझे मिलती है। यह बहुत अजीब है।

enter image description here

EDIT2: ऑफसेट और परत संख्या लागू किया। समस्या शेष: गलत निर्देशांक सीमा।

void GRAPHICS_HANDLER::listenEvents() 
{ 
    while (window->pollEvent(event)) 
    { 
     if (event.type == sf::Event::Closed) 
     { 
      window->close(); 
     } 

     if(event.type == sf::Event::KeyPressed) 
     { 
      //DISPLAY/UNDISPLAY GRID -- DEBUG FUNCTION 
      if(event.key.code == sf::Keyboard::Escape) 
      { 
       if(grid) 
        grid = false; 
       else 
        grid = true; 
      } 

//-----------------------------------------------------------------------------------DEBUG---------------------------------------------------------------// 
      if(event.key.code == sf::Keyboard::B)//ACTIVE BRUSHMODE -- NEED TO BLOCK IT WHEN ACCESS VIOLATION OF CUBES ARRAY(CRASH) 
      { 
       if(!brushMode) 
       { 
        brushMode = true; 
        std::cout << "Brush mode enabled" << std::endl; 
       } 
       else 
       { 
        brushMode = false; 
        std::cout << "Brush mode disabled" << std::endl; 
       } 
      } 

      if(event.key.code == sf::Keyboard::L)//ADD_LAYER 
      { 
       addLayer(getCurrentMapID()); 
      } 

      if(event.key.code == sf::Keyboard::M)//DELETE_LAYER 
      { 
       deleteLayer(currentMapID, maps[currentMapID].currentLayerId()); 
      } 

      if(event.key.code == sf::Keyboard::S)//ADD_LAYER 
      { 
       std::cout << "Select a texture: "; 
       std::cin >> currentSelectedTexture; std::cout << std::endl; 
      } 

      if(event.key.code == sf::Keyboard::Left)//Move in Layer 
      { 
       if(maps[currentMapID].currentLayerId() > 0) 
       { 
        maps[currentMapID].setCurrentLayerID(maps[currentMapID].currentLayerId()-1); 
       } 
      } 

      if(event.key.code == sf::Keyboard::Right)//Move in Layer 
      { 
       if(maps[currentMapID].currentLayerId() < maps[currentMapID].layers().size()-1) 
       { 
        maps[currentMapID].setCurrentLayerID(maps[currentMapID].currentLayerId()+1); 
       } 
      } 
//-----------------------------------------------------------------------------------DEBUG---------------------------------------------------------------// 
     } 

     if (event.type == sf::Event::MouseMoved) 
     { 
//--------------------------------------------------------------------------CURSOR-----------------------------------------------------------------------// 
      currentSelectedCube = maps[currentMapID].getCubeIDAt(event.mouseMove.x, event.mouseMove.y, offsetLeft, offsetTop, enableOffset); 
//--------------------------------------------------------------------------CURSOR-----------------------------------------------------------------------// 
     } 

     if (event.type == sf::Event::MouseButtonPressed) 
     { 
//--------------------------------------------------------------------------CURSOR-----------------------------------------------------------------------// 
      currentSelectedCube = maps[currentMapID].getCubeIDAt(event.mouseButton.x, event.mouseButton.y, offsetLeft, offsetTop, enableOffset); 
//--------------------------------------------------------------------------CURSOR-----------------------------------------------------------------------// 
      if (event.mouseButton.button == sf::Mouse::Left) 
      { 
//--------------------------------------------------------------------------CUBE CLICK DETECTION--------------------------------------------------// 
       if(maps.size() > 0 && maps[currentMapID].layers().size() > 0 && currentSelectedCube > -1) 
       { 
        cubeClicked = true; 
       } 
      } 

      if (event.mouseButton.button == sf::Mouse::Right) 
      { 
       if(maps.size() > 0 && maps[currentMapID].layers().size() > 0 && currentSelectedCube > -1) 
       { 
        maps[currentMapID].layers()[maps[currentMapID].currentLayerId()].cubes()[currentSelectedCube].setTexture(1); 
       } 
      } 
//--------------------------------------------------------------------------CUBE CLICK DETECTION--------------------------------------------------// 
     } 
    } 
} 

EDIT3: मैं कर सकता हूँ मैं मुझे घन के केवल नीचे की ओर आकर्षित करने के लिए अनुमति देने के लिए मेरे कोड अद्यतन, इसलिए

बस मामले में, इस 'समारोह' से निपटने की घटनाओं है यह (घास): enter image description here

समन्वय सीमा (स्क्रीनशॉट में पहले दिखाया गया लाल आइसोमेट्रिक वर्ग) थोड़ा सा बदलता है जब मैं फ्लैट वर्ग (हरा) डालता हूं। मुझे नहीं पता कि क्यों, मैं इसे सटीक करना पसंद करता हूं, बस मामले में।,

enter image description here

एक ही स्क्रीन निर्देशांक:

उत्तर

5

आपको जो घन आप वास्तव में चयन कर रहे हैं (प्रेक्षक के करीब) भेद करने में टाइल्स विमान से प्रत्येक तत्व की "ऊँचाइ" स्टोर करने के लिए की जरूरत है लेकिन विभिन्न टाइल्स।

यह मुझे स्पष्ट नहीं है कि आपने अपनी दुनिया का मॉडल कैसे किया है, इसलिए मैं आपको एक आंशिक एल्गोरिदम दूंगा ताकि यह जांच सके कि किस घन का एक क्लिक है। कृपया इसे अपने वास्तविक कोड और उन कक्षाओं में अनुकूलित करें जिन्हें आपने इसे काम करने के लिए लिखा है।

// I'll let you to add the offsets for the screen coordinates 
I = (y * 2 - x)/cubeSize; 
J = (y * 2 + x)/cubeSize; 
// find out if it is a left or right triangle 
if (x < (J - I) * (cubeSize/2)) { 
    // left triangle 
    for (k = max_n_layer; k > -1; --k) { 
     // you create the cubes nesting the I loop in the J loop, so to get the index of a cube, 
     // assuming that you have created all the cubes (even the invisible ones, like it seems from your code) 
     index = (J+1+k)*mapsize + I+1+k; 

     // I don't really get how you define the existence or not of a face, but I guess something like this: 
     if (index < map.layer[k].cubes.size() 
      && map.layer[k].cubes[index].sides[top_side] != 0) { 
     // the face selected is the top side of cube[index] of layer k 
      // you have to return index and k to select the right face, or simply a pointer to that face 
      // if this makes any sense with how you have designed your model 
      return &map.layer[k].cubes[index].sides[top_side]; 
     } 
     // now check for the side 
     index = (J+k)*mapsize + I+1+k; 
     if (index < map.layer[k].cubes.size() 
      && map.layer[k].cubes[index].sides[right_side] != 0) { 

      return &map.layer[k].cubes[index].sides[right_side]; 
     } 
     index = (J+k)*mapsize + I+k; 
     if (index < map.layer[k].cubes.size() 
      && map.layer[k].cubes[index].sides[left_side] != 0) { 

      return &map.layer[k].cubes[index].sides[left_side]; 
     } 
    } 
} else { 
    // right triangle 
    for (k = max_n_layer; k > -1; --k) { 

     index = (J+1+k)*mapsize + I+1+k; 

     if (index < map.layer[k].cubes.size() 
      && map.layer[k].cubes[index].sides[top_side] != 0) { 
      return &map.layer[k].cubes[index].sides[top_side]; 
     } 

     index = (J+1+k)*mapsize + I+k; 
     if (index < map.layer[k].cubes.size() 
      && map.layer[k].cubes[index].sides[left_side] != 0) { 

      return &map.layer[k].cubes[index].sides[left_side]; 
     } 
     index = (J+k)*mapsize + I+k; 
     if (index < map.layer[k].cubes.size() 
      && map.layer[k].cubes[index].sides[right_side] != 0) { 

      return &map.layer[k].cubes[index].sides[right_side]; 
     } 
    } 
}  
// well, no match found. As I said is up to you to decide how to do in this case 
return nullptr; 

संपादित

मैं सुझाव है कि आप एक और तरीका कोशिश करने के लिए।

स्क्रीन पर विचार करें जैसा कि चौकोर चतुर्भुज द्वारा विभाजित नहीं है, लेकिन त्रिभुजों द्वारा जो आप पहले ही चित्रित करते हैं। आपके मॉडल का प्रत्येक 2 डी टाइल दो त्रिकोणों द्वारा बनाया जाएगा और इसलिए उन cubes के सभी किनारे जिन्हें आप आकर्षित करना चाहते हैं। प्रत्येक घन के लिए पीछे की तरफ खींचना और न ही बनाने के लिए, वे कभी नहीं खींचे जाएंगे।

आप स्क्रीन पर ड्रॉइंग करने वाले त्रिकोणों में से प्रत्येक के लिए संग्रहीत करके एक विशेष प्रकार के विशेष जेड-बफर एल्गोरिदम को लागू करने का प्रयास कर सकते हैं जो पर्यवेक्षक के करीब है। सभी त्रिकोणों के कशेरुक के निर्देशांक की गणना आपके द्वारा पहले से मौजूद कोड के साथ की जाती है (एक बार)।

  (I,J)    //For every node (I,J) you have a left and a right triangle 
      . * . 
(I+1,J) * . | . * (I,J+1) 
       * 
      (I+1,J+1) 

आप परत से अपने क्यूब्स परत बना रहे हैं, मुझे लगता है कि प्रत्येक परत बेस प्लेन पर एक अलग हेगथ ​​है। पहले गणना की गई निर्देशांक का उपयोग कर घन के हर तरफ बनाएं। प्रत्येक चेहरे के लिए (केवल पर्यवेक्षक को इंगित करने वाला 3) अपने 2 त्रिकोणों में से प्रत्येक पर विचार करें। आप आसानी से निर्धारित कर सकते हैं कि यह दृश्यमान है या नहीं, यदि आप क्रम में आगे बढ़ते हैं, तो आपको केवल संबंधित त्रिभुज में संग्रहीत आईडी को अपडेट करना होगा।

एक बार इस फेज को समाप्त करने के बाद, आपको प्रत्येक त्रिभुज को एक बार खींचना होगा क्योंकि आपने पहले ही छिपे हुए लोगों को छोड़ दिया है। सेल इंडेक्स में स्क्रीन निर्देशांक से उलटा परिवर्तन निर्धारित करने के लिए, आपको केवल गणना करना होगा कि कौन सा त्रिभुज लगाया गया है और उसके बाद कौन सी आईडी उससे मेल खाती है। तो एक्स, वाई से आई, जे (आपके पास पहले से ही वे समीकरण हैं) को वापस बदलें और बाएं त्रिकोण का चयन करें यदि x < (J-I)/cubesize सही है तो अन्यथा।

+0

मैंने पहले से ही "ऊंचाई" सेट किया है, मेरे सभी कोड में, "ऊंचाई" परत संख्या है। मुझे केवल आई/जे गणना को सही करने की आवश्यकता है। – Madz

+0

आपके उत्तर के लिए धन्यवाद, दुर्भाग्य से, मुझे नहीं पता कि यह अंग्रेजी कौशल या कोडिंग (गणित?) की कमी के कारण है, लेकिन मुझे यह समझने की ज़रूरत नहीं है। मैं उस हिस्से को समझ गया जो मुझे उस चेहरे को छोड़ना पड़ा जो प्रदर्शित नहीं होगा, लेकिन नोड क्या है? – Madz

+0

@Madz अपने कोड से, आप दो घन I और J से अपने चरम के x, y निर्देशांक की गणना करने वाले प्रत्येक घन को बनाते हैं। इसलिए प्रत्येक जोड़े के indeces (I, J) एक घन परिभाषित करते हैं। आपके चित्रों (और खानों) में प्रत्येक त्रिभुज या चतुर्भुज टाइल के प्रत्येक चरम पर कुछ indeces (I, J) से मेल खाते हैं। आप जो गणित कर रहे हैं वह उन मानों को स्क्रीन निर्देशांक और पीछे की तरफ बदलना है। –

संबंधित मुद्दे