Kirjautuminen

Haku

Tehtävät

Keskustelu: Nettisivujen teko: box2dweb optimointi - collisioneiden ignorointi

Touho [23.04.2014 23:45:58]

#

Heippa,

Käytän HTML5 pelissäni box2dweb kirjastoa.

Lähes kaikilla objekteilla scenessä on box2d body. Haluisin käyttää box2d bodyjä myös partikkeliefektityyppisiin objekteihin, mutta siitä tulee turhan hidasta vaikka mask bitit on kaikki asetettu nollaan eikä mitään törmäyksiä voi tapahtua.

https://www.dropbox.com/s/xuibcsj9nyv6q4z/Screenshot 2014-04-23 23.31.25.png

Kuten kuvassa näkyy, profiler kertoo että FindNewContacts vie suurimman osan ajasta, vaikka lagin aiheuttaa pelkästää mask bit 0 objektit. En kuitenkaan saanut box2dweb sorsasta niin paljoa selvää, että osaisin optimoida collisionit pois mask bit 0 objekteista.

Olisko tommoinen optimointi tehtävissä box2d:ssä vai teenkö suosiolla omat fysiikat partikkeleille?

Metabolix [25.04.2014 17:47:49]

#

Tuostahan näkee helposti, että aika ei kulu suinkaan törmäystarkistuksessa (AddPair, ShouldCollide) vaan ylipäänsä potentiaalisten törmäysparien tallentamisessa taulukkoon (QueryCallback). Kyseinen funktio ei näennäisesti sisällä mitään kovin ihmeellistä, mutta siinä piilee pieni hämäys: siinä vertaillaan ?:-rakenteissa operaattoreilla < ja >= objekteja proxy ja queryProxy, jolloin itse asiassa objektit muutetaan vertailua varten tekstiksi, mikä on hidasta ja kuormittaa myös roskienkeruuta.

Selvitä ensin varmuuden vuoksi, millainen teksti tuohon tarkistukseen osallistuu: onko siinä jotain mielekästä vertailtavaa sisältöä vai ei. Teksti tulee käsittääkseni tässä tapauksessa metodilta valueOf. Jos teksti vaikuttaa siltä, että vertailusta luultavasti ei tule hyödyllistä tulosta, voit poistaa turhat vertailut ja sijoittaa vain suoraan proxyA:han ja proxyB:hen eri arvot. Jos taas vertailu vaikuttaa järkevältä, voit muokata vertailua niin, että vertailet suoraan olennaisia jäseniä. Tietenkin on myös turha tehdä erikseen vertailut < ja >=, vaan voit tehdä vain yhden vertailun ja käyttää sitä molemmissa ?:-rakenteissa (toisessa käänteisenä).

Jos tämä kuulosti vaikealta, kokeile tätä korjattua funktiota:

function QueryCallback(proxy) {
	if (proxy == queryProxy) return true;
	if (__this.m_pairCount == __this.m_pairBuffer.length) {
		__this.m_pairBuffer[__this.m_pairCount] = new b2DynamicTreePair();
	}

	if (proxy < queryProxy || proxy > queryProxy) {
		alert(
			"Jos et näe tätä, poista tämä if-lause ja ole tyytyväinen. " +
			"Jos näet, (a) ota riski tai (b) korjaa vanhan koodin vertailu. " +
			proxy.toString() + ", " + proxy.valueOf()
		);
	}

	var pair = __this.m_pairBuffer[__this.m_pairCount];
	pair.proxyA = proxy;
	pair.proxyB = queryProxy;
	++__this.m_pairCount;
	return true;
};

Virhe on joka tapauksessa aika koominen siihen nähden, miten paljon Box2D:tä on muuten ”optimoitu”: samoja olioita yritetään väkisin uusiokäyttää, ettei tulisi yhtään new-riviä.

Seuraavaksi voitkin ottaa käsittelyyn sendEvent-funktion alaisen puun, jossa näyttää menevän neljännes ajasta.

Jos partikkelien määrä alkaa myöhemmin todella rajoittaa nopeutta, voisit alkajaisiksi lisätä ennen tuota QueryCallback-funktiota tarkistuksen, että queryProxy ei ole tyhjä, ja QueryCallback-funktioon tarkistuksen, että proxy ei ole tyhjä. Tämän tyhjyyden selvittämisestä en nyt osaa sanoa, mutta se selvinnee jollain tavalla törmäystarkistuskoodia tutkimalla.

Touho [10.05.2014 10:14:57]

#

Tein stressitestin, jossa partikkelit voivat törmäävät pelaajaan, mutta ei toisiinsa. Se pyöri 2 fps. Sun korjauksen jälkeen nopeus oli 4 fps.

Kun laitoin partikkelien mask bitin nollaksi ja lisäsin lisätarkistuksen:

if (queryProxy.userData.m_filter.maskBits === 0) continue;

QueryCallback funktiota kutsutaan nyt maksimissaan 5000 kertaa sekunnissa 500000 sijaan. Testi pyörii nyt vähintään 8 fps.

Sitten eniten aikaa vei SynchronizeFixtures, johon laitoin saman filtteritestin. Fysiikat tuntuvat toimivan vieläkin ja stressitesti pyörii 12 fps.

Partikkelien huikean nopeuden lisäksi muidenkin box2d fysiikoiden vaatima aika taisi puoliintua. Suur kiitos! :) Tässä vaiheessa alkaa tulla pikkuhiljaa oman enginen ja javascriptin tehot vastaan, joten olen _erittäin_ tyytyväinen.

sendEventissä suurin osa ajasta meni box2d bodyn luomiseen.

Vastaus

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

Tietoa sivustosta