|
@@ -32,6 +32,8 @@ Model2DData::~Model2DData()
|
|
polygons->get( i ).tKordinaten->release();
|
|
polygons->get( i ).tKordinaten->release();
|
|
if( polygons->get( i ).vertex )
|
|
if( polygons->get( i ).vertex )
|
|
polygons->get( i ).vertex->release();
|
|
polygons->get( i ).vertex->release();
|
|
|
|
+ if( polygons->get( i ).schwerpunkt )
|
|
|
|
+ delete polygons->get( i ).schwerpunkt;
|
|
}
|
|
}
|
|
polygons = polygons->release();
|
|
polygons = polygons->release();
|
|
}
|
|
}
|
|
@@ -379,6 +381,8 @@ void Model2DData::removeModell() // setzt die Vertex daten zur
|
|
polygons->get( i ).tKordinaten->release();
|
|
polygons->get( i ).tKordinaten->release();
|
|
if( polygons->get( i ).vertex )
|
|
if( polygons->get( i ).vertex )
|
|
polygons->get( i ).vertex->release();
|
|
polygons->get( i ).vertex->release();
|
|
|
|
+ if( polygons->get( i ).schwerpunkt )
|
|
|
|
+ delete polygons->get( i ).schwerpunkt;
|
|
}
|
|
}
|
|
polygons = polygons->release();
|
|
polygons = polygons->release();
|
|
}
|
|
}
|
|
@@ -389,6 +393,250 @@ void Model2DData::removeModell() // setzt die Vertex daten zur
|
|
maxP = Punkt( 0, 0 );
|
|
maxP = Punkt( 0, 0 );
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+bool Model2DData::calcHitPoint( Vertex pos, Vertex dir, char *polygonName, Vertex &hitpoint, Vertex &moveSpeed, float &rotSpeed ) const
|
|
|
|
+{
|
|
|
|
+ bool ret = 0;
|
|
|
|
+ for( auto *polygon = &polygons->getArray(); polygon && polygon->set; polygon = polygon->next )
|
|
|
|
+ {
|
|
|
|
+ if( polygon->var.name->istGleich( polygonName ) )
|
|
|
|
+ {
|
|
|
|
+ int anz = polygon->var.vertex->getEintragAnzahl();
|
|
|
|
+ for( int i = 0; i < anz; i++ )
|
|
|
|
+ {
|
|
|
|
+ Vertex a = polygon->var.vertex->get( i );
|
|
|
|
+ Vertex b = polygon->var.vertex->get( ( i + 1 ) % anz );
|
|
|
|
+ b -= a;
|
|
|
|
+ float offset = 0;
|
|
|
|
+ if( dir.y != 0 && dir.x != 0 )
|
|
|
|
+ offset = ( ( a.y - pos.y ) / dir.y - ( a.x - pos.x ) / dir.x ) / ( b.x / dir.x - b.y / dir.y ); // solve hitpoint equasion
|
|
|
|
+ else if( dir.y == 0 )
|
|
|
|
+ offset = ( pos.y - a.y ) / b.y;
|
|
|
|
+ else if( dir.x == 0 )
|
|
|
|
+ offset = ( pos.x - a.x ) / b.x;
|
|
|
|
+ Vertex point = a + ( b * offset );
|
|
|
|
+ if( offset >= 0 && offset <= 1 )
|
|
|
|
+ {
|
|
|
|
+ if( !ret || ( hitpoint - pos ).getLengthSq() > ( point - pos ).getLengthSq() )
|
|
|
|
+ {
|
|
|
|
+ Vertex normal = b.CW90().normalize();
|
|
|
|
+ Vertex kNorm = Vertex( dir ).normalize();
|
|
|
|
+ moveSpeed = normal * ( normal * kNorm ) * dir.getLengthSq();
|
|
|
|
+ normal = ( point - *polygon->var.schwerpunkt ).CW90().normalize();
|
|
|
|
+ Vertex rotKraft = normal * ( normal * kNorm ) * dir.getLength();
|
|
|
|
+ rotSpeed = ( ( rotKraft.getLength() * ( point - *polygon->var.schwerpunkt ).getLength() ) / 180.f ) * 3.14f;
|
|
|
|
+ if( point.x >= polygon->var.schwerpunkt->x )
|
|
|
|
+ {
|
|
|
|
+ if( point.y >= polygon->var.schwerpunkt->y && rotKraft.x > 0 && rotKraft.y < 0 )
|
|
|
|
+ rotSpeed = -rotSpeed;
|
|
|
|
+ if( point.y < polygon->var.schwerpunkt->y && rotKraft.x < 0 && rotKraft.y < 0 )
|
|
|
|
+ rotSpeed = -rotSpeed;
|
|
|
|
+ }
|
|
|
|
+ else
|
|
|
|
+ {
|
|
|
|
+ if( point.y >= polygon->var.schwerpunkt->y && rotKraft.x > 0 && rotKraft.y > 0 )
|
|
|
|
+ rotSpeed = -rotSpeed;
|
|
|
|
+ if( point.y < polygon->var.schwerpunkt->y && rotKraft.x < 0 && rotKraft.y > 0 )
|
|
|
|
+ rotSpeed = -rotSpeed;
|
|
|
|
+ }
|
|
|
|
+ hitpoint = point;
|
|
|
|
+ }
|
|
|
|
+ ret = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool Model2DData::split( Vertex pos, Vertex dir, char *polygonName, Polygon2D &partA, Polygon2D &partB, Punkt &posA, Punkt &posB, std::function< double() > random ) const
|
|
|
|
+{
|
|
|
|
+ Vertex originalDir = dir;
|
|
|
|
+ bool ret = 0;
|
|
|
|
+ int num = 0;
|
|
|
|
+ for( auto *polygon = &polygons->getArray(); polygon && polygon->set; polygon = polygon->next, num++ )
|
|
|
|
+ {
|
|
|
|
+ if( polygon->var.name->istGleich( polygonName ) )
|
|
|
|
+ {
|
|
|
|
+ while( istPunktInnen( pos, num ) )
|
|
|
|
+ {
|
|
|
|
+ pos -= dir;
|
|
|
|
+ }
|
|
|
|
+ int anz = polygon->var.vertex->getEintragAnzahl();
|
|
|
|
+ Vertex startPoint;
|
|
|
|
+ Vertex texturSP;
|
|
|
|
+ int leftI = 0;
|
|
|
|
+ int rightI = 0;
|
|
|
|
+ Vertex txtChpPix( 0, 0 );
|
|
|
|
+ for( int i = 0; i < anz; i++ )
|
|
|
|
+ {
|
|
|
|
+ Vertex a = polygon->var.vertex->get( i );
|
|
|
|
+ Vertex b = polygon->var.vertex->get( ( i + 1 ) % anz );
|
|
|
|
+ b -= a;
|
|
|
|
+ if( ( txtChpPix.x == 0 || txtChpPix.y == 0 ) && b.x != 0 && b.y != 0 )
|
|
|
|
+ {
|
|
|
|
+ Vertex ta = polygon->var.tKordinaten->get( i );
|
|
|
|
+ Vertex tb = polygon->var.tKordinaten->get( ( i + 1 ) % anz );
|
|
|
|
+ tb -= ta;
|
|
|
|
+ txtChpPix = Vertex( tb.x / b.x, tb.y / b.y );
|
|
|
|
+ }
|
|
|
|
+ float offset = 0;
|
|
|
|
+ if( dir.y != 0 && dir.x != 0 )
|
|
|
|
+ offset = ( ( a.y - pos.y ) / dir.y - ( a.x - pos.x ) / dir.x ) / ( b.x / dir.x - b.y / dir.y ); // solve hitpoint equasion
|
|
|
|
+ else if( dir.y == 0 )
|
|
|
|
+ offset = ( pos.y - a.y ) / b.y;
|
|
|
|
+ else if( dir.x == 0 )
|
|
|
|
+ offset = ( pos.x - a.x ) / b.x;
|
|
|
|
+ Vertex point = a + ( b * offset );
|
|
|
|
+ if( offset >= 0 && offset <= 1 )
|
|
|
|
+ {
|
|
|
|
+ if( !ret || ( startPoint - pos ).getLengthSq() > ( point - pos ).getLengthSq() )
|
|
|
|
+ {
|
|
|
|
+ leftI = i;
|
|
|
|
+ rightI = ( i + 1 ) % anz;
|
|
|
|
+ startPoint = point;
|
|
|
|
+ texturSP = polygon->var.tKordinaten->get( i ) + ( polygon->var.tKordinaten->get( ( i + 1 ) % anz ) - polygon->var.tKordinaten->get( i ) ) * offset;
|
|
|
|
+ }
|
|
|
|
+ ret = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if( ret )
|
|
|
|
+ {
|
|
|
|
+ partA.transparent = polygon->var.transparent;
|
|
|
|
+ partA.schwerpunkt = new Vertex( 0, 0 );
|
|
|
|
+ partA.tKordinaten = new Array< Vertex >();
|
|
|
|
+ partA.name = new Text( polygon->var.name->getText() );
|
|
|
|
+ partA.vertex = new Array< Vertex >();
|
|
|
|
+ partB.transparent = polygon->var.transparent;
|
|
|
|
+ partB.schwerpunkt = new Vertex( 0, 0 );
|
|
|
|
+ partB.tKordinaten = new Array< Vertex >();
|
|
|
|
+ partB.name = new Text( polygon->var.name->getText() );
|
|
|
|
+ partB.vertex = new Array< Vertex >();
|
|
|
|
+ *partA.schwerpunkt += startPoint;
|
|
|
|
+ *partB.schwerpunkt += startPoint;
|
|
|
|
+ partA.vertex->add( startPoint );
|
|
|
|
+ partB.vertex->add( startPoint );
|
|
|
|
+ partA.tKordinaten->add( texturSP );
|
|
|
|
+ partB.tKordinaten->add( texturSP );
|
|
|
|
+ int leftIE = 0;
|
|
|
|
+ int rightIE = 0;
|
|
|
|
+ while( 1 )
|
|
|
|
+ {
|
|
|
|
+ pos = startPoint;
|
|
|
|
+ Vertex next = startPoint + dir;
|
|
|
|
+ Vertex nextT = texturSP + Vertex( dir.x * txtChpPix.x, dir.y * txtChpPix.y );
|
|
|
|
+ ret = 0;
|
|
|
|
+ bool needOne = !istPunktInnen( next );
|
|
|
|
+ int bestI = -1;
|
|
|
|
+ float bo1 = 1000;
|
|
|
|
+ float bo2 = 1000;
|
|
|
|
+ for( int i = 0; i < anz; i++ )
|
|
|
|
+ {
|
|
|
|
+ if( i == leftI )
|
|
|
|
+ continue;
|
|
|
|
+ Vertex a = polygon->var.vertex->get( i );
|
|
|
|
+ Vertex b = polygon->var.vertex->get( ( i + 1 ) % anz );
|
|
|
|
+ b -= a;
|
|
|
|
+ float offset1 = 0;
|
|
|
|
+ if( dir.y != 0 && dir.x != 0 )
|
|
|
|
+ offset1 = ( ( a.y - pos.y ) / dir.y - ( a.x - pos.x ) / dir.x ) / ( b.x / dir.x - b.y / dir.y ); // solve hitpoint equasion
|
|
|
|
+ else if( dir.y == 0 )
|
|
|
|
+ offset1 = ( pos.y - a.y ) / b.y;
|
|
|
|
+ else if( dir.x == 0 )
|
|
|
|
+ offset1 = ( pos.x - a.x ) / b.x;
|
|
|
|
+ Vertex point = a + ( b * offset1 );
|
|
|
|
+ float offset2 = 0;
|
|
|
|
+ if( dir.x != 0 )
|
|
|
|
+ offset2 = ( point.x - pos.x ) / dir.x;
|
|
|
|
+ else
|
|
|
|
+ offset2 = ( point.y - pos.y ) / dir.y;
|
|
|
|
+ if( needOne && min( abs( bo1 ), abs( bo1 - 1 ) ) + min( abs( bo2 ), bo2 - 1 ) > min( abs( offset1 ), abs( offset1 - 1 ) ) + min( abs( offset2 ), abs( offset2 - 1 ) ) )
|
|
|
|
+ {
|
|
|
|
+ bo1 = offset1;
|
|
|
|
+ bo2 = offset2;
|
|
|
|
+ bestI = i;
|
|
|
|
+ }
|
|
|
|
+ if( offset1 >= 0 && offset1 <= 1 && offset2 >= 0 && offset2 <= 1 )
|
|
|
|
+ {
|
|
|
|
+ if( !ret || ( startPoint - pos ).getLengthSq() > ( point - pos ).getLengthSq() )
|
|
|
|
+ {
|
|
|
|
+ leftIE = i;
|
|
|
|
+ rightIE = ( i + 1 ) % anz;
|
|
|
|
+ startPoint = point;
|
|
|
|
+ texturSP = polygon->var.tKordinaten->get( i ) + ( polygon->var.tKordinaten->get( ( i + 1 ) % anz ) - polygon->var.tKordinaten->get( i ) ) * offset1;
|
|
|
|
+ }
|
|
|
|
+ ret = 1;
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ if( needOne && !ret )
|
|
|
|
+ {
|
|
|
|
+ Vertex a = polygon->var.vertex->get( bestI );
|
|
|
|
+ Vertex b = polygon->var.vertex->get( ( bestI + 1 ) % anz );
|
|
|
|
+ b -= a;
|
|
|
|
+ leftIE = bestI;
|
|
|
|
+ rightIE = ( bestI + 1 ) % anz;
|
|
|
|
+ startPoint = a + ( b * bo1 );
|
|
|
|
+ texturSP = polygon->var.tKordinaten->get( bestI ) + ( polygon->var.tKordinaten->get( ( bestI + 1 ) % anz ) - polygon->var.tKordinaten->get( bestI ) ) * bo1;
|
|
|
|
+ ret = 1;
|
|
|
|
+ }
|
|
|
|
+ if( ret )
|
|
|
|
+ break;
|
|
|
|
+ *partA.schwerpunkt += next;
|
|
|
|
+ *partB.schwerpunkt += next;
|
|
|
|
+ partA.vertex->add( next );
|
|
|
|
+ partB.vertex->add( next );
|
|
|
|
+ partA.tKordinaten->add( nextT );
|
|
|
|
+ partB.tKordinaten->add( nextT );
|
|
|
|
+ startPoint = next;
|
|
|
|
+ texturSP = nextT;
|
|
|
|
+ dir = originalDir.rotation( (float)(random() - 0.5) );
|
|
|
|
+ }
|
|
|
|
+ *partA.schwerpunkt += startPoint;
|
|
|
|
+ *partB.schwerpunkt += startPoint;
|
|
|
|
+ partA.vertex->add( startPoint );
|
|
|
|
+ partB.vertex->add( startPoint );
|
|
|
|
+ partA.tKordinaten->add( texturSP );
|
|
|
|
+ partB.tKordinaten->add( texturSP );
|
|
|
|
+ for( int i = rightIE; i != leftI; i++ )
|
|
|
|
+ {
|
|
|
|
+ i = i % anz;
|
|
|
|
+ if( i == leftI )
|
|
|
|
+ break;
|
|
|
|
+ *partA.schwerpunkt += polygon->var.vertex->get( i );
|
|
|
|
+ partA.vertex->add( polygon->var.vertex->get( i ) );
|
|
|
|
+ partA.tKordinaten->add( polygon->var.tKordinaten->get( i ) );
|
|
|
|
+ }
|
|
|
|
+ *partA.schwerpunkt += polygon->var.vertex->get( leftI );
|
|
|
|
+ partA.vertex->add( polygon->var.vertex->get( leftI ) );
|
|
|
|
+ partA.tKordinaten->add( polygon->var.tKordinaten->get( leftI ) );
|
|
|
|
+ for( int i = leftIE; i != rightI; i-- )
|
|
|
|
+ {
|
|
|
|
+ if( i < 0 )
|
|
|
|
+ i += anz;
|
|
|
|
+ if( i == rightI )
|
|
|
|
+ break;
|
|
|
|
+ *partB.schwerpunkt += polygon->var.vertex->get( i );
|
|
|
|
+ partB.vertex->add( polygon->var.vertex->get( i ) );
|
|
|
|
+ partB.tKordinaten->add( polygon->var.tKordinaten->get( i ) );
|
|
|
|
+ }
|
|
|
|
+ *partB.schwerpunkt += polygon->var.vertex->get( rightI );
|
|
|
|
+ partB.vertex->add( polygon->var.vertex->get( rightI ) );
|
|
|
|
+ partB.tKordinaten->add( polygon->var.tKordinaten->get( rightI ) );
|
|
|
|
+ *partA.schwerpunkt /= (float)partA.vertex->getEintragAnzahl();
|
|
|
|
+ *partB.schwerpunkt /= (float)partB.vertex->getEintragAnzahl();
|
|
|
|
+ posA = (Punkt)*partA.schwerpunkt;
|
|
|
|
+ posB = (Punkt)*partB.schwerpunkt;
|
|
|
|
+ for( int i = 0; i < partA.vertex->getEintragAnzahl(); i++ )
|
|
|
|
+ partA.vertex->set( partA.vertex->get( i ) - *partA.schwerpunkt, i );
|
|
|
|
+ for( int i = 0; i < partB.vertex->getEintragAnzahl(); i++ )
|
|
|
|
+ partB.vertex->set( partB.vertex->get( i ) - *partB.schwerpunkt, i );
|
|
|
|
+ *partA.schwerpunkt = Vertex( 0, 0 );
|
|
|
|
+ *partB.schwerpunkt = Vertex( 0, 0 );
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ return ret;
|
|
|
|
+}
|
|
|
|
+
|
|
// Reference Counting
|
|
// Reference Counting
|
|
Model2DData *Model2DData::getThis()
|
|
Model2DData *Model2DData::getThis()
|
|
{
|
|
{
|
|
@@ -424,7 +672,7 @@ Model2D::~Model2D()
|
|
{
|
|
{
|
|
if( rData )
|
|
if( rData )
|
|
rData->release();
|
|
rData->release();
|
|
- textur->release();
|
|
|
|
|
|
+ textur->release();
|
|
}
|
|
}
|
|
|
|
|
|
// nicht constant
|
|
// nicht constant
|
|
@@ -518,7 +766,7 @@ void Model2D::render( Bild &zRObj )
|
|
{
|
|
{
|
|
if( !rData || hatStyleNicht( Model2D::Style::Sichtbar ) || !rData->polygons )
|
|
if( !rData || hatStyleNicht( Model2D::Style::Sichtbar ) || !rData->polygons )
|
|
return;
|
|
return;
|
|
- Zeichnung::render( zRObj );
|
|
|
|
|
|
+ Zeichnung::render( zRObj );
|
|
int num = 0;
|
|
int num = 0;
|
|
for( auto *p = &rData->vListen->getArray(); p && p->set; p = p->next, num++ )
|
|
for( auto *p = &rData->vListen->getArray(); p && p->set; p = p->next, num++ )
|
|
{
|
|
{
|