1 | #pragma once
|
---|
2 |
|
---|
3 |
|
---|
4 | #include "dxstdafx.h"
|
---|
5 | #include "d3ddefs.h"
|
---|
6 | #include <cstdio>
|
---|
7 | #include <ctime>
|
---|
8 | #include <ostream>
|
---|
9 | #include <cstdlib>
|
---|
10 | #include "vector4d.h"
|
---|
11 | #include "color.h"
|
---|
12 | #include "object.h"
|
---|
13 |
|
---|
14 |
|
---|
15 | ObjectModel::ObjectModel() {
|
---|
16 | this->offset=0;
|
---|
17 | nvertices = ntexcoords = ntriangles = 0;
|
---|
18 | device=NULL;
|
---|
19 | loaded=false;
|
---|
20 | vertexRotationClockwise=true;
|
---|
21 | vertexDeclarationCreated=false;
|
---|
22 | modelVertices=NULL;
|
---|
23 | vertexBuffer=NULL;
|
---|
24 | logFile=NULL;
|
---|
25 | decl=NULL;
|
---|
26 | D3DXMatrixIdentity(&transformMatrix);
|
---|
27 | }
|
---|
28 |
|
---|
29 | ObjectModel::ObjectModel(int offset) {
|
---|
30 | this->offset=offset;
|
---|
31 | nvertices = ntexcoords = ntriangles = 0;
|
---|
32 | device=NULL;
|
---|
33 | vertexBuffer=NULL;
|
---|
34 | loaded=false;
|
---|
35 | modelVertices=NULL;
|
---|
36 | logFile=NULL;
|
---|
37 | decl=NULL;
|
---|
38 | D3DXMatrixIdentity(&transformMatrix);
|
---|
39 | }
|
---|
40 |
|
---|
41 | ObjectModel::~ObjectModel( ) {
|
---|
42 | SAFE_RELEASE(decl);
|
---|
43 | SAFE_RELEASE(vertexBuffer)
|
---|
44 | if(modelVertices!=NULL){
|
---|
45 | GlobalFree((HGLOBAL)modelVertices);
|
---|
46 | }
|
---|
47 | SAFE_DELETE(logFile);
|
---|
48 | }
|
---|
49 |
|
---|
50 | HRESULT ObjectModel::Render(bool renderToAtlas){
|
---|
51 | HRESULT hr;
|
---|
52 | if(!isLoaded()){
|
---|
53 | return E_FAIL;
|
---|
54 | }
|
---|
55 | V_RETURN(device->SetVertexDeclaration(this->decl))
|
---|
56 | if(renderToAtlas){
|
---|
57 | if(this->isVertexRotationClockwise()){
|
---|
58 | V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE))
|
---|
59 | }
|
---|
60 | else{
|
---|
61 | V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_NONE))
|
---|
62 | }
|
---|
63 | }
|
---|
64 | else{
|
---|
65 | V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW))
|
---|
66 | }
|
---|
67 | V_RETURN(this->device->SetStreamSource(0,vertexBuffer,0,sizeof(D3DVERTEX_MODEL)))
|
---|
68 | V_RETURN(this->device->DrawPrimitive(D3DPT_TRIANGLELIST,0,ntriangles))
|
---|
69 | return hr;
|
---|
70 | }
|
---|
71 |
|
---|
72 | HRESULT ObjectModel::RenderWithFX(LPD3DXEFFECT m_pEffect,bool renderToAtlas,D3DXMATRIX modelview,D3DXMATRIX modelviewproj){
|
---|
73 | HRESULT hr;
|
---|
74 | if(m_pEffect==NULL){
|
---|
75 | return E_POINTER;
|
---|
76 | }
|
---|
77 | if(!isLoaded()){
|
---|
78 | return E_FAIL;
|
---|
79 | }
|
---|
80 | V_RETURN(device->SetVertexDeclaration(this->decl))
|
---|
81 | if(renderToAtlas){
|
---|
82 | if(this->isVertexRotationClockwise()){
|
---|
83 | V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_CCW))
|
---|
84 | }
|
---|
85 | else{
|
---|
86 | V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW))
|
---|
87 | }
|
---|
88 | }
|
---|
89 | else{
|
---|
90 | V_RETURN(device->SetRenderState(D3DRS_CULLMODE,D3DCULL_CW))
|
---|
91 | }
|
---|
92 | D3DXMATRIX mw;
|
---|
93 | D3DXMATRIX mwp;
|
---|
94 | D3DXMATRIX inverseWorldMatrix;
|
---|
95 | D3DXMatrixIdentity(&mw);
|
---|
96 | D3DXMatrixIdentity(&mwp);
|
---|
97 | D3DXMatrixIdentity(&inverseWorldMatrix);
|
---|
98 | D3DXMatrixMultiply(&mw,&transformMatrix,&modelview);
|
---|
99 | D3DXMatrixMultiply(&mwp,&transformMatrix,&modelviewproj);
|
---|
100 | D3DXMatrixInverse(&inverseWorldMatrix,NULL,&mw);
|
---|
101 | V_RETURN(m_pEffect->SetMatrix("modelview",&mw))
|
---|
102 | V_RETURN(m_pEffect->SetMatrix("modelviewproj",&mwp))
|
---|
103 | V_RETURN(m_pEffect->SetMatrixTranspose("modelviewIT",&inverseWorldMatrix))
|
---|
104 | V_RETURN(this->device->SetStreamSource(0,vertexBuffer,0,sizeof(D3DVERTEX_MODEL)))
|
---|
105 | V_RETURN(m_pEffect->CommitChanges())
|
---|
106 | V_RETURN(this->device->DrawPrimitive(D3DPT_TRIANGLELIST,0,ntriangles))
|
---|
107 | return S_OK;
|
---|
108 | }
|
---|
109 |
|
---|
110 | void ObjectModel::AddVertex( float x, float y, float z ) { vertices[nvertices++] = Vector(x, y, z); }
|
---|
111 | void ObjectModel::AddTexCoord( float u, float v ) { texcoords[ntexcoords++] = Vector(u, v, 0); }
|
---|
112 | void ObjectModel::AddTriangle( int i1, int t1, int i2, int t2, int i3, int t3 ) {
|
---|
113 | triangles[ntriangles++] = Triangle(i1, t1, i2, t2, i3, t3);
|
---|
114 | }
|
---|
115 |
|
---|
116 | HRESULT ObjectModel::initDeviceObjects(LPDIRECT3DDEVICE9 device){
|
---|
117 | HRESULT hr;
|
---|
118 | if(!isLoaded()){
|
---|
119 | return E_FAIL;
|
---|
120 | }
|
---|
121 | this->device=device;
|
---|
122 | D3DVERTEXELEMENT9 _decl[]=
|
---|
123 | {
|
---|
124 | {0,0,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,0 },
|
---|
125 | {0,16,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,0 },
|
---|
126 | {0,32,D3DDECLTYPE_FLOAT2, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,0 },
|
---|
127 | {0,40,D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,1 },
|
---|
128 | {0,52,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD,2 },
|
---|
129 | {0,68,D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,0 },
|
---|
130 | D3DDECL_END()
|
---|
131 | };
|
---|
132 | hr=device->CreateVertexDeclaration(_decl,&decl);
|
---|
133 | this->CreateD3DVertices();
|
---|
134 | V_RETURN(device->CreateVertexBuffer(sizeof(D3DVERTEX_MODEL)*ntriangles*3,D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX_MODEL,D3DPOOL_MANAGED,&vertexBuffer,NULL));
|
---|
135 | void* pData;
|
---|
136 | vertexBuffer->Lock(0,sizeof(pData),(void**)&pData,0);
|
---|
137 | memcpy(pData,getModelVertices(),sizeof(D3DVERTEX_MODEL)*ntriangles*3);
|
---|
138 | vertexBuffer->Unlock();
|
---|
139 | return hr;
|
---|
140 | }
|
---|
141 |
|
---|
142 | HRESULT ObjectModel::resetDeviceObjects(LPDIRECT3DDEVICE9 device){
|
---|
143 | HRESULT hr;
|
---|
144 | if(!isLoaded()){
|
---|
145 | return E_FAIL;
|
---|
146 | }
|
---|
147 | SAFE_RELEASE(vertexBuffer);
|
---|
148 | SAFE_RELEASE(decl);
|
---|
149 | this->device=device;
|
---|
150 | V_RETURN(device->CreateVertexBuffer(sizeof(D3DVERTEX_MODEL)*ntriangles*3,D3DUSAGE_WRITEONLY,D3DFVF_CUSTOMVERTEX_MODEL,D3DPOOL_MANAGED,&vertexBuffer,NULL));
|
---|
151 | void* pData;
|
---|
152 | vertexBuffer->Lock(0,sizeof(pData),(void**)&pData,0);
|
---|
153 | memcpy(pData,getModelVertices(),sizeof(D3DVERTEX_MODEL)*ntriangles*3);
|
---|
154 | vertexBuffer->Unlock();
|
---|
155 | return hr;
|
---|
156 | }
|
---|
157 |
|
---|
158 |
|
---|
159 | D3DVERTEX_MODEL* ObjectModel::getModelVertices(){
|
---|
160 | return(modelVertices);
|
---|
161 | }
|
---|
162 |
|
---|
163 | bool ObjectModel::isVertexRotationClockwise(){
|
---|
164 | return this->vertexRotationClockwise;
|
---|
165 | }
|
---|
166 |
|
---|
167 | bool ObjectModel::isLoaded(){
|
---|
168 | return loaded;
|
---|
169 | }
|
---|
170 |
|
---|
171 | void ObjectModel::CreateD3DVertices(){
|
---|
172 | if(loaded){
|
---|
173 | modelVertices=(D3DVERTEX_MODEL*)GlobalAlloc(GPTR,ntriangles*3*sizeof(D3DVERTEX_MODEL));
|
---|
174 | for(int i = 0; i < ntriangles; i++) {
|
---|
175 | for(int j = 0; j < 3; j++) {
|
---|
176 | if(j==0){ //Vertex v0 is passed to D3D vertex v0.
|
---|
177 | modelVertices[i*3+j].fX=vertices[triangles[i].v[j]].x;
|
---|
178 | modelVertices[i*3+j].fY=vertices[triangles[i].v[j]].y;
|
---|
179 | modelVertices[i*3+j].fZ=vertices[triangles[i].v[j]].z;
|
---|
180 | modelVertices[i*3+j].u1=texcoords[triangles[i].t[j]].x;
|
---|
181 | modelVertices[i*3+j].v1=texcoords[triangles[i].t[j]].y;
|
---|
182 | }
|
---|
183 | if(j==1){ //Vertex v2 is passed to D3D vertex v1.
|
---|
184 | modelVertices[i*3+j].fX=vertices[triangles[i].v[j+1]].x;
|
---|
185 | modelVertices[i*3+j].fY=vertices[triangles[i].v[j+1]].y;
|
---|
186 | modelVertices[i*3+j].fZ=vertices[triangles[i].v[j+1]].z;
|
---|
187 | modelVertices[i*3+j].u1=texcoords[triangles[i].t[j+1]].x;
|
---|
188 | modelVertices[i*3+j].v1=texcoords[triangles[i].t[j+1]].y;
|
---|
189 | }
|
---|
190 | if(j==2){ //Vertex v1 is passed to D3D vertex v2.
|
---|
191 | modelVertices[i*3+j].fX=vertices[triangles[i].v[j-1]].x;
|
---|
192 | modelVertices[i*3+j].fY=vertices[triangles[i].v[j-1]].y;
|
---|
193 | modelVertices[i*3+j].fZ=vertices[triangles[i].v[j-1]].z;
|
---|
194 | modelVertices[i*3+j].u1=texcoords[triangles[i].t[j-1]].x;
|
---|
195 | modelVertices[i*3+j].v1=texcoords[triangles[i].t[j-1]].y;
|
---|
196 | }
|
---|
197 | modelVertices[i*3+j].fW=1.0f;
|
---|
198 | /*
|
---|
199 | modelVertices[i*3+j].colorRGBr=(float)RED(i+offset)/255.0f;
|
---|
200 | modelVertices[i*3+j].colorRGBg=(float)GREEN(i+offset)/255.0f;
|
---|
201 | modelVertices[i*3+j].colorRGBb=(float)BLUE(i+offset)/255.0f;
|
---|
202 | */
|
---|
203 | modelVertices[i*3+j].colorRGBr=(float)i+offset;
|
---|
204 | modelVertices[i*3+j].colorRGBa=0.0f;
|
---|
205 | modelVertices[i*3+j].nX=triangles[i].normal.x;
|
---|
206 | modelVertices[i*3+j].nY=triangles[i].normal.y;
|
---|
207 | modelVertices[i*3+j].nZ=triangles[i].normal.z;
|
---|
208 | modelVertices[i*3+j].nW=1.0f;
|
---|
209 | modelVertices[i*3+j].u2=triangles[i].BRDF.R;
|
---|
210 | modelVertices[i*3+j].v2=triangles[i].BRDF.G;
|
---|
211 | modelVertices[i*3+j].w2=triangles[i].BRDF.B;
|
---|
212 | modelVertices[i*3+j].u3=triangles[i].emission.R;
|
---|
213 | modelVertices[i*3+j].v3=triangles[i].emission.G;
|
---|
214 | modelVertices[i*3+j].w3=triangles[i].emission.B;
|
---|
215 | modelVertices[i*3+j].a3=triangles[i].area/triangles[i].texarea;
|
---|
216 | }
|
---|
217 | }
|
---|
218 | this->vertexDeclarationCreated=true;
|
---|
219 | }
|
---|
220 | }
|
---|
221 |
|
---|
222 | void ObjectModel::Load( char * fname, bool ccw, bool cw, bool islight, float su, float sv, float ou, float ov ) {
|
---|
223 | this->vertexRotationClockwise=cw;
|
---|
224 | FILE * ifile = fopen(fname, "r");
|
---|
225 | if ( !ifile ) return;
|
---|
226 | char buffer[80];
|
---|
227 | if (!fgets(buffer, 80, ifile)) return;
|
---|
228 |
|
---|
229 | int match;
|
---|
230 | int i=0;
|
---|
231 | for( ; ; ) {
|
---|
232 | char tempc=0;
|
---|
233 | if(sscanf(buffer,"%c",&tempc)){
|
---|
234 | while((tempc!='v')&&(tempc!='f')){
|
---|
235 | if (!fgets(buffer, 80, ifile)) return;
|
---|
236 | sscanf(buffer,"%c",&tempc);
|
---|
237 | }
|
---|
238 | }
|
---|
239 |
|
---|
240 | float x, y, z;
|
---|
241 | match = sscanf(buffer, "v %f %f %f\n", &x, &y, &z);
|
---|
242 | if (match != 3)
|
---|
243 | break;
|
---|
244 | AddVertex(x, y, z);
|
---|
245 | if (!fgets(buffer, 80, ifile)) return;
|
---|
246 | i++;
|
---|
247 | }
|
---|
248 | float maxu = -1, maxv = -1, minu = 1, minv = 1;
|
---|
249 | for( ; ; ) {
|
---|
250 | char tempc=0;
|
---|
251 | if(sscanf(buffer,"%c",&tempc)){
|
---|
252 | while((tempc!='v')&&(tempc!='f')){
|
---|
253 | if (!fgets(buffer, 80, ifile)) return;
|
---|
254 | sscanf(buffer,"%c",&tempc);
|
---|
255 | }
|
---|
256 | }
|
---|
257 | float u, v, w;
|
---|
258 | match = sscanf(buffer, "vt %f %f %f\n", &u, &v, &w);
|
---|
259 | if (match != 3){
|
---|
260 | match = sscanf(buffer, "vt %f %f\n", &u, &v);
|
---|
261 | if (match != 2)
|
---|
262 | break;
|
---|
263 | }
|
---|
264 |
|
---|
265 | if (maxu < u) maxu = u;
|
---|
266 | if (maxv < v) maxv = v;
|
---|
267 | if (minu > u) minu = u;
|
---|
268 | if (minv > v) minv = v;
|
---|
269 | AddTexCoord(u, v);
|
---|
270 | if (!fgets(buffer, 80, ifile))
|
---|
271 | return;
|
---|
272 | }
|
---|
273 | for(int i = 0; i < ntexcoords; i++) {
|
---|
274 | texcoords[i].x = (texcoords[i].x - minu)/(maxu - minu) * su + ou;
|
---|
275 | texcoords[i].y = (texcoords[i].y - minv)/(maxv - minv) * sv + ov;
|
---|
276 | }
|
---|
277 | int c=0;
|
---|
278 | for( ; ; ) {
|
---|
279 | int i1, t1, i2, t2, i3, t3;
|
---|
280 | char tempc=0;
|
---|
281 | if(sscanf(buffer,"%c",&tempc)){
|
---|
282 | while((tempc!='v')&&(tempc!='f')){
|
---|
283 | if (!fgets(buffer, 80, ifile)) return;
|
---|
284 | sscanf(buffer,"%c",&tempc);
|
---|
285 | }
|
---|
286 | }
|
---|
287 | match = sscanf(buffer, "f %i/%i %i/%i %i/%i\n", &i1, &t1, &i2, &t2, &i3, &t3);
|
---|
288 | if (match != 6)
|
---|
289 | break;
|
---|
290 | AddTriangle(i1-1, t1-1, i2-1, t2-1, i3-1, t3-1);
|
---|
291 | Triangle& triang = triangles[ntriangles-1];
|
---|
292 | Vector& v1 = vertices[ triang.v[0] ],
|
---|
293 | v2 = vertices[ triang.v[1] ],
|
---|
294 | v3 = vertices[ triang.v[2] ];
|
---|
295 | triang.center = (v1 + v2 + v3)/3;
|
---|
296 | triang.normal = (ccw) ? (v2 - v1) % (v3 - v1) : (v3 - v1) % (v2 - v1);
|
---|
297 | triang.area = triang.normal.Length()/2;
|
---|
298 | triang.normal.Normalize();
|
---|
299 | triang.up = (v3 - v1) % triang.normal;
|
---|
300 |
|
---|
301 | Vector& tp1 = texcoords[ triang.t[0] ],
|
---|
302 | tp2 = texcoords[ triang.t[1] ],
|
---|
303 | tp3 = texcoords[ triang.t[2] ];
|
---|
304 | Vector tnormal = (tp2 - tp1) % (tp3 - tp1);
|
---|
305 | triang.texarea = tnormal.Length()/2;
|
---|
306 |
|
---|
307 | triang.BRDF = Color(0.74f/M_PI, 0.73f/M_PI, 0.34f/M_PI);
|
---|
308 | triang.emission = Color(0.0f, 0.0f, 0.0f);
|
---|
309 |
|
---|
310 | if(strcmp("boxl6.obj",fname)==0){
|
---|
311 | if(triang.normal.x>0.9){
|
---|
312 | triang.BRDF = Color(0.64f/M_PI, 0.06f/M_PI, 0.04f/M_PI);
|
---|
313 | }
|
---|
314 | if(triang.normal.x<-0.9){
|
---|
315 | triang.BRDF = Color(0.34f/M_PI, 0.57f/M_PI, 0.69f/M_PI);
|
---|
316 | }
|
---|
317 |
|
---|
318 | }
|
---|
319 |
|
---|
320 | /*
|
---|
321 | if(strcmp("boxl6.obj",fname)==0){
|
---|
322 | triang.BRDF=Color(0.9f/M_PI,0.9f/M_PI,0.9f/M_PI);
|
---|
323 | triang.emission = Color(0.1f, 0.1f, 0.1f);
|
---|
324 | }
|
---|
325 | */
|
---|
326 | if(strcmp("kiskocka6.obj",fname)==0){
|
---|
327 | triang.BRDF = Color(0.74f/M_PI, 0.73f/M_PI, 0.34f/M_PI);
|
---|
328 | }
|
---|
329 | if(strcmp("light.obj",fname)==0){
|
---|
330 | triang.BRDF = Color(0.74f/M_PI, 0.73f/M_PI, 0.34f/M_PI);
|
---|
331 | if(triang.normal.y<-0.9){
|
---|
332 | triang.emission = Color(20.0f, 20.0f, 20.0f);
|
---|
333 | }
|
---|
334 | }
|
---|
335 |
|
---|
336 |
|
---|
337 | /*
|
---|
338 | if (islight && (ntriangles == 2291) ){ //1500
|
---|
339 | triang.emission = Color(250,250,250);
|
---|
340 | }
|
---|
341 | if (islight && (ntriangles == 2292) ){ //1500
|
---|
342 | triang.emission = Color(250,250,250);
|
---|
343 | }
|
---|
344 | */
|
---|
345 | /*
|
---|
346 | if (islight && (ntriangles == 509) ){ //1500
|
---|
347 | triang.emission = Color(250,250,250);
|
---|
348 | }
|
---|
349 |
|
---|
350 | if (islight && (ntriangles == 510) ){ //1500
|
---|
351 | triang.emission = Color(250,250,250);
|
---|
352 | }
|
---|
353 |
|
---|
354 | if (islight && (ntriangles == 2399) ){ //1500
|
---|
355 | triang.emission = Color(250,250,250);
|
---|
356 | }
|
---|
357 | if (islight && (ntriangles == 2400) ){ //1500
|
---|
358 | triang.emission = Color(250,250,250);
|
---|
359 | }
|
---|
360 | */
|
---|
361 |
|
---|
362 | if (!fgets(buffer, 80, ifile))
|
---|
363 | break;
|
---|
364 | }
|
---|
365 | surface_area = texsurface_area = 0;
|
---|
366 | for(int i = 0; i < ntriangles; i++) {
|
---|
367 | surface_area += triangles[i].area;
|
---|
368 | texsurface_area += triangles[i].texarea;
|
---|
369 | }
|
---|
370 |
|
---|
371 | loaded=true;
|
---|
372 | }
|
---|
373 |
|
---|
374 |
|
---|
375 |
|
---|
376 | void ObjectModel::GetCenterTriangle( int i, Vector& center, Vector& normal, Vector& up ) {
|
---|
377 | if(i>=ntriangles||i>=MAXTRIANGLES||i<0){
|
---|
378 | return;
|
---|
379 | }
|
---|
380 | /*
|
---|
381 | logFile=fopen("log2.txt","a+" );
|
---|
382 | fprintf(logFile,"Shooter triangle index: %i \n Ntriangles %i\n",i,ntriangles);
|
---|
383 | fclose(logFile);
|
---|
384 | */
|
---|
385 | center = triangles[i].center;
|
---|
386 | normal = triangles[i].normal;
|
---|
387 | up = triangles[i].up;
|
---|
388 | } |
---|