UTheoJansen.pas
上传用户:zkjn0718
上传日期:2021-01-01
资源大小:776k
文件大小:8k
- unit UTheoJansen;
- interface
- {$I ......SourcePhysics2D.inc}
- uses
- UMain, UPhysics2DTypes, UPhysics2D, SysUtils;
- type
- TJansenWalker = class(TTester)
- private
- procedure CreateLeg(s: Float; const wheelAnchor: TVector2);
- public
- m_offset: TVector2;
- m_chassis, m_wheel: Tb2Body;
- m_motorJoint: Tb2RevoluteJoint;
- m_motorOn: Boolean;
- m_motorSpeed: Float;
- constructor Create; override;
- procedure Step(var settings: TSettings; timeStep: Float); override;
- procedure Keyboard(key: Byte); override;
- end;
- implementation
- { TJansenWalker }
- constructor TJansenWalker.Create;
- const
- pivot: TVector2 = (X: 0.0; Y: 0.8);
- var
- i: Integer;
- sd: Tb2PolygonDef;
- bd: Tb2BodyDef;
- cd: Tb2CircleDef;
- ground, body: Tb2Body;
- jd: Tb2RevoluteJointDef;
- wheelAnchor: TVector2;
- begin
- inherited;
- {$IFDEF OP_OVERLOAD}
- m_offset.SetValue(0.0, 8.0);
- {$ELSE}
- SetValue(m_offset, 0.0, 8.0);
- {$ENDIF}
- m_motorSpeed := 2.0;
- m_motorOn := True;
- begin
- sd := Tb2PolygonDef.Create;
- sd.SetAsBox(50.0, 10.0);
- bd := Tb2BodyDef.Create;
- {$IFDEF OP_OVERLOAD}
- bd.position.SetValue(0.0, -10.0);
- {$ELSE}
- SetValue(bd.position, 0.0, -10.0);
- {$ENDIF}
- ground := m_world.CreateBody(bd);
- ground.CreateShape(sd, False);
- sd.SetAsBox(0.5, 5.0, MakeVector(-50.0, 15.0), 0.0);
- ground.CreateShape(sd, False);
- sd.SetAsBox(0.5, 5.0, MakeVector(50.0, 15.0), 0.0);
- ground.CreateShape(sd);
- end;
- for i := 0 to 39 do
- begin
- cd := Tb2CircleDef.Create;
- cd.density := 1.0;
- cd.radius := 0.25;
- bd := Tb2BodyDef.Create;
- {$IFDEF OP_OVERLOAD}
- bd.position.SetValue(-40.0 + 2.0 * i, 0.5);
- {$ELSE}
- SetValue(bd.position, -40.0 + 2.0 * i, 0.5);
- {$ENDIF}
- body := m_world.CreateBody(bd);
- body.CreateShape(cd);
- body.SetMassFromShapes;
- end;
- begin
- sd := Tb2PolygonDef.Create;
- sd.density := 1.0;
- sd.SetAsBox(2.5, 1.0);
- sd.filter.groupIndex := -1;
- bd := Tb2BodyDef.Create;
- {$IFDEF OP_OVERLOAD}
- bd.position := pivot + m_offset;
- {$ELSE}
- bd.position := Add(pivot, m_offset);
- {$ENDIF}
- m_chassis := m_world.CreateBody(bd);
- m_chassis.CreateShape(sd);
- m_chassis.SetMassFromShapes;
- end;
- begin
- cd := Tb2CircleDef.Create;
- cd.density := 1.0;
- cd.radius := 1.6;
- cd.filter.groupIndex := -1;
- bd := Tb2BodyDef.Create;
- {$IFDEF OP_OVERLOAD}
- bd.position := pivot + m_offset;
- {$ELSE}
- bd.position := Add(pivot, m_offset);
- {$ENDIF}
- m_wheel := m_world.CreateBody(bd);
- m_wheel.CreateShape(cd);
- m_wheel.SetMassFromShapes;
- end;
- begin
- jd := Tb2RevoluteJointDef.Create;
- {$IFDEF OP_OVERLOAD}
- jd.Initialize(m_wheel, m_chassis, pivot + m_offset);
- {$ELSE}
- jd.Initialize(m_wheel, m_chassis, Add(pivot, m_offset));
- {$ENDIF}
- jd.collideConnected := false;
- jd.motorSpeed := m_motorSpeed;
- jd.maxMotorTorque := 400.0;
- jd.enableMotor := m_motorOn;
- m_motorJoint := Tb2RevoluteJoint(m_world.CreateJoint(jd));
- end;
- {$IFDEF OP_OVERLOAD}
- wheelAnchor := pivot + MakeVector(0.0, -0.8);
- {$ELSE}
- wheelAnchor := Add(pivot, MakeVector(0.0, -0.8));
- {$ENDIF}
- CreateLeg(-1.0, wheelAnchor);
- CreateLeg(1.0, wheelAnchor);
- m_wheel.SetXForm(m_wheel.GetPosition, 120.0 * Pi / 180.0);
- CreateLeg(-1.0, wheelAnchor);
- CreateLeg(1.0, wheelAnchor);
- m_wheel.SetXForm(m_wheel.GetPosition, -120.0 * Pi / 180.0);
- CreateLeg(-1.0, wheelAnchor);
- CreateLeg(1.0, wheelAnchor);
- end;
- procedure TJansenWalker.CreateLeg(s: Float; const wheelAnchor: TVector2);
- var
- p1, p2, p3, p4, p5, p6: TVector2;
- sd1, sd2: Tb2PolygonDef;
- bd1, bd2: Tb2BodyDef;
- body1, body2: Tb2Body;
- djd: Tb2DistanceJointDef;
- rjd: Tb2RevoluteJointDef;
- begin
- p1 := MakeVector(5.4 * s, -6.1);
- p2 := MakeVector(7.2 * s, -1.2);
- p3 := MakeVector(4.3 * s, -1.9);
- p4 := MakeVector(3.1 * s, 0.8);
- p5 := MakeVector(6.0 * s, 1.5);
- p6 := MakeVector(2.5 * s, 3.7);
- sd1 := Tb2PolygonDef.Create;
- sd2 := Tb2PolygonDef.Create;
- sd1.vertexCount := 3;
- sd2.vertexCount := 3;
- sd1.filter.groupIndex := -1;
- sd2.filter.groupIndex := -1;
- sd1.density := 1.0;
- sd2.density := 1.0;
- if s > 0.0 then
- begin
- sd1.vertices[0] := p1;
- sd1.vertices[1] := p2;
- sd1.vertices[2] := p3;
- sd2.vertices[0] := b2Vec2_zero;
- {$IFDEF OP_OVERLOAD}
- sd2.vertices[1] := p5 - p4;
- sd2.vertices[2] := p6 - p4;
- {$ELSE}
- sd2.vertices[1] := Subtract(p5, p4);
- sd2.vertices[2] := Subtract(p6, p4);
- {$ENDIF}
- end
- else
- begin
- sd1.vertices[0] := p1;
- sd1.vertices[1] := p3;
- sd1.vertices[2] := p2;
- sd2.vertices[0] := b2Vec2_zero;
- {$IFDEF OP_OVERLOAD}
- sd2.vertices[1] := p6 - p4;
- sd2.vertices[2] := p5 - p4;
- {$ELSE}
- sd2.vertices[1] := Subtract(p6, p4);
- sd2.vertices[2] := Subtract(p5, p4);
- {$ENDIF}
- end;
- bd1 := Tb2BodyDef.Create;
- bd2 := Tb2BodyDef.Create;
- bd1.position := m_offset;
- {$IFDEF OP_OVERLOAD}
- bd2.position := p4 + m_offset;
- {$ELSE}
- bd2.position := Add(p4, m_offset);
- {$ENDIF}
- bd1.angularDamping := 10.0;
- bd2.angularDamping := 10.0;
- body1 := m_world.CreateBody(bd1);
- body2 := m_world.CreateBody(bd2);
- body1.CreateShape(sd1);
- body2.CreateShape(sd2);
- body1.SetMassFromShapes;
- body2.SetMassFromShapes;
- djd := Tb2DistanceJointDef.Create;
- {$IFDEF OP_OVERLOAD}
- djd.Initialize(body1, body2, p2 + m_offset, p5 + m_offset);
- {$ELSE}
- djd.Initialize(body1, body2, Add(p2, m_offset), Add(p5, m_offset));
- {$ENDIF}
- m_world.CreateJoint(djd, False);
- {$IFDEF OP_OVERLOAD}
- djd.Initialize(body1, body2, p3 + m_offset, p4 + m_offset);
- {$ELSE}
- djd.Initialize(body1, body2, Add(p3, m_offset), Add(p4, m_offset));
- {$ENDIF}
- m_world.CreateJoint(djd, False);
- {$IFDEF OP_OVERLOAD}
- djd.Initialize(body1, m_wheel, p3 + m_offset, wheelAnchor + m_offset);
- {$ELSE}
- djd.Initialize(body1, m_wheel, Add(p3, m_offset), Add(wheelAnchor, m_offset));
- {$ENDIF}
- m_world.CreateJoint(djd, False);
- {$IFDEF OP_OVERLOAD}
- djd.Initialize(body2, m_wheel, p6 + m_offset, wheelAnchor + m_offset);
- {$ELSE}
- djd.Initialize(body2, m_wheel, Add(p6, m_offset), Add(wheelAnchor, m_offset));
- {$ENDIF}
- m_world.CreateJoint(djd);
- rjd := Tb2RevoluteJointDef.Create;
- {$IFDEF OP_OVERLOAD}
- rjd.Initialize(body2, m_chassis, p4 + m_offset);
- {$ELSE}
- rjd.Initialize(body2, m_chassis, Add(p4, m_offset));
- {$ENDIF}
- m_world.CreateJoint(rjd);
- end;
- procedure TJansenWalker.Step(var settings: TSettings; timeStep: Float);
- begin
- inherited;
- DrawText('Keys: left = A, brake = S, right = D, toggle motor = M');
- end;
- procedure TJansenWalker.Keyboard(key: Byte);
- begin
- case key of
- 65{A}:
- begin
- m_chassis.WakeUp;
- m_motorJoint.m_motorSpeed := -m_motorSpeed;
- end;
- 83{S}:
- begin
- m_chassis.WakeUp;
- m_motorJoint.m_motorSpeed := 0.0;
- end;
- 68{D}:
- begin
- m_chassis.WakeUp;
- m_motorJoint.m_motorSpeed := m_motorSpeed;
- end;
- 77{M}:
- begin
- m_chassis.WakeUp;
- m_motorJoint.MotorEnabled := not m_motorJoint.MotorEnabled;
- end;
- end;
- end;
- initialization
- RegisterTestEntry('Theo Jansen''s Walker', TJansenWalker);
- end.