Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: C: Polygoni joka on hiiren alla...?

Sivun loppuun

Kray [14.01.2008 19:04:02]

#

Olen ihmetellyt ja kummastellut ja miettinyt jne. sitä, että miten ihmeessä on monissa 3d:llä tehdyissä ohjelmissa, joissa kuvakulma ei ole kiinteää nähnytkään, tunnistetaan, onko hiiren alla mikä piirretty polygoni. esim. mallinnusohjelmat. Olisi mielenkiintoista tietää, miten tuo on toteutettu. Jos se jotain vaikuttaa, niin SDL ja OpenGl.

L2-K2 [14.01.2008 19:09:39]

#

Tähän on monia tapoja, yksinkertaisinta (vaan ei aina tehokkainta) on tietenkin "ampua" "säde" kamerasta hiiren osoittamaan suuntaan ja katsoa mitä verteksejä se leikkaa.

Kray [14.01.2008 19:17:27]

#

Siis...? Esimerkki? Eli siis laskettaisiin kameran sijainnin ja suunnan kohdasta kulma hiiren sijaintiin suhteutettuna? Katsos kun Yksinkertaisesti jos jotenkin tietäisi mikä polygoni hiiren alle jää...

Metabolix [14.01.2008 19:59:49]

#

3D-räiskintäpelit tunnistavat, minne ammuttu panos osuu. Samalla tavalla voidaan ratkaista tuokin ongelma, ja tietenkin suora säde ilman ajan vaikutusta on vielä laskennallisesti paljon yksinkertaisempi kuin ilmassa satunnaisella nopeudella lentävä ja putoava luoti.

Mazzimo [14.01.2008 22:48:40]

#

Ehkä helpoin tie on käyttää jotain törmäystarkistuksiin erikoistunutta kirjastoa. En mene tätä vannomaan, mutta mielestäni Opcode:n pitäisi osata tälläiset jutut. Toinen vaihtoehto on käyttää fysiikkakirjastoa, joka osaa myös nämä, mutta sisältää sitten myös kasapäin "turhaa" tavaraa.

Lisää tietoa: http://www.codercorner.com/Opcode.htm

Metabolix [14.01.2008 23:13:19]

#

Omakaan tekele ei ole sinänsä vaikea, mutta matematiikka tuossa hommassa on aika rankkaa vielä yläasteen taidoilla (monet eivät lukion jälkeenkään selviäisi). Etuna on, että rajapinta on tuttu eikä tarvitse vääntää omaa koodia muottiin, johon se ei sovi. Itse rupesin siinä peruskoulun viimeisellä luokalla noihin puuhiin, ja kyllä se viivan ja kolmion törmäystarkistus tulikin lopulta valmiiksi ja toimivaksi. Sitten pitää vain valita törmäyspisteistä se, joka on lähimpänä lähtökohtaa.

Ensin kannattaa siis tarkistaa mallien keskipisteiden sijainti suhteessa viivaan, jolloin selviää nopeasti, mitkä mallit pitää tutkia tarkemmin. Sitten voi käydä mallin läpi kolmio kerrallaan (kaikki polygonit koostuvat pohjimmiltaan kolmioista).

atomimalli [15.01.2008 02:59:38]

#

http://www.siggraph.org/education/materials/HyperGraph/raytrace/raypolygon_intersection.htm

Lähde, mistä on itselle ollut hyötyä.

Toinen, vähän karkeampi tapa on ottaa kaikkien polygonejen ääriviivat muistiin ja katsoa ruudun koordinaateissa, että minkä polygonin sisällä piste on, siinä tarvitaan tietenkin myös syvyysdatan säilyttämistä.

Mazzimo [15.01.2008 10:45:23]

#

Suoran leikkaus kolmioonhan on vielä melko helppo toteuttaa lukiomatikalla. Vaikeutta syntyy kun halutaan optimoida leikkaustarkistusta niin, ettei jouduta käymään kaikkia ohjelman kolmioita läpi. Tämän vuoksi imho on helpompi käyttää valmiita kirjastoja, joihin nämä optimoinnit on integroitu ja ne tehdään automaattisesti.

Pöytälamppu [15.01.2008 16:16:55]

#

Tai sitten voisi piirtää jokaisen polygonin eri arvolla stencil-bufferiin ja sitten lukea hiiren alla oleva arvo glReadPixels-funkkarilla (format = GL_STENCIL_INDEX) ja siitä selviäisi mikä polygoni on kyseessä. Tämä ei kuitenkaan liene tehokkain keino, mutta silläkin selvinnee.

Kray [18.01.2008 16:47:30]

#

Hmm... Miten siihen stenciliin piirretään?
Edit: En oikein onnistu, voisiko joku neuvoa tällaisen: Ohjelma lukee näytöltä halutun pikselin väriarvot floateina, en oikein onnistunut...

User137 [18.01.2008 19:07:06]

#

glRenderMode(GL_SELECT) on myös 1 tapa mutta jotkut kirjottaa että se on vanhentunut eikä käytä rautaa hyväks. Kai se kuitenkin tehokkuudessa glReadPixels:n voittaa.

Tuolla esim: http://nehe.gamedev.net/data/lessons/lesson.asp?lesson=32

Tällanen löytyy myös omasta koodikirjastosta Delphille (RenderProc on pointteri aliohjelmaan joka yksinkertaisesti renderöi sille parametrina annetun indeksin mukaisen 3d-mallin/polygonin/tms):

// Returns displaylist index if cursor points it
// or -1 if no match
function MousePick(mx, my, PickRadius: double;
  Count: integer; RenderProc: TRenderProc): integer;
var SelBuffer: array[0..511] of TGLUint;
    i,hits: integer; viewport: TGLVectori4;
    d1: double;
begin
  result:=-1;
  if count<1 then exit;
  glGetIntegerv(GL_VIEWPORT,@viewPort);

  glSelectBuffer(512, @SelBuffer);
  glRenderMode(GL_SELECT);
  glInitNames; glPushName(0);
  glMatrixMode(GL_PROJECTION);
  glPushMatrix; glLoadIdentity;
  gluPickMatrix(mx,my,PickRadius,PickRadius,viewport);
  gluPerspective(45, AspectRatio, TGL_NEARZ, TGL_FARZ);
  glMatrixMode(GL_MODELVIEW);

  for i:=0 to Count-1 do begin
    glLoadName(i);
    glPushMatrix;
    RenderProc(i);
    glPopMatrix;
  end;

  glMatrixMode(GL_PROJECTION);
  glPopMatrix;
  glMatrixMode(GL_MODELVIEW);

  hits:=glRenderMode(GL_RENDER);
  if hits>0 then begin
    d1:=selBuffer[1]; result:=selBuffer[3];
    for i:=1 to hits-1 do
      if selBuffer[i*4+1]<d1 then begin
        result:=selBuffer[i*4+3];
        d1:=selBuffer[i*4+1];
      end;
  end;
end;

Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta